mirror of
https://github.com/coder/coder.git
synced 2026-09-22 05:05:20 +08:00
chore: cleaning up workspaces table code (#2765)
* cleaning up workspace table code * Update site/src/components/WorkspacesTable/WorkspacesTableBody.tsx Co-authored-by: Joe Previte <jjprevite@gmail.com> Co-authored-by: Joe Previte <jjprevite@gmail.com>
This commit is contained in:
co-authored by
Joe Previte
parent
29be359f3d
commit
ae59f166fd
@@ -0,0 +1 @@
|
||||
export * from "./HelpTooltip"
|
||||
@@ -0,0 +1,33 @@
|
||||
import RefreshIcon from "@material-ui/icons/Refresh"
|
||||
import { FC } from "react"
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipAction,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "./HelpTooltip"
|
||||
|
||||
const Language = {
|
||||
outdatedLabel: "Outdated",
|
||||
versionTooltipText: "This workspace version is outdated and a newer version is available.",
|
||||
updateVersionLabel: "Update version",
|
||||
}
|
||||
|
||||
interface TooltipProps {
|
||||
onUpdateVersion: () => void
|
||||
}
|
||||
|
||||
export const OutdatedHelpTooltip: FC<TooltipProps> = ({ onUpdateVersion }) => {
|
||||
return (
|
||||
<HelpTooltip size="small">
|
||||
<HelpTooltipTitle>{Language.outdatedLabel}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.versionTooltipText}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipAction icon={RefreshIcon} onClick={onUpdateVersion}>
|
||||
{Language.updateVersionLabel}
|
||||
</HelpTooltipAction>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltip>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { FC } from "react"
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "./HelpTooltip"
|
||||
|
||||
const Language = {
|
||||
workspaceTooltipTitle: "What is a workspace?",
|
||||
workspaceTooltipText:
|
||||
"A workspace is your development environment in the cloud. It includes the infrastructure and tools you need to work on your project.",
|
||||
workspaceTooltipLink1: "Create workspaces",
|
||||
workspaceTooltipLink2: "Connect with SSH",
|
||||
workspaceTooltipLink3: "Editors and IDEs",
|
||||
}
|
||||
|
||||
export const WorkspaceHelpTooltip: FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipTitle>{Language.workspaceTooltipTitle}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.workspaceTooltipText}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/blob/main/docs/workspaces.md#create-workspaces">
|
||||
{Language.workspaceTooltipLink1}
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/blob/main/docs/workspaces.md#connect-with-ssh">
|
||||
{Language.workspaceTooltipLink2}
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/blob/main/docs/workspaces.md#editors-and-ides">
|
||||
{Language.workspaceTooltipLink3}
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltip>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export { AgentHelpTooltip } from "./AgentHelpTooltip"
|
||||
export { OutdatedHelpTooltip } from "./OutdatedHelpTooltip"
|
||||
export { ResourcesHelpTooltip } from "./ResourcesHelpTooltip"
|
||||
export { WorkspaceHelpTooltip } from "./WorkspaceHelpTooltip"
|
||||
@@ -47,7 +47,7 @@ export const UsersTableBody: FC<UsersTableBodyProps> = ({
|
||||
return <TableLoader />
|
||||
}
|
||||
|
||||
if (!users || users.length === 0) {
|
||||
if (!users || !users.length) {
|
||||
return (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
import { fade, makeStyles, Theme } from "@material-ui/core/styles"
|
||||
import TableRow from "@material-ui/core/TableRow"
|
||||
import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight"
|
||||
import useTheme from "@material-ui/styles/useTheme"
|
||||
import { useActor } from "@xstate/react"
|
||||
import dayjs from "dayjs"
|
||||
import relativeTime from "dayjs/plugin/relativeTime"
|
||||
import { FC } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { getDisplayStatus } from "../../util/workspace"
|
||||
import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService"
|
||||
import { AvatarData } from "../AvatarData/AvatarData"
|
||||
import { TableCellLink } from "../TableCellLink/TableCellLink"
|
||||
import { OutdatedHelpTooltip } from "../Tooltips"
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
const Language = {
|
||||
upToDateLabel: "Up to date",
|
||||
outdatedLabel: "Outdated",
|
||||
}
|
||||
|
||||
export const WorkspacesRow: FC<{ workspaceRef: WorkspaceItemMachineRef }> = ({ workspaceRef }) => {
|
||||
const styles = useStyles()
|
||||
const navigate = useNavigate()
|
||||
const theme: Theme = useTheme()
|
||||
const [workspaceState, send] = useActor(workspaceRef)
|
||||
const { data: workspace } = workspaceState.context
|
||||
const status = getDisplayStatus(theme, workspace.latest_build)
|
||||
const workspacePageLink = `/@${workspace.owner_name}/${workspace.name}`
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
hover
|
||||
data-testid={`workspace-${workspace.id}`}
|
||||
tabIndex={0}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
navigate(workspacePageLink)
|
||||
}
|
||||
}}
|
||||
className={styles.clickableTableRow}
|
||||
>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<AvatarData title={workspace.name} subtitle={workspace.owner_name} />
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>{workspace.template_name}</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
{workspace.outdated ? (
|
||||
<span className={styles.outdatedLabel}>
|
||||
{Language.outdatedLabel}
|
||||
<OutdatedHelpTooltip
|
||||
onUpdateVersion={() => {
|
||||
send("UPDATE_VERSION")
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
<span style={{ color: theme.palette.text.secondary }}>{Language.upToDateLabel}</span>
|
||||
)}
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<span data-chromatic="ignore" style={{ color: theme.palette.text.secondary }}>
|
||||
{dayjs().to(dayjs(workspace.latest_build.created_at))}
|
||||
</span>
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<span style={{ color: status.color }}>{status.status}</span>
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<div className={styles.arrowCell}>
|
||||
<KeyboardArrowRight className={styles.arrowRight} />
|
||||
</div>
|
||||
</TableCellLink>
|
||||
</TableRow>
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
clickableTableRow: {
|
||||
"&:hover td": {
|
||||
backgroundColor: fade(theme.palette.primary.light, 0.1),
|
||||
},
|
||||
|
||||
"&:focus": {
|
||||
outline: `1px solid ${theme.palette.secondary.dark}`,
|
||||
},
|
||||
|
||||
"& .MuiTableCell-root:last-child": {
|
||||
paddingRight: theme.spacing(2),
|
||||
},
|
||||
},
|
||||
arrowRight: {
|
||||
color: fade(theme.palette.primary.contrastText, 0.7),
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
arrowCell: {
|
||||
display: "flex",
|
||||
},
|
||||
outdatedLabel: {
|
||||
color: theme.palette.error.main,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: theme.spacing(0.5),
|
||||
},
|
||||
}))
|
||||
@@ -0,0 +1,42 @@
|
||||
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 { FC } from "react"
|
||||
import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService"
|
||||
import { WorkspacesTableBody } from "./WorkspacesTableBody"
|
||||
|
||||
const Language = {
|
||||
name: "Name",
|
||||
template: "Template",
|
||||
version: "Version",
|
||||
lastBuilt: "Last Built",
|
||||
status: "Status",
|
||||
}
|
||||
|
||||
export interface WorkspacesTableProps {
|
||||
isLoading?: boolean
|
||||
workspaceRefs?: WorkspaceItemMachineRef[]
|
||||
filter?: string
|
||||
}
|
||||
|
||||
export const WorkspacesTable: FC<WorkspacesTableProps> = ({ isLoading, workspaceRefs, filter }) => {
|
||||
return (
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell width="35%">{Language.name}</TableCell>
|
||||
<TableCell width="15%">{Language.template}</TableCell>
|
||||
<TableCell width="15%">{Language.version}</TableCell>
|
||||
<TableCell width="20%">{Language.lastBuilt}</TableCell>
|
||||
<TableCell width="15%">{Language.status}</TableCell>
|
||||
<TableCell width="1%"></TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<WorkspacesTableBody isLoading={isLoading} workspaceRefs={workspaceRefs} filter={filter} />
|
||||
</TableBody>
|
||||
</Table>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import Button from "@material-ui/core/Button"
|
||||
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 { FC } from "react"
|
||||
import { Link as RouterLink } from "react-router-dom"
|
||||
import { workspaceFilterQuery } from "../../util/filters"
|
||||
import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService"
|
||||
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
|
||||
}
|
||||
|
||||
export const WorkspacesTableBody: FC<TableBodyProps> = ({ isLoading, workspaceRefs, filter }) => {
|
||||
if (isLoading) {
|
||||
return <TableLoader />
|
||||
}
|
||||
|
||||
if (!workspaceRefs || !workspaceRefs.length) {
|
||||
return (
|
||||
<>
|
||||
{filter === workspaceFilterQuery.me || filter === workspaceFilterQuery.all ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message={Language.emptyCreateWorkspaceMessage}
|
||||
description={Language.emptyCreateWorkspaceDescription}
|
||||
cta={
|
||||
<Link underline="none" component={RouterLink} to="/templates">
|
||||
<Button startIcon={<AddCircleOutline />}>
|
||||
{Language.createFromTemplateButton}
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState message={Language.emptyResultsMessage} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{workspaceRefs.map((workspaceRef) => (
|
||||
<WorkspacesRow workspaceRef={workspaceRef} key={workspaceRef.id} />
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -64,7 +64,7 @@ export const UsersPageView: FC<UsersPageViewProps> = ({
|
||||
) : undefined
|
||||
}
|
||||
>
|
||||
<PageHeaderTitle>Users</PageHeaderTitle>
|
||||
<PageHeaderTitle>{Language.pageTitle}</PageHeaderTitle>
|
||||
</PageHeader>
|
||||
|
||||
<SearchBarWithFilter
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import { rest } from "msw"
|
||||
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 { Language } from "./WorkspacesPageView"
|
||||
|
||||
describe("WorkspacesPage", () => {
|
||||
beforeEach(() => {
|
||||
@@ -23,7 +23,7 @@ describe("WorkspacesPage", () => {
|
||||
render(<WorkspacesPage />)
|
||||
|
||||
// Then
|
||||
await screen.findByText(Language.emptyCreateWorkspaceMessage)
|
||||
await screen.findByText(WorkspacesTableBodyLanguage.emptyCreateWorkspaceMessage)
|
||||
})
|
||||
|
||||
it("renders a filled workspaces page", async () => {
|
||||
|
||||
@@ -32,7 +32,7 @@ const WorkspacesPage: FC = () => {
|
||||
|
||||
<WorkspacesPageView
|
||||
filter={workspacesState.context.filter}
|
||||
loading={workspacesState.hasTag("loading")}
|
||||
isLoading={workspacesState.hasTag("loading")}
|
||||
workspaceRefs={workspaceRefs}
|
||||
onFilter={(query) => {
|
||||
setSearchParams({ filter: query })
|
||||
|
||||
@@ -1,22 +1,6 @@
|
||||
import Button from "@material-ui/core/Button"
|
||||
import Link from "@material-ui/core/Link"
|
||||
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 AddCircleOutline from "@material-ui/icons/AddCircleOutline"
|
||||
import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight"
|
||||
import RefreshIcon from "@material-ui/icons/Refresh"
|
||||
import useTheme from "@material-ui/styles/useTheme"
|
||||
import { useActor } from "@xstate/react"
|
||||
import dayjs from "dayjs"
|
||||
import relativeTime from "dayjs/plugin/relativeTime"
|
||||
import { FC } from "react"
|
||||
import { Link as RouterLink, useNavigate } from "react-router-dom"
|
||||
import { AvatarData } from "../../components/AvatarData/AvatarData"
|
||||
import { EmptyState } from "../../components/EmptyState/EmptyState"
|
||||
import { Link as RouterLink } from "react-router-dom"
|
||||
import { Margins } from "../../components/Margins/Margins"
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -25,140 +9,28 @@ import {
|
||||
} 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"
|
||||
import {
|
||||
HelpTooltip,
|
||||
HelpTooltipAction,
|
||||
HelpTooltipLink,
|
||||
HelpTooltipLinksGroup,
|
||||
HelpTooltipText,
|
||||
HelpTooltipTitle,
|
||||
} from "../../components/Tooltips/HelpTooltip/HelpTooltip"
|
||||
import { WorkspaceHelpTooltip } from "../../components/Tooltips"
|
||||
import { WorkspacesTable } from "../../components/WorkspacesTable/WorkspacesTable"
|
||||
import { workspaceFilterQuery } from "../../util/filters"
|
||||
import { getDisplayStatus } from "../../util/workspace"
|
||||
import { WorkspaceItemMachineRef } from "../../xServices/workspaces/workspacesXService"
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
export const Language = {
|
||||
createFromTemplateButton: "Create from template",
|
||||
emptyCreateWorkspaceMessage: "Create your first workspace",
|
||||
emptyCreateWorkspaceDescription: "Start editing your source code and building your software",
|
||||
emptyResultsMessage: "No results matched your search",
|
||||
pageTitle: "Workspaces",
|
||||
yourWorkspacesButton: "Your workspaces",
|
||||
allWorkspacesButton: "All workspaces",
|
||||
workspaceTooltipTitle: "What is a workspace?",
|
||||
workspaceTooltipText:
|
||||
"A workspace is your development environment in the cloud. It includes the infrastructure and tools you need to work on your project.",
|
||||
workspaceTooltipLink1: "Create workspaces",
|
||||
workspaceTooltipLink2: "Connect with SSH",
|
||||
workspaceTooltipLink3: "Editors and IDEs",
|
||||
outdatedLabel: "Outdated",
|
||||
upToDateLabel: "Up to date",
|
||||
versionTooltipText: "This workspace version is outdated and a newer version is available.",
|
||||
updateVersionLabel: "Update version",
|
||||
}
|
||||
|
||||
const WorkspaceHelpTooltip: React.FC = () => {
|
||||
return (
|
||||
<HelpTooltip>
|
||||
<HelpTooltipTitle>{Language.workspaceTooltipTitle}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.workspaceTooltipText}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/blob/main/docs/workspaces.md#create-workspaces">
|
||||
{Language.workspaceTooltipLink1}
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/blob/main/docs/workspaces.md#connect-with-ssh">
|
||||
{Language.workspaceTooltipLink2}
|
||||
</HelpTooltipLink>
|
||||
<HelpTooltipLink href="https://github.com/coder/coder/blob/main/docs/workspaces.md#editors-and-ides">
|
||||
{Language.workspaceTooltipLink3}
|
||||
</HelpTooltipLink>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltip>
|
||||
)
|
||||
}
|
||||
|
||||
const OutdatedHelpTooltip: React.FC<{ onUpdateVersion: () => void }> = ({ onUpdateVersion }) => {
|
||||
return (
|
||||
<HelpTooltip size="small">
|
||||
<HelpTooltipTitle>{Language.outdatedLabel}</HelpTooltipTitle>
|
||||
<HelpTooltipText>{Language.versionTooltipText}</HelpTooltipText>
|
||||
<HelpTooltipLinksGroup>
|
||||
<HelpTooltipAction icon={RefreshIcon} onClick={onUpdateVersion}>
|
||||
{Language.updateVersionLabel}
|
||||
</HelpTooltipAction>
|
||||
</HelpTooltipLinksGroup>
|
||||
</HelpTooltip>
|
||||
)
|
||||
}
|
||||
|
||||
const WorkspaceRow: React.FC<{ workspaceRef: WorkspaceItemMachineRef }> = ({ workspaceRef }) => {
|
||||
const styles = useStyles()
|
||||
const navigate = useNavigate()
|
||||
const theme: Theme = useTheme()
|
||||
const [workspaceState, send] = useActor(workspaceRef)
|
||||
const { data: workspace } = workspaceState.context
|
||||
const status = getDisplayStatus(theme, workspace.latest_build)
|
||||
const workspacePageLink = `/@${workspace.owner_name}/${workspace.name}`
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
hover
|
||||
data-testid={`workspace-${workspace.id}`}
|
||||
tabIndex={0}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter") {
|
||||
navigate(workspacePageLink)
|
||||
}
|
||||
}}
|
||||
className={styles.clickableTableRow}
|
||||
>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<AvatarData title={workspace.name} subtitle={workspace.owner_name} />
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>{workspace.template_name}</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
{workspace.outdated ? (
|
||||
<span className={styles.outdatedLabel}>
|
||||
{Language.outdatedLabel}
|
||||
<OutdatedHelpTooltip
|
||||
onUpdateVersion={() => {
|
||||
send("UPDATE_VERSION")
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
<span style={{ color: theme.palette.text.secondary }}>{Language.upToDateLabel}</span>
|
||||
)}
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<span data-chromatic="ignore" style={{ color: theme.palette.text.secondary }}>
|
||||
{dayjs().to(dayjs(workspace.latest_build.created_at))}
|
||||
</span>
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<span style={{ color: status.color }}>{status.status}</span>
|
||||
</TableCellLink>
|
||||
<TableCellLink to={workspacePageLink}>
|
||||
<div className={styles.arrowCell}>
|
||||
<KeyboardArrowRight className={styles.arrowRight} />
|
||||
</div>
|
||||
</TableCellLink>
|
||||
</TableRow>
|
||||
)
|
||||
createANewWorkspace: `Create a new workspace from a `,
|
||||
template: "Template",
|
||||
}
|
||||
|
||||
export interface WorkspacesPageViewProps {
|
||||
loading?: boolean
|
||||
isLoading?: boolean
|
||||
workspaceRefs?: WorkspaceItemMachineRef[]
|
||||
filter?: string
|
||||
onFilter: (query: string) => void
|
||||
}
|
||||
|
||||
export const WorkspacesPageView: FC<WorkspacesPageViewProps> = ({
|
||||
loading,
|
||||
isLoading,
|
||||
workspaceRefs,
|
||||
filter,
|
||||
onFilter,
|
||||
@@ -173,15 +45,15 @@ export const WorkspacesPageView: FC<WorkspacesPageViewProps> = ({
|
||||
<PageHeader>
|
||||
<PageHeaderTitle>
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>Workspaces</span>
|
||||
<span>{Language.pageTitle}</span>
|
||||
<WorkspaceHelpTooltip />
|
||||
</Stack>
|
||||
</PageHeaderTitle>
|
||||
|
||||
<PageHeaderSubtitle>
|
||||
Create a new workspace from a{" "}
|
||||
{Language.createANewWorkspace}
|
||||
<Link component={RouterLink} to="/templates">
|
||||
Template
|
||||
{Language.template}
|
||||
</Link>
|
||||
.
|
||||
</PageHeaderSubtitle>
|
||||
@@ -189,97 +61,7 @@ export const WorkspacesPageView: FC<WorkspacesPageViewProps> = ({
|
||||
|
||||
<SearchBarWithFilter filter={filter} onFilter={onFilter} presetFilters={presetFilters} />
|
||||
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell width="35%">Name</TableCell>
|
||||
<TableCell width="15%">Template</TableCell>
|
||||
<TableCell width="15%">Version</TableCell>
|
||||
<TableCell width="20%">Last Built</TableCell>
|
||||
<TableCell width="15%">Status</TableCell>
|
||||
<TableCell width="1%"></TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{!workspaceRefs && loading && <TableLoader />}
|
||||
{workspaceRefs && workspaceRefs.length === 0 && (
|
||||
<>
|
||||
{filter === workspaceFilterQuery.me || filter === workspaceFilterQuery.all ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message={Language.emptyCreateWorkspaceMessage}
|
||||
description={Language.emptyCreateWorkspaceDescription}
|
||||
cta={
|
||||
<Link underline="none" component={RouterLink} to="/templates">
|
||||
<Button startIcon={<AddCircleOutline />}>
|
||||
{Language.createFromTemplateButton}
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState message={Language.emptyResultsMessage} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{workspaceRefs &&
|
||||
workspaceRefs.map((workspaceRef) => (
|
||||
<WorkspaceRow workspaceRef={workspaceRef} key={workspaceRef.id} />
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<WorkspacesTable isLoading={isLoading} workspaceRefs={workspaceRefs} filter={filter} />
|
||||
</Margins>
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
welcome: {
|
||||
paddingTop: theme.spacing(12),
|
||||
paddingBottom: theme.spacing(12),
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
|
||||
"& span": {
|
||||
maxWidth: 600,
|
||||
textAlign: "center",
|
||||
fontSize: theme.spacing(2),
|
||||
lineHeight: `${theme.spacing(3)}px`,
|
||||
},
|
||||
},
|
||||
clickableTableRow: {
|
||||
"&:hover td": {
|
||||
backgroundColor: fade(theme.palette.primary.light, 0.1),
|
||||
},
|
||||
|
||||
"&:focus": {
|
||||
outline: `1px solid ${theme.palette.secondary.dark}`,
|
||||
},
|
||||
|
||||
"& .MuiTableCell-root:last-child": {
|
||||
paddingRight: theme.spacing(2),
|
||||
},
|
||||
},
|
||||
arrowRight: {
|
||||
color: fade(theme.palette.primary.contrastText, 0.7),
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
arrowCell: {
|
||||
display: "flex",
|
||||
},
|
||||
outdatedLabel: {
|
||||
color: theme.palette.error.main,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: theme.spacing(0.5),
|
||||
},
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user