@theia/notebook 1.41.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.
Files changed (188) hide show
  1. package/README.md +30 -0
  2. package/lib/browser/contributions/notebook-actions-contribution.d.ts +27 -0
  3. package/lib/browser/contributions/notebook-actions-contribution.d.ts.map +1 -0
  4. package/lib/browser/contributions/notebook-actions-contribution.js +172 -0
  5. package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -0
  6. package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts +30 -0
  7. package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts.map +1 -0
  8. package/lib/browser/contributions/notebook-cell-actions-contribution.js +200 -0
  9. package/lib/browser/contributions/notebook-cell-actions-contribution.js.map +1 -0
  10. package/lib/browser/contributions/notebook-color-contribution.d.ts +6 -0
  11. package/lib/browser/contributions/notebook-color-contribution.d.ts.map +1 -0
  12. package/lib/browser/contributions/notebook-color-contribution.js +252 -0
  13. package/lib/browser/contributions/notebook-color-contribution.js.map +1 -0
  14. package/lib/browser/contributions/notebook-context-keys.d.ts +38 -0
  15. package/lib/browser/contributions/notebook-context-keys.d.ts.map +1 -0
  16. package/lib/browser/contributions/notebook-context-keys.js +95 -0
  17. package/lib/browser/contributions/notebook-context-keys.js.map +1 -0
  18. package/lib/browser/index.d.ts +11 -0
  19. package/lib/browser/index.d.ts.map +1 -0
  20. package/lib/browser/index.js +38 -0
  21. package/lib/browser/index.js.map +1 -0
  22. package/lib/browser/notebook-cell-resource-resolver.d.ts +20 -0
  23. package/lib/browser/notebook-cell-resource-resolver.d.ts.map +1 -0
  24. package/lib/browser/notebook-cell-resource-resolver.js +75 -0
  25. package/lib/browser/notebook-cell-resource-resolver.js.map +1 -0
  26. package/lib/browser/notebook-editor-widget-factory.d.ts +17 -0
  27. package/lib/browser/notebook-editor-widget-factory.d.ts.map +1 -0
  28. package/lib/browser/notebook-editor-widget-factory.js +78 -0
  29. package/lib/browser/notebook-editor-widget-factory.js.map +1 -0
  30. package/lib/browser/notebook-editor-widget.d.ts +49 -0
  31. package/lib/browser/notebook-editor-widget.d.ts.map +1 -0
  32. package/lib/browser/notebook-editor-widget.js +150 -0
  33. package/lib/browser/notebook-editor-widget.js.map +1 -0
  34. package/lib/browser/notebook-frontend-module.d.ts +5 -0
  35. package/lib/browser/notebook-frontend-module.d.ts.map +1 -0
  36. package/lib/browser/notebook-frontend-module.js +81 -0
  37. package/lib/browser/notebook-frontend-module.js.map +1 -0
  38. package/lib/browser/notebook-open-handler.d.ts +18 -0
  39. package/lib/browser/notebook-open-handler.d.ts.map +1 -0
  40. package/lib/browser/notebook-open-handler.js +94 -0
  41. package/lib/browser/notebook-open-handler.js.map +1 -0
  42. package/lib/browser/notebook-renderer-registry.d.ts +17 -0
  43. package/lib/browser/notebook-renderer-registry.d.ts.map +1 -0
  44. package/lib/browser/notebook-renderer-registry.js +63 -0
  45. package/lib/browser/notebook-renderer-registry.js.map +1 -0
  46. package/lib/browser/notebook-type-registry.d.ts +7 -0
  47. package/lib/browser/notebook-type-registry.d.ts.map +1 -0
  48. package/lib/browser/notebook-type-registry.js +42 -0
  49. package/lib/browser/notebook-type-registry.js.map +1 -0
  50. package/lib/browser/renderers/cell-output-webview.d.ts +12 -0
  51. package/lib/browser/renderers/cell-output-webview.d.ts.map +1 -0
  52. package/lib/browser/renderers/cell-output-webview.js +20 -0
  53. package/lib/browser/renderers/cell-output-webview.js.map +1 -0
  54. package/lib/browser/service/notebook-cell-context-manager.d.ts +16 -0
  55. package/lib/browser/service/notebook-cell-context-manager.d.ts.map +1 -0
  56. package/lib/browser/service/notebook-cell-context-manager.js +83 -0
  57. package/lib/browser/service/notebook-cell-context-manager.js.map +1 -0
  58. package/lib/browser/service/notebook-editor-service.d.ts +22 -0
  59. package/lib/browser/service/notebook-editor-service.d.ts.map +1 -0
  60. package/lib/browser/service/notebook-editor-service.js +95 -0
  61. package/lib/browser/service/notebook-editor-service.js.map +1 -0
  62. package/lib/browser/service/notebook-execution-service.d.ts +25 -0
  63. package/lib/browser/service/notebook-execution-service.d.ts.map +1 -0
  64. package/lib/browser/service/notebook-execution-service.js +140 -0
  65. package/lib/browser/service/notebook-execution-service.js.map +1 -0
  66. package/lib/browser/service/notebook-execution-state-service.d.ts +94 -0
  67. package/lib/browser/service/notebook-execution-state-service.d.ts.map +1 -0
  68. package/lib/browser/service/notebook-execution-state-service.js +250 -0
  69. package/lib/browser/service/notebook-execution-state-service.js.map +1 -0
  70. package/lib/browser/service/notebook-kernel-history-service.d.ts +23 -0
  71. package/lib/browser/service/notebook-kernel-history-service.d.ts.map +1 -0
  72. package/lib/browser/service/notebook-kernel-history-service.js +109 -0
  73. package/lib/browser/service/notebook-kernel-history-service.js.map +1 -0
  74. package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts +65 -0
  75. package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts.map +1 -0
  76. package/lib/browser/service/notebook-kernel-quick-pick-service.js +430 -0
  77. package/lib/browser/service/notebook-kernel-quick-pick-service.js.map +1 -0
  78. package/lib/browser/service/notebook-kernel-service.d.ts +112 -0
  79. package/lib/browser/service/notebook-kernel-service.d.ts.map +1 -0
  80. package/lib/browser/service/notebook-kernel-service.js +274 -0
  81. package/lib/browser/service/notebook-kernel-service.js.map +1 -0
  82. package/lib/browser/service/notebook-model-resolver-service.d.ts +26 -0
  83. package/lib/browser/service/notebook-model-resolver-service.d.ts.map +1 -0
  84. package/lib/browser/service/notebook-model-resolver-service.js +139 -0
  85. package/lib/browser/service/notebook-model-resolver-service.js.map +1 -0
  86. package/lib/browser/service/notebook-renderer-messaging-service.d.ts +30 -0
  87. package/lib/browser/service/notebook-renderer-messaging-service.d.ts.map +1 -0
  88. package/lib/browser/service/notebook-renderer-messaging-service.js +94 -0
  89. package/lib/browser/service/notebook-renderer-messaging-service.js.map +1 -0
  90. package/lib/browser/service/notebook-service.d.ts +64 -0
  91. package/lib/browser/service/notebook-service.d.ts.map +1 -0
  92. package/lib/browser/service/notebook-service.js +162 -0
  93. package/lib/browser/service/notebook-service.js.map +1 -0
  94. package/lib/browser/view/notebook-cell-editor.d.ts +26 -0
  95. package/lib/browser/view/notebook-cell-editor.d.ts.map +1 -0
  96. package/lib/browser/view/notebook-cell-editor.js +79 -0
  97. package/lib/browser/view/notebook-cell-editor.js.map +1 -0
  98. package/lib/browser/view/notebook-cell-list-view.d.ts +43 -0
  99. package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -0
  100. package/lib/browser/view/notebook-cell-list-view.js +111 -0
  101. package/lib/browser/view/notebook-cell-list-view.js.map +1 -0
  102. package/lib/browser/view/notebook-cell-toolbar-factory.d.ts +25 -0
  103. package/lib/browser/view/notebook-cell-toolbar-factory.d.ts.map +1 -0
  104. package/lib/browser/view/notebook-cell-toolbar-factory.js +93 -0
  105. package/lib/browser/view/notebook-cell-toolbar-factory.js.map +1 -0
  106. package/lib/browser/view/notebook-cell-toolbar.d.ts +25 -0
  107. package/lib/browser/view/notebook-cell-toolbar.d.ts.map +1 -0
  108. package/lib/browser/view/notebook-cell-toolbar.js +50 -0
  109. package/lib/browser/view/notebook-cell-toolbar.js.map +1 -0
  110. package/lib/browser/view/notebook-code-cell-view.d.ts +47 -0
  111. package/lib/browser/view/notebook-code-cell-view.d.ts.map +1 -0
  112. package/lib/browser/view/notebook-code-cell-view.js +166 -0
  113. package/lib/browser/view/notebook-code-cell-view.js.map +1 -0
  114. package/lib/browser/view/notebook-main-toolbar.d.ts +31 -0
  115. package/lib/browser/view/notebook-main-toolbar.d.ts.map +1 -0
  116. package/lib/browser/view/notebook-main-toolbar.js +118 -0
  117. package/lib/browser/view/notebook-main-toolbar.js.map +1 -0
  118. package/lib/browser/view/notebook-markdown-cell-view.d.ts +12 -0
  119. package/lib/browser/view/notebook-markdown-cell-view.d.ts.map +1 -0
  120. package/lib/browser/view/notebook-markdown-cell-view.js +70 -0
  121. package/lib/browser/view/notebook-markdown-cell-view.js.map +1 -0
  122. package/lib/browser/view-model/notebook-cell-model.d.ts +74 -0
  123. package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -0
  124. package/lib/browser/view-model/notebook-cell-model.js +226 -0
  125. package/lib/browser/view-model/notebook-cell-model.js.map +1 -0
  126. package/lib/browser/view-model/notebook-cell-output-model.d.ts +19 -0
  127. package/lib/browser/view-model/notebook-cell-output-model.d.ts.map +1 -0
  128. package/lib/browser/view-model/notebook-cell-output-model.js +61 -0
  129. package/lib/browser/view-model/notebook-cell-output-model.js.map +1 -0
  130. package/lib/browser/view-model/notebook-model.d.ts +59 -0
  131. package/lib/browser/view-model/notebook-model.d.ts.map +1 -0
  132. package/lib/browser/view-model/notebook-model.js +315 -0
  133. package/lib/browser/view-model/notebook-model.js.map +1 -0
  134. package/lib/common/index.d.ts +3 -0
  135. package/lib/common/index.d.ts.map +1 -0
  136. package/lib/common/index.js +30 -0
  137. package/lib/common/index.js.map +1 -0
  138. package/lib/common/notebook-common.d.ts +344 -0
  139. package/lib/common/notebook-common.d.ts.map +1 -0
  140. package/lib/common/notebook-common.js +112 -0
  141. package/lib/common/notebook-common.js.map +1 -0
  142. package/lib/common/notebook-protocol.d.ts +21 -0
  143. package/lib/common/notebook-protocol.d.ts.map +1 -0
  144. package/lib/common/notebook-protocol.js +18 -0
  145. package/lib/common/notebook-protocol.js.map +1 -0
  146. package/lib/common/notebook-range.d.ts +14 -0
  147. package/lib/common/notebook-range.d.ts.map +1 -0
  148. package/lib/common/notebook-range.js +18 -0
  149. package/lib/common/notebook-range.js.map +1 -0
  150. package/package.json +52 -0
  151. package/src/browser/contributions/notebook-actions-contribution.ts +171 -0
  152. package/src/browser/contributions/notebook-cell-actions-contribution.ts +204 -0
  153. package/src/browser/contributions/notebook-color-contribution.ts +268 -0
  154. package/src/browser/contributions/notebook-context-keys.ts +99 -0
  155. package/src/browser/index.ts +26 -0
  156. package/src/browser/notebook-cell-resource-resolver.ts +79 -0
  157. package/src/browser/notebook-editor-widget-factory.ts +70 -0
  158. package/src/browser/notebook-editor-widget.tsx +157 -0
  159. package/src/browser/notebook-frontend-module.ts +95 -0
  160. package/src/browser/notebook-open-handler.ts +87 -0
  161. package/src/browser/notebook-renderer-registry.ts +62 -0
  162. package/src/browser/notebook-type-registry.ts +30 -0
  163. package/src/browser/renderers/cell-output-webview.ts +32 -0
  164. package/src/browser/service/notebook-cell-context-manager.ts +70 -0
  165. package/src/browser/service/notebook-editor-service.ts +86 -0
  166. package/src/browser/service/notebook-execution-service.ts +139 -0
  167. package/src/browser/service/notebook-execution-state-service.ts +322 -0
  168. package/src/browser/service/notebook-kernel-history-service.ts +109 -0
  169. package/src/browser/service/notebook-kernel-quick-pick-service.ts +494 -0
  170. package/src/browser/service/notebook-kernel-service.ts +357 -0
  171. package/src/browser/service/notebook-model-resolver-service.ts +141 -0
  172. package/src/browser/service/notebook-renderer-messaging-service.ts +111 -0
  173. package/src/browser/service/notebook-service.ts +178 -0
  174. package/src/browser/style/index.css +236 -0
  175. package/src/browser/view/notebook-cell-editor.tsx +97 -0
  176. package/src/browser/view/notebook-cell-list-view.tsx +171 -0
  177. package/src/browser/view/notebook-cell-toolbar-factory.tsx +91 -0
  178. package/src/browser/view/notebook-cell-toolbar.tsx +70 -0
  179. package/src/browser/view/notebook-code-cell-view.tsx +190 -0
  180. package/src/browser/view/notebook-main-toolbar.tsx +115 -0
  181. package/src/browser/view/notebook-markdown-cell-view.tsx +73 -0
  182. package/src/browser/view-model/notebook-cell-model.ts +271 -0
  183. package/src/browser/view-model/notebook-cell-output-model.ts +69 -0
  184. package/src/browser/view-model/notebook-model.ts +372 -0
  185. package/src/common/index.ts +18 -0
  186. package/src/common/notebook-common.ts +462 -0
  187. package/src/common/notebook-protocol.ts +35 -0
  188. package/src/common/notebook-range.ts +30 -0
