A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/coder/coder/commit/cc89820d7ceec9ee2847b0526a22861e9adc4430 below:

add template export functionality to UI (#18214) · coder/coder@cc89820 · GitHub

File tree Expand file treeCollapse file tree 2 files changed

+58

-1

lines changed

Filter options

Expand file treeCollapse file tree 2 files changed

+58

-1

lines changed Original file line number Diff line number Diff line change

@@ -1084,6 +1084,31 @@ class ApiMethods {

1084 1084

return response.data;

1085 1085

};

1086 1086 1087 +

/**

1088 +

* Downloads a template version as a tar or zip archive

1089 +

* @param fileId The file ID from the template version's job

1090 +

* @param format Optional format: "zip" for zip archive, empty/undefined for tar

1091 +

* @returns Promise that resolves to a Blob containing the archive

1092 +

*/

1093 +

downloadTemplateVersion = async (

1094 +

fileId: string,

1095 +

format?: "zip",

1096 +

): Promise<Blob> => {

1097 +

const params = new URLSearchParams();

1098 +

if (format) {

1099 +

params.set("format", format);

1100 +

}

1101 + 1102 +

const response = await this.axios.get(

1103 +

`/api/v2/files/${fileId}?${params.toString()}`,

1104 +

{

1105 +

responseType: "blob",

1106 +

},

1107 +

);

1108 + 1109 +

return response.data;

1110 +

};

1111 + 1087 1112

updateTemplateMeta = async (

1088 1113

templateId: string,

1089 1114

data: TypesGen.UpdateTemplateMeta,

Original file line number Diff line number Diff line change

@@ -1,5 +1,6 @@

1 1

import EditIcon from "@mui/icons-material/EditOutlined";

2 2

import Button from "@mui/material/Button";

3 +

import { API } from "api/api";

3 4

import { workspaces } from "api/queries/workspaces";

4 5

import type {

5 6

AuthorizationResponse,

@@ -26,7 +27,7 @@ import {

26 27

} from "components/PageHeader/PageHeader";

27 28

import { Pill } from "components/Pill/Pill";

28 29

import { Stack } from "components/Stack/Stack";

29 -

import { CopyIcon } from "lucide-react";

30 +

import { CopyIcon, DownloadIcon } from "lucide-react";

30 31

import {

31 32

EllipsisVertical,

32 33

PlusIcon,

@@ -46,6 +47,7 @@ type TemplateMenuProps = {

46 47

templateName: string;

47 48

templateVersion: string;

48 49

templateId: string;

50 +

fileId: string;

49 51

onDelete: () => void;

50 52

};

51 53

@@ -54,6 +56,7 @@ const TemplateMenu: FC<TemplateMenuProps> = ({

54 56

templateName,

55 57

templateVersion,

56 58

templateId,

59 +

fileId,

57 60

onDelete,

58 61

}) => {

59 62

const dialogState = useDeletionDialogState(templateId, onDelete);

@@ -68,6 +71,24 @@ const TemplateMenu: FC<TemplateMenuProps> = ({

68 71 69 72

const templateLink = getLink(linkToTemplate(organizationName, templateName));

70 73 74 +

const handleExport = async (format?: "zip") => {

75 +

try {

76 +

const blob = await API.downloadTemplateVersion(fileId, format);

77 +

const url = window.URL.createObjectURL(blob);

78 +

const link = document.createElement("a");

79 +

link.href = url;

80 +

const extension = format === "zip" ? "zip" : "tar";

81 +

link.download = `${templateName}-${templateVersion}.${extension}`;

82 +

document.body.appendChild(link);

83 +

link.click();

84 +

document.body.removeChild(link);

85 +

window.URL.revokeObjectURL(url);

86 +

} catch (error) {

87 +

console.error("Failed to export template:", error);

88 +

// TODO: Show user-friendly error message

89 +

}

90 +

};

91 + 71 92

return (

72 93

<>

73 94

<DropdownMenu>

@@ -102,6 +123,16 @@ const TemplateMenu: FC<TemplateMenuProps> = ({

102 123

<CopyIcon className="size-icon-sm" />

103 124

Duplicate&hellip;

104 125

</DropdownMenuItem>

126 + 127 +

<DropdownMenuItem onClick={() => handleExport()}>

128 +

<DownloadIcon className="size-icon-sm" />

129 +

Export as TAR

130 +

</DropdownMenuItem>

131 + 132 +

<DropdownMenuItem onClick={() => handleExport("zip")}>

133 +

<DownloadIcon className="size-icon-sm" />

134 +

Export as ZIP

135 +

</DropdownMenuItem>

105 136

<DropdownMenuSeparator />

106 137

<DropdownMenuItem

107 138

className="text-content-destructive focus:text-content-destructive"

@@ -206,6 +237,7 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({

206 237

templateId={template.id}

207 238

templateName={template.name}

208 239

templateVersion={activeVersion.name}

240 +

fileId={activeVersion.job.file_id}

209 241

onDelete={onDeleteTemplate}

210 242

/>

211 243

)}

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4