Skip to content

Commit 862c8f6

Browse files
committed
feat: make dynamic parameters opt-in by default for new templates
1 parent f41275e commit 862c8f6

File tree

15 files changed

+156
-29
lines changed

15 files changed

+156
-29
lines changed

coderd/database/dbgen/dbgen.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func Template(t testing.TB, db database.Store, seed database.Template) database.
147147
DisplayName: takeFirst(seed.DisplayName, testutil.GetRandomName(t)),
148148
AllowUserCancelWorkspaceJobs: seed.AllowUserCancelWorkspaceJobs,
149149
MaxPortSharingLevel: takeFirst(seed.MaxPortSharingLevel, database.AppSharingLevelOwner),
150-
UseClassicParameterFlow: takeFirst(seed.UseClassicParameterFlow, true),
150+
UseClassicParameterFlow: takeFirst(seed.UseClassicParameterFlow, false),
151151
})
152152
require.NoError(t, err, "insert template")
153153

coderd/insights_test.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -665,10 +665,11 @@ func TestTemplateInsights_Golden(t *testing.T) {
665665
// where we can control the template ID.
666666
// createdTemplate := coderdtest.CreateTemplate(t, client, firstUser.OrganizationID, version.ID)
667667
createdTemplate := dbgen.Template(t, db, database.Template{
668-
ID: template.id,
669-
ActiveVersionID: version.ID,
670-
OrganizationID: firstUser.OrganizationID,
671-
CreatedBy: firstUser.UserID,
668+
ID: template.id,
669+
ActiveVersionID: version.ID,
670+
OrganizationID: firstUser.OrganizationID,
671+
CreatedBy: firstUser.UserID,
672+
UseClassicParameterFlow: true,
672673
GroupACL: database.TemplateACL{
673674
firstUser.OrganizationID.String(): db2sdk.TemplateRoleActions(codersdk.TemplateRoleUse),
674675
},
@@ -1556,10 +1557,11 @@ func TestUserActivityInsights_Golden(t *testing.T) {
15561557
// where we can control the template ID.
15571558
// createdTemplate := coderdtest.CreateTemplate(t, client, firstUser.OrganizationID, version.ID)
15581559
createdTemplate := dbgen.Template(t, db, database.Template{
1559-
ID: template.id,
1560-
ActiveVersionID: version.ID,
1561-
OrganizationID: firstUser.OrganizationID,
1562-
CreatedBy: firstUser.UserID,
1560+
ID: template.id,
1561+
ActiveVersionID: version.ID,
1562+
OrganizationID: firstUser.OrganizationID,
1563+
CreatedBy: firstUser.UserID,
1564+
UseClassicParameterFlow: true, // Required for parameter usage tracking in this test
15631565
GroupACL: database.TemplateACL{
15641566
firstUser.OrganizationID.String(): db2sdk.TemplateRoleActions(codersdk.TemplateRoleUse),
15651567
},

coderd/templates.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
197197
return
198198
}
199199

200-
// Default is true until dynamic parameters are promoted to stable.
201-
useClassicParameterFlow := ptr.NilToDefault(createTemplate.UseClassicParameterFlow, true)
200+
// Default is false as dynamic parameters are now the preferred approach.
201+
useClassicParameterFlow := ptr.NilToDefault(createTemplate.UseClassicParameterFlow, false)
202202

203203
// Make a temporary struct to represent the template. This is used for
204204
// auditing if any of the following checks fail. It will be overwritten when

coderd/templates_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func TestPostTemplateByOrganization(t *testing.T) {
7777
assert.Equal(t, expected.Name, got.Name)
7878
assert.Equal(t, expected.Description, got.Description)
7979
assert.Equal(t, expected.ActivityBumpMillis, got.ActivityBumpMillis)
80-
assert.Equal(t, expected.UseClassicParameterFlow, true) // Current default is true
80+
assert.Equal(t, expected.UseClassicParameterFlow, false) // Current default is false
8181

8282
require.Len(t, auditor.AuditLogs(), 3)
8383
assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs()[0].Action)
@@ -1551,7 +1551,7 @@ func TestPatchTemplateMeta(t *testing.T) {
15511551
user := coderdtest.CreateFirstUser(t, client)
15521552
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
15531553
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
1554-
require.True(t, template.UseClassicParameterFlow, "default is true")
1554+
require.False(t, template.UseClassicParameterFlow, "default is false")
15551555

15561556
bTrue := true
15571557
bFalse := false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { render, screen } from "@testing-library/react";
2+
import { ClassicParameterFlowDeprecationWarning } from "./ClassicParameterFlowDeprecationWarning";
3+
4+
jest.mock("modules/navigation", () => ({
5+
useLinks: () => () => "/mock-link",
6+
linkToTemplate: () => "/mock-template-link",
7+
}));
8+
9+
describe("ClassicParameterFlowDeprecationWarning", () => {
10+
const defaultProps = {
11+
enabled: true,
12+
organizationName: "test-org",
13+
templateName: "test-template",
14+
canUpdateTemplate: true,
15+
};
16+
17+
it("renders warning when enabled and user has template update permissions", () => {
18+
render(<ClassicParameterFlowDeprecationWarning {...defaultProps} isEnabled={true} />);
19+
20+
expect(screen.getByText("deprecated")).toBeInTheDocument();
21+
expect(screen.getByText("Go to Template Settings")).toBeInTheDocument();
22+
});
23+
24+
it("does not render when enabled is false", () => {
25+
const { container } = render(
26+
<ClassicParameterFlowDeprecationWarning
27+
{...defaultProps}
28+
isEnabled={false}
29+
/>
30+
);
31+
32+
expect(container.firstChild).toBeNull();
33+
});
34+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Alert } from "components/Alert/Alert";
2+
import { Link } from "components/Link/Link";
3+
import { linkToTemplate, useLinks } from "modules/navigation";
4+
import type { FC } from "react";
5+
6+
interface ClassicParameterFlowDeprecationWarningProps {
7+
organizationName: string;
8+
templateName: string;
9+
isEnabled: boolean;
10+
}
11+
12+
export const ClassicParameterFlowDeprecationWarning: FC<
13+
ClassicParameterFlowDeprecationWarningProps
14+
> = ({ organizationName, templateName, isEnabled }) => {
15+
const getLink = useLinks();
16+
17+
if (!isEnabled) {
18+
return null;
19+
}
20+
21+
const templateSettingsLink = `${getLink(
22+
linkToTemplate(organizationName, templateName),
23+
)}/settings`;
24+
25+
return (
26+
<Alert severity="warning" className="mb-2">
27+
<div>
28+
This template is using the classic parameter flow, which will be{" "}
29+
<strong>deprecated</strong> in a future release.
30+
Please migrate to dynamic improved functionality.
31+
</div>
32+
<Link className="text-xs" href={templateSettingsLink}>
33+
Go to Template Settings
34+
</Link>
35+
</Alert>
36+
);
37+
};

site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ const CreateWorkspacePage: FC = () => {
6969
}),
7070
enabled: !!templateQuery.data,
7171
});
72+
const templatePermissionsQuery = useQuery({
73+
...checkAuthorization({
74+
checks: {
75+
canUpdateTemplate: {
76+
object: {
77+
resource_type: "template",
78+
resource_id: templateQuery.data?.id ?? "",
79+
},
80+
action: "update",
81+
},
82+
},
83+
}),
84+
enabled: !!templateQuery.data,
85+
});
7286
const realizedVersionId =
7387
customVersionId ?? templateQuery.data?.active_version_id;
7488
const organizationId = templateQuery.data?.organization_id;
@@ -90,9 +104,10 @@ const CreateWorkspacePage: FC = () => {
90104
const isLoadingFormData =
91105
templateQuery.isLoading ||
92106
permissionsQuery.isLoading ||
107+
templatePermissionsQuery.isLoading ||
93108
richParametersQuery.isLoading;
94109
const loadFormDataError =
95-
templateQuery.error ?? permissionsQuery.error ?? richParametersQuery.error;
110+
templateQuery.error ?? permissionsQuery.error ?? templatePermissionsQuery.error ?? richParametersQuery.error;
96111

97112
const title = autoCreateWorkspaceMutation.isPending
98113
? "Creating workspace..."
@@ -208,6 +223,7 @@ const CreateWorkspacePage: FC = () => {
208223
startPollingExternalAuth={startPollingExternalAuth}
209224
hasAllRequiredExternalAuth={hasAllRequiredExternalAuth}
210225
permissions={permissionsQuery.data as CreateWorkspacePermissions}
226+
templatePermissions={templatePermissionsQuery.data as { canUpdateTemplate: boolean }}
211227
parameters={realizedParameters as TemplateVersionParameter[]}
212228
presets={templateVersionPresetsQuery.data ?? []}
213229
creatingWorkspace={createWorkspaceMutation.isPending}

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { Switch } from "components/Switch/Switch";
2727
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
2828
import { type FormikContextType, useFormik } from "formik";
2929
import type { ExternalAuthPollingState } from "hooks/useExternalAuth";
30+
import { ClassicParameterFlowDeprecationWarning } from "modules/workspaces/ClassicParameterFlowDeprecationWarning/ClassicParameterFlowDeprecationWarning";
3031
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
3132
import { type FC, useCallback, useEffect, useMemo, useState } from "react";
3233
import {
@@ -66,6 +67,7 @@ interface CreateWorkspacePageViewProps {
6667
autofillParameters: AutofillBuildParameter[];
6768
presets: TypesGen.Preset[];
6869
permissions: CreateWorkspacePermissions;
70+
templatePermissions: { canUpdateTemplate: boolean };
6971
creatingWorkspace: boolean;
7072
onCancel: () => void;
7173
onSubmit: (
@@ -91,6 +93,7 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
9193
autofillParameters,
9294
presets = [],
9395
permissions,
96+
templatePermissions,
9497
creatingWorkspace,
9598
onSubmit,
9699
onCancel,
@@ -245,6 +248,12 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
245248
</Stack>
246249
</PageHeader>
247250

251+
<ClassicParameterFlowDeprecationWarning
252+
organizationName={template.organization_name}
253+
templateName={template.name}
254+
isEnabled={templatePermissions.canUpdateTemplate}
255+
/>
256+
248257
<HorizontalForm
249258
name="create-workspace-form"
250259
onSubmit={form.handleSubmit}

site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ export const CreateWorkspacePageViewExperimental: FC<
394394
<br />
395395
<Link
396396
href={docs(
397-
"/admin/templates/extending-templates/parameters#enable-dynamic-parameters-early-access",
397+
"/admin/templates/extending-templates/dynamic-parameters",
398398
)}
399399
>
400400
View docs
@@ -542,7 +542,7 @@ export const CreateWorkspacePageViewExperimental: FC<
542542
parameters cannot be modified once the workspace is created.
543543
<Link
544544
href={docs(
545-
"/admin/templates/extending-templates/parameters#enable-dynamic-parameters-early-access",
545+
"/admin/templates/extending-templates/dynamic-parameters",
546546
)}
547547
>
548548
View docs

site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsForm.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,19 +245,20 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
245245
label={
246246
<StackLabel>
247247
<span className="flex flex-row gap-2">
248-
Enable dynamic parameters for workspace creation
248+
Enable dynamic parameters for workspace creation (recommended)
249249
</span>
250250
<StackLabelHelperText>
251251
<div>
252-
The new workspace form allows you to design your template
253-
with new form types and identity-aware conditional
254-
parameters. The form will only present options that are
255-
compatible and available.
252+
The dynamic workspace form allows you to design your
253+
template with additional form types and identity-aware
254+
conditional parameters. This is the default option for new
255+
templates. The classic workspace creation flow will be
256+
deprecated in a future release.
256257
</div>
257258
<Link
258259
className="text-xs"
259260
href={docs(
260-
"/admin/templates/extending-templates/parameters#dynamic-parameters-beta",
261+
"/admin/templates/extending-templates/dynamic-parameters",
261262
)}
262263
>
263264
Learn more

0 commit comments

Comments
 (0)