A monorepo containing jupyter-blocks and jupyter-tidyblocks. Blockly extension for JupyterLab.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #66 from hbcarlos/kernel

Kernel controls and split panel

authored by

Denisa Checiu and committed by
GitHub
638aef09 3573e986

+208 -31
+1
packages/blockly-extension/package.json
··· 48 48 "@jupyterlab/codeeditor": "^3.4", 49 49 "@jupyterlab/filebrowser": "^3.4", 50 50 "@jupyterlab/launcher": "^3.4", 51 + "@jupyterlab/mainmenu": "^3.4", 51 52 "@jupyterlab/rendermime": "^3.4", 52 53 "@jupyterlab/settingregistry": "^3.4", 53 54 "@jupyterlab/translation": "^3.4",
+36 -6
packages/blockly-extension/src/index.ts
··· 11 11 import { ILauncher } from '@jupyterlab/launcher'; 12 12 import { ITranslator } from '@jupyterlab/translation'; 13 13 import { ISettingRegistry } from '@jupyterlab/settingregistry'; 14 + import { IKernelMenu, IMainMenu } from '@jupyterlab/mainmenu'; 14 15 15 16 import { BlocklyEditorFactory } from 'jupyterlab-blockly'; 16 17 import { IBlocklyRegistry } from 'jupyterlab-blockly'; ··· 48 49 ISettingRegistry, 49 50 ITranslator 50 51 ], 51 - optional: [ILauncher, ICommandPalette], 52 + optional: [ILauncher, ICommandPalette, IMainMenu], 52 53 provides: IBlocklyRegistry, 53 54 activate: ( 54 55 app: JupyterFrontEnd, ··· 59 60 settings: ISettingRegistry, 60 61 translator: ITranslator, 61 62 launcher: ILauncher | null, 62 - palette: ICommandPalette | null 63 + palette: ICommandPalette | null, 64 + mainMenu: IMainMenu | null 63 65 ): IBlocklyRegistry => { 64 66 console.log('JupyterLab extension jupyterlab-blocky is activated!'); 65 67 ··· 80 82 } 81 83 82 84 const { commands } = app; 83 - const command = CommandIDs.createNew; 84 85 85 86 // Creating the widget factory to register it so the document manager knows about 86 87 // our new DocumentWidget ··· 159 160 widgetFactory.registry.setlanguage(language); 160 161 }); 161 162 162 - commands.addCommand(command, { 163 + commands.addCommand(CommandIDs.createNew, { 163 164 label: args => 164 165 args['isPalette'] ? 'New Blockly Editor' : 'Blockly Editor', 165 166 caption: 'Create a new Blockly Editor', ··· 188 189 // Add the command to the launcher 189 190 if (launcher) { 190 191 launcher.add({ 191 - command, 192 + command: CommandIDs.createNew, 192 193 category: 'Other', 193 194 rank: 1 194 195 }); ··· 197 198 // Add the command to the palette 198 199 if (palette) { 199 200 palette.addItem({ 200 - command, 201 + command: CommandIDs.createNew, 201 202 args: { isPalette: true }, 202 203 category: PALETTE_CATEGORY 203 204 }); 205 + } 206 + 207 + // Add the command to the main menu 208 + if (mainMenu) { 209 + mainMenu.kernelMenu.kernelUsers.add({ 210 + tracker, 211 + interruptKernel: current => { 212 + const kernel = current.context.sessionContext.session?.kernel; 213 + if (kernel) { 214 + return kernel.interrupt(); 215 + } 216 + return Promise.resolve(void 0); 217 + }, 218 + reconnectToKernel: current => { 219 + const kernel = current.context.sessionContext.session?.kernel; 220 + if (kernel) { 221 + return kernel.reconnect(); 222 + } 223 + return Promise.resolve(void 0); 224 + }, 225 + restartKernel: current => { 226 + const kernel = current.context.sessionContext.session?.kernel; 227 + if (kernel) { 228 + return kernel.restart(); 229 + } 230 + return Promise.resolve(void 0); 231 + }, 232 + shutdownKernel: current => current.context.sessionContext.shutdown() 233 + } as IKernelMenu.IKernelUser<BlocklyEditor>); 204 234 } 205 235 206 236 return widgetFactory.registry;
+22 -23
packages/blockly/src/layout.ts
··· 4 4 5 5 import { Message } from '@lumino/messaging'; 6 6 import { PartialJSONValue } from '@lumino/coreutils'; 7 - import { PanelLayout, Widget } from '@lumino/widgets'; 7 + import { SplitLayout, SplitPanel, Widget } from '@lumino/widgets'; 8 8 import { IIterator, ArrayIterator } from '@lumino/algorithm'; 9 9 import { Signal } from '@lumino/signaling'; 10 10 ··· 16 16 /** 17 17 * A blockly layout to host the Blockly editor. 18 18 */ 19 - export class BlocklyLayout extends PanelLayout { 20 - private _host: HTMLElement; 19 + export class BlocklyLayout extends SplitLayout { 20 + private _host: Widget; 21 21 private _manager: BlocklyManager; 22 22 private _workspace: Blockly.WorkspaceSvg; 23 23 private _sessionContext: ISessionContext; ··· 32 32 sessionContext: ISessionContext, 33 33 rendermime: IRenderMimeRegistry 34 34 ) { 35 - super(); 35 + super({ renderer: SplitPanel.defaultRenderer, orientation: 'vertical' }); 36 36 this._manager = manager; 37 37 this._sessionContext = sessionContext; 38 38 39 39 // Creating the container for the Blockly editor 40 40 // and the output area to render the execution replies. 41 - this._host = document.createElement('div'); 41 + this._host = new Widget(); 42 42 43 43 // Creating a CodeCell widget to render the code and 44 44 // outputs from the execution reply. ··· 83 83 init(): void { 84 84 super.init(); 85 85 // Add the blockly container into the DOM 86 - this.addWidget(new Widget({ node: this._host })); 86 + this.addWidget(this._host); 87 + this.addWidget(this._cell); 87 88 } 88 89 89 90 /** ··· 141 142 const code = 142 143 extra_init + this._manager.generator.workspaceToCode(this._workspace); 143 144 this._cell.model.sharedModel.setSource(code); 144 - this.addWidget(this._cell); 145 - this._resizeWorkspace(); 146 145 147 146 // Execute the code using the kernel, by using a static method from the 148 147 // same class to make an execution request. ··· 165 164 * Handle `update-request` messages sent to the widget. 166 165 */ 167 166 protected onUpdateRequest(msg: Message): void { 167 + super.onUpdateRequest(msg); 168 168 this._resizeWorkspace(); 169 169 } 170 170 171 171 /** 172 172 * Handle `resize-request` messages sent to the widget. 173 173 */ 174 - protected onResize(msg: Message): void { 174 + protected onResize(msg: Widget.ResizeMessage): void { 175 + super.onResize(msg); 175 176 this._resizeWorkspace(); 176 177 } 177 178 ··· 179 180 * Handle `fit-request` messages sent to the widget. 180 181 */ 181 182 protected onFitRequest(msg: Message): void { 183 + super.onFitRequest(msg); 182 184 this._resizeWorkspace(); 183 185 } 184 186 ··· 186 188 * Handle `after-attach` messages sent to the widget. 187 189 */ 188 190 protected onAfterAttach(msg: Message): void { 191 + super.onAfterAttach(msg); 189 192 //inject Blockly with appropiate JupyterLab theme. 190 - this._workspace = Blockly.inject(this._host, { 193 + this._workspace = Blockly.inject(this._host.node, { 191 194 toolbox: this._manager.toolbox, 192 195 theme: THEME 193 196 }); 197 + 198 + this._workspace.addChangeListener(() => { 199 + // Get extra code from the blocks in the workspace. 200 + const extra_init = this.getBlocksToplevelInit(); 201 + // Serializing our workspace into the chosen language generator. 202 + const code = 203 + extra_init + this._manager.generator.workspaceToCode(this._workspace); 204 + this._cell.model.sharedModel.setSource(code); 205 + }); 194 206 } 195 207 196 208 private _resizeWorkspace(): void { 197 209 //Resize logic. 198 - const rect = this.parent.node.getBoundingClientRect(); 199 - const { height } = this._cell.node.getBoundingClientRect(); 200 - const margin = rect.height / 3; 201 - 202 - if (height > margin) { 203 - this._host.style.height = rect.height - margin + 'px'; 204 - this._cell.node.style.height = margin + 'px'; 205 - this._cell.node.style.overflowY = 'scroll'; 206 - } else { 207 - this._host.style.height = rect.height - height + 'px'; 208 - this._cell.node.style.overflowY = 'scroll'; 209 - } 210 - 211 210 Blockly.svgResize(this._workspace); 212 211 } 213 212
+2 -2
packages/blockly/src/widget.ts
··· 6 6 import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; 7 7 import { runIcon } from '@jupyterlab/ui-components'; 8 8 9 - import { Panel } from '@lumino/widgets'; 9 + import { SplitPanel } from '@lumino/widgets'; 10 10 import { Signal } from '@lumino/signaling'; 11 11 12 12 import { BlocklyLayout } from './layout'; ··· 76 76 /** 77 77 * Widget that contains the main view of the DocumentWidget. 78 78 */ 79 - export class BlocklyPanel extends Panel { 79 + export class BlocklyPanel extends SplitPanel { 80 80 private _context: DocumentRegistry.IContext<DocumentModel>; 81 81 82 82 /**
+147
yarn.lock
··· 232 232 sanitize-html "~2.5.3" 233 233 url "^0.11.0" 234 234 235 + "@jupyterlab/apputils@^3.4.6": 236 + version "3.4.6" 237 + resolved "https://registry.yarnpkg.com/@jupyterlab/apputils/-/apputils-3.4.6.tgz#e86e03605926ade4b8ed337ebf62aa738148f21a" 238 + integrity sha512-/FTxFIqpgdWTYZFfB/XWKd3TjZV4WxG6i2Gwx2IFTBN2ZiRi6qRmyh7NOs6GXbOxyfw58IXFrKsqoDe6MeALbg== 239 + dependencies: 240 + "@jupyterlab/coreutils" "^5.4.6" 241 + "@jupyterlab/observables" "^4.4.6" 242 + "@jupyterlab/services" "^6.4.6" 243 + "@jupyterlab/settingregistry" "^3.4.6" 244 + "@jupyterlab/statedb" "^3.4.6" 245 + "@jupyterlab/translation" "^3.4.6" 246 + "@jupyterlab/ui-components" "^3.4.6" 247 + "@lumino/algorithm" "^1.9.0" 248 + "@lumino/commands" "^1.19.0" 249 + "@lumino/coreutils" "^1.11.0" 250 + "@lumino/disposable" "^1.10.0" 251 + "@lumino/domutils" "^1.8.0" 252 + "@lumino/messaging" "^1.10.0" 253 + "@lumino/polling" "^1.9.0" 254 + "@lumino/properties" "^1.8.0" 255 + "@lumino/signaling" "^1.10.0" 256 + "@lumino/virtualdom" "^1.14.0" 257 + "@lumino/widgets" "^1.33.0" 258 + "@types/react" "^17.0.0" 259 + react "^17.0.1" 260 + react-dom "^17.0.1" 261 + sanitize-html "~2.5.3" 262 + url "^0.11.0" 263 + 235 264 "@jupyterlab/attachments@^3.4.3": 236 265 version "3.4.3" 237 266 resolved "https://registry.yarnpkg.com/@jupyterlab/attachments/-/attachments-3.4.3.tgz#a958bb529c3f606694d0b60211b7b8b882a1ebf7" ··· 394 423 path-browserify "^1.0.0" 395 424 url-parse "~1.5.1" 396 425 426 + "@jupyterlab/coreutils@^5.4.6": 427 + version "5.4.6" 428 + resolved "https://registry.yarnpkg.com/@jupyterlab/coreutils/-/coreutils-5.4.6.tgz#abe3b66ac06ae6cfc54700e5b8ee6c91a9904187" 429 + integrity sha512-WvXhJhoDgR+KC1voJf6lLDY16nA6p2f8r0ggIBFYn9vxpd02AU1Xhocr44k5r3zXM33HT5jDz1U9hpCbkr+vCQ== 430 + dependencies: 431 + "@lumino/coreutils" "^1.11.0" 432 + "@lumino/disposable" "^1.10.0" 433 + "@lumino/signaling" "^1.10.0" 434 + minimist "~1.2.0" 435 + moment "^2.24.0" 436 + path-browserify "^1.0.0" 437 + url-parse "~1.5.1" 438 + 397 439 "@jupyterlab/docmanager@^3.4.3": 398 440 version "3.4.3" 399 441 resolved "https://registry.yarnpkg.com/@jupyterlab/docmanager/-/docmanager-3.4.3.tgz#26e9571a93f1a6a6d7b59f9296499fdcabd998b7" ··· 493 535 "@lumino/widgets" "^1.30.0" 494 536 react "^17.0.1" 495 537 538 + "@jupyterlab/mainmenu@^3.4": 539 + version "3.4.6" 540 + resolved "https://registry.yarnpkg.com/@jupyterlab/mainmenu/-/mainmenu-3.4.6.tgz#2301e8e9c441e02f900e18e9e817cdc7c88d1974" 541 + integrity sha512-LZ8Pb9VlT1MMLZC8eKfh9oJXxkhkRyNNMtceYV+nXYtx8uSn3hapP9zMhqPVwS4bTI83QNUOvYna2Rg7xwm86Q== 542 + dependencies: 543 + "@jupyterlab/apputils" "^3.4.6" 544 + "@jupyterlab/services" "^6.4.6" 545 + "@jupyterlab/translation" "^3.4.6" 546 + "@jupyterlab/ui-components" "^3.4.6" 547 + "@lumino/algorithm" "^1.9.0" 548 + "@lumino/commands" "^1.19.0" 549 + "@lumino/coreutils" "^1.11.0" 550 + "@lumino/widgets" "^1.33.0" 551 + 496 552 "@jupyterlab/nbformat@^3.4.3": 497 553 version "3.4.3" 498 554 resolved "https://registry.yarnpkg.com/@jupyterlab/nbformat/-/nbformat-3.4.3.tgz#cbab1bf507677b7f0f309d8353fc83fe5a973c82" ··· 500 556 dependencies: 501 557 "@lumino/coreutils" "^1.11.0" 502 558 559 + "@jupyterlab/nbformat@^3.4.6": 560 + version "3.4.6" 561 + resolved "https://registry.yarnpkg.com/@jupyterlab/nbformat/-/nbformat-3.4.6.tgz#926273d0e9e340adf0bdd3b3573253e5f428cfbb" 562 + integrity sha512-VWg+HfEyF59irxV+xv5Zeioqhk7M8ZdVaXaPqsvBmHP81Ew7Ss83Do6b9bb2TEe6Bz7sCcGmcRr/zSkhTatmEw== 563 + dependencies: 564 + "@lumino/coreutils" "^1.11.0" 565 + 503 566 "@jupyterlab/observables@^4.4.3": 504 567 version "4.4.3" 505 568 resolved "https://registry.yarnpkg.com/@jupyterlab/observables/-/observables-4.4.3.tgz#41d07af0987dc37953214e20ee1dfc0b15669ef0" 506 569 integrity sha512-AUuNoBIcctmJip4pZEYfmw14/FjTeyO3lVgp0pgZWTowzI6ihJP8pWaxc5GtfHOPGTn+S81r1FSPSiLLFqFyZg== 570 + dependencies: 571 + "@lumino/algorithm" "^1.9.0" 572 + "@lumino/coreutils" "^1.11.0" 573 + "@lumino/disposable" "^1.10.0" 574 + "@lumino/messaging" "^1.10.0" 575 + "@lumino/signaling" "^1.10.0" 576 + 577 + "@jupyterlab/observables@^4.4.6": 578 + version "4.4.6" 579 + resolved "https://registry.yarnpkg.com/@jupyterlab/observables/-/observables-4.4.6.tgz#970a9bbb5c31e96a2da062169e2fbc6c06817432" 580 + integrity sha512-RuSroUJalcPIGuleiLiwrtUbtNktv0mLGFcOrT24AAMC25O+caWWDUo1VLUIX56V/DYphgOzclxlDRsaDpFWgQ== 507 581 dependencies: 508 582 "@lumino/algorithm" "^1.9.0" 509 583 "@lumino/coreutils" "^1.11.0" ··· 579 653 node-fetch "^2.6.0" 580 654 ws "^7.4.6" 581 655 656 + "@jupyterlab/services@^6.4.6": 657 + version "6.4.6" 658 + resolved "https://registry.yarnpkg.com/@jupyterlab/services/-/services-6.4.6.tgz#790c2c14b82bd00f68d59675f141204ef0f6f4a2" 659 + integrity sha512-k6xUoOnamdVJETaNh0EIl3DtvK4zhB59FABBxjpyvvOixo3WShmdJVywHgpdG7MkOK9NdRM9/pNASKUj0/836w== 660 + dependencies: 661 + "@jupyterlab/coreutils" "^5.4.6" 662 + "@jupyterlab/nbformat" "^3.4.6" 663 + "@jupyterlab/observables" "^4.4.6" 664 + "@jupyterlab/settingregistry" "^3.4.6" 665 + "@jupyterlab/statedb" "^3.4.6" 666 + "@lumino/algorithm" "^1.9.0" 667 + "@lumino/coreutils" "^1.11.0" 668 + "@lumino/disposable" "^1.10.0" 669 + "@lumino/polling" "^1.9.0" 670 + "@lumino/signaling" "^1.10.0" 671 + node-fetch "^2.6.0" 672 + ws "^7.4.6" 673 + 582 674 "@jupyterlab/settingregistry@^3.4", "@jupyterlab/settingregistry@^3.4.3": 583 675 version "3.4.3" 584 676 resolved "https://registry.yarnpkg.com/@jupyterlab/settingregistry/-/settingregistry-3.4.3.tgz#531cb702a7eefdd12cce541893152056f66841d2" ··· 592 684 ajv "^6.12.3" 593 685 json5 "^2.1.1" 594 686 687 + "@jupyterlab/settingregistry@^3.4.6": 688 + version "3.4.6" 689 + resolved "https://registry.yarnpkg.com/@jupyterlab/settingregistry/-/settingregistry-3.4.6.tgz#6fd66e8568bd4fdcd598b4684c0478a232d0e38e" 690 + integrity sha512-2wKL3+yyvdRJHYhUQ6Jxbxd0HuMdS+Tj/DcIrPkA4Zp6GTsZyd1TrUisSzKxSf8YLGqy1ef3fVvNX4w5LPQ1GA== 691 + dependencies: 692 + "@jupyterlab/statedb" "^3.4.6" 693 + "@lumino/commands" "^1.19.0" 694 + "@lumino/coreutils" "^1.11.0" 695 + "@lumino/disposable" "^1.10.0" 696 + "@lumino/signaling" "^1.10.0" 697 + ajv "^6.12.3" 698 + json5 "^2.1.1" 699 + 595 700 "@jupyterlab/shared-models@^3.4.3": 596 701 version "3.4.3" 597 702 resolved "https://registry.yarnpkg.com/@jupyterlab/shared-models/-/shared-models-3.4.3.tgz#656b7108f16f78e092b11b6bf7ddaec59d518099" ··· 615 720 "@lumino/properties" "^1.8.0" 616 721 "@lumino/signaling" "^1.10.0" 617 722 723 + "@jupyterlab/statedb@^3.4.6": 724 + version "3.4.6" 725 + resolved "https://registry.yarnpkg.com/@jupyterlab/statedb/-/statedb-3.4.6.tgz#9f3548d1b8cca5ba5191b85851f34a37ade94efb" 726 + integrity sha512-3ojiwhErFNH7McL+++ApOFcxzxx20Ddwopr/rFi2ARFOu3hfhXMwuIt9272G2+RgRQebZhq7qzb7mxXZOpid4Q== 727 + dependencies: 728 + "@lumino/commands" "^1.19.0" 729 + "@lumino/coreutils" "^1.11.0" 730 + "@lumino/disposable" "^1.10.0" 731 + "@lumino/properties" "^1.8.0" 732 + "@lumino/signaling" "^1.10.0" 733 + 618 734 "@jupyterlab/statusbar@^3.4.3": 619 735 version "3.4.3" 620 736 resolved "https://registry.yarnpkg.com/@jupyterlab/statusbar/-/statusbar-3.4.3.tgz#d9a35b79bb5c61b3215b778ff563fcf260c60070" ··· 645 761 "@jupyterlab/statedb" "^3.4.3" 646 762 "@lumino/coreutils" "^1.11.0" 647 763 764 + "@jupyterlab/translation@^3.4.6": 765 + version "3.4.6" 766 + resolved "https://registry.yarnpkg.com/@jupyterlab/translation/-/translation-3.4.6.tgz#4e079cf77ca5b50d6cde3dcafff6e2117fa09926" 767 + integrity sha512-L/hSjBYyza9vWwS/+CbUkn7ad0BfJ6Q+w9XMbcf7ac/7Wycd5pSdyWc37HDbsYYwSKXe90IbdR1YKke5HKCFfw== 768 + dependencies: 769 + "@jupyterlab/coreutils" "^5.4.6" 770 + "@jupyterlab/services" "^6.4.6" 771 + "@jupyterlab/statedb" "^3.4.6" 772 + "@lumino/coreutils" "^1.11.0" 773 + 648 774 "@jupyterlab/ui-components@^3.4", "@jupyterlab/ui-components@^3.4.3": 649 775 version "3.4.3" 650 776 resolved "https://registry.yarnpkg.com/@jupyterlab/ui-components/-/ui-components-3.4.3.tgz#180ba2e0a273fce78ec9cf38782060a12064f02c" ··· 661 787 "@lumino/signaling" "^1.10.0" 662 788 "@lumino/virtualdom" "^1.14.0" 663 789 "@lumino/widgets" "^1.30.0" 790 + "@rjsf/core" "^3.1.0" 791 + react "^17.0.1" 792 + react-dom "^17.0.1" 793 + typestyle "^2.0.4" 794 + 795 + "@jupyterlab/ui-components@^3.4.6": 796 + version "3.4.6" 797 + resolved "https://registry.yarnpkg.com/@jupyterlab/ui-components/-/ui-components-3.4.6.tgz#d9b1c4ccf8d3ce94d71dd94f95b3d401aca4a6f0" 798 + integrity sha512-kLwHnQ7hNXoNU41yvN5n1ghRQA/c2jxE1EC1k6ddAtCTDlN8e+a8uDIJqxR1wYGKBAJNZEKgBPRKNk0G62VoCA== 799 + dependencies: 800 + "@blueprintjs/core" "^3.36.0" 801 + "@blueprintjs/select" "^3.15.0" 802 + "@jupyterlab/coreutils" "^5.4.6" 803 + "@jupyterlab/translation" "^3.4.6" 804 + "@lumino/algorithm" "^1.9.0" 805 + "@lumino/commands" "^1.19.0" 806 + "@lumino/coreutils" "^1.11.0" 807 + "@lumino/disposable" "^1.10.0" 808 + "@lumino/signaling" "^1.10.0" 809 + "@lumino/virtualdom" "^1.14.0" 810 + "@lumino/widgets" "^1.33.0" 664 811 "@rjsf/core" "^3.1.0" 665 812 react "^17.0.1" 666 813 react-dom "^17.0.1"