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: handle update build for dynamic params#18226

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
jaaydenh merged 16 commits intomainfromjaaydenh/update-build-parameters
Jun 5, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
16 commits
Select commitHold shift + click to select a range
39200b9
feat: handle update build for dynamic params
jaaydenhJun 4, 2025
e7d38cf
feat: pass template version id to workspace parameters page
jaaydenhJun 4, 2025
561a0eb
feat: check opt-in per template
jaaydenhJun 4, 2025
67ac3c7
fix: format
jaaydenhJun 4, 2025
38ae3c7
fix: cleanup logic
jaaydenhJun 4, 2025
8c50de0
chore: cleanup
jaaydenhJun 4, 2025
86af69d
fix: cleanup
jaaydenhJun 4, 2025
6a20a0d
fix: update test calls to match new updateWorkspace signature
blink-so[bot]Jun 5, 2025
c82b145
fix: handle missing dynamic-parameters experiment in parameter dialogs
blink-so[bot]Jun 5, 2025
9878ade
fix: format
jaaydenhJun 5, 2025
b8131a5
fix: format
jaaydenhJun 5, 2025
f2876d2
fix: lint error
jaaydenhJun 5, 2025
962f5fd
fix: remove unnecessary parameters
jaaydenhJun 5, 2025
80fd236
fix: fix tests
jaaydenhJun 5, 2025
9117b7f
fix: send existing build parameters for dynamic params
jaaydenhJun 5, 2025
d2856cd
fix: handle multi-select
jaaydenhJun 5, 2025
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
92 changes: 82 additions & 10 deletionssite/src/api/api.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,10 @@ import type dayjs from "dayjs";
import userAgentParser from "ua-parser-js";
import { OneWayWebSocket } from "../utils/OneWayWebSocket";
import { delay } from "../utils/delay";
import type { PostWorkspaceUsageRequest } from "./typesGenerated";
import type {
DynamicParametersRequest,
PostWorkspaceUsageRequest,
} from "./typesGenerated";
import * as TypesGen from "./typesGenerated";

