Merge pull request #19388 from fyyyyy/feature/zip-download-in-dry-run-results

Feature/zip download in dry run results
This commit is contained in:
Patrik Oldsberg
2023-09-12 11:42:40 +02:00
committed by GitHub
7 changed files with 125 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder': minor
---
adding a .zip download to dry run results page, including zip.js as dependency
+1
View File
@@ -81,6 +81,7 @@
"immer": "^9.0.1",
"json-schema": "^0.4.0",
"json-schema-library": "^7.3.9",
"jszip": "^3.10.1",
"lodash": "^4.17.21",
"luxon": "^3.0.0",
"qs": "^6.9.4",
@@ -40,7 +40,7 @@ interface DryRunOptions {
files: Array<{ path: string; content: string }>;
}
interface DryRunResult extends ScaffolderDryRunResponse {
export interface DryRunResult extends ScaffolderDryRunResponse {
id: number;
}
@@ -25,8 +25,10 @@ import { makeStyles } from '@material-ui/core/styles';
import CancelIcon from '@material-ui/icons/Cancel';
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 { downloadBlob } from '../../../lib/download';
const useStyles = makeStyles((theme: BackstageTheme) => ({
root: {
@@ -53,6 +55,17 @@ export function DryRunResultsList() {
<List className={classes.root} dense>
{dryRun.results.map(result => {
const failed = result.log.some(l => l.body.status === 'failed');
let isLoading = false;
async function downloadResult() {
isLoading = true;
await downloadDirectoryContents(
result.directoryContents,
`dry-run-result-${result.id}.zip`,
);
isLoading = false;
}
return (
<ListItem
button
@@ -67,9 +80,19 @@ export function DryRunResultsList() {
</ListItemIcon>
<ListItemText primary={`Result ${result.id}`} />
<ListItemSecondaryAction>
<IconButton
edge="end"
aria-label="download"
title="Download as .zip"
disabled={isLoading}
onClick={() => downloadResult()}
>
<DownloadIcon />
</IconButton>
<IconButton
edge="end"
aria-label="delete"
title="Delete result"
onClick={() => dryRun.deleteResult(result.id)}
>
<DeleteIcon />
@@ -81,3 +104,26 @@ export function DryRunResultsList() {
</List>
);
}
async function downloadDirectoryContents(
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);
}
const blob = await zip.generateAsync({ type: 'blob' });
downloadBlob(blob, name);
}
@@ -0,0 +1,24 @@
/*
* 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();
}
@@ -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';
+31 -2
View File
@@ -8837,6 +8837,7 @@ __metadata:
immer: ^9.0.1
json-schema: ^0.4.0
json-schema-library: ^7.3.9
jszip: ^3.10.1
lodash: ^4.17.21
luxon: ^3.0.0
msw: ^1.0.0
@@ -28551,6 +28552,13 @@ __metadata:
languageName: node
linkType: hard
"immediate@npm:~3.0.5":
version: 3.0.6
resolution: "immediate@npm:3.0.6"
checksum: f9b3486477555997657f70318cc8d3416159f208bec4cca3ff3442fd266bc23f50f0c9bd8547e1371a6b5e82b821ec9a7044a4f7b944798b25aa3cc6d5e63e62
languageName: node
linkType: hard
"immer@npm:9.0.7":
version: 9.0.7
resolution: "immer@npm:9.0.7"
@@ -31205,6 +31213,18 @@ __metadata:
languageName: node
linkType: hard
"jszip@npm:^3.10.1":
version: 3.10.1
resolution: "jszip@npm:3.10.1"
dependencies:
lie: ~3.3.0
pako: ~1.0.2
readable-stream: ~2.3.6
setimmediate: ^1.0.5
checksum: abc77bfbe33e691d4d1ac9c74c8851b5761fba6a6986630864f98d876f3fcc2d36817dfc183779f32c00157b5d53a016796677298272a714ae096dfe6b1c8b60
languageName: node
linkType: hard
"just-diff-apply@npm:^4.0.1":
version: 4.0.1
resolution: "just-diff-apply@npm:4.0.1"
@@ -31541,6 +31561,15 @@ __metadata:
languageName: node
linkType: hard
"lie@npm:~3.3.0":
version: 3.3.0
resolution: "lie@npm:3.3.0"
dependencies:
immediate: ~3.0.5
checksum: 33102302cf19766f97919a6a98d481e01393288b17a6aa1f030a3542031df42736edde8dab29ffdbf90bebeffc48c761eb1d064dc77592ca3ba3556f9fe6d2a8
languageName: node
linkType: hard
"lilconfig@npm:2.1.0, lilconfig@npm:^2.0.3":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
@@ -34937,7 +34966,7 @@ __metadata:
languageName: node
linkType: hard
"pako@npm:^1.0.10, pako@npm:~1.0.5":
"pako@npm:^1.0.10, pako@npm:~1.0.2, pako@npm:~1.0.5":
version: 1.0.11
resolution: "pako@npm:1.0.11"
checksum: 1be2bfa1f807608c7538afa15d6f25baa523c30ec870a3228a89579e474a4d992f4293859524e46d5d87fd30fa17c5edf34dbef0671251d9749820b488660b16
@@ -37795,7 +37824,7 @@ __metadata:
languageName: node
linkType: hard
"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.5, readable-stream@npm:^2.3.6":
"readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.5, readable-stream@npm:^2.3.6, readable-stream@npm:~2.3.6":
version: 2.3.8
resolution: "readable-stream@npm:2.3.8"
dependencies: