Move setup notebooks panel to react (#673)

Co-authored-by: Steve Faulkner <southpolesteve@gmail.com>
This commit is contained in:
vaidankarswapnil 2021-04-21 08:21:03 +05:30 committed by GitHub
parent b6d60dcc7b
commit d58fececac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 1939 additions and 409 deletions

View File

@ -126,7 +126,6 @@ src/Explorer/Panes/GraphStylingPane.ts
src/Explorer/Panes/NewVertexPane.ts src/Explorer/Panes/NewVertexPane.ts
src/Explorer/Panes/PaneComponents.ts src/Explorer/Panes/PaneComponents.ts
src/Explorer/Panes/RenewAdHocAccessPane.ts src/Explorer/Panes/RenewAdHocAccessPane.ts
src/Explorer/Panes/SetupNotebooksPane.ts
src/Explorer/Panes/StringInputPane.ts src/Explorer/Panes/StringInputPane.ts
src/Explorer/Panes/SwitchDirectoryPane.ts src/Explorer/Panes/SwitchDirectoryPane.ts
src/Explorer/Panes/Tables/AddTableEntityPane.ts src/Explorer/Panes/Tables/AddTableEntityPane.ts

View File

@ -85,10 +85,6 @@ describe("Component Registerer", () => {
expect(ko.components.isRegistered("string-input-pane")).toBe(true); expect(ko.components.isRegistered("string-input-pane")).toBe(true);
}); });
it("should register setup-notebooks-pane component", () => {
expect(ko.components.isRegistered("setup-notebooks-pane")).toBe(true);
});
it("should register dynamic-list component", () => { it("should register dynamic-list component", () => {
expect(ko.components.isRegistered("dynamic-list")).toBe(true); expect(ko.components.isRegistered("dynamic-list")).toBe(true);
}); });

View File

