diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index d8cd4aab5036e..be21ff3eaa17c 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -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"), ) @@ -228,10 +225,6 @@ export const AppRouter: FC = () => { path="builds/:buildNumber" element={} /> - } - /> } /> diff --git a/site/src/components/DropdownButton/ActionCtas.tsx b/site/src/components/DropdownButton/ActionCtas.tsx index bc505db375c5c..29b63c5fd6a6a 100644 --- a/site/src/components/DropdownButton/ActionCtas.tsx +++ b/site/src/components/DropdownButton/ActionCtas.tsx @@ -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> = ({ ) } -export const ChangeVersionButton: FC< - React.PropsWithChildren -> = ({ handleAction }) => { - const styles = useStyles() - const { t } = useTranslation("workspacePage") - - return ( - - ) -} - export const SettingsButton: FC> = ({ handleAction, }) => { diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index 22be3c6f18abe..ff4cdf7364f96 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -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> = ({ handleDelete, handleUpdate, handleCancel, - handleChangeVersion, handleSettings, workspace, isUpdating, @@ -130,7 +128,6 @@ export const Workspace: FC> = ({ handleDelete={handleDelete} handleUpdate={handleUpdate} handleCancel={handleCancel} - handleChangeVersion={handleChangeVersion} handleSettings={handleSettings} isUpdating={isUpdating} /> diff --git a/site/src/components/WorkspaceActions/WorkspaceActions.test.tsx b/site/src/components/WorkspaceActions/WorkspaceActions.test.tsx index 6220f0a987bbb..98c8c3e7fd1af 100644 --- a/site/src/components/WorkspaceActions/WorkspaceActions.test.tsx +++ b/site/src/components/WorkspaceActions/WorkspaceActions.test.tsx @@ -18,7 +18,6 @@ const renderComponent = async (props: Partial = {}) => { 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 = {}) => { handleDelete={jest.fn()} handleUpdate={jest.fn()} handleCancel={jest.fn()} - handleChangeVersion={jest.fn()} handleSettings={jest.fn()} isUpdating={false} />, diff --git a/site/src/components/WorkspaceActions/WorkspaceActions.tsx b/site/src/components/WorkspaceActions/WorkspaceActions.tsx index 9a65d0b5e5f81..c4e9fde2d25d9 100644 --- a/site/src/components/WorkspaceActions/WorkspaceActions.tsx +++ b/site/src/components/WorkspaceActions/WorkspaceActions.tsx @@ -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 = ({ handleDelete, handleUpdate, handleCancel, - handleChangeVersion, handleSettings, isUpdating, }) => { @@ -50,9 +47,6 @@ export const WorkspaceActions: FC = ({ [ButtonTypesEnum.updating]: ( ), - [ButtonTypesEnum.changeVersion]: ( - - ), [ButtonTypesEnum.settings]: ( ), diff --git a/site/src/components/WorkspaceActions/constants.ts b/site/src/components/WorkspaceActions/constants.ts index 94ccc351e8c1b..383a708f73011 100644 --- a/site/src/components/WorkspaceActions/constants.ts +++ b/site/src/components/WorkspaceActions/constants.ts @@ -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 = { actions: [ ButtonTypesEnum.stop, ButtonTypesEnum.settings, - ButtonTypesEnum.changeVersion, ButtonTypesEnum.delete, ], canCancel: false, @@ -60,7 +58,6 @@ const statusToAbilities: Record = { actions: [ ButtonTypesEnum.start, ButtonTypesEnum.settings, - ButtonTypesEnum.changeVersion, ButtonTypesEnum.delete, ], canCancel: false, @@ -71,7 +68,6 @@ const statusToAbilities: Record = { ButtonTypesEnum.start, ButtonTypesEnum.stop, ButtonTypesEnum.settings, - ButtonTypesEnum.changeVersion, ButtonTypesEnum.delete, ], canCancel: false, @@ -83,7 +79,6 @@ const statusToAbilities: Record = { ButtonTypesEnum.start, ButtonTypesEnum.stop, ButtonTypesEnum.settings, - ButtonTypesEnum.changeVersion, ButtonTypesEnum.delete, ], canCancel: false, diff --git a/site/src/i18n/en/index.ts b/site/src/i18n/en/index.ts index 8176c9d34b9bb..d1ce33a2e2e22 100644 --- a/site/src/i18n/en/index.ts +++ b/site/src/i18n/en/index.ts @@ -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, diff --git a/site/src/i18n/en/workspaceChangeVersionPage.json b/site/src/i18n/en/workspaceChangeVersionPage.json deleted file mode 100644 index 08e58705655ec..0000000000000 --- a/site/src/i18n/en/workspaceChangeVersionPage.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "title": "", - "labels": { - "workspaceVersion": "Workspace version", - "submit": "Update version", - "createdBy": "Created by", - "active": "Active" - } -} diff --git a/site/src/i18n/en/workspacePage.json b/site/src/i18n/en/workspacePage.json index 3c4de459f9fef..b9b63d1d3d9da 100644 --- a/site/src/i18n/en/workspacePage.json +++ b/site/src/i18n/en/workspacePage.json @@ -28,7 +28,6 @@ "starting": "Starting...", "stopping": "Stopping...", "deleting": "Deleting...", - "changeVersion": "Change version", "settings": "Settings" }, "disabledButton": { diff --git a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionForm.tsx b/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionForm.tsx deleted file mode 100644 index e294abe20539f..0000000000000 --- a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionForm.tsx +++ /dev/null @@ -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 ( -
- - -
- -
- - {workspace.name} - - - {workspace.template_display_name.length > 0 - ? workspace.template_display_name - : workspace.template_name} - - -
- - { - if (value) { - await formik.setFieldValue("versionId", value.id) - } - }} - renderInput={(params) => ( - - )} - getOptionLabel={(version: TemplateVersion) => version.name} - renderOption={(version: TemplateVersion) => ( -
-
-
{version.name}
-
- {t("labels.createdBy")} {version.created_by.username}{" "} - {createDayString(version.created_at)} -
-
- - {template.active_version_id === version.id && ( - - )} -
- )} - /> -
- - - - ) -} - -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), - }, -})) diff --git a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPage.test.tsx b/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPage.test.tsx deleted file mode 100644 index 9d398dce6d3bd..0000000000000 --- a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPage.test.tsx +++ /dev/null @@ -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(, { - 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, - ) - }) - }) -}) diff --git a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPage.tsx b/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPage.tsx deleted file mode 100644 index 14a1ebfdf4e07..0000000000000 --- a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPage.tsx +++ /dev/null @@ -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 ( - <> - - {`${t("title")} ยท ${workspaceName}`} - - - { - send({ - type: "UPDATE_VERSION", - versionId, - }) - }} - /> - - ) -} - -export default WorkspaceChangeVersionPage diff --git a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPageView.stories.tsx b/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPageView.stories.tsx deleted file mode 100644 index ed6cbb279fa93..0000000000000 --- a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPageView.stories.tsx +++ /dev/null @@ -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 - -const Template: Story = (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, - }, -} diff --git a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPageView.tsx b/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPageView.tsx deleted file mode 100644 index c555fea7640c9..0000000000000 --- a/site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionPageView.tsx +++ /dev/null @@ -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 ( - - - - - - {workspace && template && templateVersions ? ( - { - navigate(-1) - }} - /> - ) : ( - - )} - - - ) -} diff --git a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx index 323b685c3a449..f487ebdede725 100644 --- a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx @@ -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} diff --git a/site/src/xServices/workspace/changeWorkspaceVersionXService.ts b/site/src/xServices/workspace/changeWorkspaceVersionXService.ts deleted file mode 100644 index 4031287453c5b..0000000000000 --- a/site/src/xServices/workspace/changeWorkspaceVersionXService.ts +++ /dev/null @@ -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, - }), - }, - }, -)