Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/CodeSnippetDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -728,8 +728,10 @@ export class CodeSnippetDisplay extends React.Component<
return widget.id === widgetId;
}
);
editor.dispose();

if (editor) {
editor.dispose();
}
contentsService.delete('snippets/' + codeSnippet.name + '.json');
this.props._codeSnippetWidgetModel.deleteSnippet(codeSnippet.id);
this.props._codeSnippetWidgetModel.updateSnippetContents();
Expand Down
33 changes: 18 additions & 15 deletions src/CodeSnippetWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { IEditorServices } from '@jupyterlab/codeeditor';
/**
* A class used to indicate a snippet item.
*/
const CODE_SNIPPET_ITEM = 'codeSnippet-item';
const CODE_SNIPPET_ITEM = 'jp-codeSnippet-item';

/**
* The mimetype used for Jupyter cell data.
Expand All @@ -54,9 +54,14 @@ const JUPYTER_CELL_MIME = 'application/vnd.jupyter.cells';
/**
* A class used to indicate a drop target.
*/
const DROP_TARGET_CLASS = 'jp-snippet-dropTarget';

const DROP_TARGET_CLASS = 'jp-codeSnippet-dropTarget';
const CODE_SNIPPET_EDITOR = 'jp-codeSnippet-editor';
const PREVIEW_CLASS = '.jp-codeSnippet-preview';
const DRAG_HOVER = 'jp-codeSnippet-drag-hover';
const DRAG_HOVER_CLICKED = 'jp-codeSnippet-drag-hover-clicked';
const CODE_SNIPPET_ITEM_CLICKED = 'jp-codeSnippet-item-clicked';
const CODE_SNIPPETS_CONTAINER_NAME = 'jp-codeSnippetsContainer-name';
const INACTIVE = 'inactive';