@ -62,5 +62,4 @@ ko.components.register("table-add-entity-pane", new PaneComponents.TableAddEntit
ko.components.register("table-edit-entity-pane", new PaneComponents.TableEditEntityPaneComponent()); ko.components.register("table-edit-entity-pane", new PaneComponents.TableEditEntityPaneComponent());
ko.components.register("cassandra-add-collection-pane", new PaneComponents.CassandraAddCollectionPaneComponent()); ko.components.register("cassandra-add-collection-pane", new PaneComponents.CassandraAddCollectionPaneComponent());
ko.components.register("string-input-pane", new PaneComponents.StringInputPaneComponent()); ko.components.register("string-input-pane", new PaneComponents.StringInputPaneComponent());
ko.components.register("setup-notebooks-pane", new PaneComponents.SetupNotebooksPaneComponent());
ko.components.register("github-repos-pane", new PaneComponents.GitHubReposPaneComponent()); ko.components.register("github-repos-pane", new PaneComponents.GitHubReposPaneComponent());

View File

@ -324,20 +324,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -722,20 +708,6 @@ exports[`SettingsComponent renders 1`] = `
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {
@ -1086,20 +1058,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -1484,20 +1442,6 @@ exports[`SettingsComponent renders 1`] = `
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {
@ -1861,20 +1805,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -2259,20 +2189,6 @@ exports[`SettingsComponent renders 1`] = `
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {
@ -2623,20 +2539,6 @@ exports[`SettingsComponent renders 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -3021,20 +2923,6 @@ exports[`SettingsComponent renders 1`] = `
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {

View File

@ -61,7 +61,7 @@ import { LoadQueryPanel } from "./Panes/LoadQueryPanel";
import NewVertexPane from "./Panes/NewVertexPane"; import NewVertexPane from "./Panes/NewVertexPane";
import { SaveQueryPanel } from "./Panes/SaveQueryPanel"; import { SaveQueryPanel } from "./Panes/SaveQueryPanel";
import { SettingsPane } from "./Panes/SettingsPane"; import { SettingsPane } from "./Panes/SettingsPane";
import { SetupNotebooksPane } from "./Panes/SetupNotebooksPane"; import { SetupNoteBooksPanel } from "./Panes/SetupNotebooksPanel/SetupNotebooksPanel";
import { StringInputPane } from "./Panes/StringInputPane"; import { StringInputPane } from "./Panes/StringInputPane";
import AddTableEntityPane from "./Panes/Tables/AddTableEntityPane"; import AddTableEntityPane from "./Panes/Tables/AddTableEntityPane";
import EditTableEntityPane from "./Panes/Tables/EditTableEntityPane"; import EditTableEntityPane from "./Panes/Tables/EditTableEntityPane";
@ -182,7 +182,6 @@ export default class Explorer {
public newVertexPane: NewVertexPane; public newVertexPane: NewVertexPane;
public cassandraAddCollectionPane: CassandraAddCollectionPane; public cassandraAddCollectionPane: CassandraAddCollectionPane;
public stringInputPane: StringInputPane; public stringInputPane: StringInputPane;
public setupNotebooksPane: SetupNotebooksPane;
public gitHubReposPane: ContextualPaneBase; public gitHubReposPane: ContextualPaneBase;
public publishNotebookPaneAdapter: ReactAdapter; public publishNotebookPaneAdapter: ReactAdapter;
public copyNotebookPaneAdapter: ReactAdapter; public copyNotebookPaneAdapter: ReactAdapter;
@ -288,7 +287,6 @@ export default class Explorer {
((await this._containsDefaultNotebookWorkspace(this.databaseAccount())) || ((await this._containsDefaultNotebookWorkspace(this.databaseAccount())) ||
userContext.features.enableNotebooks) userContext.features.enableNotebooks)
); );
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, { TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
isNotebookEnabled: this.isNotebookEnabled(), isNotebookEnabled: this.isNotebookEnabled(),
dataExplorerArea: Constants.Areas.Notebook, dataExplorerArea: Constants.Areas.Notebook,
@ -551,13 +549,6 @@ export default class Explorer {
container: this, container: this,
}); });
this.setupNotebooksPane = new SetupNotebooksPane({
id: "setupnotebookspane",
visible: ko.observable<boolean>(false),
container: this,
});
this.tabsManager = params?.tabsManager ?? new TabsManager(); this.tabsManager = params?.tabsManager ?? new TabsManager();
this.tabsManager.openedTabs.subscribe((tabs) => { this.tabsManager.openedTabs.subscribe((tabs) => {
if (tabs.length === 0) { if (tabs.length === 0) {
@ -575,7 +566,6 @@ export default class Explorer {
this.newVertexPane, this.newVertexPane,
this.cassandraAddCollectionPane, this.cassandraAddCollectionPane,
this.stringInputPane, this.stringInputPane,
this.setupNotebooksPane,
]; ];
this.addDatabaseText.subscribe((addDatabaseText: string) => this.addDatabasePane.title(addDatabaseText)); this.addDatabaseText.subscribe((addDatabaseText: string) => this.addDatabasePane.title(addDatabaseText));
this.isTabsContentExpanded = ko.observable(false); this.isTabsContentExpanded = ko.observable(false);
@ -2133,7 +2123,7 @@ export default class Explorer {
const description = const description =
"You have not yet created a notebooks workspace for this account. To proceed and start using notebooks, we'll need to create a default notebooks workspace in this account."; "You have not yet created a notebooks workspace for this account. To proceed and start using notebooks, we'll need to create a default notebooks workspace in this account.";
this.setupNotebooksPane.openWithTitleAndDescription(title, description); this.openSetupNotebooksPanel(title, description);
} }
public async handleOpenFileAction(path: string): Promise<void> { public async handleOpenFileAction(path: string): Promise<void> {
@ -2273,6 +2263,19 @@ export default class Explorer {
); );
} }
public openSetupNotebooksPanel(title: string, description: string): void {
this.openSidePanel(
title,
<SetupNoteBooksPanel
explorer={this}
closePanel={this.closeSidePanel}
openNotificationConsole={() => this.expandConsole()}
panelTitle={title}
panelDescription={description}
/>
);
}
public openTableSelectQueryPanel(queryViewModal: QueryViewModel): void { public openTableSelectQueryPanel(queryViewModal: QueryViewModel): void {
this.openSidePanel( this.openSidePanel(
"Select Column", "Select Column",

View File

@ -445,7 +445,7 @@ function createEnableNotebooksButton(container: Explorer): CommandButtonComponen
return { return {
iconSrc: EnableNotebooksIcon, iconSrc: EnableNotebooksIcon,
iconAlt: label, iconAlt: label,
onCommandClick: () => container.setupNotebooksPane.openWithTitleAndDescription(label, description), onCommandClick: () => container.openSetupNotebooksPanel(label, description),
commandButtonLabel: label, commandButtonLabel: label,
hasPopup: false, hasPopup: false,
disabled: !container.isNotebooksEnabledForAccount(), disabled: !container.isNotebooksEnabledForAccount(),
@ -482,7 +482,7 @@ function createOpenMongoTerminalButton(container: Explorer): CommandButtonCompon
if (container.isNotebookEnabled()) { if (container.isNotebookEnabled()) {
container.openNotebookTerminal(ViewModels.TerminalKind.Mongo); container.openNotebookTerminal(ViewModels.TerminalKind.Mongo);
} else { } else {
container.setupNotebooksPane.openWithTitleAndDescription(title, description); container.openSetupNotebooksPanel(title, description);
} }
}, },
commandButtonLabel: label, commandButtonLabel: label,
@ -508,7 +508,7 @@ function createOpenCassandraTerminalButton(container: Explorer): CommandButtonCo
if (container.isNotebookEnabled()) { if (container.isNotebookEnabled()) {
container.openNotebookTerminal(ViewModels.TerminalKind.Cassandra); container.openNotebookTerminal(ViewModels.TerminalKind.Cassandra);
} else { } else {
container.setupNotebooksPane.openWithTitleAndDescription(title, description); container.openSetupNotebooksPanel(title, description);
} }
}, },
commandButtonLabel: label, commandButtonLabel: label,

View File

@ -10,7 +10,7 @@ describe("Browse queries panel", () => {
const fakeExplorer = {} as Explorer; const fakeExplorer = {} as Explorer;
fakeExplorer.canSaveQueries = ko.computed<boolean>(() => true); fakeExplorer.canSaveQueries = ko.computed<boolean>(() => true);
const fakeClientQuery = {} as QueriesClient; const fakeClientQuery = {} as QueriesClient;
const fakeQueryData = {} as Query[]; const fakeQueryData = [] as Query[];
fakeClientQuery.getQueries = async () => fakeQueryData; fakeClientQuery.getQueries = async () => fakeQueryData;
fakeExplorer.queriesClient = fakeClientQuery; fakeExplorer.queriesClient = fakeClientQuery;
const props = { const props = {

View File

@ -4,7 +4,6 @@ import CassandraAddCollectionPaneTemplate from "./CassandraAddCollectionPane.htm
import GitHubReposPaneTemplate from "./GitHubReposPane.html"; import GitHubReposPaneTemplate from "./GitHubReposPane.html";
import GraphNewVertexPaneTemplate from "./GraphNewVertexPane.html"; import GraphNewVertexPaneTemplate from "./GraphNewVertexPane.html";
import GraphStylingPaneTemplate from "./GraphStylingPane.html"; import GraphStylingPaneTemplate from "./GraphStylingPane.html";
import SetupNotebooksPaneTemplate from "./SetupNotebooksPane.html";
import StringInputPaneTemplate from "./StringInputPane.html"; import StringInputPaneTemplate from "./StringInputPane.html";
import TableAddEntityPaneTemplate from "./Tables/TableAddEntityPane.html"; import TableAddEntityPaneTemplate from "./Tables/TableAddEntityPane.html";
import TableEditEntityPaneTemplate from "./Tables/TableEditEntityPane.html"; import TableEditEntityPaneTemplate from "./Tables/TableEditEntityPane.html";
@ -86,15 +85,6 @@ export class StringInputPaneComponent {
} }
} }
export class SetupNotebooksPaneComponent {
constructor() {
return {
viewModel: PaneComponent,
template: SetupNotebooksPaneTemplate,
};
}
}
export class GitHubReposPaneComponent { export class GitHubReposPaneComponent {
constructor() { constructor() {
return { return {

View File

@ -300,20 +300,6 @@ exports[`Settings Pane should render Default properly 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -698,20 +684,6 @@ exports[`Settings Pane should render Default properly 1`] = `
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {
@ -1185,20 +1157,6 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -1583,20 +1541,6 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {

View File

@ -1,45 +0,0 @@
<div data-bind="visible: visible, event: { keydown: onPaneKeyDown }">
<div class="contextual-pane-out" data-bind="click: cancel, clickBubble: false"></div>
<div class="contextual-pane" id="setupnotebookspane">
<!-- Setup notebooks form -- Start -->
<div class="contextual-pane-in">
<div class="paneContentContainer">
<!-- Setup notebooks header - Start -->
<div class="firstdivbg headerline">
<span role="heading" aria-level="2" data-bind="text: title"></span>
<div
class="closeImg"
role="button"
aria-label="Close pane"
tabindex="0"
data-bind="click: cancel, event: { keypress: onCloseKeyPress }"
>
<img src="../../../images/close-black.svg" title="Close" alt="Close" />
</div>
</div>
<!-- Setup notebooks header - End -->
<div class="paneMainContent">
<div class="pkPadding">
<div data-bind="text: description"></div>
<button
id="completeSetupBtn"
class="btncreatecoll1 btnSetupQueries"
type="button"
aria-label="Complete setup"
data-bind="click: onCompleteSetupClick, event: { keypress: onCompleteSetupKeyPress }"
>
Complete setup
</button>
</div>
</div>
</div>
</div>
<!-- Setup notebooks form - Start -->
<!-- Loader - Start -->
<div class="dataExplorerLoaderContainer dataExplorerPaneLoaderContainer" data-bind="visible: isExecuting">
<img class="dataExplorerLoader" alt="loading indicator image" src="/LoadingIndicator_3Squares.gif" />
</div>
<!-- Loader - End -->
</div>
</div>

View File

@ -1,107 +0,0 @@
import * as ViewModels from "../../Contracts/ViewModels";
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import { Areas, KeyCodes } from "../../Common/Constants";
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
import { ContextualPaneBase } from "./ContextualPaneBase";
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import * as ko from "knockout";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
export class SetupNotebooksPane extends ContextualPaneBase {
private description: ko.Observable<string>;
constructor(options: ViewModels.PaneOptions) {
super(options);
this.description = ko.observable<string>();
this.resetData();
}
public openWithTitleAndDescription(title: string, description: string) {
this.title(title);
this.description(description);
this.open();
}
public open() {
super.open();
const completeSetupBtn = document.getElementById("completeSetupBtn");
completeSetupBtn && completeSetupBtn.focus();
}
public submit() {
// override default behavior because this is not a form
}
public onCompleteSetupClick = async (src: any, event: MouseEvent) => {
await this.setupNotebookWorkspace();
};
public onCompleteSetupKeyPress = async (src: any, event: KeyboardEvent) => {
if (event.keyCode === KeyCodes.Space || event.keyCode === KeyCodes.Enter) {
await this.setupNotebookWorkspace();
event.stopPropagation();
return false;
}
return true;
};
public async setupNotebookWorkspace(): Promise<void> {
if (!this.container) {
return;
}
const startKey: number = TelemetryProcessor.traceStart(Action.CreateNotebookWorkspace, {
dataExplorerArea: Areas.ContextualPane,
paneTitle: this.title(),
});
const id = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
"Creating a new default notebook workspace"
);
try {
this.isExecuting(true);
await this.container.notebookWorkspaceManager.createNotebookWorkspaceAsync(
this.container.databaseAccount() && this.container.databaseAccount().id,
"default"
);
this.container.isAccountReady.valueHasMutated(); // re-trigger init notebooks
this.close();
TelemetryProcessor.traceSuccess(
Action.CreateNotebookWorkspace,
{
dataExplorerArea: Areas.ContextualPane,
paneTitle: this.title(),
},
startKey
);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Info,
"Successfully created a default notebook workspace for the account"
);
} catch (error) {
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure(
Action.CreateNotebookWorkspace,
{
dataExplorerArea: Areas.ContextualPane,
paneTitle: this.title(),
error: errorMessage,
errorStack: getErrorStack(error),
},
startKey
);
this.formErrors("Failed to setup a default notebook workspace");
this.formErrorsDetails(`Failed to setup a default notebook workspace: ${errorMessage}`);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Failed to create a default notebook workspace: ${errorMessage}`
);
} finally {
this.isExecuting(false);
NotificationConsoleUtils.clearInProgressMessageWithId(id);
}
}
}

