diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx index d9f853275f..1765e8cb94 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunContext.tsx @@ -26,7 +26,6 @@ import React, { useRef, useState, } from 'react'; -const {default: JSZip} = await import('jszip'); import { scaffolderApiRef, ScaffolderDryRunResponse, @@ -41,7 +40,7 @@ interface DryRunOptions { files: Array<{ path: string; content: string }>; } -interface DryRunResult extends ScaffolderDryRunResponse { +export interface DryRunResult extends ScaffolderDryRunResponse { id: number; } @@ -51,7 +50,6 @@ interface DryRun { selectResult(id: number): void; deleteResult(id: number): void; - downloadResult(id: number): void; execute(options: DryRunOptions): Promise; } @@ -124,22 +122,6 @@ export function DryRunProvider(props: DryRunProviderProps) { }); }, []); - const downloadResult = useCallback((id: number) => { - setState(prevState => { - const index = prevState.results.findIndex(r => r.id === id); - if (index === -1) { - return prevState; - } - const result = prevState.results[index]; - console.log('Result', result.id); - createZipDownload(result.directoryContents, 'result_' + result.id) - return { - results: prevState.results, - selectedResult: prevState.selectedResult, - }; - }); - }, []); - const execute = useCallback( async (options: DryRunOptions) => { if (!scaffolderApi.dryRun) { @@ -176,7 +158,6 @@ export function DryRunProvider(props: DryRunProviderProps) { ...state, selectResult, deleteResult, - downloadResult, execute, }), [state, selectResult, deleteResult, execute], @@ -196,33 +177,3 @@ export function useDryRun(): DryRun { } return value; } - -async function createZipDownload(directoryContents: { path: string; base64Content: string; executable: boolean; }[], name: string) { - const zip = new JSZip(); - - for (const d of directoryContents) { - // Decode text content from base64 to ascii - const converted = atob(d.base64Content); - - // add folder/file to zip - await zip.file(d.path, converted); - } - - zip.generateAsync({type:"blob"}).then((blob) => { - saveAs(blob, name); - }, (err) => { - throw new Error(err); - }); -} - - -// Download zip -function saveAs(blob: Blob, name: string) { - const a = document.createElement('a'); - a.href = URL.createObjectURL(blob); - a.download = `dry-run-${name}.zip`; - a.click(); - URL.revokeObjectURL(a.href); - a.remove(); -} - diff --git a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx index 9163261985..384d48e871 100644 --- a/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx +++ b/plugins/scaffolder/src/components/TemplateEditorPage/DryRunResults/DryRunResultsList.tsx @@ -27,7 +27,7 @@ import CheckIcon from '@material-ui/icons/Check'; import DeleteIcon from '@material-ui/icons/Delete'; import DownloadIcon from '@material-ui/icons/GetApp'; import React from 'react'; -import { useDryRun } from '../DryRunContext'; +import { DryRunResult, useDryRun } from '../DryRunContext'; const useStyles = makeStyles((theme: BackstageTheme) => ({ root: { @@ -72,7 +72,7 @@ export function DryRunResultsList() { edge="end" aria-label="download" title="Download as .zip" - onClick={() => dryRun.downloadResult(result.id)} + onClick={() => downloadResult(result)} > @@ -91,3 +91,40 @@ export function DryRunResultsList() { ); } + + +async function downloadResult(result: DryRunResult) { + await createZipDownload(result.directoryContents, `dry-run-result-${result.id}.zip`) +} + + +async function createZipDownload(directoryContents: { path: string; base64Content: string; executable: boolean; }[], name: string) { + const {default: JSZip} = await import('jszip'); + const zip = new JSZip(); + + for (const d of directoryContents) { + // Decode text content from base64 to ascii + const converted = atob(d.base64Content); + + // add folder/file to zip + await zip.file(d.path, converted); + } + + zip.generateAsync({type:"blob"}).then((blob) => { + // Download zip + downloadBlob(blob, name); + }, (err) => { + throw new Error(err); + }); +} + + + +function downloadBlob(blob: Blob, name: string) { + const a = document.createElement('a'); + a.href = URL.createObjectURL(blob); + a.download = name; + a.click(); + URL.revokeObjectURL(a.href); + a.remove(); +} diff --git a/plugins/scaffolder/src/lib/download/helpers.ts b/plugins/scaffolder/src/lib/download/helpers.ts new file mode 100644 index 0000000000..2b596480d4 --- /dev/null +++ b/plugins/scaffolder/src/lib/download/helpers.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function downloadBlob(blob: Blob, name: string) { + const a = document.createElement('a'); + a.href = URL.createObjectURL(blob); + a.download = name; + a.click(); + URL.revokeObjectURL(a.href); + a.remove(); +} + diff --git a/plugins/scaffolder/src/lib/download/index.ts b/plugins/scaffolder/src/lib/download/index.ts new file mode 100644 index 0000000000..0b51b8e61d --- /dev/null +++ b/plugins/scaffolder/src/lib/download/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { downloadBlob } from './helpers';