const getMissingParameters = (
Expand DownExpand Up@@ -73,8 +76,10 @@ const getMissingParameters = (
if (templateParameter.options.length === 0) {
continue;
}

// Check if there is a new value
// For multi-select, extra steps are necessary to JSON parse the value.
if (templateParameter.form_type === "multi-select") {
continue;
}
let buildParameter = newBuildParameters.find(
(p) => p.name === templateParameter.name,
);
Expand DownExpand Up@@ -231,7 +236,7 @@ export const watchWorkspaceAgentLogs = (
/**
* WebSocket compression in Safari (confirmed in 16.5) is broken when
* the server sends large messages. The following error is seen:
* WebSocket connection to 'wss://...' failed: The operation couldnt be completed.
* WebSocket connection to 'wss://...' failed: The operation couldn't be completed.
*/
if (userAgentParser(navigator.userAgent).browser.name === "Safari") {
searchParams.set("no_compression", "");
Expand DownExpand Up@@ -990,6 +995,17 @@ class ApiMethods {
return response.data;
};

getTemplateVersionDynamicParameters = async (
versionId: string,
data: TypesGen.DynamicParametersRequest,
): Promise<TypesGen.DynamicParametersResponse> => {
const response = await this.axios.post(
`/api/v2/templateversions/${versionId}/dynamic-parameters/evaluate`,
data,
);
return response.data;
};

getTemplateVersionRichParameters = async (
versionId: string,
): Promise<TypesGen.TemplateVersionParameter[]> => {
Expand DownExpand Up@@ -2132,6 +2148,38 @@ class ApiMethods {
await this.axios.delete(`/api/v2/licenses/${licenseId}`);
};

getDynamicParameters = async (
templateVersionId: string,
ownerId: string,
oldBuildParameters: TypesGen.WorkspaceBuildParameter[],
) => {
const request: DynamicParametersRequest = {
id: 1,
owner_id: ownerId,
inputs: Object.fromEntries(
new Map(oldBuildParameters.map((param) => [param.name, param.value])),
),
};

const dynamicParametersResponse =
await this.getTemplateVersionDynamicParameters(
templateVersionId,
request,
);

return dynamicParametersResponse.parameters.map((p) => ({
...p,
description_plaintext: p.description || "",
default_value: p.default_value?.valid ? p.default_value.value : "",
options: p.options
? p.options.map((opt) => ({
...opt,
value: opt.value?.valid ? opt.value.value : "",
}))
: [],
}));
};

/** Steps to change the workspace version
* - Get the latest template to access the latest active version
* - Get the current build parameters
Expand All@@ -2145,11 +2193,23 @@ class ApiMethods {
workspace: TypesGen.Workspace,
templateVersionId: string,
newBuildParameters: TypesGen.WorkspaceBuildParameter[] = [],
isDynamicParametersEnabled = false,
): Promise<TypesGen.WorkspaceBuild> => {
const [currentBuildParameters, templateParameters] = await Promise.all([
this.getWorkspaceBuildParameters(workspace.latest_build.id),
this.getTemplateVersionRichParameters(templateVersionId),
]);
const currentBuildParameters = await this.getWorkspaceBuildParameters(
workspace.latest_build.id,
);

let templateParameters: TypesGen.TemplateVersionParameter[] = [];
if (isDynamicParametersEnabled) {
templateParameters = await this.getDynamicParameters(
templateVersionId,
workspace.owner_id,
currentBuildParameters,
);
} else {
templateParameters =
await this.getTemplateVersionRichParameters(templateVersionId);
}

const missingParameters = getMissingParameters(
currentBuildParameters,
Expand DownExpand Up@@ -2180,15 +2240,27 @@ class ApiMethods {
updateWorkspace = async (
workspace: TypesGen.Workspace,
newBuildParameters: TypesGen.WorkspaceBuildParameter[] = [],
isDynamicParametersEnabled = false,
): Promise<TypesGen.WorkspaceBuild> => {
const [template, oldBuildParameters] = await Promise.all([
this.getTemplate(workspace.template_id),
this.getWorkspaceBuildParameters(workspace.latest_build.id),
]);

const activeVersionId = template.active_version_id;
const templateParameters =
await this.getTemplateVersionRichParameters(activeVersionId);

let templateParameters: TypesGen.TemplateVersionParameter[] = [];

if (isDynamicParametersEnabled) {
templateParameters = await this.getDynamicParameters(
activeVersionId,
workspace.owner_id,
oldBuildParameters,
);
} else {
templateParameters =
await this.getTemplateVersionRichParameters(activeVersionId);
}

const missingParameters = getMissingParameters(
oldBuildParameters,
Expand Down
22 changes: 19 additions & 3 deletionssite/src/api/queries/workspaces.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -163,6 +163,7 @@ export const updateDeadline = (
export const changeVersion = (
workspace: Workspace,
queryClient: QueryClient,
isDynamicParametersEnabled: boolean,
) => {
return {
mutationFn: ({
Expand All@@ -172,7 +173,12 @@ export const changeVersion = (
versionId: string;
buildParameters?: WorkspaceBuildParameter[];
}) => {
return API.changeWorkspaceVersion(workspace, versionId, buildParameters);
return API.changeWorkspaceVersion(
workspace,
versionId,
buildParameters,
isDynamicParametersEnabled,
);
},
onSuccess: async (build: WorkspaceBuild) => {
await updateWorkspaceBuild(build, queryClient);
Expand All@@ -185,8 +191,18 @@ export const updateWorkspace = (
queryClient: QueryClient,
) => {
return {
mutationFn: (buildParameters?: WorkspaceBuildParameter[]) => {
return API.updateWorkspace(workspace, buildParameters);
mutationFn: ({
buildParameters,
isDynamicParametersEnabled,
}: {
buildParameters?: WorkspaceBuildParameter[];
isDynamicParametersEnabled: boolean;
}) => {
return API.updateWorkspace(
workspace,
buildParameters,
isDynamicParametersEnabled,
);
},
onSuccess: async (build: WorkspaceBuild) => {
await updateWorkspaceBuild(build, queryClient);
Expand Down
6 changes: 3 additions & 3 deletionssite/src/components/Dialog/Dialog.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,7 +45,7 @@ export const DialogContent = forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
`fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg gap-4
`fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg gap-6
border border-solid border-border bg-surface-primary p-8 shadow-lg duration-200 sm:rounded-lg
translate-x-[-50%] translate-y-[-50%]
data-[state=open]:animate-in data-[state=closed]:animate-out
Expand All@@ -68,7 +68,7 @@ export const DialogHeader: FC<HTMLAttributes<HTMLDivElement>> = ({
}) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
"flex flex-col space-y-5 text-center sm:text-left",
className,
)}
{...props}
Expand DownExpand Up@@ -108,7 +108,7 @@ export const DialogDescription = forwardRef<
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-content-secondary", className)}
className={cn("text-sm text-content-secondary font-medium", className)}
{...props}
/>
));
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
import { useQuery } from "react-query";

export const optOutKey = (id: string): string => `parameters.${id}.optOut`;

interface UseDynamicParametersOptOutOptions {
templateId: string | undefined;
templateUsesClassicParameters: boolean | undefined;
enabled: boolean;
}

export const useDynamicParametersOptOut = ({
templateId,
templateUsesClassicParameters,
enabled,
}: UseDynamicParametersOptOutOptions) => {
return useQuery({
enabled: !!templateId && enabled,
queryKey: ["dynamicParametersOptOut", templateId],
queryFn: () => {
if (!templateId) {
// This should not happen if enabled is working correctly,
// but as a type guard and sanity check.
throw new Error("templateId is required");
}
const localStorageKey = optOutKey(templateId);
const storedOptOutString = localStorage.getItem(localStorageKey);

let optedOut: boolean;

if (storedOptOutString !== null) {
optedOut = storedOptOutString === "true";
} else {
optedOut = Boolean(templateUsesClassicParameters);
}

return {
templateId,
optedOut,
};
},
});
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
import type { TemplateVersionParameter } from "api/typesGenerated";
import { Button } from "components/Button/Button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "components/Dialog/Dialog";
import type { FC } from "react";
import { useNavigate } from "react-router-dom";

type UpdateBuildParametersDialogExperimentalProps = {
open: boolean;
onClose: () => void;
missedParameters: TemplateVersionParameter[];
workspaceOwnerName: string;
workspaceName: string;
templateVersionId: string | undefined;
};

export const UpdateBuildParametersDialogExperimental: FC<
UpdateBuildParametersDialogExperimentalProps
> = ({
missedParameters,
open,
onClose,
workspaceOwnerName,
workspaceName,
templateVersionId,
}) => {
const navigate = useNavigate();

const handleGoToParameters = () => {
onClose();
navigate(
`/@${workspaceOwnerName}/${workspaceName}/settings/parameters?templateVersionId=${templateVersionId}`,
);
};

return (
<Dialog open={open} onOpenChange={(isOpen) => !isOpen && onClose()}>
<DialogContent>
<DialogHeader>
<DialogTitle>Update workspace parameters</DialogTitle>
<DialogDescription>
This template has{" "}
<strong className="text-content-primary">
{missedParameters.length} new parameter
{missedParameters.length === 1 ? "" : "s"}
</strong>{" "}
that must be configured to complete the update.
</DialogDescription>
<DialogDescription>
Would you like to go to the workspace parameters page to review and
update these parameters before continuing?
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button onClick={onClose} variant="outline">
Cancel
</Button>
<Button onClick={handleGoToParameters}>
Go to workspace parameters
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp