From da825bb91aeb1feae3ffc3f4707dba3fff444ae6 Mon Sep 17 00:00:00 2001 From: Sahitya Buddharaju Date: Sun, 28 Jul 2024 17:34:40 -0500 Subject: [PATCH] fix(notebooks): dispatch an event when cell content is edited --- libs/components/src/notebook/notebook.ts | 46 ++++++++++++++++-------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/libs/components/src/notebook/notebook.ts b/libs/components/src/notebook/notebook.ts index 1913b4552..47ad3ad1f 100644 --- a/libs/components/src/notebook/notebook.ts +++ b/libs/components/src/notebook/notebook.ts @@ -123,6 +123,7 @@ export class CovalentNotebook extends LitElement { } } + // Create a new cell object createNewCell(cellType: string): CellData { const language = cellType === 'markdown' ? cellType : this.defaultLanguage || 'python'; @@ -151,7 +152,9 @@ export class CovalentNotebook extends LitElement { // Delete the selected cell deleteCell() { if (this._selectedCellIndex !== null) { - this.cells.splice(this._selectedCellIndex, 1); + this.cells = this.cells.filter( + (_, index) => index !== this._selectedCellIndex + ); const selectedCellIndex = Math.min( this._selectedCellIndex + 1, this.cells.length - 1 @@ -172,7 +175,8 @@ export class CovalentNotebook extends LitElement { document.removeEventListener('keydown', this._handleKeydown); } - // Dispatch a custom cell event + // Dispatch a custom cell action event + // It handles actions like: run-cell, interrupt-cell, refresh-cell etc dispatchCustomCellEvent(name: string, cell?: CellData) { if (!cell && this._selectedCellIndex) { cell = this.cells[this._selectedCellIndex]; @@ -211,6 +215,7 @@ export class CovalentNotebook extends LitElement { getDragImage(cellIndex: number): HTMLElement { const cell = this.cells[cellIndex]; + // This is the drag image seen when a cell is being dragged const template = html`
({ ...cell, index: idx })); this._draggedCellIndex = null; + // Dispatch an event with updated cells this.dispatchUpdatedCells(); } } @@ -370,14 +376,17 @@ export class CovalentNotebook extends LitElement { } } + // Handle keyboard actions within the notebook private _handleKeydown(event: KeyboardEvent) { let selectedCellIndex = this.cells?.findIndex((cell) => cell.selected); switch (event.key) { case 'ArrowUp': + // Navigate to the cell above the current cell selectedCellIndex = Math.max(selectedCellIndex - 1, 0); this.scrollToSelectedCell(selectedCellIndex); break; case 'ArrowDown': + // Navigate to the cell below the current cell selectedCellIndex = Math.min( selectedCellIndex + 1, this.cells.length - 1 @@ -385,9 +394,11 @@ export class CovalentNotebook extends LitElement { this.scrollToSelectedCell(selectedCellIndex); break; case 'Enter': + // Pressing Shift + Enter key should run the cell if (event.shiftKey) { this.runCell(); } else { + // Pressing the Enter key should add focus to the code editor const selectedCellElement = this.shadowRoot?.querySelector( `#cell-${selectedCellIndex}` ); @@ -404,6 +415,7 @@ export class CovalentNotebook extends LitElement { const cell = this.cells[index]; if (cell.language === 'markdown') { cell.showEditor = true; + this.cells = this.cells.map((cell) => cell); this.dispatchUpdatedCells(); } } @@ -415,11 +427,10 @@ export class CovalentNotebook extends LitElement { this._selectedCellIndex !== null ? this._selectedCellIndex + 1 : this.cells.length; - this.deselectAllCells(); this._clipboardCell.selected = true; this.cells.splice(index, 0, { ...this._clipboardCell }); this.cells = this.cells.map((cell, idx) => ({ ...cell, index: idx })); - this._selectedCellIndex = index; + this.selectCell(index); this.dispatchUpdatedCells(); } } @@ -433,6 +444,7 @@ export class CovalentNotebook extends LitElement { const md = markdownit({ html: true }); switch (key) { case 'text/markdown': + // converts markdown to html return html`
${unsafeHTML(md.render(output.data[key]))}
`; @@ -440,12 +452,15 @@ export class CovalentNotebook extends LitElement { return html`
${unsafeHTML(output.data[key])}
`; - case 'image/png': { + case 'image/png': + case 'image/jpg': { return html`
`; } @@ -483,15 +498,15 @@ export class CovalentNotebook extends LitElement { > `; } + // Remove a css class from a target element removeCSS(className: string, targetElement: Document | ShadowRoot | null) { const elements = targetElement?.querySelectorAll(className); elements?.forEach((element) => element.classList.remove(className)); @@ -609,6 +625,7 @@ export class CovalentNotebook extends LitElement { } } + // Whether a code editor should be shown in the cell shouldRenderEditor(cell: CellData): boolean { return ( cell.language !== 'markdown' || @@ -619,12 +636,13 @@ export class CovalentNotebook extends LitElement { protected updated(_changedProperties: PropertyValues): void { if (_changedProperties.has('cells')) { this.cells.forEach((cell, index) => { - cell.showEditor = this.shouldRenderEditor(cell); + // If user input is requested in a cell, scroll to it's position if (cell.inputs?.length) { this.scrollToSelectedCell(index); } }); } + super.updated(_changedProperties); } }