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: add frontend support for enabling automatic workspace updates#10375

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
sreya merged 11 commits intomainfromjon/wsautoupdatefe
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
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
15 changes: 15 additions & 0 deletionssite/src/api/api.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -576,6 +576,21 @@ export const updateWorkspaceDormancy = async (
return response.data;
};

export const updateWorkspaceAutomaticUpdates = async (
workspaceId: string,
automaticUpdates: TypesGen.AutomaticUpdates,
): Promise<void> => {
const req: TypesGen.UpdateWorkspaceAutomaticUpdatesRequest = {
automatic_updates: automaticUpdates,
};

const response = await axios.put(
`/api/v2/workspaces/${workspaceId}/autoupdates`,
req,
);
return response.data;
};

export const restartWorkspace = async ({
workspace,
buildParameters,
Expand Down
8 changes: 8 additions & 0 deletionssite/src/components/Dashboard/DashboardProvider.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -121,3 +121,11 @@ export const useIsWorkspaceActionsEnabled = (): boolean => {
const allowWorkspaceActions = experiments.includes("workspace_actions");
return allowWorkspaceActions && allowAdvancedScheduling;
};

export const useTemplatePoliciesEnabled = (): boolean => {
const { entitlements, experiments } = useDashboard();
return (
entitlements.features.access_control.enabled &&
experiments.includes("template_update_policies")
);
};
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,18 +10,15 @@ import { useTemplateSettings } from "../TemplateSettingsLayout";
import { TemplateSettingsPageView } from "./TemplateSettingsPageView";
import { templateByNameKey } from "api/queries/templates";
import { useOrganizationId } from "hooks";
import {useDashboard } from "components/Dashboard/DashboardProvider";
import {useTemplatePoliciesEnabled } from "components/Dashboard/DashboardProvider";

export const TemplateSettingsPage: FC = () => {
const { template: templateName } = useParams() as { template: string };
const navigate = useNavigate();
const orgId = useOrganizationId();
const { template } = useTemplateSettings();
const queryClient = useQueryClient();
const { entitlements, experiments } = useDashboard();
const accessControlEnabled =
entitlements.features["advanced_template_scheduling"].enabled &&
experiments.includes("template_update_policies");
const accessControlEnabled = useTemplatePoliciesEnabled();

const {
mutate: updateTemplate,
Expand Down
1 change: 1 addition & 0 deletionssite/src/pages/WorkspacePage/Workspace.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -191,6 +191,7 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
quotaBudget={quotaBudget}
handleUpdate={handleUpdate}
canUpdateWorkspace={canUpdateWorkspace}
canChangeVersions={canChangeVersions}
maxDeadlineDecrease={scheduleProps.maxDeadlineDecrease}
maxDeadlineIncrease={scheduleProps.maxDeadlineIncrease}
onDeadlineMinus={scheduleProps.onDeadlineMinus}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
import { Workspace, WorkspaceStatus } from "api/typesGenerated";
import { ReactNode } from "react";
import { workspaceUpdatePolicy } from "utils/workspace";

// the button types we have
export enum ButtonTypesEnum {
Expand DownExpand Up@@ -43,9 +44,8 @@ export const actionsByWorkspaceStatus = (
};
}
if (
workspace.template_require_active_version &&
workspace.outdated &&
!canChangeVersions
workspaceUpdatePolicy(workspace,canChangeVersions)
) {
if (status === "running") {
return {
Expand Down
32 changes: 32 additions & 0 deletionssite/src/pages/WorkspacePage/WorkspaceStats.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,7 @@ import {
getDisplayWorkspaceBuildInitiatedBy,
getDisplayWorkspaceTemplateName,
isWorkspaceOn,
workspaceUpdatePolicy,
} from "utils/workspace";
import { Workspace } from "api/typesGenerated";
import { Stats, StatsItem } from "components/Stats/Stats";
Expand All@@ -26,6 +27,12 @@ import {
PopoverTrigger,
usePopover,
} from "components/Popover/Popover";
import { useTemplatePoliciesEnabled } from "components/Dashboard/DashboardProvider";
import {
HelpTooltip,
HelpTooltipText,
} from "components/HelpTooltip/HelpTooltip";
import { Stack } from "components/Stack/Stack";

const Language = {
workspaceDetails: "Workspace Details",
Expand All@@ -37,13 +44,15 @@ const Language = {
upToDate: "Up to date",
byLabel: "Last built by",
costLabel: "Daily cost",
updatePolicy: "Update policy",
};

export interface WorkspaceStatsProps {
workspace: Workspace;
maxDeadlineIncrease: number;
maxDeadlineDecrease: number;
canUpdateWorkspace: boolean;
canChangeVersions: boolean;
quotaBudget?: number;
onDeadlinePlus: (hours: number) => void;
onDeadlineMinus: (hours: number) => void;
Expand All@@ -56,6 +65,7 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({
maxDeadlineDecrease,
maxDeadlineIncrease,
canUpdateWorkspace,
canChangeVersions,
handleUpdate,
onDeadlineMinus,
onDeadlinePlus,
Expand All@@ -67,6 +77,7 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({
const styles = useStyles();
const deadlinePlusEnabled = maxDeadlineIncrease >= 1;
const deadlineMinusEnabled = maxDeadlineDecrease >= 1;
const templatePoliciesEnabled = useTemplatePoliciesEnabled();

return (
<>
Expand DownExpand Up@@ -198,6 +209,27 @@ export const WorkspaceStats: FC<WorkspaceStatsProps> = ({
}`}
/>
)}
{templatePoliciesEnabled && (
<Stack direction="row" spacing={0.5}>
<StatsItem
className={styles.statsItem}
label={Language.updatePolicy}
value={upperFirst(
workspaceUpdatePolicy(workspace, canChangeVersions),
)}
/>
{workspace.automatic_updates === "never" &&
workspace.template_require_active_version &&
!canChangeVersions && (
<HelpTooltip>
<HelpTooltipText>
Your workspace has not opted in to automatic updates but
your template requires updating to the active version.
</HelpTooltipText>
</HelpTooltip>
)}
</Stack>
)}
</Stats>
</>
);
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,27 +13,36 @@ import {
getFormHelpers,
onChangeTrimmed,
} from "utils/formUtils";
import { Workspace } from "api/typesGenerated";
import {
AutomaticUpdates,
AutomaticUpdateses,
Copy link
Member

Choose a reason for hiding this comment

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

this name sounds like we hired gollum 😂

sreya reacted with laugh emoji
Workspace,
} from "api/typesGenerated";
import { Alert } from "components/Alert/Alert";
import MenuItem from "@mui/material/MenuItem";
import upperFirst from "lodash/upperFirst";

export type WorkspaceSettingsFormValues = {
name: string;
automatic_updates: AutomaticUpdates;
};

export const WorkspaceSettingsForm: FC<{
isSubmitting: boolean;
workspace: Workspace;
error: unknown;
templatePoliciesEnabled: boolean;
onCancel: () => void;
onSubmit: (values: WorkspaceSettingsFormValues) => void;
}> = ({ onCancel, onSubmit, workspace, error,isSubmitting }) => {
onSubmit: (values: WorkspaceSettingsFormValues) =>Promise<void>;
}> = ({ onCancel, onSubmit, workspace, error,templatePoliciesEnabled }) => {
const form = useFormik<WorkspaceSettingsFormValues>({
onSubmit,
initialValues: {
name: workspace.name,
automatic_updates: workspace.automatic_updates,
},
validationSchema: Yup.object({
name: nameValidator("Name"),
automatic_updates: Yup.string().oneOf(AutomaticUpdateses),
}),
});
const getFieldHelpers = getFormHelpers<WorkspaceSettingsFormValues>(
Expand All@@ -43,7 +52,10 @@ export const WorkspaceSettingsForm: FC<{

return (
<HorizontalForm onSubmit={form.handleSubmit} data-testid="form">
<FormSection title="General" description="The name of your workspace.">
<FormSection
title="Workspace Name"
description="Update the name of your workspace."
>
<FormFields>
<TextField
{...getFieldHelpers("name")}
Expand All@@ -61,7 +73,30 @@ export const WorkspaceSettingsForm: FC<{
)}
</FormFields>
</FormSection>
<FormFooter onCancel={onCancel} isLoading={isSubmitting} />
{templatePoliciesEnabled && (
<FormSection
title="Automatic Updates"
description="Configure your workspace to automatically update when started."
>
<FormFields>
<TextField
{...getFieldHelpers("automatic_updates")}
id="automatic_updates"
label="Update Policy"
value={form.values.automatic_updates}
select
disabled={form.isSubmitting}
>
{AutomaticUpdateses.map((value) => (
<MenuItem value={value} key={value}>
{upperFirst(value)}
</MenuItem>
))}
</TextField>
</FormFields>
</FormSection>
)}
<FormFooter onCancel={onCancel} isLoading={form.isSubmitting} />
</HorizontalForm>
);
};
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,8 +5,9 @@ import { useWorkspaceSettings } from "./WorkspaceSettingsLayout";
import { WorkspaceSettingsPageView } from "./WorkspaceSettingsPageView";
import { useMutation } from "react-query";
import { displaySuccess } from "components/GlobalSnackbar/utils";
import { patchWorkspace } from "api/api";
import { patchWorkspace, updateWorkspaceAutomaticUpdates } from "api/api";
import { WorkspaceSettingsFormValues } from "./WorkspaceSettingsForm";
import { useTemplatePoliciesEnabled } from "components/Dashboard/DashboardProvider";

const WorkspaceSettingsPage = () => {
const params = useParams() as {
Expand All@@ -17,9 +18,18 @@ const WorkspaceSettingsPage = () => {
const username = params.username.replace("@", "");
const workspace = useWorkspaceSettings();
const navigate = useNavigate();
const templatePoliciesEnabled = useTemplatePoliciesEnabled();

const mutation = useMutation({
mutationFn: (formValues: WorkspaceSettingsFormValues) =>
patchWorkspace(workspace.id, { name: formValues.name }),
mutationFn: async (formValues: WorkspaceSettingsFormValues) => {
await Promise.all([
patchWorkspace(workspace.id, { name: formValues.name }),
updateWorkspaceAutomaticUpdates(
workspace.id,
formValues.automatic_updates,
),
]);
},
onSuccess: (_, formValues) => {
displaySuccess("Workspace updated successfully");
navigate(`/@${username}/${formValues.name}/settings`);
Expand All@@ -34,10 +44,10 @@ const WorkspaceSettingsPage = () => {

<WorkspaceSettingsPageView
error={mutation.error}
isSubmitting={mutation.isLoading}
workspace={workspace}
onCancel={() => navigate(`/@${username}/${workspaceName}`)}
onSubmit={mutation.mutate}
onSubmit={mutation.mutateAsync}
templatePoliciesEnabled={templatePoliciesEnabled}
/>
</>
);
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,14 +7,17 @@ const meta: Meta<typeof WorkspaceSettingsPageView> = {
component: WorkspaceSettingsPageView,
args: {
error: undefined,
isSubmitting: false,
workspace: MockWorkspace,
},
};

export default meta;
type Story = StoryObj<typeof WorkspaceSettingsPageView>;

const Example: Story = {};
exportconst Example: Story = {};

export { Example as WorkspaceSettingsPageView };
export const AutoUpdates: Story = {
args: {
templatePoliciesEnabled: true,
},
};
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,18 +5,18 @@ import { Workspace } from "api/typesGenerated";

export type WorkspaceSettingsPageViewProps = {
error: unknown;
isSubmitting: boolean;
workspace: Workspace;
onCancel: () => void;
onSubmit: ComponentProps<typeof WorkspaceSettingsForm>["onSubmit"];
templatePoliciesEnabled: boolean;
};

export const WorkspaceSettingsPageView: FC<WorkspaceSettingsPageViewProps> = ({
onCancel,
onSubmit,
isSubmitting,
error,
workspace,
templatePoliciesEnabled,
}) => {
return (
<>
Expand All@@ -30,10 +30,10 @@ export const WorkspaceSettingsPageView: FC<WorkspaceSettingsPageViewProps> = ({

<WorkspaceSettingsForm
error={error}
isSubmitting={isSubmitting}
workspace={workspace}
onCancel={onCancel}
onSubmit={onSubmit}
templatePoliciesEnabled={templatePoliciesEnabled}
/>
</>
);
Expand Down
12 changes: 12 additions & 0 deletionssite/src/utils/workspace.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -303,3 +303,15 @@ export const getMatchingAgentOrFirst = (
})
.filter((a) => a)[0];
};

export const workspaceUpdatePolicy = (
workspace: TypesGen.Workspace,
canChangeVersions: boolean,
): TypesGen.AutomaticUpdates => {
// If a template requires the active version and you cannot change versions
// (restricted to template admins), then your policy must be "Always".
if (workspace.template_require_active_version && !canChangeVersions) {
return "always";
}
return workspace.automatic_updates;
};

[8]ページ先頭

©2009-2025 Movatter.jp