@deephaven/dashboard-core-plugins 0.42.1-beta.4 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/prop-types/UIPropTypes.d.ts +1 -6
- package/dist/prop-types/UIPropTypes.d.ts.map +1 -1
- package/package.json +22 -22
- package/dist/ChartBuilderPlugin.js +0 -54
- package/dist/ChartBuilderPlugin.js.map +0 -1
- package/dist/ChartPlugin.js +0 -66
- package/dist/ChartPlugin.js.map +0 -1
- package/dist/ConsolePlugin.js +0 -396
- package/dist/ConsolePlugin.js.map +0 -1
- package/dist/FilterPlugin.js +0 -205
- package/dist/FilterPlugin.js.map +0 -1
- package/dist/GridPlugin.js +0 -74
- package/dist/GridPlugin.js.map +0 -1
- package/dist/LinkerPlugin.js +0 -18
- package/dist/LinkerPlugin.js.map +0 -1
- package/dist/MarkdownPlugin.js +0 -87
- package/dist/MarkdownPlugin.js.map +0 -1
- package/dist/PandasPlugin.js +0 -66
- package/dist/PandasPlugin.js.map +0 -1
- package/dist/controls/ControlType.js +0 -10
- package/dist/controls/ControlType.js.map +0 -1
- package/dist/controls/dropdown-filter/DropdownFilter.css +0 -86
- package/dist/controls/dropdown-filter/DropdownFilter.css.map +0 -1
- package/dist/controls/dropdown-filter/DropdownFilter.js +0 -417
- package/dist/controls/dropdown-filter/DropdownFilter.js.map +0 -1
- package/dist/controls/input-filter/InputFilter.css +0 -75
- package/dist/controls/input-filter/InputFilter.css.map +0 -1
- package/dist/controls/input-filter/InputFilter.js +0 -291
- package/dist/controls/input-filter/InputFilter.js.map +0 -1
- package/dist/controls/markdown/MarkdownContainer.js +0 -30
- package/dist/controls/markdown/MarkdownContainer.js.map +0 -1
- package/dist/controls/markdown/MarkdownEditor.js +0 -52
- package/dist/controls/markdown/MarkdownEditor.js.map +0 -1
- package/dist/controls/markdown/MarkdownStartPage.js +0 -109
- package/dist/controls/markdown/MarkdownStartPage.js.map +0 -1
- package/dist/controls/markdown/MarkdownUtils.js +0 -23
- package/dist/controls/markdown/MarkdownUtils.js.map +0 -1
- package/dist/events/ChartEvent.js +0 -9
- package/dist/events/ChartEvent.js.map +0 -1
- package/dist/events/ConsoleEvent.js +0 -11
- package/dist/events/ConsoleEvent.js.map +0 -1
- package/dist/events/InputFilterEvent.js +0 -14
- package/dist/events/InputFilterEvent.js.map +0 -1
- package/dist/events/IrisGridEvent.js +0 -12
- package/dist/events/IrisGridEvent.js.map +0 -1
- package/dist/events/MarkdownEvent.js +0 -4
- package/dist/events/MarkdownEvent.js.map +0 -1
- package/dist/events/NotebookEvent.js +0 -15
- package/dist/events/NotebookEvent.js.map +0 -1
- package/dist/events/PQEvent.js +0 -9
- package/dist/events/PQEvent.js.map +0 -1
- package/dist/events/PandasEvent.js +0 -8
- package/dist/events/PandasEvent.js.map +0 -1
- package/dist/events/TabEvent.js +0 -12
- package/dist/events/TabEvent.js.map +0 -1
- package/dist/events/index.js +0 -9
- package/dist/events/index.js.map +0 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +0 -1
- package/dist/linker/ColumnSelectionValidator.js +0 -2
- package/dist/linker/ColumnSelectionValidator.js.map +0 -1
- package/dist/linker/Linker.js +0 -736
- package/dist/linker/Linker.js.map +0 -1
- package/dist/linker/LinkerLink.css +0 -142
- package/dist/linker/LinkerLink.css.map +0 -1
- package/dist/linker/LinkerLink.js +0 -314
- package/dist/linker/LinkerLink.js.map +0 -1
- package/dist/linker/LinkerOverlayContent.css +0 -63
- package/dist/linker/LinkerOverlayContent.css.map +0 -1
- package/dist/linker/LinkerOverlayContent.js +0 -343
- package/dist/linker/LinkerOverlayContent.js.map +0 -1
- package/dist/linker/LinkerUtils.js +0 -139
- package/dist/linker/LinkerUtils.js.map +0 -1
- package/dist/linker/ToolType.js +0 -5
- package/dist/linker/ToolType.js.map +0 -1
- package/dist/linker/index.js +0 -2
- package/dist/linker/index.js.map +0 -1
- package/dist/panels/ChartColumnSelectorOverlay.css +0 -11
- package/dist/panels/ChartColumnSelectorOverlay.css.map +0 -1
- package/dist/panels/ChartColumnSelectorOverlay.js +0 -38
- package/dist/panels/ChartColumnSelectorOverlay.js.map +0 -1
- package/dist/panels/ChartFilterOverlay.css +0 -22
- package/dist/panels/ChartFilterOverlay.css.map +0 -1
- package/dist/panels/ChartFilterOverlay.js +0 -90
- package/dist/panels/ChartFilterOverlay.js.map +0 -1
- package/dist/panels/ChartPanel.css +0 -38
- package/dist/panels/ChartPanel.css.map +0 -1
- package/dist/panels/ChartPanel.js +0 -971
- package/dist/panels/ChartPanel.js.map +0 -1
- package/dist/panels/ChartPanelUtils.js +0 -5
- package/dist/panels/ChartPanelUtils.js.map +0 -1
- package/dist/panels/CommandHistoryPanel.css +0 -19
- package/dist/panels/CommandHistoryPanel.css.map +0 -1
- package/dist/panels/CommandHistoryPanel.js +0 -195
- package/dist/panels/CommandHistoryPanel.js.map +0 -1
- package/dist/panels/ConsolePanel.css +0 -19
- package/dist/panels/ConsolePanel.css.map +0 -1
- package/dist/panels/ConsolePanel.js +0 -365
- package/dist/panels/ConsolePanel.js.map +0 -1
- package/dist/panels/DropdownFilterPanel.css +0 -6
- package/dist/panels/DropdownFilterPanel.css.map +0 -1
- package/dist/panels/DropdownFilterPanel.js +0 -685
- package/dist/panels/DropdownFilterPanel.js.map +0 -1
- package/dist/panels/FileExplorerPanel.css +0 -6
- package/dist/panels/FileExplorerPanel.css.map +0 -1
- package/dist/panels/FileExplorerPanel.js +0 -252
- package/dist/panels/FileExplorerPanel.js.map +0 -1
- package/dist/panels/FilterSetManager.css +0 -112
- package/dist/panels/FilterSetManager.css.map +0 -1
- package/dist/panels/FilterSetManager.js +0 -689
- package/dist/panels/FilterSetManager.js.map +0 -1
- package/dist/panels/FilterSetManagerPanel.css +0 -34
- package/dist/panels/FilterSetManagerPanel.css.map +0 -1
- package/dist/panels/FilterSetManagerPanel.js +0 -345
- package/dist/panels/FilterSetManagerPanel.js.map +0 -1
- package/dist/panels/InputFilterPanel.js +0 -232
- package/dist/panels/InputFilterPanel.js.map +0 -1
- package/dist/panels/IrisGridPanel.css +0 -24
- package/dist/panels/IrisGridPanel.css.map +0 -1
- package/dist/panels/IrisGridPanel.js +0 -1018
- package/dist/panels/IrisGridPanel.js.map +0 -1
- package/dist/panels/IrisGridPanelTooltip.js +0 -39
- package/dist/panels/IrisGridPanelTooltip.js.map +0 -1
- package/dist/panels/LogPanel.css +0 -15
- package/dist/panels/LogPanel.css.map +0 -1
- package/dist/panels/LogPanel.js +0 -110
- package/dist/panels/LogPanel.js.map +0 -1
- package/dist/panels/MarkdownNotebook.css +0 -107
- package/dist/panels/MarkdownNotebook.css.map +0 -1
- package/dist/panels/MarkdownNotebook.js +0 -232
- package/dist/panels/MarkdownNotebook.js.map +0 -1
- package/dist/panels/MarkdownPanel.css +0 -90
- package/dist/panels/MarkdownPanel.css.map +0 -1
- package/dist/panels/MarkdownPanel.js +0 -202
- package/dist/panels/MarkdownPanel.js.map +0 -1
- package/dist/panels/MockFileStorage.js +0 -70
- package/dist/panels/MockFileStorage.js.map +0 -1
- package/dist/panels/MockFileStorageTable.js +0 -80
- package/dist/panels/MockFileStorageTable.js.map +0 -1
- package/dist/panels/NotebookPanel.css +0 -44
- package/dist/panels/NotebookPanel.css.map +0 -1
- package/dist/panels/NotebookPanel.js +0 -1224
- package/dist/panels/NotebookPanel.js.map +0 -1
- package/dist/panels/PandasPanel.css +0 -15
- package/dist/panels/PandasPanel.css.map +0 -1
- package/dist/panels/PandasPanel.js +0 -86
- package/dist/panels/PandasPanel.js.map +0 -1
- package/dist/panels/Panel.js +0 -314
- package/dist/panels/Panel.js.map +0 -1
- package/dist/panels/PanelContextMenu.js +0 -126
- package/dist/panels/PanelContextMenu.js.map +0 -1
- package/dist/panels/RenameDialog.js +0 -156
- package/dist/panels/RenameDialog.js.map +0 -1
- package/dist/panels/WidgetPanel.css +0 -17
- package/dist/panels/WidgetPanel.css.map +0 -1
- package/dist/panels/WidgetPanel.js +0 -189
- package/dist/panels/WidgetPanel.js.map +0 -1
- package/dist/panels/WidgetPanelTooltip.css +0 -40
- package/dist/panels/WidgetPanelTooltip.css.map +0 -1
- package/dist/panels/WidgetPanelTooltip.js +0 -49
- package/dist/panels/WidgetPanelTooltip.js.map +0 -1
- package/dist/panels/index.js +0 -22
- package/dist/panels/index.js.map +0 -1
- package/dist/prop-types/CommonPropTypes.js +0 -9
- package/dist/prop-types/CommonPropTypes.js.map +0 -1
- package/dist/prop-types/UIPropTypes.js +0 -47
- package/dist/prop-types/UIPropTypes.js.map +0 -1
- package/dist/prop-types/index.js +0 -3
- package/dist/prop-types/index.js.map +0 -1
- package/dist/redux/actionTypes.js +0 -3
- package/dist/redux/actionTypes.js.map +0 -1
- package/dist/redux/actions.js +0 -88
- package/dist/redux/actions.js.map +0 -1
- package/dist/redux/index.js +0 -10
- package/dist/redux/index.js.map +0 -1
- package/dist/redux/reducers/connection.js +0 -7
- package/dist/redux/reducers/connection.js.map +0 -1
- package/dist/redux/reducers/index.js +0 -5
- package/dist/redux/reducers/index.js.map +0 -1
- package/dist/redux/reducers/sessionWrapper.js +0 -7
- package/dist/redux/reducers/sessionWrapper.js.map +0 -1
- package/dist/redux/selectors.js +0 -92
- package/dist/redux/selectors.js.map +0 -1
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
|
-
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
3
|
-
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
4
|
-
import React, { PureComponent } from 'react';
|
|
5
|
-
import classNames from 'classnames';
|
|
6
|
-
import Markdown from 'react-markdown';
|
|
7
|
-
import remarkGfm from 'remark-gfm';
|
|
8
|
-
import { Button } from '@deephaven/components';
|
|
9
|
-
import { Code } from '@deephaven/console';
|
|
10
|
-
import { vsPlay } from '@deephaven/icons';
|
|
11
|
-
import "./MarkdownNotebook.css";
|
|
12
|
-
import { assertNotNull } from '@deephaven/utils';
|
|
13
|
-
export class MarkdownNotebook extends PureComponent {
|
|
14
|
-
constructor(props) {
|
|
15
|
-
super(props);
|
|
16
|
-
_defineProperty(this, "commands", void 0);
|
|
17
|
-
_defineProperty(this, "codeElements", void 0);
|
|
18
|
-
_defineProperty(this, "editorScrollView", void 0);
|
|
19
|
-
this.handleRunSelected = this.handleRunSelected.bind(this);
|
|
20
|
-
this.renderCodeBlock = this.renderCodeBlock.bind(this);
|
|
21
|
-
this.renderLink = this.renderLink.bind(this);
|
|
22
|
-
|
|
23
|
-
// Map of each code block from it's starting line number to the code within that block
|
|
24
|
-
this.commands = new Map();
|
|
25
|
-
this.codeElements = new Map();
|
|
26
|
-
this.editorScrollView = /*#__PURE__*/React.createRef();
|
|
27
|
-
this.state = {
|
|
28
|
-
hasCode: false,
|
|
29
|
-
// Keep track if any code has been executed yet. If not, make the run button flash
|
|
30
|
-
hasRunCode: false,
|
|
31
|
-
// Line of the next block to execute. Null to start at the first block
|
|
32
|
-
nextStartLine: null
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
componentDidMount() {
|
|
36
|
-
this.updateHasCode();
|
|
37
|
-
}
|
|
38
|
-
componentDidUpdate() {
|
|
39
|
-
this.updateHasCode();
|
|
40
|
-
}
|
|
41
|
-
updateHasCode() {
|
|
42
|
-
var {
|
|
43
|
-
hasCode
|
|
44
|
-
} = this.state;
|
|
45
|
-
if (this.commands.size === 0 && hasCode) {
|
|
46
|
-
this.setState({
|
|
47
|
-
hasCode: false
|
|
48
|
-
});
|
|
49
|
-
} else if (this.commands.size > 0 && !hasCode) {
|
|
50
|
-
this.setState({
|
|
51
|
-
hasCode: true
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* @param line The line of the code block to start from
|
|
58
|
-
* @returns The next line of the code block to start from
|
|
59
|
-
*/
|
|
60
|
-
getNextStartLine(line) {
|
|
61
|
-
var keys = [...this.commands.keys()];
|
|
62
|
-
var nextIndex = keys.findIndex(key => key === line) + 1;
|
|
63
|
-
if (nextIndex >= keys.length) {
|
|
64
|
-
// We got to the last block, disable
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
return keys[nextIndex];
|
|
68
|
-
}
|
|
69
|
-
handleRunSelected(event) {
|
|
70
|
-
var _this$codeElements$ge, _element$parentElemen;
|
|
71
|
-
event.preventDefault();
|
|
72
|
-
event.stopPropagation();
|
|
73
|
-
var {
|
|
74
|
-
nextStartLine
|
|
75
|
-
} = this.state;
|
|
76
|
-
var keys = [...this.commands.keys()];
|
|
77
|
-
var keyIndex = keys.findIndex(key => key === nextStartLine || nextStartLine == null);
|
|
78
|
-
if (keyIndex < 0) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
var startLine = keys[keyIndex];
|
|
82
|
-
var command = this.commands.get(startLine);
|
|
83
|
-
var newNextStartLine = this.getNextStartLine(startLine);
|
|
84
|
-
var element = (_this$codeElements$ge = this.codeElements.get(startLine)) === null || _this$codeElements$ge === void 0 ? void 0 : _this$codeElements$ge.current;
|
|
85
|
-
var nextElement = element === null || element === void 0 ? void 0 : (_element$parentElemen = element.parentElement) === null || _element$parentElemen === void 0 ? void 0 : _element$parentElemen.nextElementSibling;
|
|
86
|
-
if (nextElement != null) {
|
|
87
|
-
var _this$editorScrollVie;
|
|
88
|
-
var {
|
|
89
|
-
offsetTop
|
|
90
|
-
} = nextElement;
|
|
91
|
-
var top = offsetTop;
|
|
92
|
-
(_this$editorScrollVie = this.editorScrollView.current) === null || _this$editorScrollVie === void 0 ? void 0 : _this$editorScrollVie.scroll({
|
|
93
|
-
top,
|
|
94
|
-
left: 0
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
this.runCode(command);
|
|
98
|
-
this.setState({
|
|
99
|
-
nextStartLine: newNextStartLine
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
runCode(command) {
|
|
103
|
-
var {
|
|
104
|
-
onRunCode
|
|
105
|
-
} = this.props;
|
|
106
|
-
onRunCode(command);
|
|
107
|
-
this.setState({
|
|
108
|
-
hasRunCode: true
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
renderCodeBlock(props) {
|
|
112
|
-
var {
|
|
113
|
-
children,
|
|
114
|
-
className,
|
|
115
|
-
inline,
|
|
116
|
-
node
|
|
117
|
-
} = props;
|
|
118
|
-
var {
|
|
119
|
-
hasRunCode,
|
|
120
|
-
nextStartLine
|
|
121
|
-
} = this.state;
|
|
122
|
-
var {
|
|
123
|
-
children: nodeChildren,
|
|
124
|
-
position
|
|
125
|
-
} = node;
|
|
126
|
-
assertNotNull(position);
|
|
127
|
-
var {
|
|
128
|
-
start
|
|
129
|
-
} = position;
|
|
130
|
-
var {
|
|
131
|
-
line
|
|
132
|
-
} = start;
|
|
133
|
-
var command = nodeChildren[0].value;
|
|
134
|
-
var ref = /*#__PURE__*/React.createRef();
|
|
135
|
-
var isFirstBlock = this.commands.size === 0;
|
|
136
|
-
var isSelected = nextStartLine === line || isFirstBlock && nextStartLine == null && !hasRunCode;
|
|
137
|
-
var language = className !== undefined && className.startsWith('language-') ? className.substring(9) : 'plaintext';
|
|
138
|
-
if (inline != null && inline) {
|
|
139
|
-
return /*#__PURE__*/React.createElement("code", {
|
|
140
|
-
className: className
|
|
141
|
-
}, children);
|
|
142
|
-
}
|
|
143
|
-
this.commands.set(line, command);
|
|
144
|
-
this.codeElements.set(line, ref);
|
|
145
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
146
|
-
className: classNames('markdown-notebook-code-block', {
|
|
147
|
-
'is-selected': isSelected
|
|
148
|
-
}),
|
|
149
|
-
ref: ref,
|
|
150
|
-
onClick: () => {
|
|
151
|
-
this.setState({
|
|
152
|
-
nextStartLine: line
|
|
153
|
-
});
|
|
154
|
-
},
|
|
155
|
-
role: "presentation"
|
|
156
|
-
}, /*#__PURE__*/React.createElement(Button, {
|
|
157
|
-
kind: "ghost",
|
|
158
|
-
icon: vsPlay,
|
|
159
|
-
className: "btn-play-block",
|
|
160
|
-
onClick: event => {
|
|
161
|
-
event.stopPropagation();
|
|
162
|
-
event.preventDefault();
|
|
163
|
-
this.runCode(command);
|
|
164
|
-
this.setState({
|
|
165
|
-
nextStartLine: line
|
|
166
|
-
});
|
|
167
|
-
},
|
|
168
|
-
tooltip: "Run code"
|
|
169
|
-
}), /*#__PURE__*/React.createElement("code", null, /*#__PURE__*/React.createElement(Code, {
|
|
170
|
-
language: language
|
|
171
|
-
}, React.Children.map(children, child => typeof child === 'string' ? child.trim() : child))));
|
|
172
|
-
}
|
|
173
|
-
renderLink(props) {
|
|
174
|
-
var {
|
|
175
|
-
onLinkClick
|
|
176
|
-
} = this.props;
|
|
177
|
-
var {
|
|
178
|
-
href,
|
|
179
|
-
children,
|
|
180
|
-
target
|
|
181
|
-
} = props;
|
|
182
|
-
return /*#__PURE__*/React.createElement("a", {
|
|
183
|
-
href: href,
|
|
184
|
-
onClick: onLinkClick,
|
|
185
|
-
target: target
|
|
186
|
-
}, children);
|
|
187
|
-
}
|
|
188
|
-
render() {
|
|
189
|
-
var {
|
|
190
|
-
content,
|
|
191
|
-
transformImageUri,
|
|
192
|
-
transformLinkUri
|
|
193
|
-
} = this.props;
|
|
194
|
-
var {
|
|
195
|
-
hasCode,
|
|
196
|
-
hasRunCode,
|
|
197
|
-
nextStartLine
|
|
198
|
-
} = this.state;
|
|
199
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
200
|
-
className: "markdown-notebook"
|
|
201
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
202
|
-
className: "markdown-notebook-toolbar"
|
|
203
|
-
}, /*#__PURE__*/React.createElement(Button, {
|
|
204
|
-
className: classNames('btn-play-selected-cell', {
|
|
205
|
-
flashing: hasCode && !hasRunCode
|
|
206
|
-
}),
|
|
207
|
-
kind: "ghost",
|
|
208
|
-
icon: vsPlay,
|
|
209
|
-
onClick: this.handleRunSelected,
|
|
210
|
-
tooltip: "Run code and select next",
|
|
211
|
-
disabled: hasRunCode && nextStartLine == null || !hasCode
|
|
212
|
-
}, "Run Selected Code")), /*#__PURE__*/React.createElement("div", {
|
|
213
|
-
className: "markdown-notebook-content",
|
|
214
|
-
ref: this.editorScrollView
|
|
215
|
-
}, /*#__PURE__*/React.createElement(Markdown, {
|
|
216
|
-
components: {
|
|
217
|
-
code: this.renderCodeBlock,
|
|
218
|
-
a: this.renderLink
|
|
219
|
-
},
|
|
220
|
-
linkTarget: "_blank",
|
|
221
|
-
remarkPlugins: [remarkGfm],
|
|
222
|
-
transformLinkUri: transformLinkUri,
|
|
223
|
-
transformImageUri: transformImageUri,
|
|
224
|
-
includeElementIndex: true
|
|
225
|
-
}, content)));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
_defineProperty(MarkdownNotebook, "defaultProps", {
|
|
229
|
-
onRunCode: () => undefined
|
|
230
|
-
});
|
|
231
|
-
export default MarkdownNotebook;
|
|
232
|
-
//# sourceMappingURL=MarkdownNotebook.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownNotebook.js","names":["React","PureComponent","classNames","Markdown","remarkGfm","Button","Code","vsPlay","assertNotNull","MarkdownNotebook","constructor","props","handleRunSelected","bind","renderCodeBlock","renderLink","commands","Map","codeElements","editorScrollView","createRef","state","hasCode","hasRunCode","nextStartLine","componentDidMount","updateHasCode","componentDidUpdate","size","setState","getNextStartLine","line","keys","nextIndex","findIndex","key","length","event","preventDefault","stopPropagation","keyIndex","startLine","command","get","newNextStartLine","element","current","nextElement","parentElement","nextElementSibling","offsetTop","top","scroll","left","runCode","onRunCode","children","className","inline","node","nodeChildren","position","start","value","ref","isFirstBlock","isSelected","language","undefined","startsWith","substring","set","Children","map","child","trim","onLinkClick","href","target","render","content","transformImageUri","transformLinkUri","flashing","code","a"],"sources":["../../src/panels/MarkdownNotebook.tsx"],"sourcesContent":["import React, {\n PureComponent,\n ReactElement,\n RefObject,\n MouseEvent,\n MouseEventHandler,\n} from 'react';\nimport classNames from 'classnames';\nimport Markdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { Button } from '@deephaven/components';\nimport { Code } from '@deephaven/console';\nimport { vsPlay } from '@deephaven/icons';\nimport './MarkdownNotebook.scss';\nimport {\n ReactMarkdownProps,\n TransformImage,\n TransformLink,\n} from 'react-markdown/src/ast-to-react';\nimport { assertNotNull } from '@deephaven/utils';\n\ninterface MarkdownNotebookProps {\n onRunCode: (command?: string) => void;\n content: string;\n onLinkClick: MouseEventHandler<HTMLAnchorElement>;\n transformImageUri?: TransformImage;\n transformLinkUri?: false | TransformLink | null;\n}\n\ninterface MarkdownNotebookState {\n hasCode: boolean;\n\n // Keep track if any code has been executed yet. If not, make the run button flash\n hasRunCode: boolean;\n\n // Line of the next block to execute. Null to start at the first block\n nextStartLine: number | null;\n}\n\nexport class MarkdownNotebook extends PureComponent<\n MarkdownNotebookProps,\n MarkdownNotebookState\n> {\n static defaultProps = {\n onRunCode: (): void => undefined,\n };\n\n constructor(props: MarkdownNotebookProps) {\n super(props);\n\n this.handleRunSelected = this.handleRunSelected.bind(this);\n this.renderCodeBlock = this.renderCodeBlock.bind(this);\n this.renderLink = this.renderLink.bind(this);\n\n // Map of each code block from it's starting line number to the code within that block\n this.commands = new Map();\n this.codeElements = new Map();\n this.editorScrollView = React.createRef();\n\n this.state = {\n hasCode: false,\n\n // Keep track if any code has been executed yet. If not, make the run button flash\n hasRunCode: false,\n\n // Line of the next block to execute. Null to start at the first block\n nextStartLine: null,\n };\n }\n\n componentDidMount(): void {\n this.updateHasCode();\n }\n\n componentDidUpdate(): void {\n this.updateHasCode();\n }\n\n commands: Map<number, string>;\n\n codeElements: Map<number, React.RefObject<HTMLDivElement>>;\n\n editorScrollView: RefObject<HTMLDivElement>;\n\n updateHasCode(): void {\n const { hasCode } = this.state;\n if (this.commands.size === 0 && hasCode) {\n this.setState({ hasCode: false });\n } else if (this.commands.size > 0 && !hasCode) {\n this.setState({ hasCode: true });\n }\n }\n\n /**\n * @param line The line of the code block to start from\n * @returns The next line of the code block to start from\n */\n getNextStartLine(line: number | null): number | null {\n const keys = [...this.commands.keys()];\n const nextIndex = keys.findIndex(key => key === line) + 1;\n if (nextIndex >= keys.length) {\n // We got to the last block, disable\n return null;\n }\n\n return keys[nextIndex];\n }\n\n handleRunSelected(event: MouseEvent<HTMLButtonElement>): void {\n event.preventDefault();\n event.stopPropagation();\n\n const { nextStartLine } = this.state;\n const keys = [...this.commands.keys()];\n const keyIndex = keys.findIndex(\n key => key === nextStartLine || nextStartLine == null\n );\n if (keyIndex < 0) {\n return;\n }\n const startLine = keys[keyIndex];\n const command = this.commands.get(startLine);\n const newNextStartLine = this.getNextStartLine(startLine);\n const element = this.codeElements.get(startLine)?.current;\n const nextElement = element?.parentElement?.nextElementSibling;\n if (nextElement != null) {\n const { offsetTop } = nextElement as HTMLElement;\n const top = offsetTop;\n this.editorScrollView.current?.scroll({\n top,\n left: 0,\n });\n }\n\n this.runCode(command);\n this.setState({ nextStartLine: newNextStartLine });\n }\n\n runCode(command?: string): void {\n const { onRunCode } = this.props;\n onRunCode(command);\n\n this.setState({ hasRunCode: true });\n }\n\n renderCodeBlock(\n props: JSX.IntrinsicElements['code'] &\n ReactMarkdownProps & {\n inline?: boolean;\n }\n ): ReactElement {\n const { children, className, inline, node } = props;\n const { hasRunCode, nextStartLine } = this.state;\n const { children: nodeChildren, position } = node;\n assertNotNull(position);\n const { start } = position;\n const { line } = start;\n const command = (nodeChildren[0] as { value: string }).value;\n const ref = React.createRef<HTMLDivElement>();\n const isFirstBlock = this.commands.size === 0;\n const isSelected =\n nextStartLine === line ||\n (isFirstBlock && nextStartLine == null && !hasRunCode);\n const language =\n className !== undefined && className.startsWith('language-')\n ? className.substring(9)\n : 'plaintext';\n\n if (inline != null && inline) {\n return <code className={className}>{children}</code>;\n }\n\n this.commands.set(line, command);\n this.codeElements.set(line, ref);\n\n return (\n <div\n className={classNames('markdown-notebook-code-block', {\n 'is-selected': isSelected,\n })}\n ref={ref}\n onClick={() => {\n this.setState({ nextStartLine: line });\n }}\n role=\"presentation\"\n >\n <Button\n kind=\"ghost\"\n icon={vsPlay}\n className=\"btn-play-block\"\n onClick={event => {\n event.stopPropagation();\n event.preventDefault();\n\n this.runCode(command);\n this.setState({ nextStartLine: line });\n }}\n tooltip=\"Run code\"\n />\n <code>\n <Code language={language}>\n {React.Children.map(children, child =>\n typeof child === 'string' ? child.trim() : child\n )}\n </Code>\n </code>\n </div>\n );\n }\n\n renderLink(\n props: React.ClassAttributes<HTMLAnchorElement> &\n React.AnchorHTMLAttributes<HTMLAnchorElement> &\n ReactMarkdownProps\n ): ReactElement {\n const { onLinkClick } = this.props;\n const { href, children, target } = props;\n return (\n <a href={href} onClick={onLinkClick} target={target}>\n {children}\n </a>\n );\n }\n\n render(): ReactElement {\n const { content, transformImageUri, transformLinkUri } = this.props;\n const { hasCode, hasRunCode, nextStartLine } = this.state;\n return (\n <div className=\"markdown-notebook\">\n <div className=\"markdown-notebook-toolbar\">\n <Button\n className={classNames('btn-play-selected-cell', {\n flashing: hasCode && !hasRunCode,\n })}\n kind=\"ghost\"\n icon={vsPlay}\n onClick={this.handleRunSelected}\n tooltip=\"Run code and select next\"\n disabled={(hasRunCode && nextStartLine == null) || !hasCode}\n >\n Run Selected Code\n </Button>\n </div>\n <div className=\"markdown-notebook-content\" ref={this.editorScrollView}>\n <Markdown\n components={{ code: this.renderCodeBlock, a: this.renderLink }}\n linkTarget=\"_blank\"\n remarkPlugins={[remarkGfm]}\n transformLinkUri={transformLinkUri}\n transformImageUri={transformImageUri}\n includeElementIndex\n >\n {content}\n </Markdown>\n </div>\n </div>\n );\n }\n}\n\nexport default MarkdownNotebook;\n"],"mappings":"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"}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/* stylelint-disable scss/at-import-no-partial-leading-underscore */
|
|
2
|
-
.markdown-editor-container {
|
|
3
|
-
padding: 5px;
|
|
4
|
-
}
|
|
5
|
-
.markdown-editor-container .edit-hint {
|
|
6
|
-
padding: 5px 20px;
|
|
7
|
-
text-align: right;
|
|
8
|
-
width: 100%;
|
|
9
|
-
min-height: 30px;
|
|
10
|
-
height: 30px;
|
|
11
|
-
opacity: 0;
|
|
12
|
-
user-select: none;
|
|
13
|
-
transition: opacity 0.15s ease-out;
|
|
14
|
-
}
|
|
15
|
-
.markdown-editor-container .markdown-editor-container {
|
|
16
|
-
height: calc(100% - 30px - 10px);
|
|
17
|
-
padding: 0 15px;
|
|
18
|
-
overflow: auto;
|
|
19
|
-
}
|
|
20
|
-
.markdown-editor-container:hover .edit-hint.viewing {
|
|
21
|
-
opacity: 1;
|
|
22
|
-
}
|
|
23
|
-
.markdown-editor-container blockquote {
|
|
24
|
-
border-left: 0.25em solid #929192;
|
|
25
|
-
padding: 0 1em;
|
|
26
|
-
color: #f0f0ee;
|
|
27
|
-
}
|
|
28
|
-
.markdown-editor-container code {
|
|
29
|
-
color: #f0f0ee;
|
|
30
|
-
background: #403e41;
|
|
31
|
-
padding: 2px 0.5rem;
|
|
32
|
-
border-radius: 4px;
|
|
33
|
-
border: 1px solid #1a171a;
|
|
34
|
-
}
|
|
35
|
-
.markdown-editor-container pre > code {
|
|
36
|
-
display: block;
|
|
37
|
-
padding: 0.5rem;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.markdown-panel-start-page {
|
|
41
|
-
overflow: auto;
|
|
42
|
-
padding: 50px;
|
|
43
|
-
}
|
|
44
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list {
|
|
45
|
-
padding-bottom: 20px;
|
|
46
|
-
}
|
|
47
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-title {
|
|
48
|
-
padding-left: calc(1rem + 2px);
|
|
49
|
-
}
|
|
50
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-item {
|
|
51
|
-
color: #4878ea;
|
|
52
|
-
border-radius: 25px;
|
|
53
|
-
width: 28rem;
|
|
54
|
-
max-width: 28rem;
|
|
55
|
-
cursor: pointer;
|
|
56
|
-
display: flex;
|
|
57
|
-
justify-content: space-between;
|
|
58
|
-
}
|
|
59
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-item button.title {
|
|
60
|
-
padding: 0.375rem 1rem;
|
|
61
|
-
color: #4878ea;
|
|
62
|
-
text-align: left;
|
|
63
|
-
overflow: hidden;
|
|
64
|
-
text-overflow: ellipsis;
|
|
65
|
-
}
|
|
66
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-item button.icon {
|
|
67
|
-
visibility: hidden;
|
|
68
|
-
position: relative;
|
|
69
|
-
background: none;
|
|
70
|
-
border: none;
|
|
71
|
-
color: #5b5a5c;
|
|
72
|
-
cursor: pointer;
|
|
73
|
-
margin: 0;
|
|
74
|
-
padding: 0.375px;
|
|
75
|
-
padding-right: 1.75rem;
|
|
76
|
-
}
|
|
77
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-item:hover {
|
|
78
|
-
background: #373438;
|
|
79
|
-
}
|
|
80
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-item:hover button.icon {
|
|
81
|
-
visibility: visible;
|
|
82
|
-
}
|
|
83
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-item:hover button.icon:hover {
|
|
84
|
-
color: #4878ea;
|
|
85
|
-
}
|
|
86
|
-
.markdown-panel-start-page .markdown-panel-start-page-container .markdown-panel-start-list .list-item:hover button.icon:focus {
|
|
87
|
-
outline: none;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/*# sourceMappingURL=MarkdownPanel.css.map */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sourceRoot":"","sources":["../../../../node_modules/@deephaven/components/scss/custom.scss","../../src/panels/MarkdownPanel.scss","../../../../node_modules/@deephaven/components/scss/bootstrap_overrides.scss","../../../../node_modules/@deephaven/components/scss/new_variables.scss"],"names":[],"mappings":"AAAA;ACKA;EACE;;AAEA;EACE;EACA;EACA;EACA,YAVe;EAWf,QAXe;EAYf;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;EACA,OCnBa;;ADsBf;EACE,OCvBa;EDwBb,YCbO;EDcP;EACA,eCkFY;EDjFZ;;AAGF;EACE;EACA,SE1CO;;;AF8CX;EACE;EACA;;AAEE;EACE;;AACA;EACE;;AAEF;EACE,OC/CQ;EDgDR;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA,OCzDM;ED0DN;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA,OC1DC;ED2DD;EACA;EACA;EACA;;AAGF;EACE,YC/DC;;ADgED;EACE;;AAEA;EACE,OCjFE;;ADmFJ;EACE","file":"MarkdownPanel.css","sourcesContent":["/* stylelint-disable scss/at-import-no-partial-leading-underscore */\n// Consumers should be able to resolve bootstrap/ to node_modules/bootstrap\n\n//Make bootstrap functions available for use in overrides\n@import 'bootstrap/scss/_functions.scss';\n@import './bootstrap_overrides.scss';\n\n//_variable imports come after bootstrap default overrides,\n// makes all other variables and mixins from bootstrap available\n/// with just importing customer.scss\n@import 'bootstrap/scss/_variables.scss';\n@import 'bootstrap/scss/_mixins.scss';\n\n//New variables come after imports\n@import './new_variables.scss';\n","@import '@deephaven/components/scss/custom.scss';\n\n$edit-hint-height: 30px;\n$panel-container-padding: 10px;\n\n.markdown-editor-container {\n padding: 5px;\n\n .edit-hint {\n padding: 5px 20px;\n text-align: right;\n width: 100%;\n min-height: $edit-hint-height;\n height: $edit-hint-height;\n opacity: 0;\n user-select: none;\n transition: opacity $transition ease-out;\n }\n\n .markdown-editor-container {\n height: calc(100% - #{$edit-hint-height} - #{$panel-container-padding});\n padding: 0 15px;\n overflow: auto;\n }\n\n &:hover .edit-hint.viewing {\n opacity: 1;\n }\n\n blockquote {\n border-left: 0.25em solid $gray-400;\n padding: 0 1em;\n color: $foreground;\n }\n\n code {\n color: $foreground;\n background: $gray-700;\n padding: 2px $spacer-2;\n border-radius: $border-radius;\n border: 1px solid $black;\n }\n\n pre > code {\n display: block;\n padding: $spacer-2;\n }\n}\n\n.markdown-panel-start-page {\n overflow: auto;\n padding: 50px;\n .markdown-panel-start-page-container {\n .markdown-panel-start-list {\n padding-bottom: 20px;\n .list-title {\n padding-left: calc(1rem + 2px);\n }\n .list-item {\n color: $primary;\n border-radius: 25px;\n width: 28rem;\n max-width: 28rem;\n cursor: pointer;\n display: flex;\n justify-content: space-between;\n\n button.title {\n padding: 0.375rem 1rem;\n color: $primary;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n button.icon {\n visibility: hidden;\n position: relative;\n background: none;\n border: none;\n color: $gray-500;\n cursor: pointer;\n margin: 0;\n padding: 0.375px;\n padding-right: 1.75rem;\n }\n\n &:hover {\n background: $gray-800;\n button.icon {\n visibility: visible;\n\n &:hover {\n color: $primary;\n }\n &:focus {\n outline: none;\n }\n }\n }\n }\n }\n }\n}\n","// Styling overrides for bootstrap\n\n// Override / set color variables\n$red: #f95d84;\n$orange: #f37e3f;\n$yellow: #fcd65b;\n$green: #9edc6f;\n$blue: #76d9e4;\n$purple: #aa9af4;\n\n//Define some UI colors\n$interfacegray: #2d2a2e;\n$interfaceblue: #4878ea;\n$interfacewhite: #f0f0ee; //same as gray-200\n$interfaceblack: #1a171a;\n\n//Define our Gray scale\n$white: $interfacewhite;\n$gray-100: #fcfcfa;\n$gray-200: $interfacewhite;\n$gray-300: #c0bfbf;\n$gray-400: #929192;\n$gray-500: #5b5a5c;\n$gray-600: #555356;\n$gray-700: #403e41;\n$gray-800: #373438;\n$gray-850: #322f33;\n$gray-900: #211f22;\n$black: $interfaceblack;\n$content-bg: $interfacegray;\n$background: $interfaceblack;\n$foreground: $interfacewhite;\n\n//Load colors into map\n$colors: ();\n$colors: map-merge(\n (\n 'red': $red,\n 'orange': $orange,\n 'yellow': $yellow,\n 'green': $green,\n 'blue': $blue,\n 'purple': $purple,\n 'white': $white,\n 'black': $black,\n ),\n $colors\n);\n\n//Set default colors\n$body-bg: $black;\n$body-color: $interfacewhite;\n\n// Set brand colors\n$primary: $interfaceblue;\n$primary-hover: darken($primary, 8%);\n$primary-dark: mix($primary, $content-bg, 25%);\n$primary-light: scale-color($primary, $lightness: -25%);\n$secondary: $gray-500;\n$secondary-hover: darken($secondary, 8%);\n$success: $green;\n$info: $yellow;\n$warning: $orange;\n$danger: $red;\n$danger-hover: darken($danger, 8%);\n$light: $gray-100;\n$mid: $gray-400; //Added a mid color, useful for input styling\n$dark: $gray-800;\n$green-dark: scale-color($green, $lightness: -45%, $saturation: -10%);\n\n$theme-colors: () !default;\n$theme-colors: map-merge(\n (\n 'primary': $primary,\n 'primary-hover': $primary-hover,\n 'primary-light': $primary-light,\n 'primary-dark': $primary-dark,\n 'secondary': $secondary,\n 'success': $success,\n 'info': $info,\n 'warning': $warning,\n 'danger': $danger,\n 'light': $light,\n 'dark': $dark,\n 'mid': $mid,\n 'content-bg': $interfacegray,\n 'background': $interfaceblack,\n 'foreground': $interfacewhite,\n ),\n $theme-colors\n);\n\n$component-active-bg: $primary;\n$theme-color-interval: 9%;\n$yiq-contrasted-threshold: 180;\n\n// Override fonts\n$font-family-sans-serif: 'Fira Sans', -apple-system, blinkmacsystemfont,\n 'Segoe UI', 'Roboto', 'Helvetica Neue', arial, sans-serif; //fira sans then native system ui fallbacks\n$font-family-monospace: 'Fira Mono', menlo, monaco, consolas, 'Liberation Mono',\n 'Courier New', monospace;\n$font-family-base: $font-family-sans-serif;\n\n$headings-font-weight: 400;\n\n//Text overides\n$text-muted: $gray-400;\n\n//Style Selection highlight color\n//so browsers add alpha to your color by default, ignoring opacity 1\n//by setting rgba with 0.99 it tricks browser into thinking there is alpha applied\n$text-select-color: $primary-hover;\n$text-select-color-editor: lighten(\n $gray-700,\n 15%\n); //we lighten it abit to account for that 0.01 loss, and because it needs some anyways.\n\n//Grid variables, same value as default just making easily accessible\n$grid-gutter-width: 30px;\n\n//Visual Overrides\n$border-radius: 4px;\n$box-shadow: 0 0.1rem 1rem rgba($black, 45%); //because our UI is so dark, we need darker default shadows\n$box-shadow-900: 0 0.1rem 1rem rgba(0, 0, 0, 45%); //darkest shadow for $black popups over $black UI\n\n//Override Btn\n$btn-border-radius: 4rem;\n$btn-padding-x: 1.5rem;\n$btn-transition: color 0.12s ease-in-out, background-color 0.12s ease-in-out,\n border-color 0.12s ease-in-out, box-shadow 0.12s ease-in-out; //default 0.15 is too long\n$btn-border-width: 2px;\n\n//Override Inputs\n$input-bg: $gray-600;\n$input-disabled-bg: $gray-800;\n$input-color: $foreground;\n$input-border-color: $gray-400;\n$input-placeholder-color: $gray-400;\n$input-focus-border-color: rgba($primary, 85%);\n\n$input-btn-focus-width: 0.2rem;\n$input-btn-focus-color: rgba($component-active-bg, 35%);\n$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color;\n\n//checkbox\n$custom-control-indicator-bg: $gray-600;\n$custom-control-indicator-bg-size: 75% 75%;\n$custom-control-indicator-disabled-bg: $gray-800;\n$custom-control-indicator-checked-disabled-bg: $gray-800;\n$custom-control-label-disabled-color: $gray-400;\n\n//Custom Select\n$custom-select-indicator-color: $gray-400;\n$custom-select-bg-size: 16px 16px;\n//dhSort icon encoded\n$custom-select-indicator: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M4 7l-.4-.8 4-3.7h.8l4 3.7-.4.8H4zm0 2l-.4.8 4 3.7h.8l4-3.7L12 9H4z'/%3E%3C/svg%3E\"),\n '#',\n '%23'\n);\n$custom-select-focus-box-shadow: $input-btn-focus-box-shadow;\n$custom-select-disabled-color: darken($gray-400, 5%);\n$custom-select-disabled-bg: $gray-800;\n\n//modal\n$modal-content-bg: $gray-200;\n$modal-content-border-width: 0;\n$modal-md: 550px;\n\n// Toast notification\n$toast-bg: $primary-dark;\n$toast-color: $foreground;\n$toast-error-bg: mix($danger, $content-bg, 15%);\n$toast-error-color: $foreground;\n\n//tooltips\n$tooltip-bg: $gray-700;\n$tooltip-color: $foreground;\n$tooltip-box-shadow: 0 0.1rem 1.5rem 0.1rem rgba($black, 80%);\n\n//drowdowns\n$dropdown-bg: $gray-600;\n$dropdown-link-color: $foreground;\n$dropdown-link-hover-color: $foreground;\n$dropdown-link-hover-bg: $primary;\n$dropdown-divider-bg: $gray-700;\n\n//context menus\n$contextmenu-bg: $gray-600;\n$contextmenu-color: $foreground;\n$contextmenu-disabled-color: $text-muted;\n$contextmenu-keyboard-selected-bg: rgba($primary, 50%);\n$contextmenu-selected-bg: $primary;\n$contextmenu-selected-color: $foreground;\n\n//links\n$link-color: $gray-400;\n$link-hover-color: $foreground;\n\n//progress-bar\n$progress-bg: $gray-600;\n$progress-border-radius: 1rem;\n\n// Set global options\n$enable-shadows: false;\n$enable-gradients: false;\n$enable-print-styles: false; //I don't think anyone should expect to \"print\" this app.\n\n// Transition times\n$transition: 0.15s;\n$transition-mid: 0.2s;\n$transition-long: 0.3s;\n$transition-slow: 0.6s;\n\n//form-validation icon, uses vsWarning icon encoded here as svg\n$form-feedback-icon-invalid-color: theme-color('danger');\n$form-feedback-icon-invalid: str-replace(\n url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cg fill='none'%3E%3Cg fill='#{$form-feedback-icon-invalid-color}'%3E%3Cpath d='M7.56 1h.88l6.54 12.26-.44.74H1.44L1 13.26 7.56 1zM8 2.28 2.28 13H13.7L8 2.28zM8.625 12v-1h-1.25v1h1.25zm-1.25-2V6h1.25v4h-1.25z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E \"),\n '#',\n '%23'\n);\n","//Set of spacer variables from the spacer map\n$spacer-0: map-get($spacers, 0); //0\n$spacer-1: map-get($spacers, 1);\n$spacer-2: map-get($spacers, 2);\n$spacer-3: map-get($spacers, 3);\n$spacer-4: map-get($spacers, 4);\n$spacer-5: map-get($spacers, 5);\n\n//Marching Ants for golden layout dropzone and drag and drop\n//top bottom, left right.\n//create 4 background images that are 50% color 1, 50% color 2 using graidents, two veritical, two horizontal\n//size them to ant-size and thickness\n//position those images along the egdes and make top/bottom repeat-x and left/right repeat-y\n//then offest each of those background positions by ant-size in animation to make them march.\n$ant-size: 8px;\n$ant-thickness: 1px;\n\n@mixin ants-base($color-1: black, $color-2: white) {\n background-image: linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to right, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%),\n linear-gradient(to bottom, $color-2 50%, $color-1 50%);\n background-size: $ant-size $ant-thickness, $ant-size $ant-thickness,\n $ant-thickness $ant-size, $ant-thickness $ant-size;\n background-position: 0 top, 0 bottom, left 0, right 0;\n background-repeat: repeat-x, repeat-x, repeat-y, repeat-y;\n animation: march 0.5s;\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n}\n\n@mixin drag-stack($pseudo-element) {\n &::#{$pseudo-element} {\n content: ' ';\n background: $primary;\n box-shadow: $box-shadow;\n border-radius: $border-radius;\n position: absolute;\n height: 100%;\n width: 100%;\n @content;\n }\n}\n\n$focus-bg-transparency: 0.12;\n$hover-bg-transparency: 0.14;\n$active-bg-transparency: 0.28;\n$exception-transparency: 0.13;\n"]}
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
|
-
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
3
|
-
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
4
|
-
import React, { Component } from 'react';
|
|
5
|
-
import memoize from 'memoize-one';
|
|
6
|
-
import { connect } from 'react-redux';
|
|
7
|
-
import { getClosedPanelsForDashboard, LayoutUtils, PanelEvent } from '@deephaven/dashboard';
|
|
8
|
-
import Log from '@deephaven/log';
|
|
9
|
-
import { assertNotNull } from '@deephaven/utils';
|
|
10
|
-
import Panel from "./Panel.js";
|
|
11
|
-
import MarkdownContainer from "../controls/markdown/MarkdownContainer.js";
|
|
12
|
-
import MarkdownStartPage from "../controls/markdown/MarkdownStartPage.js";
|
|
13
|
-
import MarkdownEditor from "../controls/markdown/MarkdownEditor.js";
|
|
14
|
-
import "./MarkdownPanel.css";
|
|
15
|
-
var log = Log.module('MarkdownPanel');
|
|
16
|
-
export class MarkdownPanel extends Component {
|
|
17
|
-
constructor(props) {
|
|
18
|
-
super(props);
|
|
19
|
-
_defineProperty(this, "markdownEditor", void 0);
|
|
20
|
-
_defineProperty(this, "editor", void 0);
|
|
21
|
-
_defineProperty(this, "getClosedMarkdowns", memoize(closedPanels => closedPanels.filter(panel => panel.component === 'MarkdownPanel').reverse()));
|
|
22
|
-
this.handleContainerDoubleClick = this.handleContainerDoubleClick.bind(this);
|
|
23
|
-
this.handleCreateMarkdown = this.handleCreateMarkdown.bind(this);
|
|
24
|
-
this.handleDeleteMarkdown = this.handleDeleteMarkdown.bind(this);
|
|
25
|
-
this.handleOpenMarkdown = this.handleOpenMarkdown.bind(this);
|
|
26
|
-
this.handleEditorInitialized = this.handleEditorInitialized.bind(this);
|
|
27
|
-
this.handleEditorBlur = this.handleEditorBlur.bind(this);
|
|
28
|
-
this.handleEditorResize = this.handleEditorResize.bind(this);
|
|
29
|
-
var {
|
|
30
|
-
panelState
|
|
31
|
-
} = props;
|
|
32
|
-
var content = null;
|
|
33
|
-
if (panelState != null && panelState.content != null) {
|
|
34
|
-
({
|
|
35
|
-
content
|
|
36
|
-
} = panelState);
|
|
37
|
-
}
|
|
38
|
-
this.state = {
|
|
39
|
-
isStartPageShown: content == null,
|
|
40
|
-
isEditing: false,
|
|
41
|
-
content,
|
|
42
|
-
// eslint-disable-next-line react/no-unused-state
|
|
43
|
-
panelState
|
|
44
|
-
};
|
|
45
|
-
this.markdownEditor = null;
|
|
46
|
-
}
|
|
47
|
-
setEditorPosition(clickPositionY) {
|
|
48
|
-
assertNotNull(this.markdownEditor);
|
|
49
|
-
var {
|
|
50
|
-
container: markdownEditorContainer
|
|
51
|
-
} = this.markdownEditor;
|
|
52
|
-
if (this.editor && markdownEditorContainer) {
|
|
53
|
-
var _this$editor$getModel, _this$editor$getModel2;
|
|
54
|
-
var contentTop = markdownEditorContainer.getBoundingClientRect().top;
|
|
55
|
-
var contentScrollTop = markdownEditorContainer.scrollTop;
|
|
56
|
-
var contentScrollHeight = markdownEditorContainer.scrollHeight;
|
|
57
|
-
var totalLines = (_this$editor$getModel = (_this$editor$getModel2 = this.editor.getModel()) === null || _this$editor$getModel2 === void 0 ? void 0 : _this$editor$getModel2.getLineCount()) !== null && _this$editor$getModel !== void 0 ? _this$editor$getModel : 0;
|
|
58
|
-
var lineToFocus = Math.round((contentScrollTop + clickPositionY - contentTop) / contentScrollHeight * totalLines);
|
|
59
|
-
if (lineToFocus > totalLines) {
|
|
60
|
-
lineToFocus = totalLines;
|
|
61
|
-
}
|
|
62
|
-
this.editor.revealLine(lineToFocus);
|
|
63
|
-
this.editor.setPosition({
|
|
64
|
-
lineNumber: lineToFocus,
|
|
65
|
-
column: 1
|
|
66
|
-
});
|
|
67
|
-
this.editor.focus();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
handleContainerDoubleClick(event) {
|
|
71
|
-
var {
|
|
72
|
-
isEditing
|
|
73
|
-
} = this.state;
|
|
74
|
-
var dbClickPositionY = event.clientY;
|
|
75
|
-
if (!isEditing) {
|
|
76
|
-
this.setState({
|
|
77
|
-
isEditing: true
|
|
78
|
-
}, () => {
|
|
79
|
-
this.setEditorPosition(dbClickPositionY);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
handleEditorInitialized(editor) {
|
|
84
|
-
log.debug('Markdown Editor Initialized...');
|
|
85
|
-
this.editor = editor;
|
|
86
|
-
}
|
|
87
|
-
handleCreateMarkdown() {
|
|
88
|
-
log.debug('create markdown...');
|
|
89
|
-
this.setState({
|
|
90
|
-
isStartPageShown: false,
|
|
91
|
-
content: '',
|
|
92
|
-
isEditing: true,
|
|
93
|
-
// eslint-disable-next-line react/no-unused-state
|
|
94
|
-
panelState: {
|
|
95
|
-
content: ''
|
|
96
|
-
}
|
|
97
|
-
}, () => {
|
|
98
|
-
if (this.editor != null && this.editor.focus != null) {
|
|
99
|
-
this.editor.focus();
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
handleOpenMarkdown(markdown) {
|
|
104
|
-
log.debug('open markdown...', markdown);
|
|
105
|
-
var {
|
|
106
|
-
glContainer,
|
|
107
|
-
glEventHub
|
|
108
|
-
} = this.props;
|
|
109
|
-
var config = LayoutUtils.getComponentConfigFromContainer(glContainer);
|
|
110
|
-
glEventHub.emit(PanelEvent.REOPEN, markdown, config);
|
|
111
|
-
}
|
|
112
|
-
handleDeleteMarkdown(markdown) {
|
|
113
|
-
var {
|
|
114
|
-
glEventHub
|
|
115
|
-
} = this.props;
|
|
116
|
-
glEventHub.emit(PanelEvent.DELETE, markdown);
|
|
117
|
-
}
|
|
118
|
-
handleEditorBlur(event) {
|
|
119
|
-
var _this$editor;
|
|
120
|
-
log.debug("markdown content changed, saving...");
|
|
121
|
-
var {
|
|
122
|
-
isEditing
|
|
123
|
-
} = this.state;
|
|
124
|
-
|
|
125
|
-
// if not in edit mode, or in edit mode but blur went to an internal monaco field (like search)
|
|
126
|
-
if (!isEditing || this.markdownEditor != null && this.markdownEditor.container != null && this.markdownEditor.container.contains(event.relatedTarget)) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
var content = (_this$editor = this.editor) === null || _this$editor === void 0 ? void 0 : _this$editor.getValue();
|
|
130
|
-
this.setState({
|
|
131
|
-
content,
|
|
132
|
-
isEditing: false,
|
|
133
|
-
// eslint-disable-next-line react/no-unused-state
|
|
134
|
-
panelState: {
|
|
135
|
-
content
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
handleEditorResize() {
|
|
140
|
-
var {
|
|
141
|
-
isEditing
|
|
142
|
-
} = this.state;
|
|
143
|
-
if (isEditing && this.editor) {
|
|
144
|
-
this.editor.layout();
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
render() {
|
|
148
|
-
var {
|
|
149
|
-
glContainer,
|
|
150
|
-
glEventHub,
|
|
151
|
-
closedPanels
|
|
152
|
-
} = this.props;
|
|
153
|
-
var {
|
|
154
|
-
isEditing,
|
|
155
|
-
isStartPageShown,
|
|
156
|
-
content
|
|
157
|
-
} = this.state;
|
|
158
|
-
var closedMarkdowns = this.getClosedMarkdowns(closedPanels);
|
|
159
|
-
return /*#__PURE__*/React.createElement(Panel, {
|
|
160
|
-
glContainer: glContainer,
|
|
161
|
-
glEventHub: glEventHub,
|
|
162
|
-
className: "markdown-panel",
|
|
163
|
-
componentPanel: this,
|
|
164
|
-
onResize: this.handleEditorResize,
|
|
165
|
-
onBlur: this.handleEditorBlur,
|
|
166
|
-
isClonable: true,
|
|
167
|
-
isRenamable: true
|
|
168
|
-
}, isStartPageShown ? /*#__PURE__*/React.createElement(MarkdownStartPage, {
|
|
169
|
-
closedMarkdowns: closedMarkdowns,
|
|
170
|
-
onCreate: this.handleCreateMarkdown,
|
|
171
|
-
onOpen: this.handleOpenMarkdown,
|
|
172
|
-
onDelete: this.handleDeleteMarkdown
|
|
173
|
-
}) : /*#__PURE__*/React.createElement(MarkdownContainer, {
|
|
174
|
-
isEditing: isEditing,
|
|
175
|
-
onDoubleClick: this.handleContainerDoubleClick
|
|
176
|
-
}, /*#__PURE__*/React.createElement(MarkdownEditor, {
|
|
177
|
-
ref: markdownEditor => {
|
|
178
|
-
this.markdownEditor = markdownEditor;
|
|
179
|
-
},
|
|
180
|
-
isEditing: isEditing,
|
|
181
|
-
content: content !== null && content !== void 0 ? content : undefined,
|
|
182
|
-
onEditorInitialized: this.handleEditorInitialized
|
|
183
|
-
})));
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
_defineProperty(MarkdownPanel, "defaultProps", {
|
|
187
|
-
panelState: null
|
|
188
|
-
});
|
|
189
|
-
_defineProperty(MarkdownPanel, "COMPONENT", 'MarkdownPanel');
|
|
190
|
-
var mapStateToProps = (state, ownProps) => {
|
|
191
|
-
var {
|
|
192
|
-
localDashboardId
|
|
193
|
-
} = ownProps;
|
|
194
|
-
return {
|
|
195
|
-
closedPanels: getClosedPanelsForDashboard(state, localDashboardId)
|
|
196
|
-
};
|
|
197
|
-
};
|
|
198
|
-
var ConnectedMarkdownPanel = connect(mapStateToProps, null, null, {
|
|
199
|
-
forwardRef: true
|
|
200
|
-
})(MarkdownPanel);
|
|
201
|
-
export default ConnectedMarkdownPanel;
|
|
202
|
-
//# sourceMappingURL=MarkdownPanel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownPanel.js","names":["React","Component","memoize","connect","getClosedPanelsForDashboard","LayoutUtils","PanelEvent","Log","assertNotNull","Panel","MarkdownContainer","MarkdownStartPage","MarkdownEditor","log","module","MarkdownPanel","constructor","props","closedPanels","filter","panel","component","reverse","handleContainerDoubleClick","bind","handleCreateMarkdown","handleDeleteMarkdown","handleOpenMarkdown","handleEditorInitialized","handleEditorBlur","handleEditorResize","panelState","content","state","isStartPageShown","isEditing","markdownEditor","setEditorPosition","clickPositionY","container","markdownEditorContainer","editor","contentTop","getBoundingClientRect","top","contentScrollTop","scrollTop","contentScrollHeight","scrollHeight","totalLines","getModel","getLineCount","lineToFocus","Math","round","revealLine","setPosition","lineNumber","column","focus","event","dbClickPositionY","clientY","setState","debug","markdown","glContainer","glEventHub","config","getComponentConfigFromContainer","emit","REOPEN","DELETE","contains","relatedTarget","getValue","layout","render","closedMarkdowns","getClosedMarkdowns","undefined","mapStateToProps","ownProps","localDashboardId","ConnectedMarkdownPanel","forwardRef"],"sources":["../../src/panels/MarkdownPanel.tsx"],"sourcesContent":["import React, { Component, FocusEvent, MouseEvent, ReactElement } from 'react';\nimport memoize from 'memoize-one';\nimport { connect } from 'react-redux';\nimport {\n ClosedPanel,\n ClosedPanels,\n getClosedPanelsForDashboard,\n LayoutUtils,\n PanelEvent,\n} from '@deephaven/dashboard';\nimport Log from '@deephaven/log';\nimport type {\n Container,\n EventEmitter,\n ReactComponentConfig,\n} from '@deephaven/golden-layout';\nimport type * as monaco from 'monaco-editor';\nimport { assertNotNull } from '@deephaven/utils';\nimport { RootState } from '@deephaven/redux';\nimport Panel from './Panel';\nimport MarkdownContainer from '../controls/markdown/MarkdownContainer';\nimport MarkdownStartPage from '../controls/markdown/MarkdownStartPage';\nimport MarkdownEditor from '../controls/markdown/MarkdownEditor';\nimport './MarkdownPanel.scss';\n\nconst log = Log.module('MarkdownPanel');\n\ninterface PanelState {\n content?: string;\n}\n\ninterface MarkdownPanelProps {\n glContainer: Container;\n glEventHub: EventEmitter;\n panelState: PanelState;\n closedPanels: ClosedPanel[];\n}\n\ninterface MarkdownPanelState {\n isStartPageShown: boolean;\n isEditing: boolean;\n content?: string | null;\n\n // eslint-disable-next-line react/no-unused-state\n panelState: PanelState;\n}\n\nexport class MarkdownPanel extends Component<\n MarkdownPanelProps,\n MarkdownPanelState\n> {\n static defaultProps = {\n panelState: null,\n };\n\n static COMPONENT = 'MarkdownPanel';\n\n constructor(props: MarkdownPanelProps) {\n super(props);\n\n this.handleContainerDoubleClick = this.handleContainerDoubleClick.bind(\n this\n );\n this.handleCreateMarkdown = this.handleCreateMarkdown.bind(this);\n this.handleDeleteMarkdown = this.handleDeleteMarkdown.bind(this);\n this.handleOpenMarkdown = this.handleOpenMarkdown.bind(this);\n this.handleEditorInitialized = this.handleEditorInitialized.bind(this);\n this.handleEditorBlur = this.handleEditorBlur.bind(this);\n this.handleEditorResize = this.handleEditorResize.bind(this);\n\n const { panelState } = props;\n let content = null;\n if (panelState != null && panelState.content != null) {\n ({ content } = panelState);\n }\n\n this.state = {\n isStartPageShown: content == null,\n isEditing: false,\n content,\n\n // eslint-disable-next-line react/no-unused-state\n panelState,\n };\n\n this.markdownEditor = null;\n }\n\n markdownEditor: MarkdownEditor | null;\n\n editor?: monaco.editor.IStandaloneCodeEditor;\n\n setEditorPosition(clickPositionY: number): void {\n assertNotNull(this.markdownEditor);\n const { container: markdownEditorContainer } = this.markdownEditor;\n if (this.editor && markdownEditorContainer) {\n const contentTop = markdownEditorContainer.getBoundingClientRect().top;\n const contentScrollTop = markdownEditorContainer.scrollTop;\n const contentScrollHeight = markdownEditorContainer.scrollHeight;\n const totalLines = this.editor.getModel()?.getLineCount() ?? 0;\n\n let lineToFocus = Math.round(\n ((contentScrollTop + clickPositionY - contentTop) /\n contentScrollHeight) *\n totalLines\n );\n if (lineToFocus > totalLines) {\n lineToFocus = totalLines;\n }\n\n this.editor.revealLine(lineToFocus);\n this.editor.setPosition({\n lineNumber: lineToFocus,\n column: 1,\n });\n this.editor.focus();\n }\n }\n\n getClosedMarkdowns = memoize((closedPanels: ClosedPanels) =>\n closedPanels.filter(panel => panel.component === 'MarkdownPanel').reverse()\n );\n\n handleContainerDoubleClick(event: MouseEvent<Element>): void {\n const { isEditing } = this.state;\n const dbClickPositionY = event.clientY;\n\n if (!isEditing) {\n this.setState({ isEditing: true }, () => {\n this.setEditorPosition(dbClickPositionY);\n });\n }\n }\n\n handleEditorInitialized(editor: monaco.editor.IStandaloneCodeEditor): void {\n log.debug('Markdown Editor Initialized...');\n this.editor = editor;\n }\n\n handleCreateMarkdown(): void {\n log.debug('create markdown...');\n\n this.setState(\n {\n isStartPageShown: false,\n content: '',\n isEditing: true,\n\n // eslint-disable-next-line react/no-unused-state\n panelState: { content: '' },\n },\n () => {\n if (this.editor != null && this.editor.focus != null) {\n this.editor.focus();\n }\n }\n );\n }\n\n handleOpenMarkdown(markdown: ReactComponentConfig): void {\n log.debug('open markdown...', markdown);\n\n const { glContainer, glEventHub } = this.props;\n const config = LayoutUtils.getComponentConfigFromContainer(glContainer);\n glEventHub.emit(PanelEvent.REOPEN, markdown, config);\n }\n\n handleDeleteMarkdown(markdown: ReactComponentConfig): void {\n const { glEventHub } = this.props;\n glEventHub.emit(PanelEvent.DELETE, markdown);\n }\n\n handleEditorBlur(event: FocusEvent<HTMLDivElement>): void {\n log.debug(`markdown content changed, saving...`);\n const { isEditing } = this.state;\n\n // if not in edit mode, or in edit mode but blur went to an internal monaco field (like search)\n if (\n !isEditing ||\n (this.markdownEditor != null &&\n this.markdownEditor.container != null &&\n this.markdownEditor.container.contains(event.relatedTarget))\n ) {\n return;\n }\n\n const content = this.editor?.getValue();\n\n this.setState({\n content,\n isEditing: false,\n\n // eslint-disable-next-line react/no-unused-state\n panelState: { content },\n });\n }\n\n handleEditorResize(): void {\n const { isEditing } = this.state;\n if (isEditing && this.editor) {\n this.editor.layout();\n }\n }\n\n render(): ReactElement {\n const { glContainer, glEventHub, closedPanels } = this.props;\n const { isEditing, isStartPageShown, content } = this.state;\n const closedMarkdowns = this.getClosedMarkdowns(closedPanels);\n\n return (\n <Panel\n glContainer={glContainer}\n glEventHub={glEventHub}\n className=\"markdown-panel\"\n componentPanel={this}\n onResize={this.handleEditorResize}\n onBlur={this.handleEditorBlur}\n isClonable\n isRenamable\n >\n {isStartPageShown ? (\n <MarkdownStartPage\n closedMarkdowns={closedMarkdowns}\n onCreate={this.handleCreateMarkdown}\n onOpen={this.handleOpenMarkdown}\n onDelete={this.handleDeleteMarkdown}\n />\n ) : (\n <MarkdownContainer\n isEditing={isEditing}\n onDoubleClick={this.handleContainerDoubleClick}\n >\n <MarkdownEditor\n ref={markdownEditor => {\n this.markdownEditor = markdownEditor;\n }}\n isEditing={isEditing}\n content={content ?? undefined}\n onEditorInitialized={this.handleEditorInitialized}\n />\n </MarkdownContainer>\n )}\n </Panel>\n );\n }\n}\n\nconst mapStateToProps = (\n state: RootState,\n ownProps: { localDashboardId: string }\n) => {\n const { localDashboardId } = ownProps;\n return {\n closedPanels: getClosedPanelsForDashboard(state, localDashboardId),\n };\n};\n\nconst ConnectedMarkdownPanel = connect(mapStateToProps, null, null, {\n forwardRef: true,\n})(MarkdownPanel);\n\nexport default ConnectedMarkdownPanel;\n"],"mappings":"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"}
|