Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: resources card#1627

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
presleyp merged 17 commits intomainfromresources/presleyp/1031
May 20, 2022
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
17 commits
Select commitHold shift + click to select a range
448070b
Set up table
presleypMay 18, 2022
99e63e5
Format
presleypMay 18, 2022
7b318ee
Hook up api and test - bug assigning resources
presleypMay 18, 2022
8cfb56a
Remove debugging code
presleypMay 18, 2022
2a3897c
Merge branch 'main' into resources/presleyp/1031
presleypMay 18, 2022
c5b60dd
Format
presleypMay 18, 2022
c4257a2
Remove unnecessary cards
presleypMay 18, 2022
be67df8
Fix test
presleypMay 20, 2022
85a869d
Fix assignment
presleypMay 20, 2022
1289ad2
Fix tests
presleypMay 20, 2022
abc7703
Lint
presleypMay 20, 2022
416be20
Merge branch 'main' into resources/presleyp/1031
presleypMay 20, 2022
c300c07
Merge branch 'main' into resources/presleyp/1031
presleypMay 20, 2022
13ba13c
Merge branch 'main' of github.com:coder/coder into resources/presleyp…
BrunoQuaresmaMay 20, 2022
85c2ac8
Refactor design
BrunoQuaresmaMay 20, 2022
e7b1110
Refactor resources table
BrunoQuaresmaMay 20, 2022
f645de3
Fix tests
BrunoQuaresmaMay 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletionsite/src/components/BuildsTable/BuildsTable.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -34,7 +34,7 @@ export const BuildsTable: React.FC<BuildsTableProps> = ({ builds, className }) =
conststyles=useStyles()