@@ -0,0 +1,91 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import * as React from '@theia/core/shared/react';
18
+ import { CommandRegistry, CompoundMenuNodeRole, MenuModelRegistry, MenuNode } from '@theia/core';
19
+ import { inject, injectable } from '@theia/core/shared/inversify';
20
+ import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
21
+ import { NotebookCellSidebar, NotebookCellToolbar } from './notebook-cell-toolbar';
22
+ import { ContextMenuRenderer } from '@theia/core/lib/browser';
23
+ import { NotebookModel } from '../view-model/notebook-model';
24
+ import { NotebookCellModel } from '../view-model/notebook-cell-model';
25
+ import { NotebookCellOutputModel } from '../view-model/notebook-cell-output-model';
26
+
27
+ export interface NotebookCellToolbarItem {
28
+ id: string;
29
+ icon?: string;
30
+ label?: string;
31
+ onClick: (e: React.MouseEvent) => void;
32
+ }
33
+
34
+ @injectable()
35
+ export class NotebookCellToolbarFactory {
36
+
37
+ @inject(MenuModelRegistry)
38
+ protected menuRegistry: MenuModelRegistry;
39
+
40
+ @inject(ContextKeyService)
41
+ protected contextKeyService: ContextKeyService;
42
+
43
+ @inject(ContextMenuRenderer)
44
+ protected readonly contextMenuRenderer: ContextMenuRenderer;
45
+
46
+ @inject(CommandRegistry)
47
+ protected readonly commandRegistry: CommandRegistry;
48
+
49
+ renderCellToolbar(menuPath: string[], notebookModel: NotebookModel, cell: NotebookCellModel): React.ReactNode {
50
+ return <NotebookCellToolbar getMenuItems={() => this.getMenuItems(menuPath, notebookModel, cell)}
51
+ onContextKeysChanged={cell.notebookCellContextManager.onDidChangeContext} />;
52
+ }
53
+
54
+ renderSidebar(menuPath: string[], notebookModel: NotebookModel, cell: NotebookCellModel, output?: NotebookCellOutputModel): React.ReactNode {
55
+ return <NotebookCellSidebar getMenuItems={() => this.getMenuItems(menuPath, notebookModel, cell, output)}
56
+ onContextKeysChanged={cell.notebookCellContextManager.onDidChangeContext} />;
57
+ }
58
+
59
+ private getMenuItems(menuItemPath: string[], notebookModel: NotebookModel, cell: NotebookCellModel, output?: NotebookCellOutputModel): NotebookCellToolbarItem[] {
60
+ const inlineItems: NotebookCellToolbarItem[] = [];
61
+
62
+ for (const menuNode of this.menuRegistry.getMenu(menuItemPath).children) {
63
+ if (!menuNode.when || this.contextKeyService.match(menuNode.when, cell.context ?? undefined)) {
64
+ if (menuNode.role === CompoundMenuNodeRole.Flat) {
65
+ inlineItems.push(...menuNode.children?.map(child => this.createToolbarItem(child, notebookModel, cell, output)) ?? []);
66
+ } else {
67
+ inlineItems.push(this.createToolbarItem(menuNode, notebookModel, cell, output));
68
+ }
69
+ }
70
+ }
71
+ return inlineItems;
72
+ }
73
+
74
+ private createToolbarItem(menuNode: MenuNode, notebookModel: NotebookModel, cell: NotebookCellModel, output?: NotebookCellOutputModel): NotebookCellToolbarItem {
75
+ const menuPath = menuNode.role === CompoundMenuNodeRole.Submenu ? this.menuRegistry.getPath(menuNode) : undefined;
76
+ return {
77
+ id: menuNode.id,
78
+ icon: menuNode.icon,
79
+ label: menuNode.label,
80
+ onClick: menuPath ?
81
+ e => this.contextMenuRenderer.render(
82
+ {
83
+ anchor: e.nativeEvent,
84
+ menuPath,
85
+ includeAnchorArg: false,
86
+ args: [notebookModel, cell, output]
87
+ }) :
88
+ () => this.commandRegistry.executeCommand(menuNode.command!, notebookModel, cell, output)
89
+ };
90
+ }
91
+ }
@@ -0,0 +1,70 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import * as React from '@theia/core/shared/react';
17
+ import { ACTION_ITEM } from '@theia/core/lib/browser';
18
+ import { NotebookCellToolbarItem } from './notebook-cell-toolbar-factory';
19
+ import { DisposableCollection, Event } from '@theia/core';
20
+
21
+ export interface NotebookCellToolbarProps {
22
+ getMenuItems: () => NotebookCellToolbarItem[];
23
+ onContextKeysChanged: Event<void>;
24
+ }
25
+
26
+ interface NotebookCellToolbarState {
27
+ inlineItems: NotebookCellToolbarItem[];
28
+ }
29
+
30
+ abstract class NotebookCellActionItems extends React.Component<NotebookCellToolbarProps, NotebookCellToolbarState> {
31
+
32
+ protected toDispose = new DisposableCollection();
33
+
34
+ constructor(props: NotebookCellToolbarProps) {
35
+ super(props);
36
+ this.toDispose.push(props.onContextKeysChanged(e => {
37
+ this.setState({ inlineItems: this.props.getMenuItems() });
38
+ }));
39
+ this.state = { inlineItems: this.props.getMenuItems() };
40
+ }
41
+
42
+ override componentWillUnmount(): void {
43
+ this.toDispose.dispose();
44
+ }
45
+
46
+ protected renderItem(item: NotebookCellToolbarItem): React.ReactNode {
47
+ return <div key={item.id} title={item.label} onClick={item.onClick} className={`${item.icon} ${ACTION_ITEM} theia-notebook-cell-toolbar-item`} />;
48
+ }
49
+
50
+ }
51
+
52
+ export class NotebookCellToolbar extends NotebookCellActionItems {
53
+
54
+ override render(): React.ReactNode {
55
+ return <div className='theia-notebook-cell-toolbar'>
56
+ {this.state.inlineItems.map(item => this.renderItem(item))}
57
+ </div>;
58
+ }
59
+
60
+ }
61
+
62
+ export class NotebookCellSidebar extends NotebookCellActionItems {
63
+
64
+ override render(): React.ReactNode {
65
+ return <div className='theia-notebook-cell-sidebar'>
66
+ {this.state.inlineItems.map(item => this.renderItem(item))}
67
+ </div>;
68
+ }
69
+ }
70
+
@@ -0,0 +1,190 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { inject, injectable } from '@theia/core/shared/inversify';
18
+ import * as React from '@theia/core/shared/react';
19
+ import { MonacoEditorServices } from '@theia/monaco/lib/browser/monaco-editor';
20
+ import { CellOutputWebviewFactory, CellOutputWebview } from '../renderers/cell-output-webview';
21
+ import { NotebookRendererRegistry } from '../notebook-renderer-registry';
22
+ import { NotebookCellModel } from '../view-model/notebook-cell-model';
23
+ import { NotebookModel } from '../view-model/notebook-model';
24
+ import { CellEditor } from './notebook-cell-editor';
25
+ import { CellRenderer } from './notebook-cell-list-view';
26
+ import { NotebookCellToolbarFactory } from './notebook-cell-toolbar-factory';
27
+ import { NotebookCellActionContribution } from '../contributions/notebook-cell-actions-contribution';
28
+ import { CellExecution, NotebookExecutionStateService } from '../service/notebook-execution-state-service';
29
+ import { codicon } from '@theia/core/lib/browser';
30
+ import { NotebookCellExecutionState } from '../../common';
31
+ import { DisposableCollection } from '@theia/core';
32
+
33
+ @injectable()
34
+ export class NotebookCodeCellRenderer implements CellRenderer {
35
+ @inject(MonacoEditorServices)
36
+ protected readonly monacoServices: MonacoEditorServices;
37
+
38
+ @inject(NotebookRendererRegistry)
39
+ protected readonly notebookRendererRegistry: NotebookRendererRegistry;
40
+
41
+ @inject(CellOutputWebviewFactory)
42
+ protected readonly cellOutputWebviewFactory: CellOutputWebviewFactory;
43
+
44
+ @inject(NotebookCellToolbarFactory)
45
+ protected readonly notebookCellToolbarFactory: NotebookCellToolbarFactory;
46
+
47
+ @inject(NotebookExecutionStateService)
48
+ protected readonly executionStateService: NotebookExecutionStateService;
49
+
50
+ render(notebookModel: NotebookModel, cell: NotebookCellModel, handle: number): React.ReactNode {
51
+ return <div>
52
+ <div className='theia-notebook-cell-with-sidebar'>
53
+ <div>
54
+ {this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.CODE_CELL_SIDEBAR_MENU, notebookModel, cell)}
55
+ {/* cell-execution-order needs an own component. Could be a little more complicated
56
+ <p className='theia-notebook-code-cell-execution-order'>{`[${cell.exec ?? ' '}]`}</p> */}
57
+ </div>
58
+ <div className='theia-notebook-cell-editor-container'>
59
+ <CellEditor notebookModel={notebookModel} cell={cell} monacoServices={this.monacoServices} />
60
+ <NotebookCodeCellStatus cell={cell} executionStateService={this.executionStateService}></NotebookCodeCellStatus>
61
+ </div>
62
+ </div>
63
+ <div className='theia-notebook-cell-with-sidebar'>
64
+ <NotebookCodeCellOutputs cell={cell} outputWebviewFactory={this.cellOutputWebviewFactory}
65
+ renderSidebar={() =>
66
+ this.notebookCellToolbarFactory.renderSidebar(NotebookCellActionContribution.OUTPUT_SIDEBAR_MENU, notebookModel, cell, cell.outputs[0])} />
67
+ </div>
68
+ </div >;
69
+ }
70
+ }
71
+
72
+ export interface NotebookCodeCellStatusProps {
73
+ cell: NotebookCellModel;
74
+ executionStateService: NotebookExecutionStateService
75
+ }
76
+
77
+ export class NotebookCodeCellStatus extends React.Component<NotebookCodeCellStatusProps, { currentExecution?: CellExecution }> {
78
+
79
+ protected toDispose = new DisposableCollection();
80
+
81
+ constructor(props: NotebookCodeCellStatusProps) {
82
+ super(props);
83
+
84
+ this.state = {};
85
+
86
+ this.toDispose.push(props.executionStateService.onDidChangeExecution(event => {
87
+ if (event.affectsCell(this.props.cell.uri)) {
88
+ this.setState({ currentExecution: event.changed });
89
+ }
90
+ }));
91
+ }
92
+
93
+ override componentWillUnmount(): void {
94
+ this.toDispose.dispose();
95
+ }
96
+
97
+ override render(): React.ReactNode {
98
+ return <div className='notebook-cell-status'>
99
+ <div className='notebook-cell-status-left'>
100
+ {this.renderExecutionState()}
101
+ </div>
102
+ <div className='notebook-cell-status-right'>
103
+ <span>{this.props.cell.language}</span>
104
+ </div>
105
+ </div>;
106
+ }
107
+
108
+ private renderExecutionState(): React.ReactNode {
109
+ const state = this.state.currentExecution?.state;
110
+ const { lastRunSuccess } = this.props.cell.internalMetadata;
111
+
112
+ let iconClasses: string | undefined = undefined;
113
+ let color: string | undefined = undefined;
114
+ if (!state && lastRunSuccess) {
115
+ iconClasses = codicon('check');
116
+ color = 'green';
117
+ } else if (!state && lastRunSuccess === false) {
118
+ iconClasses = codicon('error');
119
+ color = 'red';
120
+ } else if (state === NotebookCellExecutionState.Pending || state === NotebookCellExecutionState.Unconfirmed) {
121
+ iconClasses = codicon('clock');
122
+ } else if (state === NotebookCellExecutionState.Executing) {
123
+ iconClasses = `${codicon('sync')} theia-animation-spin`;
124
+ }
125
+ return <>
126
+ {iconClasses &&
127
+ <>
128
+ <span className={`${iconClasses} notebook-cell-status-item`} style={{ color }}></span>
129
+ <div className='notebook-cell-status-item'>{this.getExecutionTime()}</div>
130
+ </>}
131
+ </>;
132
+ }
133
+
134
+ private getExecutionTime(): string {
135
+ const { runStartTime, runEndTime } = this.props.cell.internalMetadata;
136
+ if (runStartTime && runEndTime) {
137
+ return `${((runEndTime - runStartTime) / 1000).toLocaleString(undefined, { maximumFractionDigits: 1, minimumFractionDigits: 1 })}s`;
138
+ }
139
+ return '0.0s';
140
+ }
141
+ }
142
+
143
+ interface NotebookCellOutputProps {
144
+ cell: NotebookCellModel;
145
+ outputWebviewFactory: CellOutputWebviewFactory;
146
+ renderSidebar: () => React.ReactNode;
147
+ }
148
+
149
+ export class NotebookCodeCellOutputs extends React.Component<NotebookCellOutputProps> {
150
+
151
+ protected outputsWebview: CellOutputWebview | undefined;
152
+
153
+ constructor(props: NotebookCellOutputProps) {
154
+ super(props);
155
+ }
156
+
157
+ override async componentDidMount(): Promise<void> {
158
+ const { cell, outputWebviewFactory } = this.props;
159
+ cell.onDidChangeOutputs(async () => {
160
+ if (!this.outputsWebview && cell.outputs.length > 0) {
161
+ this.outputsWebview = await outputWebviewFactory(cell);
162
+ } else if (this.outputsWebview && cell.outputs.length === 0) {
163
+ this.outputsWebview.dispose();
164
+ this.outputsWebview = undefined;
165
+ }
166
+ this.forceUpdate();
167
+ });
168
+ if (cell.outputs.length > 0) {
169
+ this.outputsWebview = await outputWebviewFactory(cell);
170
+ this.forceUpdate();
171
+ }
172
+ }
173
+
174
+ override componentDidUpdate(): void {
175
+ if (!this.outputsWebview?.isAttached()) {
176
+ this.outputsWebview?.attachWebview();
177
+ }
178
+ }
179
+
180
+ override render(): React.ReactNode {
181
+ return this.outputsWebview ?
182
+ <>
183
+ {this.props.renderSidebar()}
184
+ {this.outputsWebview.render()}
185
+ </> :
186
+ <></>;
187
+
188
+ }
189
+
190
+ }
@@ -0,0 +1,115 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+ import { CommandRegistry, CompoundMenuNodeRole, DisposableCollection, MenuModelRegistry, MenuNode, nls } from '@theia/core';
17
+ import * as React from '@theia/core/shared/react';
18
+ import { codicon } from '@theia/core/lib/browser';
19
+ import { NotebookCommands, NotebookMenus } from '../contributions/notebook-actions-contribution';
20
+ import { NotebookModel } from '../view-model/notebook-model';
21
+ import { NotebookKernelService } from '../service/notebook-kernel-service';
22
+ import { inject, injectable } from '@theia/core/shared/inversify';
23
+ import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
24
+
25
+ export interface NotebookMainToolbarProps {
26
+ notebookModel: NotebookModel
27
+ menuRegistry: MenuModelRegistry;
28
+ notebookKernelService: NotebookKernelService;
29
+ commandRegistry: CommandRegistry;
30
+ contextKeyService: ContextKeyService;
31
+ }
32
+
33
+ @injectable()
34
+ export class NotebookMainToolbarRenderer {
35
+ @inject(NotebookKernelService) protected readonly notebookKernelService: NotebookKernelService;
36
+ @inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry;
37
+ @inject(MenuModelRegistry) protected readonly menuRegistry: MenuModelRegistry;
38
+ @inject(ContextKeyService) protected readonly contextKeyService: ContextKeyService;
39
+
40
+ render(notebookModel: NotebookModel): React.ReactNode {
41
+ return <NotebookMainToolbar notebookModel={notebookModel}
42
+ menuRegistry={this.menuRegistry}
43
+ notebookKernelService={this.notebookKernelService}
44
+ commandRegistry={this.commandRegistry}
45
+ contextKeyService={this.contextKeyService}
46
+ />;
47
+ }
48
+ }
49
+
50
+ export class NotebookMainToolbar extends React.Component<NotebookMainToolbarProps, { selectedKernelLabel?: string }> {
51
+
52
+ protected toDispose = new DisposableCollection();
53
+
54
+ constructor(props: NotebookMainToolbarProps) {
55
+ super(props);
56
+
57
+ this.state = { selectedKernelLabel: props.notebookKernelService.getSelectedOrSuggestedKernel(props.notebookModel)?.label };
58
+ this.toDispose.push(props.notebookKernelService.onDidChangeSelectedKernel(event => {
59
+ if (props.notebookModel.uri.isEqual(event.notebook)) {
60
+ this.setState({ selectedKernelLabel: props.notebookKernelService.getKernel(event.newKernel ?? '')?.label });
61
+ }
62
+ }));
63
+ // in case the selected kernel is added after the notebook is loaded
64
+ this.toDispose.push(props.notebookKernelService.onDidAddKernel(() => {
65
+ if (!this.state.selectedKernelLabel) {
66
+ this.setState({ selectedKernelLabel: props.notebookKernelService.getSelectedOrSuggestedKernel(props.notebookModel)?.label });
67
+ }
68
+ }));
69
+ }
70
+
71
+ override componentWillUnmount(): void {
72
+ this.toDispose.dispose();
73
+ }
74
+
75
+ override render(): React.ReactNode {
76
+ return <div className='theia-notebook-main-toolbar'>
77
+ {this.getMenuItems().map(item => this.renderMenuItem(item))}
78
+ <div style={{ flexGrow: 1 }}></div>
79
+ <div className='theia-notebook-main-toolbar-item'
80
+ onClick={() => this.props.commandRegistry.executeCommand(NotebookCommands.SELECT_KERNEL_COMMAND.id, this.props.notebookModel)}>
81
+ <span className={codicon('server-environment')} />
82
+ <span className=' theia-notebook-main-toolbar-item-text'>
83
+ {this.state.selectedKernelLabel ?? nls.localizeByDefault('Select Kernel')}
84
+ </span>
85
+ </div>
86
+ </div>;
87
+ }
88
+
89
+ protected renderMenuItem(item: MenuNode): React.ReactNode {
90
+ if (item.role === CompoundMenuNodeRole.Group) {
91
+ const itemNodes = item.children?.map(child => this.renderMenuItem(child)).filter(child => !!child);
92
+ return <React.Fragment key={item.id}>
93
+ {itemNodes}
94
+ {itemNodes && itemNodes.length > 0 && <span key={`${item.id}-separator`} className='theia-notebook-toolbar-separator'></span>}
95
+ </React.Fragment>;
96
+ } else if (!item.when || this.props.contextKeyService.match(item.when)) {
97
+ return <div key={item.id} title={item.id} className='theia-notebook-main-toolbar-item'
98
+ onClick={() => {
99
+ if (item.command) {
100
+ this.props.commandRegistry.executeCommand(item.command, this.props.notebookModel);
101
+ }
102
+ }}>
103
+ <span className={item.icon} />
104
+ <span className='theia-notebook-main-toolbar-item-text'>{item.label}</span>
105
+ </div>;
106
+ }
107
+ return undefined;
108
+ }
109
+
110
+ private getMenuItems(): readonly MenuNode[] {
111
+ const menuPath = NotebookMenus.NOTEBOOK_MAIN_TOOLBAR;
112
+ const pluginCommands = this.props.menuRegistry.getMenuNode(menuPath).children;
113
+ return this.props.menuRegistry.getMenu([menuPath]).children.concat(pluginCommands);
114
+ }
115
+ }
@@ -0,0 +1,73 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import * as React from '@theia/core/shared/react';
18
+ import { MarkdownRenderer } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
19
+ import { MarkdownStringImpl } from '@theia/core/lib/common/markdown-rendering/markdown-string';
20
+ import { NotebookModel } from '../view-model/notebook-model';
21
+ import { CellRenderer } from './notebook-cell-list-view';
22
+ import { NotebookCellModel } from '../view-model/notebook-cell-model';
23
+ import { CellEditor } from './notebook-cell-editor';
24
+ import { inject, injectable } from '@theia/core/shared/inversify';
25
+ import { MonacoEditorServices } from '@theia/monaco/lib/browser/monaco-editor';
26
+ import { nls } from '@theia/core';
27
+
28
+ @injectable()
29
+ export class NotebookMarkdownCellRenderer implements CellRenderer {
30
+
31
+ @inject(MarkdownRenderer)
32
+ private readonly markdownRenderer: MarkdownRenderer;
33
+ @inject(MonacoEditorServices)
34
+ protected readonly monacoServices: MonacoEditorServices;
35
+
36
+ render(notebookModel: NotebookModel, cell: NotebookCellModel): React.ReactNode {
37
+ return <MarkdownCell markdownRenderer={this.markdownRenderer} monacoServices={this.monacoServices}
38
+ cell={cell} notebookModel={notebookModel} />;
39
+ }
40
+
41
+ }
42
+
43
+ interface MarkdownCellProps {
44
+ markdownRenderer: MarkdownRenderer,
45
+ monacoServices: MonacoEditorServices
46
+
47
+ cell: NotebookCellModel,
48
+ notebookModel: NotebookModel
49
+ }
50
+
51
+ function MarkdownCell({ markdownRenderer, monacoServices, cell, notebookModel }: MarkdownCellProps): React.JSX.Element {
52
+ const [editMode, setEditMode] = React.useState(false);
53
+
54
+ React.useEffect(() => {
55
+ const listener = cell.onDidRequestCellEditChange(cellEdit => setEditMode(cellEdit));
56
+ return () => listener.dispose();
57
+ }, [editMode]);
58
+
59
+ let markdownContent = React.useMemo(() => markdownRenderer.render(new MarkdownStringImpl(cell.source)).element.innerHTML, [cell, editMode]);
60
+ if (markdownContent.length === 0) {
61
+ markdownContent = `<i class="theia-notebook-empty-markdown">${nls.localizeByDefault('Empty markdown cell, double-click or press enter to edit.')}</i>`;
62
+ }
63
+
64
+ return editMode ?
65
+ <CellEditor cell={cell} notebookModel={notebookModel} monacoServices={monacoServices} /> :
66
+ <div className='theia-notebook-markdown-content'
67
+ onDoubleClick={() => cell.requestEdit()}
68
+ // This sets the non React HTML node from the markdown renderers output as a child node to this react component
69
+ // This is currently sadly the best way we have to combine React (Virtual Nodes) and normal dom nodes
70
+ // the HTML is allready sanitized by the markdown renderer, so we don't need to sanitize it again
71
+ dangerouslySetInnerHTML={{ __html: markdownContent }} // eslint-disable-line react/no-danger
72
+ />;
73
+ }