const commands = {
OPEN_CODE_SNIPPET_EDITOR: `${CODE_SNIPPET_EDITOR}:open`
Expand Down Expand Up @@ -250,25 +255,23 @@ export class CodeSnippetWidget extends ReactWidget {
//get rid of preview by clicking anything
const target = event.target as HTMLElement;

const preview = document.querySelector('.jp-preview');
const preview = document.querySelector(PREVIEW_CLASS);
if (preview) {
// if target is not the code snippet name area, then add inactive
// if target area is the code snippet name area, previewSnippet widget will handle preview.
if (
!preview.classList.contains('inactive') &&
!target.classList.contains('expandableContainer-name')
!preview.classList.contains(INACTIVE) &&
!target.classList.contains(CODE_SNIPPETS_CONTAINER_NAME)
) {
preview.classList.add('inactive');
for (const elem of document.getElementsByClassName('drag-hover')) {
if (elem.classList.contains('drag-hover-clicked')) {
elem.classList.remove('drag-hover-clicked');
preview.classList.add(INACTIVE);
for (const elem of document.getElementsByClassName(DRAG_HOVER)) {
if (elem.classList.contains(DRAG_HOVER_CLICKED)) {
elem.classList.remove(DRAG_HOVER_CLICKED);
}
}
for (const item of document.getElementsByClassName(
'codeSnippet-item'
)) {
if (item.classList.contains('codeSnippet-item-clicked')) {
item.classList.remove('codeSnippet-item-clicked');
for (const item of document.getElementsByClassName(CODE_SNIPPET_ITEM)) {
if (item.classList.contains(CODE_SNIPPET_ITEM_CLICKED)) {
item.classList.remove(CODE_SNIPPET_ITEM_CLICKED);
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/ConfirmMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { ArrayExt } from '@lumino/algorithm';
/**
* The class name for confirmation box
*/
const CONFIRM_CLASS = 'jp-confirm';
const CONFIRM_CLASS = 'jp-codeSnippet-confirm';
const CONFIRM_CONTENT = 'jp-codeSnippet-Message-content';
const CONFIRM_BODY = 'jp-codeSnippet-Message-body';

/**
* Create and show a dialog.
Expand Down Expand Up @@ -36,11 +38,10 @@ export class ConfirmMessage<T> extends Widget {
this._host = options.host || document.body;
const layout = (this.layout = new PanelLayout());
const content = new Panel();
content.addClass('jp-Message-content');
content.addClass(CONFIRM_CONTENT);
layout.addWidget(content);

const body = renderer.createBody(options.body || '');
// body.addClass('jp-Message-body');
// const icon = renderer.createIcon();
// content.addWidget(icon);
content.addWidget(body);
Expand Down Expand Up @@ -102,7 +103,7 @@ export class ConfirmMessage<T> extends Widget {
*/
protected _evtClick(event: MouseEvent): void {
const content = this.node.getElementsByClassName(
'jp-Message-content'
CONFIRM_CONTENT
)[0] as HTMLElement;
if (!content.contains(event.target as HTMLElement)) {
event.stopPropagation();
Expand Down Expand Up @@ -318,7 +319,7 @@ export namespace ConfirmMessage {
// const iconNode = new Widget({ node: document.createElement('div') });
// iconNode.title.icon = checkIcon;
// body.
body.addClass('jp-Message-body');
body.addClass(CONFIRM_BODY);
// Styling.styleNode(body.node);
return body;
}
Expand Down
45 changes: 25 additions & 20 deletions src/FilterTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ interface IFilterSnippetState {
searchValue: string;
}

const FILTER_ARROW_UP = '.jp-codeSnippet-filter-arrow-up';
const FILTER_OPTION = '.jp-codeSnippet-filter-option';
const FILTER_TAGS = 'jp-codeSnippet-filter-tags';
const FILTER_TAG = 'jp-codeSnippet-filter-tag';
const FILTER_CHECK = 'jp-codeSnippet-filter-check';
const FILTER_TITLE = 'jp-codeSnippet-filter-title';
const FILTER_TOOLS = 'jp-codeSnippet-filterTools';
const FILTER_SEARCHBAR = 'jp-codeSnippet-searchbar';
const FILTER_SEARCHWRAPPER = 'jp-codesnippet-searchwrapper';
const FILTER_CLASS = 'jp-codeSnippet-filter';
const FILTER_BUTTON = 'jp-codeSnippet-filter-btn';

export class FilterTools extends React.Component<
IFilterSnippetProps,
IFilterSnippetState
Expand All @@ -36,21 +48,17 @@ export class FilterTools extends React.Component<
// this.setState(state => ({
// show: !state.show
// }));
const filterArrow = document.querySelector(
'.jp-codeSnippet-filter-arrow-up'
);
const filterArrow = document.querySelector(FILTER_ARROW_UP);

const filterOption = document.querySelector(
'.jp-codeSnippet-filter-option'
);
const filterOption = document.querySelector(FILTER_OPTION);

filterArrow.classList.toggle('idle');
filterOption.classList.toggle('idle');
}

renderTags(): JSX.Element {
return (
<div className={'jp-codeSnippet-filter-tags'}>
<div className={FILTER_TAGS}>
{this.props.tags.map((tag: string, index: number) =>
this.renderTag(tag, index.toString())
)}
Expand All @@ -61,7 +69,7 @@ export class FilterTools extends React.Component<
renderTag(tag: string, index: string): JSX.Element {
return (
<div
className={'jp-codeSnippet-filter-tag tag unapplied-tag'}
className={`${FILTER_TAG} tag unapplied-tag`}
id={'filter' + '-' + tag + '-' + index}
key={'filter' + '-' + tag + '-' + index}
>
Expand Down Expand Up @@ -97,7 +105,7 @@ export class FilterTools extends React.Component<
if (parent.classList.contains('unapplied-tag')) {
parent.classList.replace('unapplied-tag', 'applied-tag');
const iconContainer = checkIcon.element({
className: 'jp-codeSnippet-filter-check',
className: FILTER_CHECK,
tag: 'span',
elementPosition: 'center',
height: '18px',
Expand Down Expand Up @@ -143,8 +151,8 @@ export class FilterTools extends React.Component<

renderFilterOption(): JSX.Element {
return (
<div className={'jp-codeSnippet-filter-option idle'}>
<div className={'jp-codeSnippet-filter-title'}>
<div className={`${FILTER_OPTION} idle`}>
<div className={FILTER_TITLE}>
<span>cell tags</span>
</div>
{this.renderTags()}
Expand All @@ -154,26 +162,23 @@ export class FilterTools extends React.Component<

render(): JSX.Element {
return (
<div className="jp-codeSnippet-filterTools">
<div className="jp-codeSnippet-searchbar">
<div className={FILTER_TOOLS}>
<div className={FILTER_SEARCHBAR}>
<InputGroup
className="jp-codesnippet-searchwrapper"
className={FILTER_SEARCHWRAPPER}
type="text"
placeholder="SEARCH SNIPPETS"
onChange={this.handleSearch}
rightIcon="search"
value={this.state.searchValue}
/>
</div>
<div className={'jp-codeSnippet-filter'}>
<button
className={'jp-codeSnippet-filter-btn'}
onClick={this.createFilterBox}
>
<div className={FILTER_CLASS}>
<button className={FILTER_BUTTON} onClick={this.createFilterBox}>
Filter By Tags
</button>
{/* <div className="jp-codeSnippet-filterContainer idle"> */}
<div className="jp-codeSnippet-filter-arrow-up idle"></div>
<div className={`${FILTER_ARROW_UP} idle`}></div>
{this.renderFilterOption()}
</div>
{/* </div> */}
Expand Down
10 changes: 6 additions & 4 deletions src/MoreOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { ArrayExt } from '@lumino/algorithm';
/**
* The class name for options box
*/
const OPTIONS_CLASS = 'jp-options';
const OPTIONS_CLASS = 'jp-codeSnippet-options';
const OPTIONS_CONTENT = 'jp-codeSnippet-Options-content';
const OPTIONS_BODY = 'jp-codeSnippet-Options-body';

/**
* Create and show a dialog.
Expand Down Expand Up @@ -36,7 +38,7 @@ export class OptionsMessage<T> extends Widget {
this._host = options.host || document.body;
const layout = (this.layout = new PanelLayout());
const content = new Panel();
content.addClass('jp-Options-content');
content.addClass(OPTIONS_CONTENT);
layout.addWidget(content);

const body = renderer.createBody(options.body || '');
Expand Down Expand Up @@ -100,7 +102,7 @@ export class OptionsMessage<T> extends Widget {
*/
protected _evtClick(event: MouseEvent): void {
const content = this.node.getElementsByClassName(
'jp-Options-content'
OPTIONS_CONTENT
)[0] as HTMLElement;
if (!content.contains(event.target as HTMLElement)) {
event.stopPropagation();
Expand Down Expand Up @@ -289,7 +291,7 @@ export namespace OptionsMessage {
// order to trigger a render of the DOM nodes from the React element.
MessageLoop.sendMessage(body, Widget.Msg.UpdateRequest);
}
body.addClass('jp-Options-body');
body.addClass(OPTIONS_BODY);
return body;
}
}
Expand Down
77 changes: 9 additions & 68 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import '../style/index.css';

import { codeSnippetIcon } from '@elyra/ui-components';
import codeSnippetIconSVGstr from '../style/icon/jupyter_snippeticon.svg';

import {
JupyterFrontEnd,
Expand Down Expand Up @@ -105,6 +105,14 @@ const editorIcon = new LabIcon({
svgstr: editorIconSVGstr
});

/**
* Snippet Icon
*/
const codeSnippetIcon = new LabIcon({
name: 'custom-ui-compnents:codeSnippetIcon',
svgstr: codeSnippetIconSVGstr
});

// get item that is right clicked (what opens the context menu)
//let clicked: EventTarget;

Expand Down Expand Up @@ -342,71 +350,4 @@ function getSelectedText(): string {
return selectedText.toString();
}

/**
* Wouldn't it be better to factor this class out to different class with a better name?
*/
// class MessageHandler extends Widget {
// constructor(codeSnippet: CodeSnippetWidget, id: number) {
// super({ node: createUndoDeleteNode(codeSnippet, id) });
// }
// }

// export function onDelete(codeSnippet: CodeSnippetWidget, id: number): void {
// const temp: HTMLElement = document.getElementById('jp-undo-delete-id');
// temp.parentElement.parentElement.removeChild(temp.parentElement);
// console.log(temp);
// const snippetToDeleteName =
// codeSnippet.codeSnippetWidgetModel.snippets[id].name;
// CodeSnippetContentsService.getInstance().delete(
// 'snippets/' + snippetToDeleteName + '.json'
// );
// codeSnippet.codeSnippetWidgetModel.deleteSnippet(id);
// const savedSnippets = codeSnippet.codeSnippetWidgetModel.snippets;
// codeSnippet.codeSnippets = savedSnippets;
// codeSnippet.renderCodeSnippetsSignal.emit(savedSnippets);
// }

// export function onUndo(codeSnippet: CodeSnippetWidget): void {
// codeSnippet.codeSnippets = codeSnippet.codeSnippetWidgetModel.snippets;
// codeSnippet.renderCodeSnippetsSignal.emit(
// codeSnippet.codeSnippetWidgetModel.snippets
// );
// const temp: HTMLElement = document.getElementById('jp-undo-delete-id');
// temp.parentElement.parentElement.removeChild(temp.parentElement);
// }

// export function createUndoDeleteNode(
// codeSnippet: CodeSnippetWidget,
// snippetID: number
// ): HTMLElement {
// const body = document.createElement('div');
// body.innerHTML = undoDeleteSVG;
// body.id = 'jp-undo-delete-id';

// const messageContainer = document.createElement('div');
// messageContainer.className = 'jp-confirm-text';
// const message = document.createElement('text');
// message.textContent = 'Click to ';
// const undo = document.createElement('span');
// undo.textContent = 'undo';
// undo.className = 'jp-click-undo';
// undo.onclick = function(): void {
// onUndo(codeSnippet);
// };
// const messageEnd = document.createElement('text');
// messageEnd.textContent = ' delete';
// messageContainer.appendChild(message);
// messageContainer.appendChild(undo);
// messageContainer.appendChild(messageEnd);
// body.append(messageContainer);

// const deleteMessage = document.createElement('div');
// deleteMessage.className = 'jp-undo-delete-close';
// deleteMessage.onclick = function(): void {
// onDelete(codeSnippet, snippetID);
// };
// body.append(deleteMessage);
// return body;
// }

export default code_snippet_extension;
3 changes: 3 additions & 0 deletions style/icon/jupyter_snippeticon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading