Skip to content

feat: Workspace StatusBar #1362

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 52 commits into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
b1cc9d6
Move component and prep
presleyp May 5, 2022
0da5e7e
Make WorkspaceSection more reusable
presleyp May 5, 2022
580e801
Lay out elements
presleyp May 5, 2022
b995f4a
Layout tweaks
presleyp May 6, 2022
e7dc082
Add outdated to Workspace type
presleyp May 6, 2022
7f6bbda
Fill out status bar component
presleyp May 6, 2022
08b01c0
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 6, 2022
1bc3e35
Format
presleyp May 6, 2022
ccbf527
Add transition to types
presleyp May 6, 2022
f6bcbaa
Add api handlers for build toggle
presleyp May 9, 2022
db348a6
Format
presleyp May 9, 2022
8d5fcfd
Parallelize machine
presleyp May 9, 2022
62c40f4
Lay out basics of build submachine
presleyp May 9, 2022
eaa353d
Pipe start and stop events through - needs status
presleyp May 9, 2022
399390e
Attempt at a machine
presleyp May 10, 2022
c100ec5
Update mock
presleyp May 10, 2022
903e8ee
Render status and buttons
presleyp May 10, 2022
e8e81ce
Fix type error on template page
presleyp May 10, 2022
2226fea
Move Settings
presleyp May 10, 2022
df0bc5b
Format
presleyp May 10, 2022
14bd598
Keep refreshed workspace
presleyp May 10, 2022
c93dde3
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 10, 2022
1093103
Make it switch workspaces
presleyp May 10, 2022
478db51
Lint
presleyp May 10, 2022
40a62a8
Fix relative api path
presleyp May 10, 2022
bd3a026
Test
presleyp May 10, 2022
9786f6c
Fix polling
presleyp May 10, 2022
7727a1b
Add loading workspace state
presleyp May 10, 2022
4a57152
Format
presleyp May 10, 2022
e3ae1b8
Add stub settings page
presleyp May 11, 2022
2695a29
Format
presleyp May 11, 2022
44e4552
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 11, 2022
d83e5ac
Lint
presleyp May 11, 2022
f909a86
Get rid of let
presleyp May 11, 2022
5dcec61
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 11, 2022
be86750
Add update
presleyp May 12, 2022
992ee0c
Make start use version id
presleyp May 12, 2022
9903c96
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 12, 2022
91d5811
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 12, 2022
9cd386e
Fix imports
presleyp May 12, 2022
1a09166
Add polling for outdated
presleyp May 12, 2022
aee54a0
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 12, 2022
e9758c7
Rely on context instead of finite state for status
presleyp May 12, 2022
87fee06
Handle canceling
presleyp May 13, 2022
b3f6b8c
Fix tests
presleyp May 13, 2022
39e84d9
Format
presleyp May 13, 2022
06abf62
Display errors so users know when button presses didn't work
presleyp May 13, 2022
8552ea2
Fix api typo, remove logging
presleyp May 13, 2022
72c856e
Lint
presleyp May 13, 2022
259d517
Merge branch 'main' into statusbar/presleyp/1032
presleyp May 13, 2022
24829be
Simplify type
presleyp May 16, 2022
542d865
Add type, extract helper
presleyp May 16, 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
Prev Previous commit
Next Next commit
Merge branch 'main' into statusbar/presleyp/1032
  • Loading branch information
presleyp committed May 12, 2022
commit 91d581166d3ed9eb661ccd21a5681722f5eb04a7
2 changes: 1 addition & 1 deletion site/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const startWorkspace = postWorkspaceBuild("start")
export const stopWorkspace = postWorkspaceBuild("stop")
export const deleteWorkspace = postWorkspaceBuild("delete")

