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:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': minor
|
||||
---
|
||||
|
||||
adding a .zip download to dry run results page, including zip.js as dependency
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+46
@@ -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';
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user