+
diff --git a/src/sql/parts/notebook/cellViews/textCell.component.ts b/src/sql/parts/notebook/cellViews/textCell.component.ts
index f7299f78f7..6696a8541a 100644
--- a/src/sql/parts/notebook/cellViews/textCell.component.ts
+++ b/src/sql/parts/notebook/cellViews/textCell.component.ts
@@ -83,6 +83,9 @@ export class TextCellComponent extends CellView implements OnInit {
this.updatePreview();
this._register(this.themeService.onDidColorThemeChange(this.updateTheme, this));
this.updateTheme(this.themeService.getColorTheme());
+ this.cellModel.onOutputsChanged(e => {
+ this.updatePreview();
+ });
}
// Todo: implement layout
diff --git a/src/sql/parts/notebook/media/dark/add_inverse.svg b/src/sql/parts/notebook/media/dark/add_inverse.svg
new file mode 100644
index 0000000000..8542ea93aa
--- /dev/null
+++ b/src/sql/parts/notebook/media/dark/add_inverse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/sql/parts/notebook/media/dark/nottrusted_inverse.svg b/src/sql/parts/notebook/media/dark/nottrusted_inverse.svg
new file mode 100644
index 0000000000..bd3832e82a
--- /dev/null
+++ b/src/sql/parts/notebook/media/dark/nottrusted_inverse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/sql/parts/notebook/media/dark/trusted_inverse.svg b/src/sql/parts/notebook/media/dark/trusted_inverse.svg
new file mode 100644
index 0000000000..25967f45aa
--- /dev/null
+++ b/src/sql/parts/notebook/media/dark/trusted_inverse.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/sql/parts/notebook/media/light/add_code_cell.svg b/src/sql/parts/notebook/media/light/add_code_cell.svg
deleted file mode 100644
index 375721a2d1..0000000000
--- a/src/sql/parts/notebook/media/light/add_code_cell.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/sql/parts/notebook/media/light/add_text_cell.svg b/src/sql/parts/notebook/media/light/add_text_cell.svg
deleted file mode 100644
index f6c97e09f4..0000000000
--- a/src/sql/parts/notebook/media/light/add_text_cell.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/sql/parts/notebook/media/light/cell_output.svg b/src/sql/parts/notebook/media/light/cell_output.svg
deleted file mode 100644
index 706b5a4f05..0000000000
--- a/src/sql/parts/notebook/media/light/cell_output.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/sql/parts/notebook/media/light/nottrusted.svg b/src/sql/parts/notebook/media/light/nottrusted.svg
new file mode 100644
index 0000000000..cc199359bd
--- /dev/null
+++ b/src/sql/parts/notebook/media/light/nottrusted.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/sql/parts/notebook/media/light/trusted.svg b/src/sql/parts/notebook/media/light/trusted.svg
new file mode 100644
index 0000000000..721fc0bd8f
--- /dev/null
+++ b/src/sql/parts/notebook/media/light/trusted.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/sql/parts/notebook/models/modelInterfaces.ts b/src/sql/parts/notebook/models/modelInterfaces.ts
index 17baf6f61d..b94cb3608a 100644
--- a/src/sql/parts/notebook/models/modelInterfaces.ts
+++ b/src/sql/parts/notebook/models/modelInterfaces.ts
@@ -341,6 +341,7 @@ export interface ICellModel {
readonly outputs: ReadonlyArray
;
equals(cellModel: ICellModel): boolean;
toJSON(): nb.ICell;
+ onOutputsChanged: Event>;
}
export interface IModelFactory {
diff --git a/src/sql/parts/notebook/notebook.component.ts b/src/sql/parts/notebook/notebook.component.ts
index 5c05c767e6..0a8a32d294 100644
--- a/src/sql/parts/notebook/notebook.component.ts
+++ b/src/sql/parts/notebook/notebook.component.ts
@@ -31,7 +31,7 @@ import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
-import { KernelsDropdown, AttachToDropdown, AddCellAction } from 'sql/parts/notebook/notebookActions';
+import { KernelsDropdown, AttachToDropdown, AddCellAction, TrustedAction } from 'sql/parts/notebook/notebookActions';
import { attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
export const NOTEBOOK_SELECTOR: string = 'notebook-component';
@@ -53,6 +53,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit {
private _modelReadyDeferred = new Deferred();
private _modelRegisteredDeferred = new Deferred();
private profile: IConnectionProfile;
+ private _trustedAction: TrustedAction;
constructor(
@@ -108,12 +109,23 @@ export class NotebookComponent extends AngularDisposable implements OnInit {
}
}
- //Add cell based on cell type
+ // Add cell based on cell type
public addCell(cellType: CellType)
{
this._model.addCell(cellType);
}
+ // Updates Notebook model's trust details
+ public updateModelTrustDetails(isTrusted: boolean)
+ {
+ this._model.trustedMode = isTrusted;
+ this._model.cells.forEach(cell => {
+ cell.trustedMode = isTrusted;
+ });
+ this.setDirty(true);
+ this._changeRef.detectChanges();
+ }
+
public onKeyDown(event) {
switch (event.key) {
case 'ArrowDown':
@@ -164,12 +176,23 @@ export class NotebookComponent extends AngularDisposable implements OnInit {
await model.requestModelLoad(this.notebookParams.isTrusted);
model.contentChanged((change) => this.handleContentChanged(change));
this._model = model;
+ this.updateToolbarComponents(this._model.trustedMode);
this._register(model);
this._modelRegisteredDeferred.resolve(this._model);
model.backgroundStartSession();
this._changeRef.detectChanges();
}
+ // Updates toolbar components
+ private updateToolbarComponents(isTrusted: boolean)
+ {
+ if(this._trustedAction)
+ {
+ this._trustedAction.enabled = true;
+ this._trustedAction.trusted = isTrusted;
+ }
+ }
+
private get modelFactory(): IModelFactory {
if (!this.notebookParams.modelFactory) {
this.notebookParams.modelFactory = new ModelFactory();
@@ -212,12 +235,15 @@ export class NotebookComponent extends AngularDisposable implements OnInit {
attachToInfoText.className = 'notebook-info-label';
attachToInfoText.innerText = 'Attach To: ';
- let addCodeCellButton = new AddCellAction('notebook.AddCodeCell', localize('code', 'Code'), 'notebook-info-button');
+ let addCodeCellButton = new AddCellAction('notebook.AddCodeCell', localize('code', 'Code'), 'notebook-button icon-add');
addCodeCellButton.cellType = CellTypes.Code;
- let addTextCellButton = new AddCellAction('notebook.AddTextCell',localize('text', 'Text'), 'notebook-info-button');
+ let addTextCellButton = new AddCellAction('notebook.AddTextCell',localize('text', 'Text'), 'notebook-button icon-add');
addTextCellButton.cellType = CellTypes.Markdown;
+ this._trustedAction = this.instantiationService.createInstance(TrustedAction, 'notebook.Trusted');
+ this._trustedAction.enabled = false;
+
let taskbar = this.toolbar.nativeElement;
this._actionBar = new Taskbar(taskbar, this.contextMenuService);
this._actionBar.context = this;
@@ -225,7 +251,8 @@ export class NotebookComponent extends AngularDisposable implements OnInit {
{ element: kernelContainer },
{ element: attachToContainer },
{ action: addCodeCellButton},
- { action: addTextCellButton}
+ { action: addTextCellButton},
+ { action: this._trustedAction}
]);
}
diff --git a/src/sql/parts/notebook/notebook.css b/src/sql/parts/notebook/notebook.css
index 5d1240483f..b745c693f4 100644
--- a/src/sql/parts/notebook/notebook.css
+++ b/src/sql/parts/notebook/notebook.css
@@ -24,7 +24,7 @@
padding-top: 0px;
}
-.notebookEditor .notebook-info-button {
+.notebookEditor .notebook-button {
display: inline-block;
width: 100%;
padding: 0px;
@@ -34,5 +34,31 @@
background-size: 11px;
margin-right: 0.3em;
font-size: 11px;
- background-image: url("./media/light/add.svg")
+}
+
+.notebookEditor .notebook-button.icon-add{
+ background-image: url("./media/light/add.svg");
+}
+
+.vs-dark .notebookEditor .notebook-button.icon-add,
+.hc-black .notebookEditor .notebook-button.icon-add{
+ background-image: url("./media/dark/add_inverse.svg");
+}
+
+.notebookEditor .notebook-button.icon-trusted{
+ background-image: url("./media/light/trusted.svg");
+}
+
+.vs-dark .notebookEditor .notebook-button.icon-trusted,
+.hc-black .notebookEditor .notebook-button.icon-trusted{
+ background-image: url("./media/dark/trusted_inverse.svg");
+}
+
+.notebookEditor .notebook-button.icon-notTrusted{
+ background-image: url("./media/light/nottrusted.svg");
+}
+
+.vs-dark .notebookEditor .notebook-button.icon-notTrusted,
+.hc-black .notebookEditor .notebook-button.icon-notTrusted{
+ background-image: url("./media/dark/nottrusted_inverse.svg");
}
\ No newline at end of file
diff --git a/src/sql/parts/notebook/notebookActions.ts b/src/sql/parts/notebook/notebookActions.ts
index 2aa859d075..4e8184dafe 100644
--- a/src/sql/parts/notebook/notebookActions.ts
+++ b/src/sql/parts/notebook/notebookActions.ts
@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
- import * as sqlops from 'sqlops';
+import * as sqlops from 'sqlops';
import { Action } from 'vs/base/common/actions';
import { TPromise } from 'vs/base/common/winjs.base';
@@ -14,13 +14,15 @@ import { SelectBox, ISelectBoxOptionsWithLabel } from 'sql/base/browser/ui/selec
import { INotebookModel } from 'sql/parts/notebook/models/modelInterfaces';
import { CellTypes, CellType } from 'sql/parts/notebook/models/contracts';
import { NotebookComponent } from 'sql/parts/notebook/notebook.component';
+import { INotificationService, Severity, INotificationActions } from 'vs/platform/notification/common/notification';
+import { NotificationService } from 'vs/workbench/services/notification/common/notificationService';
const msgLoading = localize('loading', 'Loading kernels...');
const kernelLabel: string = localize('Kernel', 'Kernel: ');
const attachToLabel: string = localize('AttachTo', 'Attach to: ');
const msgLocalHost: string = localize('localhost', 'Localhost');
-//Action to add a cell to notebook based on cell type(code/markdown).
+// Action to add a cell to notebook based on cell type(code/markdown).
export class AddCellAction extends Action {
public cellType: CellType;
@@ -41,6 +43,51 @@ export class AddCellAction extends Action {
}
}
+export class TrustedAction extends Action {
+ // Constants
+ private static readonly trustLabel = localize('trustLabel', 'Trusted');
+ private static readonly notTrustLabel = localize('untrustLabel', 'Not Trusted');
+ private static readonly alreadyTrustedMsg = localize('alreadyTrustedMsg', 'Notebook is already trusted.');
+ private static readonly trustedCssClass = 'notebook-button icon-trusted';
+ private static readonly notTrustedCssClass = 'notebook-button icon-notTrusted';
+ // Properties
+ private _isTrusted: boolean = false;
+ public get trusted(): boolean {
+ return this._isTrusted;
+ }
+ public set trusted(value: boolean) {
+ this._isTrusted = value;
+ this._setClass(value ? TrustedAction.trustedCssClass : TrustedAction.notTrustedCssClass);
+ this._setLabel(value ? TrustedAction.trustLabel : TrustedAction.notTrustLabel);
+ }
+
+ constructor(
+ id: string,
+ @INotificationService private _notificationService: INotificationService
+ ) {
+ super(id, TrustedAction.notTrustLabel, TrustedAction.notTrustedCssClass);
+ }
+
+ public run(context: NotebookComponent): TPromise {
+ let self = this;
+ return new TPromise((resolve, reject) => {
+ try {
+ if (self._isTrusted) {
+ const actions: INotificationActions = { primary: [] };
+ self._notificationService.notify({ severity: Severity.Info, message: TrustedAction.alreadyTrustedMsg, actions });
+ }
+ else {
+ self.trusted = !self._isTrusted;
+ context.updateModelTrustDetails(self.trusted);
+ }
+ resolve(true);
+ } catch (e) {
+ reject(e);
+ }
+ });
+ }
+}
+
export class KernelsDropdown extends SelectBox {
private model: INotebookModel;
constructor(container: HTMLElement, contextViewProvider: IContextViewProvider, modelRegistered: Promise