Skip to content

Commit 28789d7

Browse files
feat: add View Source button for template administrators in workspace creation (#18951)
1 parent bb83071 commit 28789d7

7 files changed

+100
-9
lines changed

site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ const CreateWorkspacePage: FC = () => {
6565
});
6666
const permissionsQuery = useQuery({
6767
...checkAuthorization({
68-
checks: createWorkspaceChecks(templateQuery.data?.organization_id ?? ""),
68+
checks: createWorkspaceChecks(
69+
templateQuery.data?.organization_id ?? "",
70+
templateQuery.data?.id,
71+
),
6972
}),
7073
enabled: !!templateQuery.data,
7174
});
@@ -208,6 +211,7 @@ const CreateWorkspacePage: FC = () => {
208211
startPollingExternalAuth={startPollingExternalAuth}
209212
hasAllRequiredExternalAuth={hasAllRequiredExternalAuth}
210213
permissions={permissionsQuery.data as CreateWorkspacePermissions}
214+
canUpdateTemplate={permissionsQuery.data?.canUpdateTemplate}
211215
parameters={realizedParameters as TemplateVersionParameter[]}
212216
presets={templateVersionPresetsQuery.data ?? []}
213217
creatingWorkspace={createWorkspaceMutation.isPending}

site/src/pages/CreateWorkspacePage/CreateWorkspacePageExperimental.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ const CreateWorkspacePageExperimental: FC = () => {
7979
});
8080
const permissionsQuery = useQuery({
8181
...checkAuthorization({
82-
checks: createWorkspaceChecks(templateQuery.data?.organization_id ?? ""),
82+
checks: createWorkspaceChecks(
83+
templateQuery.data?.organization_id ?? "",
84+
templateQuery.data?.id,
85+
),
8386
}),
8487
enabled: !!templateQuery.data,
8588
});
@@ -292,6 +295,7 @@ const CreateWorkspacePageExperimental: FC = () => {
292295
owner={owner}
293296
setOwner={setOwner}
294297
autofillParameters={autofillParameters}
298+
canUpdateTemplate={permissionsQuery.data?.canUpdateTemplate}
295299
error={
296300
wsError ||
297301
createWorkspaceMutation.error ||

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.stories.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const meta: Meta<typeof CreateWorkspacePageView> = {
2828
mode: "form",
2929
permissions: {
3030
createWorkspaceForAny: true,
31+
canUpdateTemplate: false,
3132
},
3233
onCancel: action("onCancel"),
3334
},
@@ -382,3 +383,23 @@ export const ExternalAuthAllConnected: Story = {
382383
],
383384
},
384385
};
386+
387+
export const WithViewSourceButton: Story = {
388+
args: {
389+
canUpdateTemplate: true,
390+
versionId: "template-version-123",
391+
template: {
392+
...MockTemplate,
393+
organization_name: "default",
394+
name: "docker-template",
395+
},
396+
},
397+
parameters: {
398+
docs: {
399+
description: {
400+
story:
401+
"This story shows the View Source button that appears for template administrators. The button allows quick navigation to the template editor from the workspace creation page.",
402+
},
403+
},
404+
},
405+
};

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ 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 { ExternalLinkIcon } from "lucide-react";
3031
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
3132
import { type FC, useCallback, useEffect, useMemo, useState } from "react";
33+
import { Link } from "react-router-dom";
3234
import {
3335
getFormHelpers,
3436
nameValidator,
@@ -67,6 +69,7 @@ interface CreateWorkspacePageViewProps {
6769
presets: TypesGen.Preset[];
6870
permissions: CreateWorkspacePermissions;
6971
creatingWorkspace: boolean;
72+
canUpdateTemplate?: boolean;
7073
onCancel: () => void;
7174
onSubmit: (
7275
req: TypesGen.CreateWorkspaceRequest,
@@ -92,6 +95,7 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
9295
presets = [],
9396
permissions,
9497
creatingWorkspace,
98+
canUpdateTemplate,
9599
onSubmit,
96100
onCancel,
97101
}) => {
@@ -218,9 +222,21 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
218222
<Margins size="medium">
219223
<PageHeader
220224
actions={
221-
<Button size="sm" variant="outline" onClick={onCancel}>
222-
Cancel
223-
</Button>
225+
<Stack direction="row" spacing={2}>
226+
{canUpdateTemplate && (
227+
<Button asChild size="sm" variant="outline">
228+
<Link
229+
to={`/templates/${template.organization_name}/${template.name}/versions/${versionId}/edit`}
230+
>
231+
<ExternalLinkIcon />
232+
View source
233+
</Link>
234+
</Button>
235+
)}
236+
<Button size="sm" variant="outline" onClick={onCancel}>
237+
Cancel
238+
</Button>
239+
</Stack>
224240
}
225241
>
226242
<Stack direction="row">

site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.stories.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const meta: Meta<typeof CreateWorkspacePageViewExperimental> = {
2020
parameters: [],
2121
permissions: {
2222
createWorkspaceForAny: true,
23+
canUpdateTemplate: false,
2324
},
2425
presets: [],
2526
sendMessage: () => {},
@@ -38,3 +39,23 @@ export const WebsocketError: Story = {
3839
),
3940
},
4041
};
42+
43+
export const WithViewSourceButton: Story = {
44+
args: {
45+
canUpdateTemplate: true,
46+
versionId: "template-version-123",
47+
template: {
48+
...MockTemplate,
49+
organization_name: "default",
50+
name: "docker-template",
51+
},
52+
},
53+
parameters: {
54+
docs: {
55+
description: {
56+
story:
57+
"This story shows the View Source button that appears for template administrators in the experimental workspace creation page. The button allows quick navigation to the template editor.",
58+
},
59+
},
60+
},
61+
};

site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete";
2727
import { type FormikContextType, useFormik } from "formik";
2828
import type { ExternalAuthPollingState } from "hooks/useExternalAuth";
29-
import { ArrowLeft, CircleHelp } from "lucide-react";
29+
import { ArrowLeft, CircleHelp, ExternalLinkIcon } from "lucide-react";
3030
import { useSyncFormParameters } from "modules/hooks/useSyncFormParameters";
3131
import {
3232
Diagnostics,
@@ -43,6 +43,7 @@ import {
4343
useRef,
4444
useState,
4545
} from "react";
46+
import { Link as RouterLink } from "react-router-dom";
4647
import { docs } from "utils/docs";
4748
import { nameValidator } from "utils/formUtils";
4849
import type { AutofillBuildParameter } from "utils/richParameters";
@@ -53,6 +54,7 @@ import type { CreateWorkspacePermissions } from "./permissions";
5354

5455
interface CreateWorkspacePageViewExperimentalProps {
5556
autofillParameters: AutofillBuildParameter[];
57+
canUpdateTemplate?: boolean;
5658
creatingWorkspace: boolean;
5759
defaultName?: string | null;
5860
defaultOwner: TypesGen.User;
@@ -84,6 +86,7 @@ export const CreateWorkspacePageViewExperimental: FC<
8486
CreateWorkspacePageViewExperimentalProps
8587
> = ({
8688
autofillParameters,
89+
canUpdateTemplate,
8790
creatingWorkspace,
8891
defaultName,
8992
defaultOwner,
@@ -378,6 +381,16 @@ export const CreateWorkspacePageViewExperimental: FC<
378381
</Badge>
379382
)}
380383
</span>
384+
{canUpdateTemplate && (
385+
<Button asChild size="sm" variant="outline">
386+
<RouterLink
387+
to={`/templates/${template.organization_name}/${template.name}/versions/${versionId}/edit`}
388+
>
389+
<ExternalLinkIcon />
390+
View source
391+
</RouterLink>
392+
</Button>
393+
)}
381394
</div>
382395
<span className="flex flex-row items-center gap-2">
383396
<h1 className="text-3xl font-semibold m-0">New workspace</h1>

site/src/pages/CreateWorkspacePage/permissions.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
export const createWorkspaceChecks = (organizationId: string) =>
1+
export const createWorkspaceChecks = (
2+
organizationId: string,
3+
templateId?: string,
4+
) =>
25
({
36
createWorkspaceForAny: {
47
object: {
5-
resource_type: "workspace",
8+
resource_type: "workspace" as const,
69
organization_id: organizationId,
710
owner_id: "*",
811
},
9-
action: "create",
12+
action: "create" as const,
1013
},
14+
...(templateId && {
15+
canUpdateTemplate: {
16+
object: {
17+
resource_type: "template" as const,
18+
resource_id: templateId,
19+
},
20+
action: "update" as const,
21+
},
22+
}),
1123
}) as const;
1224

1325
export type CreateWorkspacePermissions = Record<

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy