Skip to content

feat: give users ability to duplicate existing workspaces #10195

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

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d126314
refactor: clean up CreateWorkspacePage
Parkreiner Oct 9, 2023
881d4a3
fix: remove unnecessary state
Parkreiner Oct 9, 2023
f793fe4
refactor: clean up auth logic more
Parkreiner Oct 10, 2023
2416958
refactor: remove enums from workspace actions
Parkreiner Oct 10, 2023
e97cdd8
fix: export ButtonType type
Parkreiner Oct 10, 2023
0af0352
refactor: remove workspace error enums
Parkreiner Oct 10, 2023
61b26f5
chore: get basic clone functionality done for UI
Parkreiner Oct 10, 2023
f0e120b
fix: clean up Create page view again
Parkreiner Oct 11, 2023
f2380fe
Merge branch 'main' into mes/workspace-clone
Parkreiner Oct 11, 2023
53a9cae
refactor/fix: reconcile merge changes from new PR
Parkreiner Oct 11, 2023
d98a5e0
refactor: centralize workspace duplication logic
Parkreiner Oct 12, 2023
ac86d94
refactor: rename rich params validator for clarity
Parkreiner Oct 12, 2023
e290ece
refactor: clean up getInitialRichParameterValues for clarity
Parkreiner Oct 13, 2023
49b4ad6
refactor: clean up TemplateParameters components
Parkreiner Oct 13, 2023
f6b9285
fix: update imports for validator name change
Parkreiner Oct 13, 2023
ba6e20c
wip: commit progress for creating workspaces
Parkreiner Oct 13, 2023
2a7f9e0
refactor: centralize out workspace parameter fetching logic
Parkreiner Oct 13, 2023
bbe44a1
refactor: centralize workspace parameter mutation logic
Parkreiner Oct 13, 2023
1fb2205
feat: get cloning functionality finished
Parkreiner Oct 13, 2023
a7d1ea9
Merge branch 'main' into mes/workspace-clone
Parkreiner Oct 16, 2023
239bddc
fix: make sure button does not auto-submit connected forms
Parkreiner Oct 16, 2023
8dcbc61
fix: add mocked response for created workspaces
Parkreiner Oct 16, 2023
81f868f
Merge branch 'main' into mes/workspace-clone
Parkreiner Oct 19, 2023
2d51fc9
fix: make it possible to split immutable/mutable params
Parkreiner Oct 19, 2023
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
13 changes: 12 additions & 1 deletion site/src/api/queries/workspaceBuilds.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { UseInfiniteQueryOptions } from "react-query";
import { QueryOptions, UseInfiniteQueryOptions } from "react-query";
import * as API from "api/api";
import { WorkspaceBuild, WorkspaceBuildsRequest } from "api/typesGenerated";

export function workspaceBuildParametersKey(workspaceId: string) {
return ["workspaceBuilds", workspaceId, "parameters"] as const;
}

export function workspaceBuildParameters(workspaceBuildId: string) {
return {
queryKey: workspaceBuildParametersKey(workspaceBuildId),
queryFn: () => API.getWorkspaceBuildParameters(workspaceBuildId),
} as const satisfies QueryOptions;
}

export const workspaceBuildByNumber = (
username: string,
workspaceName: string,
Expand Down
23 changes: 22 additions & 1 deletion site/src/api/queries/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const workspaceByOwnerAndName = (
};
};

type AutoCreateWorkspaceOptions = {
export type AutoCreateWorkspaceOptions = {
templateName: string;
versionId?: string;
organizationId: string;
Expand Down Expand Up @@ -84,6 +84,27 @@ export const autoCreateWorkspace = (queryClient: QueryClient) => {
};
};

export function workspaceParametersKey(workspaceId: string) {
return ["workspaces", workspaceId, "parameters"] as const;
}

export function workspaceParameters(workspace: Workspace) {
return {
queryKey: workspaceParametersKey(workspace.id),
queryFn: () => API.getWorkspaceParameters(workspace),
} as const;
}

export function updateWorkspaceParameters(workspaceId: string) {
return {
mutationFn: (buildParameters: WorkspaceBuildParameter[]) =>
API.postWorkspaceBuild(workspaceId, {
transition: "start",
rich_parameter_values: buildParameters,
}),
} as const;
}

export function workspacesKey(config: WorkspacesRequest = {}) {
const { q, limit } = config;
return ["workspaces", { q, limit }] as const;
Expand Down
98 changes: 45 additions & 53 deletions site/src/components/TemplateParameters/TemplateParameters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,68 +17,60 @@ export type TemplateParametersSectionProps = {
export const MutableTemplateParametersSection: FC<
TemplateParametersSectionProps
> = ({ templateParameters, getInputProps, ...formSectionProps }) => {
const hasMutableParameters =
templateParameters.filter((p) => p.mutable).length > 0;
const mutableParameters = templateParameters.filter((p) => p.mutable);

if (mutableParameters.length === 0) {
return null;
}

return (
<>
{hasMutableParameters && (
<FormSection
{...formSectionProps}
title="Parameters"
description="Settings used by your template"
>
<FormFields>
{templateParameters.map(
(parameter, index) =>
parameter.mutable && (
<RichParameterInput
{...getInputProps(parameter, index)}
key={parameter.name}
parameter={parameter}
/>
),
)}
</FormFields>
</FormSection>
)}
</>
<FormSection
{...formSectionProps}
title="Parameters"
description="Settings used by your template"
>
<FormFields>
{mutableParameters.map((parameter, index) => (
<RichParameterInput
{...getInputProps(parameter, index)}
key={parameter.name}
parameter={parameter}
/>
))}
</FormFields>
</FormSection>
);
};

export const ImmutableTemplateParametersSection: FC<
TemplateParametersSectionProps
> = ({ templateParameters, getInputProps, ...formSectionProps }) => {
const hasImmutableParameters =
templateParameters.filter((p) => !p.mutable).length > 0;
const immutableParams = templateParameters.filter((p) => !p.mutable);

if (immutableParams.length === 0) {
return null;
}

return (
<>
{hasImmutableParameters && (
<FormSection
{...formSectionProps}
title="Immutable parameters"
description={
<>
These settings <strong>cannot be changed</strong> after creating
the workspace.
</>
}
>
<FormFields>
{templateParameters.map(
(parameter, index) =>
!parameter.mutable && (
<RichParameterInput
{...getInputProps(parameter, index)}
key={parameter.name}
parameter={parameter}
/>
),
)}
</FormFields>
</FormSection>
)}
</>
<FormSection
{...formSectionProps}
title="Immutable parameters"
description={
<>
These settings <strong>cannot be changed</strong> after creating the
workspace.
</>
}
>
<FormFields>
{immutableParams.map((parameter, index) => (
<RichParameterInput
{...getInputProps(parameter, index)}
key={parameter.name}
parameter={parameter}
/>
))}
</FormFields>
</FormSection>
);
};
Loading