return(
<TableclassName={className}>
<TableclassName={className}data-testid="builds-table">
<TableHead>
<TableRow>
<TableCellwidth="20%">{Language.actionLabel}</TableCell>
Expand Down
109 changes: 109 additions & 0 deletionssite/src/components/Resources/Resources.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
import { 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 useTheme from "@material-ui/styles/useTheme"
import React from "react"
import { WorkspaceResource } from "../../api/typesGenerated"
import { getDisplayAgentStatus } from "../../util/workspace"
import { TableHeaderRow } from "../TableHeaders/TableHeaders"
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"

const Language = {
resources: "Resources",
resourceLabel: "Resource",
agentsLabel: "Agents",
agentLabel: "Agent",
statusLabel: "Status",
}

interface ResourcesProps {
resources?: WorkspaceResource[]
getResourcesError?: Error
}

export const Resources: React.FC<ResourcesProps> = ({ resources, getResourcesError }) => {
const styles = useStyles()
const theme: Theme = useTheme()

return (
<WorkspaceSection title={Language.resources} contentsProps={{ className: styles.sectionContents }}>
{getResourcesError ? (
{ getResourcesError }
) : (
<Table className={styles.table}>
<TableHead>
<TableHeaderRow>
<TableCell>{Language.resourceLabel}</TableCell>
<TableCell className={styles.agentColumn}>{Language.agentLabel}</TableCell>
<TableCell>{Language.statusLabel}</TableCell>
</TableHeaderRow>
</TableHead>
<TableBody>
{resources?.map((resource) => {
{
/* We need to initialize the agents to display the resource */
}
const agents = resource.agents ?? [null]
return agents.map((agent, agentIndex) => {
{
/* If there is no agent, just display the resource name */
}
if (!agent) {
return (
<TableRow>
<TableCell className={styles.resourceNameCell}>{resource.name}</TableCell>
<TableCell colSpan={2}></TableCell>
</TableRow>
)
}

return (
<TableRow key={`${resource.id}-${agent.id}`}>
{/* We only want to display the name in the first row because we are using rowSpan */}
{/* The rowspan should be the same than the number of agents */}
{agentIndex === 0 && (
<TableCell className={styles.resourceNameCell} rowSpan={agents.length}>
{resource.name}
</TableCell>
)}

<TableCell className={styles.agentColumn}>
<span style={{ color: theme.palette.text.secondary }}>{agent.name}</span>
</TableCell>
<TableCell>
<span style={{ color: getDisplayAgentStatus(theme, agent).color }}>
{getDisplayAgentStatus(theme, agent).status}
</span>
</TableCell>
</TableRow>
)
})
})}
</TableBody>
</Table>
)}
</WorkspaceSection>
)
}

const useStyles = makeStyles((theme) => ({
sectionContents: {
margin: 0,
},

table: {
border: 0,
},

resourceNameCell: {
borderRight: `1px solid ${theme.palette.divider}`,
},

// Adds some left spacing
agentColumn: {
paddingLeft: `${theme.spacing(2)}px !important`,
},
}))
8 changes: 7 additions & 1 deletionsite/src/components/Workspace/Workspace.stories.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
import { action } from "@storybook/addon-actions"
import { Story } from "@storybook/react"
import React from "react"
import { MockOutdatedWorkspace, MockWorkspace } from "../../testHelpers/renderHelpers"
import {
MockOutdatedWorkspace,
MockWorkspace,
MockWorkspaceResource,
MockWorkspaceResource2,
} from "../../testHelpers/renderHelpers"
import { Workspace, WorkspaceProps } from "./Workspace"

export default {
Expand All@@ -19,6 +24,7 @@ Started.args = {
handleStop: action("stop"),
handleRetry: action("retry"),
workspaceStatus: "started",
resources: [MockWorkspaceResource, MockWorkspaceResource2],
}

export const Starting = Template.bind({})
Expand Down
6 changes: 6 additions & 0 deletionssite/src/components/Workspace/Workspace.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,6 +5,7 @@ import * as TypesGen from "../../api/typesGenerated"
import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
import { WorkspaceStatus } from "../../util/workspace"
import { BuildsTable } from "../BuildsTable/BuildsTable"
import { Resources } from "../Resources/Resources"
import { Stack } from "../Stack/Stack"
import { WorkspaceActions } from "../WorkspaceActions/WorkspaceActions"
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
Expand All@@ -17,6 +18,8 @@ export interface WorkspaceProps {
handleUpdate: () => void
workspace: TypesGen.Workspace
workspaceStatus: WorkspaceStatus
resources?: TypesGen.WorkspaceResource[]
getResourcesError?: Error
builds?: TypesGen.WorkspaceBuild[]
}

Expand All@@ -30,6 +33,8 @@ export const Workspace: React.FC<WorkspaceProps> = ({
handleUpdate,
workspace,
workspaceStatus,
resources,
getResourcesError,
builds,
}) => {
const styles = useStyles()
Expand DownExpand Up@@ -61,6 +66,7 @@ export const Workspace: React.FC<WorkspaceProps> = ({

<Stack spacing={3}>
<WorkspaceStats workspace={workspace} />
<Resources resources={resources} getResourcesError={getResourcesError} />
<WorkspaceSection title="Timeline" contentsProps={{ className: styles.timelineContents }}>
<BuildsTable builds={builds} className={styles.timelineTable} />
</WorkspaceSection>
Expand Down
31 changes: 25 additions & 6 deletionssite/src/pages/WorkspacePage/WorkspacePage.test.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,11 +16,13 @@ import {
MockStoppingWorkspace,
MockTemplate,
MockWorkspace,
MockWorkspaceAgent,
MockWorkspaceAgentDisconnected,
MockWorkspaceBuild,
renderWithAuth,
} from "../../testHelpers/renderHelpers"
import { server } from "../../testHelpers/server"
import { DisplayStatusLanguage } from "../../util/workspace"
import {DisplayAgentStatusLanguage,DisplayStatusLanguage } from "../../util/workspace"
import { WorkspacePage } from "./WorkspacePage"

// It renders the workspace page and waits for it be loaded
Expand DownExpand Up@@ -157,10 +159,27 @@ describe("Workspace Page", () => {
it("shows the Deleted status when the workspace is deleted", async () => {
await testStatus(MockDeletedWorkspace, DisplayStatusLanguage.deleted)
})
it("shows the timeline build", async () => {
await renderWorkspacePage()
const table = await screen.findByRole("table")
const rows = table.querySelectorAll("tbody > tr")
expect(rows).toHaveLength(MockBuilds.length)

describe("Timeline", () => {
it("shows the timeline build", async () => {
await renderWorkspacePage()
const table = await screen.findByTestId("builds-table")
const rows = table.querySelectorAll("tbody > tr")
expect(rows).toHaveLength(MockBuilds.length)
})
})

describe("Resources", () => {
it("shows the status of each agent in each resource", async () => {
renderWithAuth(<WorkspacePage />, { route: `/workspaces/${MockWorkspace.id}`, path: "/workspaces/:workspace" })
const agent1Names = await screen.findAllByText(MockWorkspaceAgent.name)
expect(agent1Names.length).toEqual(2)
const agent2Names = await screen.findAllByText(MockWorkspaceAgentDisconnected.name)
expect(agent2Names.length).toEqual(2)
const agent1Status = await screen.findAllByText(DisplayAgentStatusLanguage[MockWorkspaceAgent.status])
expect(agent1Status.length).toEqual(2)
const agent2Status = await screen.findAllByText(DisplayAgentStatusLanguage[MockWorkspaceAgentDisconnected.status])
expect(agent2Status.length).toEqual(2)
})
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

🎉

})
12 changes: 6 additions & 6 deletionssite/src/pages/WorkspacePage/WorkspacePage.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
import { useActor, useSelector } from "@xstate/react"
import { useActor } from "@xstate/react"
import React, { useContext, useEffect } from "react"
import { useParams } from "react-router-dom"
import { ErrorSummary } from "../../components/ErrorSummary/ErrorSummary"
Expand All@@ -16,10 +16,8 @@ export const WorkspacePage: React.FC = () => {

const xServices = useContext(XServiceContext)
const [workspaceState, workspaceSend] = useActor(xServices.workspaceXService)
const { workspace, getWorkspaceError, getTemplateError, getOrganizationError, builds } = workspaceState.context
const workspaceStatus = useSelector(xServices.workspaceXService, (state) => {
return getWorkspaceStatus(state.context.workspace?.latest_build)
})
const { workspace, resources, getWorkspaceError, getResourcesError, builds } = workspaceState.context
const workspaceStatus = getWorkspaceStatus(workspace?.latest_build)

/**
* Get workspace, template, and organization on mount and whenever workspaceId changes.
Expand All@@ -30,7 +28,7 @@ export const WorkspacePage: React.FC = () => {
}, [workspaceId, workspaceSend])

if (workspaceState.matches("error")) {
return <ErrorSummary error={getWorkspaceError || getTemplateError || getOrganizationError} />
return <ErrorSummary error={getWorkspaceError} />
} else if (!workspace) {
return <FullScreenLoader />
} else {
Expand All@@ -44,6 +42,8 @@ export const WorkspacePage: React.FC = () => {
handleRetry={() => workspaceSend("RETRY")}
handleUpdate={() => workspaceSend("UPDATE")}
workspaceStatus={workspaceStatus}
resources={resources}
getResourcesError={getResourcesError instanceof Error ? getResourcesError : undefined}
builds={builds}
/>
</Stack>
Expand Down
15 changes: 14 additions & 1 deletionsite/src/testHelpers/entities.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -188,8 +188,15 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
updated_at: "",
}

export const MockWorkspaceAgentDisconnected: TypesGen.WorkspaceAgent = {
...MockWorkspaceAgent,
id: "test-workspace-agent-2",
name: "another-workspace-agent",
status: "disconnected",
}

export const MockWorkspaceResource: TypesGen.WorkspaceResource = {
agents: [MockWorkspaceAgent],
agents: [MockWorkspaceAgent, MockWorkspaceAgentDisconnected],
created_at: "",
id: "test-workspace-resource",
job_id: "",
Expand All@@ -198,6 +205,12 @@ export const MockWorkspaceResource: TypesGen.WorkspaceResource = {
workspace_transition: "start",
}

export const MockWorkspaceResource2 = {
...MockWorkspaceResource,
id: "test-workspace-resource-2",
name: "another-workspace-resource",
}

export const MockUserAgent: Types.UserAgent = {
browser: "Chrome 99.0.4844",
device: "Other",
Expand Down
2 changes: 1 addition & 1 deletionsite/src/testHelpers/handlers.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -125,7 +125,7 @@ export const handlers = [
return res(ctx.status(200), ctx.json(M.MockWorkspaceBuild))
}),
rest.get("/api/v2/workspacebuilds/:workspaceBuildId/resources", (req, res, ctx) => {
return res(ctx.status(200), ctx.json([M.MockWorkspaceResource]))
return res(ctx.status(200), ctx.json([M.MockWorkspaceResource, M.MockWorkspaceResource2]))
}),
rest.get("/api/v2/workspacebuilds/:workspaceBuildId/logs", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(M.MockWorkspaceBuildLogs))
Expand Down
39 changes: 38 additions & 1 deletionsite/src/util/workspace.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
import{Theme}from"@material-ui/core/styles"
importdayjsfrom"dayjs"
import{WorkspaceBuildTransition}from"../api/types"
import{WorkspaceBuild}from"../api/typesGenerated"
import{WorkspaceAgent,WorkspaceBuild}from"../api/typesGenerated"

exporttypeWorkspaceStatus=
|"queued"
Expand DownExpand Up@@ -148,3 +148,40 @@ export const displayWorkspaceBuildDuration = (build: WorkspaceBuild, inProgressL
constduration=getWorkspaceBuildDurationInSeconds(build)
returnduration ?`${duration} seconds` :inProgressLabel
}

exportconstDisplayAgentStatusLanguage={
connected:"⦿ Connected",
connecting:"⦿ Connecting",
disconnected:"◍ Disconnected",
}

exportconstgetDisplayAgentStatus=(
theme:Theme,
agent:WorkspaceAgent,
):{
color:string
status:string
}=>{
switch(agent.status){
caseundefined:
return{
color:theme.palette.text.secondary,
status:DisplayStatusLanguage.loading,
}
case"connected":
return{
color:theme.palette.success.main,
status:DisplayAgentStatusLanguage["connected"],
}
case"connecting":
return{
color:theme.palette.success.main,
status:DisplayAgentStatusLanguage["connecting"],
}
case"disconnected":
return{
color:theme.palette.text.secondary,
status:DisplayAgentStatusLanguage["disconnected"],
}
}
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp