diff --git a/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx b/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx index 07f0a9eba..d5f4bf697 100644 --- a/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx +++ b/src/Explorer/Tabs/QueryTab/QueryTabComponent.tsx @@ -22,6 +22,7 @@ import "react-splitter-layout/lib/index.css"; import { format } from "react-string-format"; import QueryCommandIcon from "../../../../images/CopilotCommand.svg"; import LaunchCopilot from "../../../../images/CopilotTabIcon.svg"; +import DownloadQueryIcon from "../../../../images/DownloadQuery.svg"; import CancelQueryIcon from "../../../../images/Entity_cancel.svg"; import ExecuteQueryIcon from "../../../../images/ExecuteQuery.svg"; import SaveQueryIcon from "../../../../images/save-cosmos.svg"; @@ -225,6 +226,20 @@ export default class QueryTabComponent extends React.Component { + const text = this.getCurrentEditorQuery(); + const queryFile = new File([text], `SavedQuery.txt`, { type: "text/plain" }); + + // It appears the most consistent to download a file from a blob is to create an anchor element and simulate clicking it + const blobUrl = URL.createObjectURL(queryFile); + const anchor = document.createElement("a"); + anchor.href = blobUrl; + anchor.download = queryFile.name; + document.body.appendChild(anchor); // Must put the anchor in the document. + anchor.click(); + document.body.removeChild(anchor); // Clean up the anchor. + }; + public onSaveQueryClick = (): void => { useSidePanel.getState().openSidePanel("Save Query", ); }; @@ -405,15 +420,28 @@ export default class QueryTabComponent extends React.Component 0; + useCommandBar.getState().setContextButtons(this.getTabsButtons()); } diff --git a/src/KeyboardShortcuts.tsx b/src/KeyboardShortcuts.tsx index 5ce91b8f2..98f988038 100644 --- a/src/KeyboardShortcuts.tsx +++ b/src/KeyboardShortcuts.tsx @@ -29,6 +29,7 @@ export enum KeyboardAction { EXECUTE_ITEM = "EXECUTE_ITEM", CANCEL_OR_DISCARD = "CANCEL_OR_DISCARD", SAVE_ITEM = "SAVE_ITEM", + DOWNLOAD_ITEM = "DOWNLOAD_ITEM", OPEN_QUERY = "OPEN_QUERY", OPEN_QUERY_FROM_DISK = "OPEN_QUERY_FROM_DISK", NEW_SPROC = "NEW_SPROC", @@ -57,6 +58,7 @@ const bindings: Record = { [KeyboardAction.EXECUTE_ITEM]: ["Shift+Enter", "F5"], [KeyboardAction.CANCEL_OR_DISCARD]: ["Escape"], [KeyboardAction.SAVE_ITEM]: ["$mod+S"], + [KeyboardAction.DOWNLOAD_ITEM]: ["$mod+Shift+S"], [KeyboardAction.OPEN_QUERY]: ["$mod+O"], [KeyboardAction.OPEN_QUERY_FROM_DISK]: ["$mod+Shift+O"], [KeyboardAction.NEW_SPROC]: ["Alt+N P"],