export const createUser = async (user: Types.CreateUserRequest): Promise<TypesGen.User> => {
export const createUser = async (user: TypesGen.CreateUserRequest): Promise<TypesGen.User> => {
const response = await axios.post<TypesGen.User>("/api/v2/users", user)
return response.data
}
Expand Down
120 changes: 2 additions & 118 deletions site/src/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,130 +1,14 @@
import * as TypesGen from "./typesGenerated"

/**
* `BuildInfoResponse` must be kept in sync with the go struct in buildinfo.go.
*/
export interface BuildInfoResponse {
external_url: string
version: string
}

export interface LoginResponse {
session_token: string
}

export interface CreateUserRequest {
username: string
email: string
password: string
organization_id: string
}

export interface UserResponse {
readonly id: string
readonly username: string
readonly email: string
readonly created_at: string
readonly status: "active" | "suspended"
readonly organization_ids: string[]
readonly roles: { name: string; display_name: string }[]
}

/**
* `Organization` must be kept in sync with the go struct in organizations.go
*/
export interface Organization {
id: string
name: string
created_at: string
updated_at: string
}

export interface Provisioner {
id: string
name: string
}

// This must be kept in sync with the `Template` struct in the back-end
export interface Template {
id: string
created_at: string
updated_at: string
organization_id: string
name: string
provisioner: string
active_version_id: string
}

export interface CreateTemplateRequest {
name: string
organizationId: string
provisioner: string
}

export interface CreateWorkspaceRequest {
name: string
template_id: string
organization_id: string
}

export interface WorkspaceBuild {
id: string
transition: WorkspaceBuildTransition
job: TypesGen.ProvisionerJob
}

export interface Workspace {
id: string
outdated: boolean
created_at: string
updated_at: string
owner_id: string
template_id: string
name: string
autostart_schedule: string
autostop_schedule: string
latest_build: WorkspaceBuild
}

export interface WorkspaceResource {
id: string
agents?: WorkspaceAgent[]
}

export interface WorkspaceAgent {
id: string
name: string
operating_system: string
}

export interface APIKeyResponse {
key: string
}

export interface UserAgent {
readonly browser: string
readonly device: string
readonly ip_address: string
readonly os: string
}

export interface WorkspaceAutostartRequest {
schedule: string
}

export interface WorkspaceAutostopRequest {
schedule: string
}

export type WorkspaceBuildTransition = "start" | "stop" | "delete"

export interface UpdateProfileRequest {
readonly username: string
readonly email: string
}

export interface ReconnectingPTYRequest {
readonly data?: string
readonly height?: number
readonly width?: number
}

export type WorkspaceBuildTransition = "start" | "stop" | "delete"
8 changes: 4 additions & 4 deletions site/src/components/Workspace/Workspace.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { makeStyles } from "@material-ui/core/styles"
import Typography from "@material-ui/core/Typography"
import React from "react"
import * as Types from "../../api/types"
import * as TypesGen from "../../api/typesGenerated"
import { WorkspaceStatus } from "../../pages/WorkspacePage/WorkspacePage"
import { WorkspaceSchedule } from "../WorkspaceSchedule/WorkspaceSchedule"
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
import { WorkspaceStatusBar } from "../WorkspaceStatusBar/WorkspaceStatusBar"

export interface WorkspaceProps {
organization?: Types.Organization
workspace: Types.Workspace
template?: Types.Template
organization?: TypesGen.Organization
workspace: TypesGen.Workspace
template?: TypesGen.Template
handleStart: () => void
handleStop: () => void
handleRetry: () => void
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react"
import { Link, useNavigate, useParams } from "react-router-dom"
import useSWR from "swr"
import { Organization, Template, Workspace } from "../../../../api/types"
import * as TypesGen from "../../../../api/typesGenerated"
import { EmptyState } from "../../../../components/EmptyState/EmptyState"
import { ErrorSummary } from "../../../../components/ErrorSummary/ErrorSummary"
import { Header } from "../../../../components/Header/Header"
Expand Down Expand Up @@ -66,8 +66,8 @@ export const TemplatePage: React.FC = () => {
{
key: "name",
name: "Name",
renderer: (_, workspace: Workspace) => {
return <Link to={`/workspaces/${workspace.id}`}>{workspace.name}</Link>
renderer: (nameField: string | TypesGen.WorkspaceBuild, workspace: TypesGen.Workspace) => {
return <Link to={`/workspaces/${workspace.id}`}>{nameField}</Link>
},
},
]
Expand Down
85 changes: 27 additions & 58 deletions site/src/testHelpers/entities.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import {
BuildInfoResponse,
Organization,
Provisioner,
Template,
UserAgent,
UserResponse,
Workspace,
WorkspaceAgent,
WorkspaceAutostartRequest,
WorkspaceBuildTransition,
WorkspaceResource,
} from "../api/types"
import { AuthMethods, ProvisionerJobStatus, Role } from "../api/typesGenerated"
import * as Types from "../api/types"
import * as TypesGen from "../api/typesGenerated"

export const MockSessionToken: TypesGen.LoginWithPasswordResponse = {
session_token: "my-session-token",
Expand Down Expand Up @@ -83,6 +71,8 @@ export const MockProvisionerJob: TypesGen.ProvisionerJob = {
status: "succeeded",
}

export const MockFailedProvisionerJob = { ...MockProvisionerJob, status: "failed" as TypesGen.ProvisionerJobStatus }

export const MockTemplate: TypesGen.Template = {
id: "test-template",
created_at: "",
Expand Down Expand Up @@ -113,80 +103,59 @@ export const MockWorkspaceAutostopEnabled: TypesGen.UpdateWorkspaceAutostartRequ
schedule: "CRON_TZ=America/Toronto 30 21 * * 1-5",
}

export const MockProvisionerJob = {
id: "test-provisioner-job",
created_at: "",
started_at: "",
completed_at: "",
error: "",
status: "succeeded" as ProvisionerJobStatus,
worker_id: "test-worker-id",
}

export const MockFailedProvisionerJob = {
id: "test-provisioner-job",
export const MockWorkspaceBuild: TypesGen.WorkspaceBuild = {
after_id: "",
before_id: "",
created_at: "",
started_at: "",
completed_at: "",
error: "",
status: "failed" as ProvisionerJobStatus,
worker_id: "test-worker-id",
}

export const MockWorkspaceBuild = {
id: "test-workspace-build",
transition: "start" as WorkspaceBuildTransition,
job: MockProvisionerJob,
}

export const MockWorkspaceBuildStop = {
id: "test-workspace-build",
transition: "stop" as WorkspaceBuildTransition,
initiator_id: "",
job: MockProvisionerJob,
name: "a-workspace-build",
template_version_id: "",
transition: "start",
updated_at: "",
workspace_id: "test-workspace",
}

export const MockFailedWorkspaceBuild = {
id: "test-workspace-build",
transition: "start" as WorkspaceBuildTransition,
...MockWorkspaceBuild,
job: MockFailedProvisionerJob,
}

// These are special cases of MockWorkspaceBuild for more precise testing
export const MockWorkspaceStart = {
id: "test-workspace-build-start",
transition: "start",
}

export const MockWorkspaceStop = {
id: "test-workspace-build-stop",
export const MockWorkspaceBuildStop = {
...MockWorkspaceBuild,
transition: "stop",
}

export const MockWorkspaceDelete = {
id: "test-workspace-build-delete",
export const MockWorkspaceBuildDelete = {
...MockWorkspaceBuild,
transition: "delete",
}

export const MockWorkspace: Workspace = {
export const MockWorkspace: TypesGen.Workspace = {
id: "test-workspace",
name: "Test-Workspace",
created_at: "",
updated_at: "",
template_id: MockTemplate.id,
template_name: MockTemplate.name,
outdated: false,
owner_id: MockUser.id,
autostart_schedule: MockWorkspaceAutostartEnabled.schedule,
autostop_schedule: MockWorkspaceAutostopEnabled.schedule,
latest_build: MockWorkspaceBuild,
}

export const MockStoppedWorkspace: Workspace = { ...MockWorkspace, latest_build: MockWorkspaceBuildStop }
export const MockStoppedWorkspace: TypesGen.Workspace = { ...MockWorkspace, latest_build: MockWorkspaceBuildStop }

export const MockFailedWorkspace: Workspace = { ...MockWorkspace, latest_build: MockFailedWorkspaceBuild }
export const MockFailedWorkspace: TypesGen.Workspace = { ...MockWorkspace, latest_build: MockFailedWorkspaceBuild }

export const MockOutdatedWorkspace: Workspace = { ...MockWorkspace, outdated: true }
export const MockOutdatedWorkspace: TypesGen.Workspace = { ...MockWorkspace, outdated: true }

export const MockWorkspaceAgent: WorkspaceAgent = {
export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
architecture: "amd64",
created_at: "",
environment_variables: {},
id: "test-workspace-agent",
name: "a-workspace-agent",
operating_system: "linux",
Expand Down
9 changes: 4 additions & 5 deletions site/src/xServices/workspace/workspaceXService.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { assign, createMachine } from "xstate"
import * as API from "../../api/api"
import * as Types from "../../api/types"
import * as TypesGen from "../../api/typesGenerated"

interface WorkspaceContext {
workspace?: Types.Workspace
template?: Types.Template
organization?: Types.Organization
workspace?: TypesGen.Workspace
template?: TypesGen.Template
organization?: TypesGen.Organization
build?: TypesGen.WorkspaceBuild
getWorkspaceError?: Error | unknown
getTemplateError?: Error | unknown
Expand Down Expand Up @@ -51,7 +50,7 @@ export const workspaceMachine = createMachine(
data: TypesGen.WorkspaceBuild
}
refreshWorkspace: {
data: Types.Workspace | undefined
data: TypesGen.Workspace | undefined
}
},
},
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.