View File

@ -0,0 +1,50 @@
import { mount } from "enzyme";
import { PrimaryButton } from "office-ui-fabric-react";
import React from "react";
import Explorer from "../../Explorer";
import { SetupNoteBooksPanel } from "./SetupNotebooksPanel";
describe("Setup Notebooks Panel", () => {
it("should render Default properly", () => {
const fakeExplorer = {} as Explorer;
const props = {
explorer: fakeExplorer,
closePanel: (): void => undefined,
openNotificationConsole: (): void => undefined,
panelTitle: "",
panelDescription: "",
};
const wrapper = mount(<SetupNoteBooksPanel {...props} />);
expect(wrapper).toMatchSnapshot();
});
it("should render button", () => {
const fakeExplorer = {} as Explorer;
const props = {
explorer: fakeExplorer,
closePanel: (): void => undefined,
openNotificationConsole: (): void => undefined,
panelTitle: "",
panelDescription: "",
};
const wrapper = mount(<SetupNoteBooksPanel {...props} />);
const button = wrapper.find("PrimaryButton").first();
expect(button).toBeDefined();
});
it("Button onClick should call onCompleteSetup", () => {
const onCompleteSetupClick = jest.fn();
const wrapper = mount(<PrimaryButton onClick={onCompleteSetupClick} />);
wrapper.find("button").simulate("click");
expect(onCompleteSetupClick).toHaveBeenCalled();
});
it("Button onKeyPress should call onCompleteSetupKeyPress", () => {
const onCompleteSetupKeyPress = jest.fn();
const wrapper = mount(<PrimaryButton onKeyPress={onCompleteSetupKeyPress} />);
wrapper.find("button").simulate("keypress");
expect(onCompleteSetupKeyPress).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,125 @@
import { useBoolean } from "@uifabric/react-hooks";
import { PrimaryButton } from "office-ui-fabric-react";
import React, { FunctionComponent, KeyboardEvent, useState } from "react";
import { Areas, NormalizedEventKey } from "../../../Common/Constants";
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
import { userContext } from "../../../UserContext";
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
import Explorer from "../../Explorer";
import { PanelInfoErrorComponent } from "../PanelInfoErrorComponent";
import { PanelLoadingScreen } from "../PanelLoadingScreen";
interface SetupNoteBooksPanelProps {
explorer: Explorer;
closePanel: () => void;
openNotificationConsole: () => void;
panelTitle: string;
panelDescription: string;
}
export const SetupNoteBooksPanel: FunctionComponent<SetupNoteBooksPanelProps> = ({
explorer,
closePanel,
openNotificationConsole,
panelTitle,
panelDescription,
}: SetupNoteBooksPanelProps): JSX.Element => {
const title = panelTitle;
const description = panelDescription;
const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false);
const [errorMessage, setErrorMessage] = useState<string>("");
const [showErrorDetails, setShowErrorDetails] = useState<boolean>(false);
const onCompleteSetupClick = async () => {
await setupNotebookWorkspace();
};
const onCompleteSetupKeyPress = async (event: KeyboardEvent<HTMLButtonElement>) => {
if (event.key === " " || event.key === NormalizedEventKey.Enter) {
await setupNotebookWorkspace();
event.stopPropagation();
return false;
}
return true;
};
const setupNotebookWorkspace = async (): Promise<void> => {
if (!explorer) {
return;
}
const startKey: number = TelemetryProcessor.traceStart(Action.CreateNotebookWorkspace, {
dataExplorerArea: Areas.ContextualPane,
paneTitle: title,
});
const clear = NotificationConsoleUtils.logConsoleProgress("Creating a new default notebook workspace");
try {
setLoadingTrue();
await explorer.notebookWorkspaceManager.createNotebookWorkspaceAsync(
userContext.databaseAccount && userContext.databaseAccount.id,
"default"
);
explorer.isAccountReady.valueHasMutated(); // re-trigger init notebooks
closePanel();
TelemetryProcessor.traceSuccess(
Action.CreateNotebookWorkspace,
{
dataExplorerArea: Areas.ContextualPane,
paneTitle: title,
},
startKey
);
NotificationConsoleUtils.logConsoleInfo("Successfully created a default notebook workspace for the account");
} catch (error) {
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure(
Action.CreateNotebookWorkspace,
{
dataExplorerArea: Areas.ContextualPane,
paneTitle: title,
error: errorMessage,
errorStack: getErrorStack(error),
},
startKey
);
setErrorMessage(`Failed to setup a default notebook workspace: ${errorMessage}`);
setShowErrorDetails(true);
NotificationConsoleUtils.logConsoleError(`Failed to create a default notebook workspace: ${errorMessage}`);
} finally {
setLoadingFalse();
clear();
}
};
return (
<form className="panelFormWrapper">
{errorMessage && (
<PanelInfoErrorComponent
message={errorMessage}
messageType="error"
showErrorDetails={showErrorDetails}
openNotificationConsole={openNotificationConsole}
/>
)}
<div className="panelMainContent">
<div className="pkPadding">
<div>{description}</div>
<PrimaryButton
id="completeSetupBtn"
className="btncreatecoll1 btnSetupQueries"
text="Complete Setup"
onClick={onCompleteSetupClick}
onKeyPress={onCompleteSetupKeyPress}
aria-label="Complete setup"
/>
</div>
</div>
{isLoading && <PanelLoadingScreen />}
</form>
);
};

View File

@ -300,20 +300,6 @@ exports[`Upload Items Pane should render Default properly 1`] = `
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -698,20 +684,6 @@ exports[`Upload Items Pane should render Default properly 1`] = `
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {

View File

@ -301,20 +301,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
"title": [Function], "title": [Function],
"visible": [Function], "visible": [Function],
}, },
SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
], ],
"_refreshSparkEnabledStateForAccount": [Function], "_refreshSparkEnabledStateForAccount": [Function],
"_resetNotebookWorkspace": [Function], "_resetNotebookWorkspace": [Function],
@ -703,20 +689,6 @@ exports[`Delete Database Confirmation Pane submit() Should call delete database
"setInProgressConsoleDataIdToBeDeleted": undefined, "setInProgressConsoleDataIdToBeDeleted": undefined,
"setIsNotificationConsoleExpanded": undefined, "setIsNotificationConsoleExpanded": undefined,
"setNotificationConsoleData": undefined, "setNotificationConsoleData": undefined,
"setupNotebooksPane": SetupNotebooksPane {
"container": [Circular],
"description": [Function],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "setupnotebookspane",
"isExecuting": [Function],
"isTemplateReady": [Function],
"onCompleteSetupClick": [Function],
"onCompleteSetupKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"signInAad": [Function], "signInAad": [Function],
"sparkClusterConnectionInfo": [Function], "sparkClusterConnectionInfo": [Function],
"splitter": Splitter { "splitter": Splitter {

View File

@ -238,7 +238,6 @@ const App: React.FunctionComponent = () => {
<div data-bind='component: { name: "table-edit-entity-pane", params: { data: editTableEntityPane} }' /> <div data-bind='component: { name: "table-edit-entity-pane", params: { data: editTableEntityPane} }' />
<div data-bind='component: { name: "cassandra-add-collection-pane", params: { data: cassandraAddCollectionPane} }' /> <div data-bind='component: { name: "cassandra-add-collection-pane", params: { data: cassandraAddCollectionPane} }' />
<div data-bind='component: { name: "string-input-pane", params: { data: stringInputPane} }' /> <div data-bind='component: { name: "string-input-pane", params: { data: stringInputPane} }' />
<div data-bind='component: { name: "setup-notebooks-pane", params: { data: setupNotebooksPane} }' />
<KOCommentIfStart if="isGitHubPaneEnabled" /> <KOCommentIfStart if="isGitHubPaneEnabled" />
<div data-bind='component: { name: "github-repos-pane", params: { data: gitHubReposPane } }' /> <div data-bind='component: { name: "github-repos-pane", params: { data: gitHubReposPane } }' />
<KOCommentEnd /> <KOCommentEnd />