mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor(site): Remove change version from the UI (#6621)
This commit is contained in:
@@ -43,9 +43,6 @@ const WorkspaceBuildPage = lazy(
|
||||
() => import("./pages/WorkspaceBuildPage/WorkspaceBuildPage"),
|
||||
)
|
||||
const WorkspacePage = lazy(() => import("./pages/WorkspacePage/WorkspacePage"))
|
||||
const WorkspaceChangeVersionPage = lazy(
|
||||
() => import("./pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPage"),
|
||||
)
|
||||
const WorkspaceSchedulePage = lazy(
|
||||
() => import("./pages/WorkspaceSchedulePage/WorkspaceSchedulePage"),
|
||||
)
|
||||
@@ -235,10 +232,6 @@ export const AppRouter: FC = () => {
|
||||
path="builds/:buildNumber"
|
||||
element={<WorkspaceBuildPage />}
|
||||
/>
|
||||
<Route
|
||||
path="change-version"
|
||||
element={<WorkspaceChangeVersionPage />}
|
||||
/>
|
||||
<Route path="settings" element={<WorkspaceSettingsPage />} />
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
@@ -3,7 +3,6 @@ import Button from "@material-ui/core/Button"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import BlockIcon from "@material-ui/icons/Block"
|
||||
import CloudQueueIcon from "@material-ui/icons/CloudQueue"
|
||||
import UpdateOutlined from "@material-ui/icons/UpdateOutlined"
|
||||
import SettingsOutlined from "@material-ui/icons/SettingsOutlined"
|
||||
import CropSquareIcon from "@material-ui/icons/CropSquare"
|
||||
import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"
|
||||
@@ -36,24 +35,6 @@ export const UpdateButton: FC<React.PropsWithChildren<WorkspaceAction>> = ({
|
||||
)
|
||||
}
|
||||
|
||||
export const ChangeVersionButton: FC<
|
||||
React.PropsWithChildren<WorkspaceAction>
|
||||
> = ({ handleAction }) => {
|
||||
const styles = useStyles()
|
||||
const { t } = useTranslation("workspacePage")
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="outlined"
|
||||
className={styles.actionButton}
|
||||
startIcon={<UpdateOutlined />}
|
||||
onClick={handleAction}
|
||||
>
|
||||
{t("actionButton.changeVersion")}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
export const SettingsButton: FC<React.PropsWithChildren<WorkspaceAction>> = ({
|
||||
handleAction,
|
||||
}) => {
|
||||
|
||||
@@ -42,7 +42,6 @@ export interface WorkspaceProps {
|
||||
handleDelete: () => void
|
||||
handleUpdate: () => void
|
||||
handleCancel: () => void
|
||||
handleChangeVersion: () => void
|
||||
handleSettings: () => void
|
||||
isUpdating: boolean
|
||||
workspace: TypesGen.Workspace
|
||||
@@ -68,7 +67,6 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
|
||||
handleDelete,
|
||||
handleUpdate,
|
||||
handleCancel,
|
||||
handleChangeVersion,
|
||||
handleSettings,
|
||||
workspace,
|
||||
isUpdating,
|
||||
@@ -130,7 +128,6 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
|
||||
handleDelete={handleDelete}
|
||||
handleUpdate={handleUpdate}
|
||||
handleCancel={handleCancel}
|
||||
handleChangeVersion={handleChangeVersion}
|
||||
handleSettings={handleSettings}
|
||||
isUpdating={isUpdating}
|
||||
/>
|
||||
|
||||
@@ -18,7 +18,6 @@ const renderComponent = async (props: Partial<WorkspaceActionsProps> = {}) => {
|
||||
handleDelete={jest.fn()}
|
||||
handleUpdate={jest.fn()}
|
||||
handleCancel={jest.fn()}
|
||||
handleChangeVersion={jest.fn()}
|
||||
handleSettings={jest.fn()}
|
||||
isUpdating={false}
|
||||
/>,
|
||||
@@ -37,7 +36,6 @@ const renderAndClick = async (props: Partial<WorkspaceActionsProps> = {}) => {
|
||||
handleDelete={jest.fn()}
|
||||
handleUpdate={jest.fn()}
|
||||
handleCancel={jest.fn()}
|
||||
handleChangeVersion={jest.fn()}
|
||||
handleSettings={jest.fn()}
|
||||
isUpdating={false}
|
||||
/>,
|
||||
|
||||
@@ -4,7 +4,6 @@ import { useTranslation } from "react-i18next"
|
||||
import { WorkspaceStatus } from "../../api/typesGenerated"
|
||||
import {
|
||||
ActionLoadingButton,
|
||||
ChangeVersionButton,
|
||||
DeleteButton,
|
||||
DisabledButton,
|
||||
SettingsButton,
|
||||
@@ -22,7 +21,6 @@ export interface WorkspaceActionsProps {
|
||||
handleDelete: () => void
|
||||
handleUpdate: () => void
|
||||
handleCancel: () => void
|
||||
handleChangeVersion: () => void
|
||||
handleSettings: () => void
|
||||
isUpdating: boolean
|
||||
children?: ReactNode
|
||||
@@ -36,7 +34,6 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
|
||||
handleDelete,
|
||||
handleUpdate,
|
||||
handleCancel,
|
||||
handleChangeVersion,
|
||||
handleSettings,
|
||||
isUpdating,
|
||||
}) => {
|
||||
@@ -50,9 +47,6 @@ export const WorkspaceActions: FC<WorkspaceActionsProps> = ({
|
||||
[ButtonTypesEnum.updating]: (
|
||||
<ActionLoadingButton label={t("actionButton.updating")} />
|
||||
),
|
||||
[ButtonTypesEnum.changeVersion]: (
|
||||
<ChangeVersionButton handleAction={handleChangeVersion} />
|
||||
),
|
||||
[ButtonTypesEnum.settings]: (
|
||||
<SettingsButton handleAction={handleSettings} />
|
||||
),
|
||||
|
||||
@@ -11,7 +11,6 @@ export enum ButtonTypesEnum {
|
||||
deleting = "deleting",
|
||||
update = "update",
|
||||
updating = "updating",
|
||||
changeVersion = "changeVersion",
|
||||
settings = "settings",
|
||||
// disabled buttons
|
||||
canceling = "canceling",
|
||||
@@ -45,7 +44,6 @@ const statusToAbilities: Record<WorkspaceStatus, WorkspaceAbilities> = {
|
||||
actions: [
|
||||
ButtonTypesEnum.stop,
|
||||
ButtonTypesEnum.settings,
|
||||
ButtonTypesEnum.changeVersion,
|
||||
ButtonTypesEnum.delete,
|
||||
],
|
||||
canCancel: false,
|
||||
@@ -60,7 +58,6 @@ const statusToAbilities: Record<WorkspaceStatus, WorkspaceAbilities> = {
|
||||
actions: [
|
||||
ButtonTypesEnum.start,
|
||||
ButtonTypesEnum.settings,
|
||||
ButtonTypesEnum.changeVersion,
|
||||
ButtonTypesEnum.delete,
|
||||
],
|
||||
canCancel: false,
|
||||
@@ -71,7 +68,6 @@ const statusToAbilities: Record<WorkspaceStatus, WorkspaceAbilities> = {
|
||||
ButtonTypesEnum.start,
|
||||
ButtonTypesEnum.stop,
|
||||
ButtonTypesEnum.settings,
|
||||
ButtonTypesEnum.changeVersion,
|
||||
ButtonTypesEnum.delete,
|
||||
],
|
||||
canCancel: false,
|
||||
@@ -83,7 +79,6 @@ const statusToAbilities: Record<WorkspaceStatus, WorkspaceAbilities> = {
|
||||
ButtonTypesEnum.start,
|
||||
ButtonTypesEnum.stop,
|
||||
ButtonTypesEnum.settings,
|
||||
ButtonTypesEnum.changeVersion,
|
||||
ButtonTypesEnum.delete,
|
||||
],
|
||||
canCancel: false,
|
||||
|
||||
@@ -12,7 +12,6 @@ import templateSettingsPage from "./templateSettingsPage.json"
|
||||
import templateVariablesPage from "./templateVariablesPage.json"
|
||||
import templateVersionPage from "./templateVersionPage.json"
|
||||
import loginPage from "./loginPage.json"
|
||||
import workspaceChangeVersionPage from "./workspaceChangeVersionPage.json"
|
||||
import workspaceSchedulePage from "./workspaceSchedulePage.json"
|
||||
import appearanceSettings from "./appearanceSettings.json"
|
||||
import starterTemplatesPage from "./starterTemplatesPage.json"
|
||||
@@ -37,7 +36,6 @@ export const en = {
|
||||
templateVariablesPage,
|
||||
templateVersionPage,
|
||||
loginPage,
|
||||
workspaceChangeVersionPage,
|
||||
workspaceSchedulePage,
|
||||
appearanceSettings,
|
||||
starterTemplatesPage,
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"title": "",
|
||||
"labels": {
|
||||
"workspaceVersion": "Workspace version",
|
||||
"submit": "Update version",
|
||||
"createdBy": "Created by",
|
||||
"active": "Active"
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@
|
||||
"starting": "Starting...",
|
||||
"stopping": "Stopping...",
|
||||
"deleting": "Deleting...",
|
||||
"changeVersion": "Change version",
|
||||
"settings": "Settings"
|
||||
},
|
||||
"disabledButton": {
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import TextField from "@material-ui/core/TextField"
|
||||
import Autocomplete from "@material-ui/lab/Autocomplete"
|
||||
import { Template, TemplateVersion, Workspace } from "api/typesGenerated"
|
||||
import { FormFooter } from "components/FormFooter/FormFooter"
|
||||
import { Pill } from "components/Pill/Pill"
|
||||
import { Stack } from "components/Stack/Stack"
|
||||
import { useFormik } from "formik"
|
||||
import { FC } from "react"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { createDayString } from "util/createDayString"
|
||||
import * as Yup from "yup"
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
versionId: Yup.string().required(),
|
||||
})
|
||||
|
||||
export const WorkspaceChangeVersionForm: FC<{
|
||||
isLoading: boolean
|
||||
workspace: Workspace
|
||||
template: Template
|
||||
versions: TemplateVersion[]
|
||||
onSubmit: (versionId: string) => void
|
||||
onCancel: () => void
|
||||
}> = ({ isLoading, workspace, template, versions, onSubmit, onCancel }) => {
|
||||
const styles = useStyles()
|
||||
const { t } = useTranslation("workspaceChangeVersionPage")
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
versionId: workspace.latest_build.template_version_id,
|
||||
},
|
||||
validationSchema,
|
||||
onSubmit: ({ versionId }) => onSubmit(versionId),
|
||||
})
|
||||
const autocompleteValue = versions.find(
|
||||
(version) => version.id === formik.values.versionId,
|
||||
)
|
||||
|
||||
return (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<Stack direction="column" spacing={3}>
|
||||
<Stack direction="row" className={styles.workspace} alignItems="center">
|
||||
<div className={styles.workspaceIcon}>
|
||||
<img src={workspace.template_icon} alt="" />
|
||||
</div>
|
||||
<Stack direction="column" spacing={0.5}>
|
||||
<span className={styles.workspaceName}>{workspace.name}</span>
|
||||
|
||||
<span className={styles.workspaceDescription}>
|
||||
{workspace.template_display_name.length > 0
|
||||
? workspace.template_display_name
|
||||
: workspace.template_name}
|
||||
</span>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
<Autocomplete
|
||||
id="workspaceVersion"
|
||||
disableClearable
|
||||
options={versions.slice().reverse()}
|
||||
value={autocompleteValue}
|
||||
onChange={async (_event, value) => {
|
||||
if (value) {
|
||||
await formik.setFieldValue("versionId", value.id)
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label={t("labels.workspaceVersion")}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
/>
|
||||
)}
|
||||
getOptionLabel={(version: TemplateVersion) => version.name}
|
||||
renderOption={(version: TemplateVersion) => (
|
||||
<div className={styles.menuItem}>
|
||||
<div>
|
||||
<div>{version.name}</div>
|
||||
<div className={styles.versionDescription}>
|
||||
{t("labels.createdBy")} {version.created_by.username}{" "}
|
||||
{createDayString(version.created_at)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{template.active_version_id === version.id && (
|
||||
<Pill
|
||||
type="success"
|
||||
text={t("labels.active")}
|
||||
className={styles.activePill}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
<FormFooter
|
||||
onCancel={onCancel}
|
||||
isLoading={isLoading}
|
||||
submitLabel={t("labels.submit")}
|
||||
/>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
workspace: {
|
||||
padding: theme.spacing(2.5, 3),
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
},
|
||||
|
||||
workspaceName: {
|
||||
fontSize: theme.spacing(2),
|
||||
},
|
||||
|
||||
workspaceDescription: {
|
||||
fontSize: theme.spacing(1.75),
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
|
||||
workspaceIcon: {
|
||||
width: theme.spacing(5),
|
||||
lineHeight: 1,
|
||||
|
||||
"& img": {
|
||||
width: "100%",
|
||||
},
|
||||
},
|
||||
|
||||
menuItem: {
|
||||
paddingTop: theme.spacing(1),
|
||||
paddingBottom: theme.spacing(1),
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
},
|
||||
|
||||
versionDescription: {
|
||||
fontSize: theme.spacing(1.5),
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
|
||||
activePill: {
|
||||
position: "absolute",
|
||||
top: theme.spacing(2),
|
||||
right: theme.spacing(2),
|
||||
},
|
||||
}))
|
||||
@@ -1,64 +0,0 @@
|
||||
import {
|
||||
MockTemplateVersion2,
|
||||
MockUser,
|
||||
MockWorkspace,
|
||||
renderWithAuth,
|
||||
waitForLoaderToBeRemoved,
|
||||
} from "testHelpers/renderHelpers"
|
||||
import WorkspaceChangeVersionPage from "./WorkspaceChangeVersionPage"
|
||||
import { screen, waitFor } from "@testing-library/react"
|
||||
import * as API from "api/api"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import * as CreateDayString from "util/createDayString"
|
||||
import i18next from "i18next"
|
||||
|
||||
const t = (path: string) => {
|
||||
return i18next.t(path, { ns: "workspaceChangeVersionPage" })
|
||||
}
|
||||
|
||||
const renderPage = async () => {
|
||||
renderWithAuth(<WorkspaceChangeVersionPage />, {
|
||||
path: "/@:username/:workspace/change-version",
|
||||
route: `/@${MockUser.username}/${MockWorkspace.name}/change-version`,
|
||||
})
|
||||
await waitForLoaderToBeRemoved()
|
||||
}
|
||||
|
||||
describe("WorkspaceChangeVersionPage", () => {
|
||||
beforeEach(() => {
|
||||
jest
|
||||
.spyOn(CreateDayString, "createDayString")
|
||||
.mockImplementation(() => "a minute ago")
|
||||
})
|
||||
|
||||
it("sends the update request with the right version", async () => {
|
||||
const user = userEvent.setup()
|
||||
const updateSpy = jest.spyOn(API, "startWorkspace")
|
||||
await renderPage()
|
||||
|
||||
// Type the version name and select it
|
||||
const autocompleteInput = screen.getByLabelText(
|
||||
t("labels.workspaceVersion"),
|
||||
)
|
||||
await user.clear(autocompleteInput)
|
||||
await user.type(autocompleteInput, MockTemplateVersion2.name)
|
||||
const newOption = screen.getByRole("option", {
|
||||
// Using RegExp so we can match a substring
|
||||
name: new RegExp(MockTemplateVersion2.name),
|
||||
})
|
||||
await user.click(newOption)
|
||||
|
||||
// Submit the form
|
||||
const submitButton = screen.getByRole("button", {
|
||||
name: t("labels.submit"),
|
||||
})
|
||||
await user.click(submitButton)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(updateSpy).toBeCalledWith(
|
||||
MockWorkspace.id,
|
||||
MockTemplateVersion2.id,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,48 +0,0 @@
|
||||
import { useMachine } from "@xstate/react"
|
||||
import { FC } from "react"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useNavigate, useParams } from "react-router-dom"
|
||||
import { changeWorkspaceVersionMachine } from "xServices/workspace/changeWorkspaceVersionXService"
|
||||
import { WorkspaceChangeVersionPageView } from "./WorkspaceChangeVersionPageView"
|
||||
|
||||
export const WorkspaceChangeVersionPage: FC = () => {
|
||||
const navigate = useNavigate()
|
||||
const { t } = useTranslation("workspaceChangeVersionPage")
|
||||
const { username: owner, workspace: workspaceName } = useParams() as {
|
||||
username: string
|
||||
workspace: string
|
||||
}
|
||||
const [state, send] = useMachine(changeWorkspaceVersionMachine, {
|
||||
context: {
|
||||
owner,
|
||||
workspaceName,
|
||||
},
|
||||
actions: {
|
||||
onUpdateVersion: () => {
|
||||
navigate(-1)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{`${t("title")} · ${workspaceName}`}</title>
|
||||
</Helmet>
|
||||
|
||||
<WorkspaceChangeVersionPageView
|
||||
isUpdating={state.matches("updatingVersion")}
|
||||
context={state.context}
|
||||
onSubmit={(versionId) => {
|
||||
send({
|
||||
type: "UPDATE_VERSION",
|
||||
versionId,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default WorkspaceChangeVersionPage
|
||||
@@ -1,51 +0,0 @@
|
||||
import { action } from "@storybook/addon-actions"
|
||||
import { ComponentMeta, Story } from "@storybook/react"
|
||||
import {
|
||||
makeMockApiError,
|
||||
MockTemplate,
|
||||
MockTemplateVersion,
|
||||
MockTemplateVersion2,
|
||||
MockUser,
|
||||
MockWorkspace,
|
||||
} from "testHelpers/entities"
|
||||
import {
|
||||
WorkspaceChangeVersionPageView,
|
||||
WorkspaceChangeVersionPageViewProps,
|
||||
} from "./WorkspaceChangeVersionPageView"
|
||||
|
||||
export default {
|
||||
title: "pages/WorkspaceChangeVersionPageView",
|
||||
component: WorkspaceChangeVersionPageView,
|
||||
} as ComponentMeta<typeof WorkspaceChangeVersionPageView>
|
||||
|
||||
const Template: Story<WorkspaceChangeVersionPageViewProps> = (args) => (
|
||||
<WorkspaceChangeVersionPageView {...args} />
|
||||
)
|
||||
|
||||
export const Example = Template.bind({})
|
||||
Example.args = {
|
||||
isUpdating: false,
|
||||
onSubmit: action("submit"),
|
||||
context: {
|
||||
error: undefined,
|
||||
owner: MockUser.username,
|
||||
workspaceName: MockWorkspace.name,
|
||||
template: MockTemplate,
|
||||
templateVersions: [MockTemplateVersion2, MockTemplateVersion],
|
||||
workspace: MockWorkspace,
|
||||
},
|
||||
}
|
||||
|
||||
export const Error = Template.bind({})
|
||||
Error.args = {
|
||||
isUpdating: false,
|
||||
onSubmit: action("submit"),
|
||||
context: {
|
||||
error: makeMockApiError({ message: "Error on updating the version." }),
|
||||
owner: MockUser.username,
|
||||
workspaceName: MockWorkspace.name,
|
||||
template: MockTemplate,
|
||||
templateVersions: [MockTemplateVersion2, MockTemplateVersion],
|
||||
workspace: MockWorkspace,
|
||||
},
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import { AlertBanner } from "components/AlertBanner/AlertBanner"
|
||||
import { Maybe } from "components/Conditionals/Maybe"
|
||||
import { FullPageForm } from "components/FullPageForm/FullPageForm"
|
||||
import { Loader } from "components/Loader/Loader"
|
||||
import { Stack } from "components/Stack/Stack"
|
||||
import { FC } from "react"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { ChangeWorkspaceVersionContext } from "xServices/workspace/changeWorkspaceVersionXService"
|
||||
import { WorkspaceChangeVersionForm } from "./WorkspaceChangeVersionForm"
|
||||
|
||||
export interface WorkspaceChangeVersionPageViewProps {
|
||||
isUpdating: boolean
|
||||
context: ChangeWorkspaceVersionContext
|
||||
onSubmit: (versionId: string) => void
|
||||
}
|
||||
|
||||
export const WorkspaceChangeVersionPageView: FC<
|
||||
WorkspaceChangeVersionPageViewProps
|
||||
> = ({ context, onSubmit, isUpdating }) => {
|
||||
const navigate = useNavigate()
|
||||
const { workspace, templateVersions, template, error } = context
|
||||
|
||||
return (
|
||||
<FullPageForm title="Change version">
|
||||
<Stack>
|
||||
<Maybe condition={Boolean(error)}>
|
||||
<AlertBanner severity="error" error={error} />
|
||||
</Maybe>
|
||||
{workspace && template && templateVersions ? (
|
||||
<WorkspaceChangeVersionForm
|
||||
isLoading={isUpdating}
|
||||
versions={templateVersions}
|
||||
workspace={workspace}
|
||||
template={template}
|
||||
onSubmit={onSubmit}
|
||||
onCancel={() => {
|
||||
navigate(-1)
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Loader />
|
||||
)}
|
||||
</Stack>
|
||||
</FullPageForm>
|
||||
)
|
||||
}
|
||||
@@ -111,7 +111,6 @@ export const WorkspaceReadyPage = ({
|
||||
handleDelete={() => workspaceSend({ type: "ASK_DELETE" })}
|
||||
handleUpdate={() => workspaceSend({ type: "UPDATE" })}
|
||||
handleCancel={() => workspaceSend({ type: "CANCEL" })}
|
||||
handleChangeVersion={() => navigate("change-version")}
|
||||
handleSettings={() => navigate("settings")}
|
||||
resources={workspace.latest_build.resources}
|
||||
builds={builds}
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
import {
|
||||
getTemplate,
|
||||
getTemplateVersions,
|
||||
getWorkspaceByOwnerAndName,
|
||||
startWorkspace,
|
||||
} from "api/api"
|
||||
import {
|
||||
Template,
|
||||
TemplateVersion,
|
||||
Workspace,
|
||||
WorkspaceBuild,
|
||||
} from "api/typesGenerated"
|
||||
import { assign, createMachine } from "xstate"
|
||||
|
||||
export interface ChangeWorkspaceVersionContext {
|
||||
owner: string
|
||||
workspaceName: string
|
||||
workspace?: Workspace
|
||||
template?: Template
|
||||
templateVersions?: TemplateVersion[]
|
||||
error?: unknown
|
||||
}
|
||||
|
||||
interface ChangeWorkspaceVersionSchema {
|
||||
context: ChangeWorkspaceVersionContext
|
||||
|
||||
services: {
|
||||
getWorkspace: {
|
||||
data: Workspace
|
||||
}
|
||||
getTemplateData: {
|
||||
data: {
|
||||
template: Template
|
||||
versions: TemplateVersion[]
|
||||
}
|
||||
}
|
||||
updateVersion: {
|
||||
data: WorkspaceBuild
|
||||
}
|
||||
}
|
||||
|
||||
events: {
|
||||
type: "UPDATE_VERSION"
|
||||
versionId: string
|
||||
}
|
||||
}
|
||||
|
||||
export const changeWorkspaceVersionMachine = createMachine(
|
||||
{
|
||||
id: "changeWorkspaceVersion",
|
||||
predictableActionArguments: true,
|
||||
schema: {} as ChangeWorkspaceVersionSchema,
|
||||
tsTypes: {} as import("./changeWorkspaceVersionXService.typegen").Typegen0,
|
||||
initial: "loadingWorkspace",
|
||||
states: {
|
||||
loadingWorkspace: {
|
||||
invoke: {
|
||||
src: "getWorkspace",
|
||||
onDone: {
|
||||
target: "loadingTemplateData",
|
||||
actions: "assignWorkspace",
|
||||
},
|
||||
onError: {
|
||||
target: "idle",
|
||||
actions: "assignError",
|
||||
},
|
||||
},
|
||||
},
|
||||
loadingTemplateData: {
|
||||
invoke: {
|
||||
src: "getTemplateData",
|
||||
onDone: {
|
||||
target: "idle",
|
||||
actions: "assignTemplateData",
|
||||
},
|
||||
onError: {
|
||||
target: "idle",
|
||||
actions: "assignError",
|
||||
},
|
||||
},
|
||||
},
|
||||
idle: {
|
||||
on: {
|
||||
UPDATE_VERSION: "updatingVersion",
|
||||
},
|
||||
},
|
||||
updatingVersion: {
|
||||
invoke: {
|
||||
src: "updateVersion",
|
||||
onDone: {
|
||||
target: "idle",
|
||||
actions: "onUpdateVersion",
|
||||
},
|
||||
onError: {
|
||||
target: "idle",
|
||||
actions: "assignError",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
services: {
|
||||
getWorkspace: ({ owner, workspaceName }) =>
|
||||
getWorkspaceByOwnerAndName(owner, workspaceName),
|
||||
|
||||
getTemplateData: async ({ workspace }) => {
|
||||
if (!workspace) {
|
||||
throw new Error("Workspace not defined.")
|
||||
}
|
||||
|
||||
const [template, versions] = await Promise.all([
|
||||
getTemplate(workspace.template_id),
|
||||
getTemplateVersions(workspace.template_id),
|
||||
])
|
||||
|
||||
return { template, versions }
|
||||
},
|
||||
|
||||
updateVersion: ({ workspace }, { versionId }) => {
|
||||
if (!workspace) {
|
||||
throw new Error("Workspace not defined.")
|
||||
}
|
||||
|
||||
return startWorkspace(workspace.id, versionId)
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
assignError: assign({
|
||||
error: (_, { data }) => data,
|
||||
}),
|
||||
|
||||
assignWorkspace: assign({
|
||||
workspace: (_, { data }) => data,
|
||||
}),
|
||||
|
||||
assignTemplateData: assign({
|
||||
template: (_, { data }) => data.template,
|
||||
templateVersions: (_, { data }) => data.versions,
|
||||
}),
|
||||
},
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user