fix(site): use version name instead of ID in View source button URL (#21784)

Fixes #19921

The "View source" button was using `versionId` (UUID) instead of version
name in the URL, causing broken links.
This commit is contained in:
Marcin Tojek
2026-01-30 12:43:09 +01:00
committed by GitHub
parent 4847920407
commit 90cf4809ec
3 changed files with 33 additions and 10 deletions
@@ -3,6 +3,7 @@ import { type ApiErrorResponse, DetailedError } from "api/errors";
import { checkAuthorization } from "api/queries/authCheck";
import {
templateByName,
templateVersion,
templateVersionExternalAuth,
templateVersionPresets,
} from "api/queries/templates";
@@ -88,6 +89,11 @@ const CreateWorkspacePage: FC = () => {
const realizedVersionId =
customVersionId ?? templateQuery.data?.active_version_id;
const templateVersionQuery = useQuery({
...templateVersion(realizedVersionId ?? ""),
enabled: realizedVersionId !== undefined,
});
const autofillParameters = getAutofillParameters(searchParams);
const sendMessage = useEffectEvent(
@@ -308,6 +314,7 @@ const CreateWorkspacePage: FC = () => {
resetMutation={createWorkspaceMutation.reset}
template={templateQuery.data}
versionId={realizedVersionId}
versionName={templateVersionQuery.data?.name}
externalAuth={externalAuth ?? []}
externalAuthPollingState={externalAuthPollingState}
startPollingExternalAuth={startPollingExternalAuth}
@@ -2,6 +2,7 @@ import { chromatic } from "testHelpers/chromatic";
import { MockTemplate, MockUserOwner } from "testHelpers/entities";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { DetailedError } from "api/errors";
import { expect, screen, within } from "storybook/test";
import { CreateWorkspacePageView } from "./CreateWorkspacePageView";
const meta: Meta<typeof CreateWorkspacePageView> = {
@@ -43,19 +44,32 @@ export const WebsocketError: Story = {
export const WithViewSourceButton: Story = {
args: {
canUpdateTemplate: true,
versionId: "template-version-123",
versionName: "foobar-template-version",
template: {
...MockTemplate,
organization_name: "default",
name: "docker-template",
},
},
parameters: {
docs: {
description: {
story:
"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.",
},
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const viewSourceLink = canvas.getByRole("link", { name: /view source/i });
expect(viewSourceLink).toBeInTheDocument();
expect(viewSourceLink).toHaveAttribute(
"href",
"/templates/default/docker-template/versions/foobar-template-version/edit",
);
},
};
export const ViewSourceButtonHiddenWithoutPermission: Story = {
args: {
canUpdateTemplate: false,
versionName: "foobar-template-version",
},
play: async () => {
expect(
screen.queryByRole("link", { name: /view source/i }),
).not.toBeInTheDocument();
},
};
@@ -64,6 +64,7 @@ interface CreateWorkspacePageViewProps {
presets: TypesGen.Preset[];
template: TypesGen.Template;
versionId?: string;
versionName?: string;
onCancel: () => void;
onSubmit: (
req: TypesGen.CreateWorkspaceRequest,
@@ -94,6 +95,7 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
presets = [],
template,
versionId,
versionName,
onSubmit,
onCancel,
resetMutation,
@@ -380,10 +382,10 @@ export const CreateWorkspacePageView: FC<CreateWorkspacePageViewProps> = ({
</Badge>
)}
</span>
{canUpdateTemplate && (
{canUpdateTemplate && versionName && (
<Button asChild size="sm" variant="outline">
<RouterLink
to={`/templates/${template.organization_name}/${template.name}/versions/${versionId}/edit`}
to={`/templates/${template.organization_name}/${template.name}/versions/${versionName}/edit`}
>
<ExternalLinkIcon />
View source