Fix file downloads from notebooks container (#196)
* Fix file downloads from notebooks container * Add downloading message
This commit is contained in:
parent
83b13de685
commit
728eeefa17
|
@ -87,6 +87,7 @@ import { ContextualPaneBase } from "./Panes/ContextualPaneBase";
|
||||||
import TabsBase from "./Tabs/TabsBase";
|
import TabsBase from "./Tabs/TabsBase";
|
||||||
import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandButtonComponent";
|
||||||
import { updateUserContext, userContext } from "../UserContext";
|
import { updateUserContext, userContext } from "../UserContext";
|
||||||
|
import { stringToBlob } from "../Utils/BlobUtils";
|
||||||
|
|
||||||
BindingHandlersRegisterer.registerBindingHandlers();
|
BindingHandlersRegisterer.registerBindingHandlers();
|
||||||
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
|
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
|
||||||
|
@ -2621,9 +2622,11 @@ export default class Explorer {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clearMessage = NotificationConsoleUtils.logConsoleProgress(`Downloading ${notebookFile.path}`);
|
||||||
|
|
||||||
return this.notebookManager?.notebookContentClient.readFileContent(notebookFile.path).then(
|
return this.notebookManager?.notebookContentClient.readFileContent(notebookFile.path).then(
|
||||||
(content: string) => {
|
(content: string) => {
|
||||||
const blob = new Blob([content], { type: "octet/stream" });
|
const blob = stringToBlob(content, "text/plain");
|
||||||
if (navigator.msSaveBlob) {
|
if (navigator.msSaveBlob) {
|
||||||
// for IE and Edge
|
// for IE and Edge
|
||||||
navigator.msSaveBlob(blob, notebookFile.name);
|
navigator.msSaveBlob(blob, notebookFile.name);
|
||||||
|
@ -2640,12 +2643,16 @@ export default class Explorer {
|
||||||
downloadLink.click();
|
downloadLink.click();
|
||||||
downloadLink.remove();
|
downloadLink.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearMessage();
|
||||||
},
|
},
|
||||||
(error: any) => {
|
(error: any) => {
|
||||||
NotificationConsoleUtils.logConsoleMessage(
|
NotificationConsoleUtils.logConsoleMessage(
|
||||||
ConsoleDataType.Error,
|
ConsoleDataType.Error,
|
||||||
`Could not download notebook ${JSON.stringify(error)}`
|
`Could not download notebook ${JSON.stringify(error)}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
clearMessage();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,18 +194,24 @@ export class NotebookContentClient {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readFileContent(filePath: string): Promise<string> {
|
public async readFileContent(filePath: string): Promise<string> {
|
||||||
const fileType = NotebookUtil.isNotebookFile(filePath) ? "notebook" : "file";
|
const xhr = await this.contentProvider.get(this.getServerConfig(), filePath, { content: 1 }).toPromise();
|
||||||
return this.contentProvider
|
const content = (xhr.response as any).content;
|
||||||
.get(this.getServerConfig(), filePath, { type: fileType, format: "text", content: 1 })
|
if (!content) {
|
||||||
.toPromise()
|
throw new Error("No content read");
|
||||||
.then(xhr => {
|
}
|
||||||
const content = (xhr.response as any).content;
|
|
||||||
if (!content) {
|
const format = (xhr.response as any).format;
|
||||||
throw new Error("No content read");
|
switch (format) {
|
||||||
}
|
case "text":
|
||||||
|
return content;
|
||||||
|
case "base64":
|
||||||
|
return atob(content);
|
||||||
|
case "json":
|
||||||
return stringifyNotebook(content);
|
return stringifyNotebook(content);
|
||||||
});
|
default:
|
||||||
|
throw new Error(`Unsupported content format ${format}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private deleteNotebookFile(path: string): Promise<string> {
|
private deleteNotebookFile(path: string): Promise<string> {
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
export const stringToBlob = (data: string, contentType: string, sliceSize = 512): Blob => {
|
||||||
|
const byteArrays = [];
|
||||||
|
|
||||||
|
for (let offset = 0; offset < data.length; offset += sliceSize) {
|
||||||
|
const slice = data.slice(offset, offset + sliceSize);
|
||||||
|
|
||||||
|
const byteNumbers = new Array(slice.length);
|
||||||
|
for (let i = 0; i < slice.length; i++) {
|
||||||
|
byteNumbers[i] = slice.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const byteArray = new Uint8Array(byteNumbers);
|
||||||
|
byteArrays.push(byteArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Blob(byteArrays, { type: contentType });
|
||||||
|
};
|
Loading…
Reference in New Issue