Skip to content

Commit 20288b5

Browse files
authored
Merge pull request #185 from jahn96/downloadSnippet
Implement downloading snippet
2 parents dfb8e54 + 551ee52 commit 20288b5

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

src/CodeSnippetDisplay.tsx

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
* See the License for the specific language governing permissions a* limitations under the License.
1616
*/
1717

18-
import { Clipboard, Dialog, showDialog } from '@jupyterlab/apputils';
18+
import {
19+
Clipboard,
20+
Dialog,
21+
InputDialog,
22+
showDialog,
23+
} from '@jupyterlab/apputils';
1924
import { PathExt } from '@jupyterlab/coreutils';
2025
import { DocumentWidget } from '@jupyterlab/docregistry';
2126
import { FileEditor } from '@jupyterlab/fileeditor';
@@ -50,10 +55,9 @@ import { CodeSnippetService, ICodeSnippet } from './CodeSnippetService';
5055
import { FilterTools } from './FilterTools';
5156
import { showPreview } from './PreviewSnippet';
5257
import { showMoreOptions } from './CodeSnippetMenu';
53-
// import {
54-
// ICodeSnippet,
55-
// CodeSnippetContentsService
56-
// } from './CodeSnippetContentsService';
58+
// import { showCodeSnippetForm, CodeSnippetForm } from './CodeSnippetForm';
59+
60+
import { CodeSnippetContentsService } from './CodeSnippetContentsService';
5761

5862
import moreSVGstr from '../style/icon/jupyter_moreicon.svg';
5963
import {
@@ -96,6 +100,7 @@ import {
96100
sasIcon,
97101
} from './CodeSnippetLanguages';
98102
import { ICodeSnippetEditorMetadata } from './CodeSnippetEditor';
103+
// import { CodeSnippetContentsService } from './CodeSnippetContentsService';
99104

100105
/**
101106
* The CSS class added to code snippet widget.
@@ -121,6 +126,8 @@ const CODE_SNIPPET_MORE_OTPIONS_COPY = 'jp-codeSnippet-more-options-copy';
121126
const CODE_SNIPPET_MORE_OTPIONS_INSERT = 'jp-codeSnippet-more-options-insert';
122127
const CODE_SNIPPET_MORE_OTPIONS_EDIT = 'jp-codeSnippet-more-options-edit';
123128
const CODE_SNIPPET_MORE_OTPIONS_DELETE = 'jp-codeSnippet-more-options-delete';
129+
const CODE_SNIPPET_MORE_OTPIONS_DOWNLOAD =
130+
'jp-codeSnippet-more-options-download';
124131
const CODE_SNIPPET_CREATE_NEW_BTN = 'jp-createSnippetBtn';
125132
const CODE_SNIPPET_NAME = 'jp-codeSnippet-name';
126133

@@ -195,7 +202,7 @@ export class CodeSnippetDisplay extends React.Component<
195202
this.handleRenameSnippet = this.handleRenameSnippet.bind(this);
196203
}
197204

198-
// Handle code snippet insert into an editor
205+
// Handle code snippet insert into a notebook or document
199206
private insertCodeSnippet = async (snippet: ICodeSnippet): Promise<void> => {
200207
const widget: Widget = this.props.getCurrentWidget();
201208
const snippetStr: string = snippet.code.join('\n');
@@ -1415,6 +1422,38 @@ export class CodeSnippetDisplay extends React.Component<
14151422
});
14161423
}
14171424

1425+
private downloadCommand(codeSnippet: ICodeSnippet): void {
1426+
// Request a text
1427+
InputDialog.getText({
1428+
title: 'Download Snippet?',
1429+
label: 'Directory to Download: ',
1430+
placeholder: 'share/snippet',
1431+
okLabel: 'Download',
1432+
}).then((value: Dialog.IResult<string>) => {
1433+
if (value.button.accept) {
1434+
const dirs = value.value.split('/');
1435+
1436+
const codeSnippetDownloader = CodeSnippetContentsService.getInstance();
1437+
1438+
let path = '';
1439+
for (let i = 0; i < dirs.length; i++) {
1440+
path += dirs[i] + '/';
1441+
codeSnippetDownloader.save(path, { type: 'directory' }).catch((_) => {
1442+
alert('Path should be a relative path');
1443+
});
1444+
}
1445+
1446+
path += codeSnippet.name + '.json';
1447+
1448+
codeSnippetDownloader.save(path, {
1449+
type: 'file',
1450+
format: 'text',
1451+
content: JSON.stringify(codeSnippet),
1452+
});
1453+
}
1454+
});
1455+
}
1456+
14181457
// remove dropdown menu
14191458
private removeOptionsNode(): void {
14201459
const temp = document.getElementsByClassName(CODE_SNIPPET_MORE_OPTIONS)[0];
@@ -1468,9 +1507,19 @@ export class CodeSnippetDisplay extends React.Component<
14681507
this.deleteCommand(codeSnippet);
14691508
this.removeOptionsNode();
14701509
};
1510+
1511+
const downloadSnip = document.createElement('div');
1512+
downloadSnip.className = CODE_SNIPPET_MORE_OTPIONS_DOWNLOAD;
1513+
downloadSnip.textContent = 'Download snippet';
1514+
downloadSnip.onclick = (): void => {
1515+
this.downloadCommand(codeSnippet);
1516+
this.removeOptionsNode();
1517+
};
1518+
14711519
optionsContainer.appendChild(insertSnip);
14721520
optionsContainer.appendChild(copySnip);
14731521
optionsContainer.appendChild(editSnip);
1522+
optionsContainer.appendChild(downloadSnip);
14741523
optionsContainer.appendChild(deleteSnip);
14751524
body.append(optionsContainer);
14761525
return body;

src/CodeSnippetInputDialog.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ export function validateForm(
252252
}
253253
return status;
254254
}
255+
255256
/**
256257
* A widget used to get input data.
257258
*/

style/base.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,17 @@ mark.jp-codeSnippet-search-bolding {
660660
cursor: pointer;
661661
}
662662

663+
.jp-codeSnippet-more-options-download {
664+
color: var(--jp-brand-color0);
665+
padding-bottom: 5px;
666+
cursor: pointer;
667+
}
668+
669+
.jp-codeSnippet-more-options-download:hover {
670+
background-color: var(--jp-layout-color2);
671+
cursor: pointer;
672+
}
673+
663674
.jp-dropdown-delete-button {
664675
border: none;
665676
}

0 commit comments

Comments
 (0)