diff --git a/src/sql/workbench/browser/modelComponents/card.component.ts b/src/sql/workbench/browser/modelComponents/card.component.ts
index 4545c4003a..5acaa23786 100644
--- a/src/sql/workbench/browser/modelComponents/card.component.ts
+++ b/src/sql/workbench/browser/modelComponents/card.component.ts
@@ -18,8 +18,9 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import * as DOM from 'vs/base/browser/dom';
import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/platform/dashboard/browser/interfaces';
-import { IColorTheme } from 'vs/platform/theme/common/themeService';
+import { IColorTheme, ICssStyleCollector, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { ILogService } from 'vs/platform/log/common/log';
+import { CARD_OVERLAY_BACKGROUND, CARD_OVERLAY_FOREGROUND } from 'vs/workbench/common/theme';
export interface ActionDescriptor {
label: string;
@@ -52,7 +53,8 @@ export interface CardDescriptionItem {
export enum CardType {
VerticalButton = 'VerticalButton',
Details = 'Details',
- ListItem = 'ListItem'
+ ListItem = 'ListItem',
+ Image = 'Image'
}
@Component({
@@ -119,6 +121,11 @@ export default class CardComponent extends ComponentWithIconBase
{
+ const backgroundColor = theme.getColor(CARD_OVERLAY_BACKGROUND);
+ const foregroundColor = theme.getColor(CARD_OVERLAY_FOREGROUND);
+ if (backgroundColor) {
+ collector.addRule(`
+ .model-card-legacy .card-label-overlay {
+ background-color: ${backgroundColor.toString()};
+ }
+ `);
+ }
+
+ if (foregroundColor) {
+ collector.addRule(`
+ .model-card-legacy.image-card .card-label {
+ color: ${foregroundColor.toString()};
+ }
+ `);
+ }
+});
diff --git a/src/sql/workbench/browser/modelComponents/media/legacycard.css b/src/sql/workbench/browser/modelComponents/media/legacycard.css
index 86a4aa9998..6c72141091 100644
--- a/src/sql/workbench/browser/modelComponents/media/legacycard.css
+++ b/src/sql/workbench/browser/modelComponents/media/legacycard.css
@@ -26,6 +26,47 @@
min-width: 30px;
}
+.model-card-legacy.image-card {
+ height: auto;
+ margin: 0;
+ display: block;
+}
+
+.model-card-legacy.image-card .card-content {
+ display: block;
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ min-height: 100px;
+}
+
+.model-card-legacy.image-card .card-image {
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ background-size: contain;
+ background-position: initial;
+ background-repeat: no-repeat;
+ max-width: unset;
+ max-height: unset;
+}
+
+.model-card-legacy.image-card .card-label-overlay {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ height: 25px;
+ line-height: 25px;
+ padding: 0;
+ margin: 0;
+ display: block;
+}
+
+.model-card-legacy.image-card .card-label {
+ margin: 0;
+ padding: 0px 10px
+}
+
.model-card-legacy .card-vertical-button {
position: relative;
display: flex;
@@ -103,6 +144,7 @@
border-width: 1px;
border-color: rgb(0, 120, 215);
border-style: solid;
+ z-index: 1;
}
.model-card-list-item-legacy .selection-indicator-container, .model-card-legacy .selection-indicator-container {
diff --git a/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.module.ts b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.module.ts
new file mode 100644
index 0000000000..7575334b6d
--- /dev/null
+++ b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.module.ts
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+import {
+ ApplicationRef, ComponentFactoryResolver, NgModule,
+ Inject, forwardRef, Type
+} from '@angular/core';
+import { APP_BASE_HREF, CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { BrowserModule } from '@angular/platform-browser';
+import { providerIterator } from 'sql/workbench/services/bootstrap/browser/bootstrapService';
+import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
+import { IBootstrapParams, ISelector } from 'sql/workbench/services/bootstrap/common/bootstrapParams';
+import CardComponent from 'sql/workbench/browser/modelComponents/card.component';
+import DivContainer from 'sql/workbench/browser/modelComponents/divContainer.component';
+import { ModelComponentWrapper } from 'sql/workbench/browser/modelComponents/modelComponentWrapper.component';
+import { InsertCellsScreenshots } from 'sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.component';
+import ImageComponent from 'sql/workbench/browser/modelComponents/image.component';
+
+// Insertcells main angular module
+export const InsertCellsModule = (params: IBootstrapParams, selector: string, instantiationService: IInstantiationService): Type => {
+ @NgModule({
+ declarations: [
+ CardComponent,
+ DivContainer,
+ ModelComponentWrapper,
+ InsertCellsScreenshots,
+ ImageComponent,
+ ],
+ entryComponents: [InsertCellsScreenshots, CardComponent, ImageComponent],
+ imports: [
+ FormsModule,
+ CommonModule,
+ BrowserModule
+ ],
+ providers: [
+ { provide: APP_BASE_HREF, useValue: '/' },
+ { provide: IBootstrapParams, useValue: params },
+ { provide: ISelector, useValue: selector },
+ ...providerIterator(instantiationService)
+ ]
+ })
+ class ModuleClass {
+ constructor(
+ @Inject(forwardRef(() => ComponentFactoryResolver)) private _resolver: ComponentFactoryResolver,
+ @Inject(ISelector) private selector: string
+ ) {
+ }
+ ngDoBootstrap(appRef: ApplicationRef) {
+ const factory = this._resolver.resolveComponentFactory(InsertCellsScreenshots);
+ (factory).factory.selector = this.selector;
+ appRef.bootstrap(factory);
+ }
+ }
+ return ModuleClass;
+};
diff --git a/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.ts b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.ts
index 4a9d0c3522..c3bd15c4a1 100644
--- a/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.ts
+++ b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.ts
@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./insertCellsModal';
-import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox';
import { Button } from 'sql/base/browser/ui/button/button';
import { IClipboardService } from 'sql/platform/clipboard/common/clipboardService';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
@@ -13,22 +12,24 @@ import { ITextResourcePropertiesService } from 'vs/editor/common/services/textRe
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { ILogService } from 'vs/platform/log/common/log';
-import { IColorTheme, ICssStyleCollector, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
-import * as DOM from 'vs/base/browser/dom';
-import { attachCheckboxStyler } from 'sql/platform/theme/common/styler';
+import { IThemeService } from 'vs/platform/theme/common/themeService';
import { ServiceOptionType } from 'sql/platform/connection/common/interfaces';
import { ServiceOption } from 'azdata';
import * as DialogHelper from 'sql/workbench/browser/modal/dialogHelper';
import { TextCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/textCell.component';
-import { ComponentFactoryResolver, ViewContainerRef } from '@angular/core';
+import { NgModuleRef, ComponentFactoryResolver, ViewContainerRef } from '@angular/core';
import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { NotebookModel } from 'sql/workbench/services/notebook/browser/models/notebookModel';
-import { inputBorder, inputValidationInfoBorder } from 'vs/platform/theme/common/colorRegistry';
+import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
+import { bootstrapAngular } from 'sql/workbench/services/bootstrap/browser/bootstrapService';
import { localize } from 'vs/nls';
import { NotebookViewsExtension } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViewsExtension';
+import { InsertCellsModule } from 'sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal.module';
import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { truncate } from 'vs/base/common/strings';
import { toJpeg } from 'html-to-image';
+import { IComponentEventArgs } from 'sql/platform/dashboard/browser/interfaces';
+import { Thumbnail } from 'sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.component';
type CellOption = {
optionMetadata: ServiceOption,
@@ -54,6 +55,10 @@ export class CellOptionsModel {
});
}
+ public get checkedOptions(): CellOption[] {
+ return Object.values(this._optionsMap).filter(o => o.currentValue === true);
+ }
+
private getDisplayValue(optionMetadata: ServiceOption, optionValue: string): boolean {
let displayValue: boolean = false;
switch (optionMetadata.valueType) {
@@ -93,8 +98,8 @@ export class InsertCellsModal extends Modal {
private _submitButton: Button;
private _cancelButton: Button;
- private _optionsMap: { [name: string]: Checkbox } = {};
private _maxTitleLength: number = 20;
+ private _moduleRef?: NgModuleRef;
constructor(
private onInsert: (cell: ICellModel) => void,
@@ -107,6 +112,7 @@ export class InsertCellsModal extends Modal {
@IClipboardService clipboardService: IClipboardService,
@IContextKeyService contextKeyService: IContextKeyService,
@IAdsTelemetryService telemetryService: IAdsTelemetryService,
+ @IInstantiationService private _instantiationService: IInstantiationService,
@ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService,
) {
super(
@@ -127,21 +133,7 @@ export class InsertCellsModal extends Modal {
}
protected renderBody(container: HTMLElement): void {
- const grid = DOM.$('div#insert-dialog-cell-grid');
-
- grid.style.display = 'grid';
- grid.style.gridTemplateColumns = '1fr 1fr';
- grid.style.gap = '10px';
- grid.style.padding = '10px';
- grid.style.overflowY = 'auto';
- grid.style.maxHeight = 'calc(100% - 40px)';
-
- const gridTitle = DOM.$('h2.grid-title');
- gridTitle.title = localize("insertCellsModal.selectCells", "Select cell sources");
-
- DOM.append(container, grid);
-
- this.createOptions(grid)
+ this.createOptions(container)
.catch((e) => { this.setError(localize("insertCellsModal.thumbnailError", "Error: Unable to generate thumbnails.")); });
}
@@ -153,59 +145,48 @@ export class InsertCellsModal extends Modal {
const activeView = this._context.getActiveView();
const cellsAvailableToInsert = activeView.hiddenCells;
- cellsAvailableToInsert.forEach(async (cell) => {
- const optionWidget = this.createCheckBoxHelper(
- container,
- '',
- false,
- () => this.onOptionChecked(cell.cellGuid)
- );
+ const thumbnails = await Promise.all(
+ cellsAvailableToInsert.map(async (cell) => {
+ return {
+ id: cell.cellGuid,
+ path: await this.generateScreenshot(cell),
+ title: localize("insertCellsModal.cellTitle", "Cell {0}", Number.parseInt(cell.id) + 1)
+ } as Thumbnail;
+ })
+ );
- const img = await this.generateScreenshot(cell);
- const wrapper = DOM.$('div.thumnail-wrapper');
- const thumbnail = DOM.$('img.thumbnail');
-
- thumbnail.src = img;
- thumbnail.style.maxWidth = '100%';
- DOM.append(wrapper, thumbnail);
- optionWidget.label = wrapper.outerHTML;
-
- this._optionsMap[cell.cellGuid] = optionWidget;
- });
+ this.bootstrapAngular(container, thumbnails);
}
- private createCheckBoxHelper(container: HTMLElement, label: string, isChecked: boolean, onCheck: (viaKeyboard: boolean) => void): Checkbox {
- const checkbox = new Checkbox(DOM.append(container, DOM.$('.dialog-input-section')), {
- label: label,
- checked: isChecked,
- onChange: onCheck,
- ariaLabel: label
- });
- this._register(attachCheckboxStyler(checkbox, this._themeService));
- return checkbox;
- }
-
- public onOptionChecked(optionName: string) {
- this.viewModel.setOptionValue(optionName, (this._optionsMap[optionName]).checked);
- this.validate();
+ public onOptionChecked(e: IComponentEventArgs) {
+ if (e.args?.value) {
+ let optionName: string = e.args.value;
+ this.viewModel.setOptionValue(optionName, e.args.selected);
+ this.validate();
+ }
}
public async generateScreenshot(cell: ICellModel, screenshotWidth: number = 300, screenshowHeight: number = 300, backgroundColor: string = '#ffffff'): Promise {
- let componentFactory = this._componentFactoryResolver.resolveComponentFactory(TextCellComponent);
- let component = this._containerRef.createComponent(componentFactory);
+ try {
+ let componentFactory = this._componentFactoryResolver.resolveComponentFactory(TextCellComponent);
+ let component = this._containerRef.createComponent(componentFactory);
- component.instance.model = this._context.notebook as NotebookModel;
- component.instance.cellModel = cell;
+ component.instance.model = this._context.notebook as NotebookModel;
+ component.instance.cellModel = cell;
- component.instance.handleContentChanged();
+ component.instance.handleContentChanged();
- const element: HTMLElement = component.instance.outputRef.nativeElement;
+ const element: HTMLElement = component.instance.outputRef.nativeElement;
- const scale = element.clientWidth / screenshotWidth;
- const canvasWidth = element.clientWidth / scale;
- const canvasHeight = element.clientHeight / scale;
+ const scale = element.clientWidth / screenshotWidth;
+ const canvasWidth = element.clientWidth / scale;
+ const canvasHeight = element.clientHeight / scale;
- return toJpeg(component.instance.outputRef.nativeElement, { quality: .6, canvasWidth, canvasHeight, backgroundColor });
+ return toJpeg(component.instance.outputRef.nativeElement, { quality: .6, canvasWidth, canvasHeight, backgroundColor });
+ } catch (e) {
+ this.logService.error(`Error generating screenshot: ${e}`);
+ return '';
+ }
}
private getOptions(): ServiceOption[] {
@@ -239,7 +220,7 @@ export class InsertCellsModal extends Modal {
}
private validate() {
- if (Object.keys(this._optionsMap).length) {
+ if (this.viewModel.checkedOptions.length) {
this._submitButton.enabled = true;
} else {
this._submitButton.enabled = false;
@@ -265,34 +246,25 @@ export class InsertCellsModal extends Modal {
public override dispose(): void {
super.dispose();
- for (let key in this._optionsMap) {
- let widget = this._optionsMap[key];
- widget.dispose();
- delete this._optionsMap[key];
+
+ if (this._moduleRef) {
+ this._moduleRef.destroy();
}
}
+
+ /**
+ * Get the bootstrap params and perform the bootstrap
+ */
+ private bootstrapAngular(bodyContainer: HTMLElement, thumbnails: Thumbnail[]) {
+ this._instantiationService.invokeFunction(bootstrapAngular,
+ InsertCellsModule,
+ bodyContainer,
+ 'insert-cells-screenshots-component',
+ {
+ thumbnails,
+ onClick: (e: IComponentEventArgs) => { this.onOptionChecked(e); }
+ },
+ undefined,
+ (moduleRef: NgModuleRef) => this._moduleRef = moduleRef);
+ }
}
-
-registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
- const inputBorderColor = theme.getColor(inputBorder);
- if (inputBorderColor) {
- collector.addRule(`
- #insert-dialog-cell-grid input[type="checkbox"] + label {
- border: 2px solid;
- border-color: ${inputBorderColor.toString()};
- display: flex;
- height: 125px;
- overflow: hidden;
- }
- `);
- }
-
- const inputActiveOptionBorderColor = theme.getColor(inputValidationInfoBorder);
- if (inputActiveOptionBorderColor) {
- collector.addRule(`
- #insert-dialog-cell-grid input[type="checkbox"]:checked + label {
- border-color: ${inputActiveOptionBorderColor.toString()};
- }
- `);
- }
-});
diff --git a/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.component.ts b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.component.ts
new file mode 100644
index 0000000000..56fb5dc857
--- /dev/null
+++ b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.component.ts
@@ -0,0 +1,54 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the Source EULA. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+import 'vs/css!./insertCellsScreenshots';
+import { Component, AfterViewInit, forwardRef, Inject, ComponentFactoryResolver, ViewContainerRef, ViewChild } from '@angular/core';
+import { IBootstrapParams } from 'sql/workbench/services/bootstrap/common/bootstrapParams';
+import { IComponentEventArgs } from 'sql/platform/dashboard/browser/interfaces';
+import CardComponent, { CardType } from 'sql/workbench/browser/modelComponents/card.component';
+import { URI } from 'vs/base/common/uri';
+
+
+export interface LayoutRequestParams {
+ modelViewId?: string;
+ alwaysRefresh?: boolean;
+}
+
+export interface Thumbnail {
+ id: string,
+ path: string,
+ title: string
+}
+
+export interface InsertCellsComponentParams extends IBootstrapParams {
+ thumbnails: Thumbnail[],
+ onClick: (e: IComponentEventArgs) => void
+}
+
+@Component({
+ selector: 'insert-cells-screenshots-component',
+ template: '
'
+})
+export class InsertCellsScreenshots implements AfterViewInit {
+ @ViewChild('divContainer', { read: ViewContainerRef }) _containerRef: ViewContainerRef;
+
+ constructor(
+ @Inject(IBootstrapParams) private _params: InsertCellsComponentParams,
+ @Inject(forwardRef(() => ComponentFactoryResolver)) private _componentFactoryResolver: ComponentFactoryResolver
+ ) { }
+
+ ngAfterViewInit(): void {
+ this._params.thumbnails.forEach((thumbnail: Thumbnail, idx: number) => {
+ const cellImageUri = URI.parse(thumbnail.path);
+
+ let cardComponentFactory = this._componentFactoryResolver.resolveComponentFactory(CardComponent);
+ let cardComponent = this._containerRef.createComponent(cardComponentFactory);
+
+ cardComponent.instance.setProperties({ iconPath: cellImageUri, label: thumbnail.title, value: thumbnail.id, cardType: CardType.Image });
+
+ cardComponent.instance.enabled = true;
+ cardComponent.instance.registerEventHandler(e => this._params.onClick(e));
+ });
+ }
+}
diff --git a/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.css b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.css
new file mode 100644
index 0000000000..af19905403
--- /dev/null
+++ b/src/sql/workbench/contrib/notebook/browser/notebookViews/insertCellsScreenshots.css
@@ -0,0 +1,8 @@
+.insert-cells-screenshot-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 10px;
+ padding: 10px;
+ overflow-y: auto;
+ max-height: calc(100% - 40px);
+}
diff --git a/src/sql/workbench/contrib/notebook/browser/notebookViews/notebookViews.component.ts b/src/sql/workbench/contrib/notebook/browser/notebookViews/notebookViews.component.ts
index c2a94d72ca..9836851175 100644
--- a/src/sql/workbench/contrib/notebook/browser/notebookViews/notebookViews.component.ts
+++ b/src/sql/workbench/contrib/notebook/browser/notebookViews/notebookViews.component.ts
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Component, Input, ViewChildren, QueryList, ChangeDetectorRef, forwardRef, Inject, ViewChild, ElementRef, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { ICellModel, INotebookModel, ISingleNotebookEditOperation, NotebookContentChange } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
+import 'vs/css!./notebookViewsGrid';
import { CodeCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/codeCell.component';
import { TextCellComponent } from 'sql/workbench/contrib/notebook/browser/cellViews/textCell.component';
import { ICellEditorProvider, INotebookParams, INotebookService, INotebookEditor, NotebookRange, INotebookSection, DEFAULT_NOTEBOOK_PROVIDER, SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/browser/notebookService';
@@ -260,6 +261,10 @@ export class NotebookViewComponent extends AngularDisposable implements INoteboo
let insertCellsAction = this._instantiationService.createInstance(InsertCellAction, this.insertCell.bind(this), this.views, this._containerRef, this._componentFactoryResolver);
+ // Hide the insert cell action button if no cells can be added
+ insertCellsAction.enabled = this.activeView?.hiddenCells.length > 0;
+ this.activeView.onCellVisibilityChanged(e => { insertCellsAction.enabled = this.activeView?.hiddenCells.length > 0; });
+
this._runAllCellsAction = this._instantiationService.createInstance(RunAllCellsAction, 'notebook.runAllCells', localize('runAllPreview', "Run all"), 'notebook-button masked-pseudo start-outline');
let spacerElement = document.createElement('li');
diff --git a/src/sql/workbench/contrib/notebook/test/stubs.ts b/src/sql/workbench/contrib/notebook/test/stubs.ts
index 2e42d30735..1d64e258d1 100644
--- a/src/sql/workbench/contrib/notebook/test/stubs.ts
+++ b/src/sql/workbench/contrib/notebook/test/stubs.ts
@@ -770,6 +770,7 @@ export class NotebookViewStub implements INotebookView {
displayedCells: readonly ICellModel[];
onDeleted: vsEvent.Event;
+ onCellVisibilityChanged: vsEvent.Event;
initialize(): void {
throw new Error('Method not implemented.');
}
diff --git a/src/sql/workbench/services/notebook/browser/notebookViews/notebookViewModel.ts b/src/sql/workbench/services/notebook/browser/notebookViews/notebookViewModel.ts
index 56961133fc..b7cb649afe 100644
--- a/src/sql/workbench/services/notebook/browser/notebookViews/notebookViewModel.ts
+++ b/src/sql/workbench/services/notebook/browser/notebookViews/notebookViewModel.ts
@@ -21,10 +21,12 @@ function cellCollides(c1: INotebookViewCell, c2: INotebookViewCell): boolean {
export class NotebookViewModel implements INotebookView {
private _onDeleted = new Emitter();
+ private _onCellVisibilityChanged = new Emitter();
private _isNew: boolean = false;
public readonly guid: string;
public readonly onDeleted = this._onDeleted.event;
+ public readonly onCellVisibilityChanged = this._onCellVisibilityChanged.event;
constructor(
protected _name: string,
@@ -119,10 +121,12 @@ export class NotebookViewModel implements INotebookView {
public insertCell(cell: ICellModel) {
this.updateCell(cell, this, { hidden: false });
+ this._onCellVisibilityChanged.fire(cell);
}
public hideCell(cell: ICellModel) {
this.updateCell(cell, this, { hidden: true });
+ this._onCellVisibilityChanged.fire(cell);
}
public moveCell(cell: ICellModel, x: number, y: number) {
diff --git a/src/sql/workbench/services/notebook/browser/notebookViews/notebookViews.d.ts b/src/sql/workbench/services/notebook/browser/notebookViews/notebookViews.d.ts
index d115891a54..1861e78e08 100644
--- a/src/sql/workbench/services/notebook/browser/notebookViews/notebookViews.d.ts
+++ b/src/sql/workbench/services/notebook/browser/notebookViews/notebookViews.d.ts
@@ -26,8 +26,9 @@ export interface INotebookViews {
export interface INotebookView {
readonly guid: string;
readonly onDeleted: Event;
- isNew: boolean;
+ readonly onCellVisibilityChanged: Event;
+ isNew: boolean;
cells: Readonly;
hiddenCells: Readonly;
displayedCells: Readonly;
diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts
index 07b267f341..8c0fe5ef7b 100644
--- a/src/vs/workbench/common/theme.ts
+++ b/src/vs/workbench/common/theme.ts
@@ -696,3 +696,17 @@ export const WINDOW_INACTIVE_BORDER = registerColor('window.inactiveBorder', {
light: null,
hc: contrastBorder
}, localize('windowInactiveBorder', "The color used for the border of the window when it is inactive. Only supported in the desktop client when using the custom title bar."));
+
+
+// < --- Card --- >
+export const CARD_OVERLAY_FOREGROUND = registerColor('card.overlayForeground', {
+ dark: null,
+ light: null,
+ hc: null
+}, localize('cardOverlayForeground', "The card overlay foreground color."));
+
+export const CARD_OVERLAY_BACKGROUND = registerColor('card.overlayBackground', {
+ dark: '#252526',
+ light: '#F3F3F3',
+ hc: '#000000'
+}, localize('cardOverlayBackground', "The card overlay background color."));