mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-28 06:04:25 +00:00
Compare commits
2 Commits
v-yiq
...
user/swvis
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6852515b7c | ||
|
|
b1862bb566 |
20302
package-lock.json
generated
20302
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
42
package.json
42
package.json
@@ -6,26 +6,26 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/cosmos": "3.9.0",
|
"@azure/cosmos": "3.9.0",
|
||||||
"@azure/cosmos-language-service": "0.0.4",
|
"@azure/cosmos-language-service": "0.0.4",
|
||||||
"@jupyterlab/services": "6.0.0-rc.2",
|
"@jupyterlab/services": "4.2.0",
|
||||||
"@jupyterlab/terminal": "3.0.0-rc.2",
|
"@jupyterlab/terminal": "1.2.1",
|
||||||
"@microsoft/applicationinsights-web": "2.5.8",
|
"@microsoft/applicationinsights-web": "2.5.8",
|
||||||
"@nteract/commutable": "7.3.2",
|
"@nteract/commutable": "7.1.4",
|
||||||
"@nteract/connected-components": "6.8.2",
|
"@nteract/connected-components": "6.7.8",
|
||||||
"@nteract/core": "15.1.0",
|
"@nteract/core": "13.0.0",
|
||||||
"@nteract/data-explorer": "8.0.3",
|
"@nteract/data-explorer": "8.0.3",
|
||||||
"@nteract/directory-listing": "2.0.6",
|
"@nteract/directory-listing": "2.0.6",
|
||||||
"@nteract/dropdown-menu": "1.0.1",
|
"@nteract/dropdown-menu": "1.0.1",
|
||||||
"@nteract/editor": "10.1.2",
|
"@nteract/editor": "9.6.6",
|
||||||
"@nteract/fixtures": "2.3.0",
|
"@nteract/fixtures": "2.3.0",
|
||||||
"@nteract/iron-icons": "1.0.0",
|
"@nteract/iron-icons": "1.0.0",
|
||||||
"@nteract/jupyter-widgets": "2.0.0",
|
"@nteract/jupyter-widgets": "2.0.0",
|
||||||
"@nteract/logos": "1.0.0",
|
"@nteract/logos": "1.0.0",
|
||||||
"@nteract/markdown": "4.4.0",
|
"@nteract/markdown": "4.4.0",
|
||||||
"@nteract/monaco-editor": "3.2.0",
|
"@nteract/monaco-editor": "3.0.3",
|
||||||
"@nteract/octicons": "2.0.0",
|
"@nteract/octicons": "2.0.0",
|
||||||
"@nteract/outputs": "3.0.9",
|
"@nteract/outputs": "3.0.9",
|
||||||
"@nteract/presentational-components": "3.0.7",
|
"@nteract/presentational-components": "3.0.7",
|
||||||
"@nteract/stateful-components": "1.7.0",
|
"@nteract/stateful-components": "1.4.0",
|
||||||
"@nteract/styles": "2.0.2",
|
"@nteract/styles": "2.0.2",
|
||||||
"@nteract/transform-geojson": "5.1.8",
|
"@nteract/transform-geojson": "5.1.8",
|
||||||
"@nteract/transform-model-debug": "5.0.1",
|
"@nteract/transform-model-debug": "5.0.1",
|
||||||
@@ -42,12 +42,12 @@
|
|||||||
"applicationinsights": "1.8.0",
|
"applicationinsights": "1.8.0",
|
||||||
"babel-polyfill": "6.26.0",
|
"babel-polyfill": "6.26.0",
|
||||||
"bootstrap": "3.4.1",
|
"bootstrap": "3.4.1",
|
||||||
|
"botframework-webchat": "4.10.1",
|
||||||
"canvas": "2.6.1",
|
"canvas": "2.6.1",
|
||||||
"clean-webpack-plugin": "0.1.19",
|
"clean-webpack-plugin": "0.1.19",
|
||||||
"copy-webpack-plugin": "6.0.2",
|
"copy-webpack-plugin": "6.0.2",
|
||||||
"crossroads": "0.12.2",
|
"crossroads": "0.12.2",
|
||||||
"css-element-queries": "1.1.1",
|
"css-element-queries": "1.1.1",
|
||||||
"d3": "6.1.1",
|
|
||||||
"datatables.net-colreorder-dt": "1.5.1",
|
"datatables.net-colreorder-dt": "1.5.1",
|
||||||
"datatables.net-dt": "1.10.19",
|
"datatables.net-dt": "1.10.19",
|
||||||
"date-fns": "1.29.0",
|
"date-fns": "1.29.0",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"promise-polyfill": "8.1.0",
|
"promise-polyfill": "8.1.0",
|
||||||
"promise.prototype.finally": "3.1.0",
|
"promise.prototype.finally": "3.1.0",
|
||||||
"q": "1.5.1",
|
"q": "1.5.1",
|
||||||
"react": "16.13.1",
|
"react": "16.9.0",
|
||||||
"react-animate-height": "2.0.8",
|
"react-animate-height": "2.0.8",
|
||||||
"react-dnd": "9.4.0",
|
"react-dnd": "9.4.0",
|
||||||
"react-dnd-html5-backend": "9.4.0",
|
"react-dnd-html5-backend": "9.4.0",
|
||||||
@@ -83,12 +83,11 @@
|
|||||||
"react-notification-system": "0.2.17",
|
"react-notification-system": "0.2.17",
|
||||||
"react-redux": "7.1.3",
|
"react-redux": "7.1.3",
|
||||||
"redux": "4.0.4",
|
"redux": "4.0.4",
|
||||||
"rx-jupyter": "5.5.12",
|
"rx-jupyter": "5.5.2",
|
||||||
"rxjs": "6.6.3",
|
"rxjs": "6.5.3",
|
||||||
"styled-components": "4.3.2",
|
"styled-components": "4.3.2",
|
||||||
"text-encoding": "0.7.0",
|
"text-encoding": "0.7.0",
|
||||||
"underscore": "1.9.1",
|
"underscore": "1.9.1",
|
||||||
"utility-types": "3.10.0",
|
|
||||||
"url-polyfill": "1.1.7",
|
"url-polyfill": "1.1.7",
|
||||||
"webcrypto-liner": "1.1.4",
|
"webcrypto-liner": "1.1.4",
|
||||||
"webfontloader": "1.6.28",
|
"webfontloader": "1.6.28",
|
||||||
@@ -102,9 +101,9 @@
|
|||||||
"@types/applicationinsights-js": "1.0.7",
|
"@types/applicationinsights-js": "1.0.7",
|
||||||
"@types/codemirror": "0.0.56",
|
"@types/codemirror": "0.0.56",
|
||||||
"@types/crossroads": "0.0.30",
|
"@types/crossroads": "0.0.30",
|
||||||
"@types/d3": "5.9.2",
|
"@types/d3": "4.13.2",
|
||||||
"@types/enzyme": "3.10.7",
|
"@types/enzyme": "3.10.3",
|
||||||
"@types/enzyme-adapter-react-16": "1.0.6",
|
"@types/enzyme-adapter-react-16": "1.0.5",
|
||||||
"@types/expect-puppeteer": "4.4.3",
|
"@types/expect-puppeteer": "4.4.3",
|
||||||
"@types/hasher": "0.0.31",
|
"@types/hasher": "0.0.31",
|
||||||
"@types/jest": "23.3.10",
|
"@types/jest": "23.3.10",
|
||||||
@@ -115,7 +114,7 @@
|
|||||||
"@types/prop-types": "15.5.8",
|
"@types/prop-types": "15.5.8",
|
||||||
"@types/puppeteer": "3.0.1",
|
"@types/puppeteer": "3.0.1",
|
||||||
"@types/q": "1.5.1",
|
"@types/q": "1.5.1",
|
||||||
"@types/react": "16.9.49",
|
"@types/react": "16.8.25",
|
||||||
"@types/react-dom": "16.0.7",
|
"@types/react-dom": "16.0.7",
|
||||||
"@types/react-notification-system": "0.2.39",
|
"@types/react-notification-system": "0.2.39",
|
||||||
"@types/react-redux": "7.1.7",
|
"@types/react-redux": "7.1.7",
|
||||||
@@ -134,9 +133,10 @@
|
|||||||
"case-sensitive-paths-webpack-plugin": "2.3.0",
|
"case-sensitive-paths-webpack-plugin": "2.3.0",
|
||||||
"create-file-webpack": "1.0.2",
|
"create-file-webpack": "1.0.2",
|
||||||
"css-loader": "1.0.0",
|
"css-loader": "1.0.0",
|
||||||
"enzyme": "3.11.0",
|
"d3": "4.13.0",
|
||||||
"enzyme-adapter-react-16": "1.15.5",
|
"enzyme": "3.10.0",
|
||||||
"enzyme-to-json": "3.6.1",
|
"enzyme-adapter-react-16": "1.15.1",
|
||||||
|
"enzyme-to-json": "3.4.3",
|
||||||
"eslint": "7.8.1",
|
"eslint": "7.8.1",
|
||||||
"eslint-cli": "1.1.1",
|
"eslint-cli": "1.1.1",
|
||||||
"eslint-plugin-no-null": "1.0.2",
|
"eslint-plugin-no-null": "1.0.2",
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
"less-vars-loader": "1.1.0",
|
"less-vars-loader": "1.1.0",
|
||||||
"mini-css-extract-plugin": "0.4.3",
|
"mini-css-extract-plugin": "0.4.3",
|
||||||
"monaco-editor-webpack-plugin": "1.7.0",
|
"monaco-editor-webpack-plugin": "1.7.0",
|
||||||
"node-fetch": "2.6.1",
|
"node-fetch": "2.6.0",
|
||||||
"prettier": "1.19.1",
|
"prettier": "1.19.1",
|
||||||
"puppeteer": "4.0.0",
|
"puppeteer": "4.0.0",
|
||||||
"raw-loader": "0.5.1",
|
"raw-loader": "0.5.1",
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ interface ConfigContext {
|
|||||||
GITHUB_CLIENT_ID: string;
|
GITHUB_CLIENT_ID: string;
|
||||||
GITHUB_CLIENT_SECRET?: string; // No need to inject secret for prod. Juno already knows it.
|
GITHUB_CLIENT_SECRET?: string; // No need to inject secret for prod. Juno already knows it.
|
||||||
hostedExplorerURL: string;
|
hostedExplorerURL: string;
|
||||||
armAPIVersion?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default configuration
|
// Default configuration
|
||||||
@@ -94,10 +93,6 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
|||||||
}
|
}
|
||||||
// Allow override of platform value with URL query parameter
|
// Allow override of platform value with URL query parameter
|
||||||
const params = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
if (params.has("armAPIVersion")) {
|
|
||||||
const armAPIVersion = params.get("armAPIVersion") || "";
|
|
||||||
updateConfigContext({ armAPIVersion });
|
|
||||||
}
|
|
||||||
if (params.has("platform")) {
|
if (params.has("platform")) {
|
||||||
const platform = params.get("platform");
|
const platform = params.get("platform");
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
|
|||||||
@@ -78,3 +78,4 @@ ko.components.register("upload-file-pane", new PaneComponents.UploadFilePaneComp
|
|||||||
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("setup-notebooks-pane", new PaneComponents.SetupNotebooksPaneComponent());
|
||||||
ko.components.register("github-repos-pane", new PaneComponents.GitHubReposPaneComponent());
|
ko.components.register("github-repos-pane", new PaneComponents.GitHubReposPaneComponent());
|
||||||
|
ko.components.register("support-pane", new PaneComponents.SupportPaneComponent());
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ exports[`GalleryCardComponent renders 1`] = `
|
|||||||
/>
|
/>
|
||||||
</CardItem>
|
</CardItem>
|
||||||
<CardItem>
|
<CardItem>
|
||||||
<StyledImageBase
|
<Memo(StyledImageBase)
|
||||||
alt="name cover image"
|
alt="name cover image"
|
||||||
height={144}
|
height={144}
|
||||||
imageFit={2}
|
imageFit={2}
|
||||||
@@ -95,7 +95,7 @@ exports[`GalleryCardComponent renders 1`] = `
|
|||||||
}
|
}
|
||||||
variant="tiny"
|
variant="tiny"
|
||||||
>
|
>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
iconName="RedEye"
|
iconName="RedEye"
|
||||||
styles={
|
styles={
|
||||||
Object {
|
Object {
|
||||||
@@ -119,7 +119,7 @@ exports[`GalleryCardComponent renders 1`] = `
|
|||||||
}
|
}
|
||||||
variant="tiny"
|
variant="tiny"
|
||||||
>
|
>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
iconName="Download"
|
iconName="Download"
|
||||||
styles={
|
styles={
|
||||||
Object {
|
Object {
|
||||||
@@ -143,7 +143,7 @@ exports[`GalleryCardComponent renders 1`] = `
|
|||||||
}
|
}
|
||||||
variant="tiny"
|
variant="tiny"
|
||||||
>
|
>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
iconName="Heart"
|
iconName="Heart"
|
||||||
styles={
|
styles={
|
||||||
Object {
|
Object {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ exports[`InfoComponent renders 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="infoPanelMain"
|
className="infoPanelMain"
|
||||||
>
|
>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
className="infoIconMain"
|
className="infoIconMain"
|
||||||
iconName="Help"
|
iconName="Help"
|
||||||
styles={
|
styles={
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export class NotebookViewerComponent extends React.Component<
|
|||||||
databaseAccountName: undefined,
|
databaseAccountName: undefined,
|
||||||
defaultExperience: "NotebookViewer",
|
defaultExperience: "NotebookViewer",
|
||||||
isReadOnly: true,
|
isReadOnly: true,
|
||||||
cellEditorType: "monaco",
|
cellEditorType: "codemirror",
|
||||||
autoSaveInterval: 365 * 24 * 3600 * 1000, // There is no way to turn off auto-save, set to 1 year
|
autoSaveInterval: 365 * 24 * 3600 * 1000, // There is no way to turn off auto-save, set to 1 year
|
||||||
contentProvider: contents.JupyterContentProvider // NotebookViewer only knows how to talk to Jupyter contents API
|
contentProvider: contents.JupyterContentProvider // NotebookViewer only knows how to talk to Jupyter contents API
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ exports[`NotebookMetadataComponent renders liked notebook 1`] = `
|
|||||||
Invalid Date
|
Invalid Date
|
||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
iconName="RedEye"
|
iconName="RedEye"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
0
|
0
|
||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
iconName="Download"
|
iconName="Download"
|
||||||
/>
|
/>
|
||||||
0
|
0
|
||||||
@@ -156,14 +156,14 @@ exports[`NotebookMetadataComponent renders un-liked notebook 1`] = `
|
|||||||
Invalid Date
|
Invalid Date
|
||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
iconName="RedEye"
|
iconName="RedEye"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
0
|
0
|
||||||
</Text>
|
</Text>
|
||||||
<Text>
|
<Text>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
iconName="Download"
|
iconName="Download"
|
||||||
/>
|
/>
|
||||||
0
|
0
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ exports[`ToolTipLabelComponent renders 1`] = `
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<StyledIconBase
|
<Memo(StyledIconBase)
|
||||||
ariaLabel="Info"
|
ariaLabel="Info"
|
||||||
iconName="Info"
|
iconName="Info"
|
||||||
styles={
|
styles={
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import * as _ from "underscore";
|
||||||
|
import React from "react";
|
||||||
|
import ReactWebChat, { createDirectLine } from "botframework-webchat";
|
||||||
|
|
||||||
|
export interface SupportPaneComponentProps {
|
||||||
|
directLineToken: string;
|
||||||
|
userToken: string;
|
||||||
|
subId: string;
|
||||||
|
rg:string;
|
||||||
|
accName:string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SupportPaneComponent extends React.Component<SupportPaneComponentProps> {
|
||||||
|
private readonly userId: string = _.uniqueId();
|
||||||
|
|
||||||
|
|
||||||
|
constructor(props: SupportPaneComponentProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
const styleOptions = {
|
||||||
|
bubbleBackground: "rgba(0, 0, 255, .1)",
|
||||||
|
bubbleFromUserBackground: "rgba(0, 255, 0, .1)"
|
||||||
|
};
|
||||||
|
|
||||||
|
const directLine = createDirectLine({ token: this.props.directLineToken });
|
||||||
|
const dl =
|
||||||
|
{
|
||||||
|
...directLine,
|
||||||
|
postActivity: (activity: any) => {
|
||||||
|
// Add whatever needs to be added.
|
||||||
|
activity.channelData.token = this.props.userToken;
|
||||||
|
activity.channelData.subId = this.props.subId;
|
||||||
|
activity.channelData.rg = this.props.rg;
|
||||||
|
activity.channelData.accName = this.props.accName;
|
||||||
|
|
||||||
|
//activity.channelData.MyKey = "hello";
|
||||||
|
return directLine.postActivity(activity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return <ReactWebChat directLine={dl} userid={this.userId} styleOptions={styleOptions}/>;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import * as ko from "knockout";
|
||||||
|
import * as React from "react";
|
||||||
|
import { ReactAdapter } from "../../../Bindings/ReactBindingHandler";
|
||||||
|
import Explorer from "../../Explorer";
|
||||||
|
import { SupportPaneComponent } from "./SupportPaneComponent";
|
||||||
|
import { userContext } from "../../../UserContext";
|
||||||
|
|
||||||
|
export interface SupportPaneComponentParams {
|
||||||
|
directLineAccessToken: string;
|
||||||
|
userToken: string;
|
||||||
|
subId: string;
|
||||||
|
rg: string;
|
||||||
|
accName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SupportPaneComponentAdapter implements ReactAdapter {
|
||||||
|
public parameters: ko.Observable<SupportPaneComponentParams>;
|
||||||
|
|
||||||
|
constructor(private container: Explorer) {
|
||||||
|
|
||||||
|
this.parameters = ko.observable<SupportPaneComponentParams>({
|
||||||
|
directLineAccessToken: this.container.conversationToken(),
|
||||||
|
userToken: this.container.userToken(),
|
||||||
|
subId: this.container.subId(),
|
||||||
|
rg: this.container.rg(),
|
||||||
|
accName: this.container.accName()
|
||||||
|
});
|
||||||
|
this.container.conversationToken.subscribe(accessToken => {
|
||||||
|
this.parameters().directLineAccessToken = accessToken;
|
||||||
|
this.forceRender();
|
||||||
|
});
|
||||||
|
this.container.userToken.subscribe(userToken => {
|
||||||
|
this.parameters().userToken = userToken;
|
||||||
|
this.forceRender();
|
||||||
|
});
|
||||||
|
this.container.subId.subscribe(subId => {
|
||||||
|
this.parameters().subId = subId;
|
||||||
|
this.forceRender();
|
||||||
|
});
|
||||||
|
this.container.rg.subscribe(rg => {
|
||||||
|
this.parameters().rg = rg;
|
||||||
|
this.forceRender();
|
||||||
|
});
|
||||||
|
this.container.accName.subscribe(accName => {
|
||||||
|
this.parameters().accName = accName;
|
||||||
|
this.forceRender();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public renderComponent(): JSX.Element {
|
||||||
|
return <SupportPaneComponent
|
||||||
|
directLineToken={this.parameters().directLineAccessToken}
|
||||||
|
userToken={this.parameters().userToken}
|
||||||
|
subId={this.parameters().subId}
|
||||||
|
rg={this.parameters().rg}
|
||||||
|
accName={this.parameters().accName}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
|
||||||
|
public forceRender(): void {
|
||||||
|
this.parameters.valueHasMutated();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -69,6 +69,7 @@ import { RouteHandler } from "../RouteHandlers/RouteHandler";
|
|||||||
import { SaveQueryPane } from "./Panes/SaveQueryPane";
|
import { SaveQueryPane } from "./Panes/SaveQueryPane";
|
||||||
import { SettingsPane } from "./Panes/SettingsPane";
|
import { SettingsPane } from "./Panes/SettingsPane";
|
||||||
import { SetupNotebooksPane } from "./Panes/SetupNotebooksPane";
|
import { SetupNotebooksPane } from "./Panes/SetupNotebooksPane";
|
||||||
|
import { SupportPane } from "./Panes/SupportPane";
|
||||||
import { SplashScreenComponentAdapter } from "./SplashScreen/SplashScreenComponentApdapter";
|
import { SplashScreenComponentAdapter } from "./SplashScreen/SplashScreenComponentApdapter";
|
||||||
import { Splitter, SplitterBounds, SplitterDirection } from "../Common/Splitter";
|
import { Splitter, SplitterBounds, SplitterDirection } from "../Common/Splitter";
|
||||||
import { StringInputPane } from "./Panes/StringInputPane";
|
import { StringInputPane } from "./Panes/StringInputPane";
|
||||||
@@ -175,6 +176,11 @@ export default class Explorer {
|
|||||||
public isAuthWithResourceToken: ko.Observable<boolean>;
|
public isAuthWithResourceToken: ko.Observable<boolean>;
|
||||||
public isResourceTokenCollectionNodeSelected: ko.Computed<boolean>;
|
public isResourceTokenCollectionNodeSelected: ko.Computed<boolean>;
|
||||||
private resourceTreeForResourceToken: ResourceTreeAdapterForResourceToken;
|
private resourceTreeForResourceToken: ResourceTreeAdapterForResourceToken;
|
||||||
|
public conversationToken: ko.Observable<string>;
|
||||||
|
public userToken: ko.Observable<string>;
|
||||||
|
public subId: ko.Observable<string>;
|
||||||
|
public rg: ko.Observable<string>;
|
||||||
|
public accName: ko.Observable<string>;
|
||||||
|
|
||||||
// Tabs
|
// Tabs
|
||||||
public isTabsContentExpanded: ko.Observable<boolean>;
|
public isTabsContentExpanded: ko.Observable<boolean>;
|
||||||
@@ -195,6 +201,7 @@ export default class Explorer {
|
|||||||
public newVertexPane: NewVertexPane;
|
public newVertexPane: NewVertexPane;
|
||||||
public cassandraAddCollectionPane: CassandraAddCollectionPane;
|
public cassandraAddCollectionPane: CassandraAddCollectionPane;
|
||||||
public settingsPane: SettingsPane;
|
public settingsPane: SettingsPane;
|
||||||
|
public supportPane: SupportPane;
|
||||||
public executeSprocParamsPane: ExecuteSprocParamsPane;
|
public executeSprocParamsPane: ExecuteSprocParamsPane;
|
||||||
public renewAdHocAccessPane: RenewAdHocAccessPane;
|
public renewAdHocAccessPane: RenewAdHocAccessPane;
|
||||||
public uploadItemsPane: UploadItemsPane;
|
public uploadItemsPane: UploadItemsPane;
|
||||||
@@ -325,10 +332,16 @@ export default class Explorer {
|
|||||||
this.hasStorageAnalyticsAfecFeature = ko.observable(false);
|
this.hasStorageAnalyticsAfecFeature = ko.observable(false);
|
||||||
this.hasStorageAnalyticsAfecFeature.subscribe((enabled: boolean) => this.refreshCommandBarButtons());
|
this.hasStorageAnalyticsAfecFeature.subscribe((enabled: boolean) => this.refreshCommandBarButtons());
|
||||||
this.isSynapseLinkUpdating = ko.observable<boolean>(false);
|
this.isSynapseLinkUpdating = ko.observable<boolean>(false);
|
||||||
|
this.conversationToken = ko.observable<string>();
|
||||||
|
this.userToken = ko.observable<string>();
|
||||||
|
this.subId = ko.observable<string>();
|
||||||
|
this.rg = ko.observable<string>();
|
||||||
|
this.accName = ko.observable<string>();
|
||||||
this.isAccountReady.subscribe(async (isAccountReady: boolean) => {
|
this.isAccountReady.subscribe(async (isAccountReady: boolean) => {
|
||||||
if (isAccountReady) {
|
if (isAccountReady) {
|
||||||
this.isAuthWithResourceToken() ? this.refreshDatabaseForResourceToken() : this.refreshAllDatabases(true);
|
this.isAuthWithResourceToken() ? this.refreshDatabaseForResourceToken() : this.refreshAllDatabases(true);
|
||||||
RouteHandler.getInstance().initHandler();
|
RouteHandler.getInstance().initHandler();
|
||||||
|
this.generateConversationToken();
|
||||||
this.notebookWorkspaceManager = new NotebookWorkspaceManager(this.armEndpoint());
|
this.notebookWorkspaceManager = new NotebookWorkspaceManager(this.armEndpoint());
|
||||||
this.arcadiaWorkspaces = ko.observableArray();
|
this.arcadiaWorkspaces = ko.observableArray();
|
||||||
this._arcadiaManager = new ArcadiaResourceManager(this.armEndpoint());
|
this._arcadiaManager = new ArcadiaResourceManager(this.armEndpoint());
|
||||||
@@ -702,6 +715,12 @@ export default class Explorer {
|
|||||||
container: this
|
container: this
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.supportPane = new SupportPane({
|
||||||
|
id: "supportpane",
|
||||||
|
visible: ko.observable<boolean>(false),
|
||||||
|
container: this
|
||||||
|
});
|
||||||
|
|
||||||
this.executeSprocParamsPane = new ExecuteSprocParamsPane({
|
this.executeSprocParamsPane = new ExecuteSprocParamsPane({
|
||||||
id: "executesprocparamspane",
|
id: "executesprocparamspane",
|
||||||
visible: ko.observable<boolean>(false),
|
visible: ko.observable<boolean>(false),
|
||||||
@@ -1592,6 +1611,52 @@ export default class Explorer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async generateConversationToken() {
|
||||||
|
const response = await fetch("https://directline.botframework.com/v3/directline/tokens/generate", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
[Constants.HttpHeaders.authorization]: "Bearer BSjLmJJHZRA.PxahjJGCNOKl7q9tiodWyVcqJOIzG894vAAqCme639o",
|
||||||
|
Accept: "application/json",
|
||||||
|
[Constants.HttpHeaders.contentType]: "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"user": {
|
||||||
|
"id": `dl_${_.uniqueId()}`,
|
||||||
|
"name": this.getUserName()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(await response.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokenResponse: { conversationId: string; token: string; expires_in: number } = await response.json();
|
||||||
|
this.conversationToken(tokenResponse?.token);
|
||||||
|
if (tokenResponse?.expires_in) {
|
||||||
|
setTimeout(() => this.generateConversationToken(), (tokenResponse?.expires_in - 1000) * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getUserName() {
|
||||||
|
const accessToken = userContext?.authorizationToken;
|
||||||
|
if (!accessToken) {
|
||||||
|
return "Cosmos DB User";
|
||||||
|
}
|
||||||
|
|
||||||
|
let name;
|
||||||
|
try {
|
||||||
|
const tokenPayload = decryptJWTToken(accessToken);
|
||||||
|
if (tokenPayload && tokenPayload.hasOwnProperty("name")) {
|
||||||
|
name = tokenPayload.name;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// ignore
|
||||||
|
} finally {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _getArcadiaWorkspaces(): Promise<ArcadiaWorkspaceItem[]> {
|
private async _getArcadiaWorkspaces(): Promise<ArcadiaWorkspaceItem[]> {
|
||||||
try {
|
try {
|
||||||
const workspaces = await this._arcadiaManager.listWorkspacesAsync([userContext.subscriptionId]);
|
const workspaces = await this._arcadiaManager.listWorkspacesAsync([userContext.subscriptionId]);
|
||||||
@@ -1940,6 +2005,11 @@ export default class Explorer {
|
|||||||
resourceGroup: inputs.resourceGroup,
|
resourceGroup: inputs.resourceGroup,
|
||||||
subscriptionId: inputs.subscriptionId
|
subscriptionId: inputs.subscriptionId
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.userToken(userContext.authorizationToken);
|
||||||
|
this.subId(userContext.subscriptionId);
|
||||||
|
this.rg(userContext.resourceGroup);
|
||||||
|
this.accName(userContext.databaseAccount.name);
|
||||||
TelemetryProcessor.traceSuccess(
|
TelemetryProcessor.traceSuccess(
|
||||||
Action.LoadDatabaseAccount,
|
Action.LoadDatabaseAccount,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import * as ko from "knockout";
|
import * as ko from "knockout";
|
||||||
import Q from "q";
|
import Q from "q";
|
||||||
import { schemeCategory10 } from "d3-scale-chromatic";
|
import { schemeCategory20 } from "d3";
|
||||||
import { selectAll, select } from "d3-selection";
|
import { event as d3Event, selectAll, select } from "d3-selection";
|
||||||
import { zoom, zoomIdentity } from "d3-zoom";
|
import { zoom, zoomIdentity } from "d3-zoom";
|
||||||
import { scaleOrdinal } from "d3-scale";
|
import { scaleOrdinal } from "d3-scale";
|
||||||
import { forceSimulation, forceLink, forceCollide, forceManyBody } from "d3-force";
|
import { forceSimulation, forceLink, forceCollide, forceManyBody } from "d3-force";
|
||||||
import { interpolateNumber, interpolate } from "d3-interpolate";
|
import { interpolateNumber, interpolate } from "d3-interpolate";
|
||||||
import { map as d3Map } from "d3-collection";
|
import { map as d3Map } from "d3-collection";
|
||||||
import { drag, D3DragEvent } from "d3-drag";
|
import { drag } from "d3-drag";
|
||||||
|
|
||||||
import _ from "underscore";
|
import _ from "underscore";
|
||||||
import { NeighborType } from "../../../Contracts/ViewModels";
|
import { NeighborType } from "../../../Contracts/ViewModels";
|
||||||
@@ -89,7 +89,7 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
private static readonly PAGINATION_LINE2_Y_OFFSET_PX = 14;
|
private static readonly PAGINATION_LINE2_Y_OFFSET_PX = 14;
|
||||||
|
|
||||||
// We limit the number of different colors to 20
|
// We limit the number of different colors to 20
|
||||||
private static readonly COLOR_SCHEME = scaleOrdinal(schemeCategory10);
|
private static readonly COLOR_SCHEME_20 = scaleOrdinal(schemeCategory20);
|
||||||
private static readonly MAX_COLOR_NB = 20;
|
private static readonly MAX_COLOR_NB = 20;
|
||||||
|
|
||||||
// Some state variables
|
// Some state variables
|
||||||
@@ -344,13 +344,13 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
} while ((el = el && el.parentNode));
|
} while ((el = el && el.parentNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
private zoomed(event: any) {
|
private zoomed() {
|
||||||
this.zoomTransform = {
|
this.zoomTransform = {
|
||||||
x: event.transform.x,
|
x: d3Event.transform.x,
|
||||||
y: event.transform.y,
|
y: d3Event.transform.y,
|
||||||
k: event.transform.k
|
k: d3Event.transform.k
|
||||||
};
|
};
|
||||||
this.g.attr("transform", event.transform);
|
this.g.attr("transform", d3Event.transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
private instantiateSimulation() {
|
private instantiateSimulation() {
|
||||||
@@ -719,17 +719,17 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
})
|
})
|
||||||
.call(
|
.call(
|
||||||
drag()
|
drag()
|
||||||
.on("start", ((e: D3DragEvent<SVGGElement, D3Node, unknown>, d: D3Node) => {
|
.on("start", (d: D3Node) => {
|
||||||
return this.dragstarted(d, e);
|
return this.dragstarted(d);
|
||||||
}) as any)
|
})
|
||||||
.on("drag", ((e: D3DragEvent<SVGGElement, D3Node, unknown>, d: D3Node) => {
|
.on("drag", (d: D3Node) => {
|
||||||
return this.dragged(d, e);
|
return this.dragged(d);
|
||||||
}) as any)
|
})
|
||||||
.on("end", ((e: D3DragEvent<SVGGElement, D3Node, unknown>, d: D3Node) => {
|
.on("end", (d: D3Node) => {
|
||||||
return this.dragended(d, e);
|
return this.dragended(d);
|
||||||
}) as any)
|
})
|
||||||
)
|
)
|
||||||
.on("mouseover", (_: MouseEvent, d: D3Node) => {
|
.on("mouseover", (d: D3Node) => {
|
||||||
if (this.isHighlightDisabled || this.selectedNode || this.isDragging) {
|
if (this.isHighlightDisabled || this.selectedNode || this.isDragging) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -737,7 +737,7 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
this.highlightNode(this, d);
|
this.highlightNode(this, d);
|
||||||
this.simulation.stop();
|
this.simulation.stop();
|
||||||
})
|
})
|
||||||
.on("mouseout", (_: MouseEvent, d: D3Node) => {
|
.on("mouseout", (d: D3Node) => {
|
||||||
if (this.isHighlightDisabled || this.selectedNode || this.isDragging) {
|
if (this.isHighlightDisabled || this.selectedNode || this.isDragging) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -765,17 +765,17 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
.attr("aria-label", (d: D3Node) => {
|
.attr("aria-label", (d: D3Node) => {
|
||||||
return this.retrieveNodeCaption(d);
|
return this.retrieveNodeCaption(d);
|
||||||
})
|
})
|
||||||
.on("dblclick", function(_: MouseEvent, d: D3Node) {
|
.on("dblclick", function(d: D3Node) {
|
||||||
// this is the <g> element
|
// this is the <g> element
|
||||||
self.onNodeClicked(this.parentNode, d);
|
self.onNodeClicked(this.parentNode, d);
|
||||||
})
|
})
|
||||||
.on("click", function(_: MouseEvent, d: D3Node) {
|
.on("click", function(d: D3Node) {
|
||||||
// this is the <g> element
|
// this is the <g> element
|
||||||
self.onNodeClicked(this.parentNode, d);
|
self.onNodeClicked(this.parentNode, d);
|
||||||
})
|
})
|
||||||
.on("keypress", function(event: KeyboardEvent, d: D3Node) {
|
.on("keypress", function(d: D3Node) {
|
||||||
if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) {
|
if (d3Event.charCode === Constants.KeyCodes.Space || d3Event.charCode === Constants.KeyCodes.Enter) {
|
||||||
event.stopPropagation();
|
d3Event.stopPropagation();
|
||||||
// this is the <g> element
|
// this is the <g> element
|
||||||
self.onNodeClicked(this.parentNode, d);
|
self.onNodeClicked(this.parentNode, d);
|
||||||
}
|
}
|
||||||
@@ -850,24 +850,24 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
return `Next page of nodes for ${this.retrieveNodeCaption(d)}`;
|
return `Next page of nodes for ${this.retrieveNodeCaption(d)}`;
|
||||||
})
|
})
|
||||||
.attr("tabindex", 0)
|
.attr("tabindex", 0)
|
||||||
.on("click", ((_: MouseEvent, d: D3Node) => {
|
.on("click", function(d: D3Node) {
|
||||||
self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
|
||||||
}) as any)
|
})
|
||||||
.on("dblclick", ((_: MouseEvent, d: D3Node) => {
|
.on("dblclick", function(d: D3Node) {
|
||||||
self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
|
||||||
}) as any)
|
})
|
||||||
.on("keypress", ((event: KeyboardEvent, d: D3Node) => {
|
.on("keypress", function(d: D3Node) {
|
||||||
if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) {
|
if (d3Event.charCode === Constants.KeyCodes.Space || d3Event.charCode === Constants.KeyCodes.Enter) {
|
||||||
event.stopPropagation();
|
d3Event.stopPropagation();
|
||||||
self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
|
||||||
}
|
}
|
||||||
}) as any)
|
})
|
||||||
.on("mouseover", ((e: MouseEvent, d: D3Node) => {
|
.on("mouseover", function(d: D3Node) {
|
||||||
select(e.target as any).classed("active", true);
|
select(this).classed("active", true);
|
||||||
}) as any)
|
})
|
||||||
.on("mouseout", ((e: MouseEvent, d: D3Node) => {
|
.on("mouseout", function(d: D3Node) {
|
||||||
select(e.target as any).classed("active", false);
|
select(this).classed("active", false);
|
||||||
}) as any)
|
})
|
||||||
.attr("visibility", (d: D3Node) => (!d._outEAllLoaded || !d._inEAllLoaded ? "visible" : "hidden"));
|
.attr("visibility", (d: D3Node) => (!d._outEAllLoaded || !d._inEAllLoaded ? "visible" : "hidden"));
|
||||||
parent
|
parent
|
||||||
.append("use")
|
.append("use")
|
||||||
@@ -879,24 +879,24 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
return `Previous page of nodes for ${this.retrieveNodeCaption(d)}`;
|
return `Previous page of nodes for ${this.retrieveNodeCaption(d)}`;
|
||||||
})
|
})
|
||||||
.attr("tabindex", 0)
|
.attr("tabindex", 0)
|
||||||
.on("click", ((_: MouseEvent, d: D3Node) => {
|
.on("click", function(d: D3Node) {
|
||||||
self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
|
||||||
}) as any)
|
})
|
||||||
.on("dblclick", ((_: MouseEvent, d: D3Node) => {
|
.on("dblclick", function(d: D3Node) {
|
||||||
self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
|
||||||
}) as any)
|
})
|
||||||
.on("keypress", ((event: KeyboardEvent, d: D3Node) => {
|
.on("keypress", function(d: D3Node) {
|
||||||
if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) {
|
if (d3Event.charCode === Constants.KeyCodes.Space || d3Event.charCode === Constants.KeyCodes.Enter) {
|
||||||
event.stopPropagation();
|
d3Event.stopPropagation();
|
||||||
self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
|
||||||
}
|
}
|
||||||
}) as any)
|
})
|
||||||
.on("mouseover", ((e: MouseEvent, d: D3Node) => {
|
.on("mouseover", function(d: D3Node) {
|
||||||
select(e.target as any).classed("active", true);
|
select(this).classed("active", true);
|
||||||
}) as any)
|
})
|
||||||
.on("mouseout", ((e: MouseEvent, d: D3Node) => {
|
.on("mouseout", function(d: D3Node) {
|
||||||
select(e.target as any).classed("active", false);
|
select(this).classed("active", false);
|
||||||
}) as any)
|
})
|
||||||
.attr("visibility", (d: D3Node) =>
|
.attr("visibility", (d: D3Node) =>
|
||||||
!d._pagination || d._pagination.currentPage.start !== 0 ? "visible" : "hidden"
|
!d._pagination || d._pagination.currentPage.start !== 0 ? "visible" : "hidden"
|
||||||
);
|
);
|
||||||
@@ -975,24 +975,24 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
return `Load adjacent nodes for ${this.retrieveNodeCaption(d)}`;
|
return `Load adjacent nodes for ${this.retrieveNodeCaption(d)}`;
|
||||||
})
|
})
|
||||||
.attr("tabindex", 0)
|
.attr("tabindex", 0)
|
||||||
.on("click", ((_: MouseEvent, d: D3Node) => {
|
.on("click", function(d: D3Node) {
|
||||||
self.loadNeighbors(d, PAGE_ACTION.FIRST_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.FIRST_PAGE);
|
||||||
}) as any)
|
})
|
||||||
.on("dblclick", ((_: MouseEvent, d: D3Node) => {
|
.on("dblclick", function(d: D3Node) {
|
||||||
self.loadNeighbors(d, PAGE_ACTION.FIRST_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.FIRST_PAGE);
|
||||||
}) as any)
|
})
|
||||||
.on("keypress", ((event: KeyboardEvent, d: D3Node) => {
|
.on("keypress", function(d: D3Node) {
|
||||||
if (event.charCode === Constants.KeyCodes.Space || event.charCode === Constants.KeyCodes.Enter) {
|
if (d3Event.charCode === Constants.KeyCodes.Space || d3Event.charCode === Constants.KeyCodes.Enter) {
|
||||||
event.stopPropagation();
|
d3Event.stopPropagation();
|
||||||
self.loadNeighbors(d, PAGE_ACTION.FIRST_PAGE);
|
self.loadNeighbors(d, PAGE_ACTION.FIRST_PAGE);
|
||||||
}
|
}
|
||||||
}) as any)
|
})
|
||||||
.on("mouseover", ((e: MouseEvent, d: D3Node) => {
|
.on("mouseover", function(d: D3Node) {
|
||||||
select(e.target as any).classed("active", true);
|
select(this).classed("active", true);
|
||||||
}) as any)
|
})
|
||||||
.on("mouseout", ((e: MouseEvent, d: D3Node) => {
|
.on("mouseout", function(d: D3Node) {
|
||||||
select(e.target as any).classed("active", false);
|
select(this).classed("active", false);
|
||||||
}) as any);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1053,7 +1053,7 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
if (index < 0 || index >= D3ForceGraph.MAX_COLOR_NB) {
|
if (index < 0 || index >= D3ForceGraph.MAX_COLOR_NB) {
|
||||||
index = D3ForceGraph.MAX_COLOR_NB - 1;
|
index = D3ForceGraph.MAX_COLOR_NB - 1;
|
||||||
}
|
}
|
||||||
return D3ForceGraph.COLOR_SCHEME(index.toString());
|
return D3ForceGraph.COLOR_SCHEME_20(index.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1071,23 +1071,23 @@ export class D3ForceGraph implements GraphRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private dragstarted(d: D3Node, event: D3DragEvent<SVGGElement, D3Node, unknown>) {
|
private dragstarted(d: D3Node) {
|
||||||
this.isDragging = true;
|
this.isDragging = true;
|
||||||
if (!event.active) {
|
if (!d3Event.active) {
|
||||||
this.simulation.alphaTarget(0.3).restart();
|
this.simulation.alphaTarget(0.3).restart();
|
||||||
}
|
}
|
||||||
d.fx = d.x;
|
d.fx = d.x;
|
||||||
d.fy = d.y;
|
d.fy = d.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
private dragged(d: D3Node, event: D3DragEvent<SVGGElement, D3Node, unknown>) {
|
private dragged(d: D3Node) {
|
||||||
d.fx = event.x;
|
d.fx = d3Event.x;
|
||||||
d.fy = event.y;
|
d.fy = d3Event.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
private dragended(d: D3Node, event: D3DragEvent<SVGGElement, D3Node, unknown>) {
|
private dragended(d: D3Node) {
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
if (!event.active) {
|
if (!d3Event.active) {
|
||||||
this.simulation.alphaTarget(0);
|
this.simulation.alphaTarget(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import SynapseIcon from "../../../../images/synapse-link.svg";
|
|||||||
import { configContext, Platform } from "../../../ConfigContext";
|
import { configContext, Platform } from "../../../ConfigContext";
|
||||||
import Explorer from "../../Explorer";
|
import Explorer from "../../Explorer";
|
||||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||||
|
import { AuthType } from "../../../AuthType";
|
||||||
|
|
||||||
export class CommandBarComponentButtonFactory {
|
export class CommandBarComponentButtonFactory {
|
||||||
private static counter: number = 0;
|
private static counter: number = 0;
|
||||||
@@ -178,6 +179,21 @@ export class CommandBarComponentButtonFactory {
|
|||||||
buttons.push(settingsPaneButton);
|
buttons.push(settingsPaneButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window.authType === AuthType.AAD) {
|
||||||
|
const label = "Chat Assistant";
|
||||||
|
const supportPaneButton: CommandButtonComponentProps = {
|
||||||
|
iconSrc: FeedbackIcon,
|
||||||
|
iconAlt: label,
|
||||||
|
onCommandClick: () => container.supportPane.open(),
|
||||||
|
commandButtonLabel: null,
|
||||||
|
ariaLabel: label,
|
||||||
|
tooltipText: label,
|
||||||
|
hasPopup: true,
|
||||||
|
disabled: false
|
||||||
|
};
|
||||||
|
buttons.push(supportPaneButton);
|
||||||
|
}
|
||||||
|
|
||||||
if (container.isHostedDataExplorerEnabled()) {
|
if (container.isHostedDataExplorerEnabled()) {
|
||||||
const label = "Open Full Screen";
|
const label = "Open Full Screen";
|
||||||
const fullScreenButton: CommandButtonComponentProps = {
|
const fullScreenButton: CommandButtonComponentProps = {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
makeAppRecord,
|
makeAppRecord,
|
||||||
makeCommsRecord,
|
makeCommsRecord,
|
||||||
makeContentsRecord,
|
makeContentsRecord,
|
||||||
makeEditorsRecord,
|
|
||||||
makeEntitiesRecord,
|
makeEntitiesRecord,
|
||||||
makeHostsRecord,
|
makeHostsRecord,
|
||||||
makeJupyterHostRecord,
|
makeJupyterHostRecord,
|
||||||
@@ -35,7 +34,6 @@ import configureStore from "./NotebookComponent/store";
|
|||||||
import { Notification } from "react-notification-system";
|
import { Notification } from "react-notification-system";
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
import { configOption, createConfigCollection, defineConfigOption } from "@nteract/mythic-configuration";
|
|
||||||
|
|
||||||
export type KernelSpecsDisplay = { name: string; displayName: string };
|
export type KernelSpecsDisplay = { name: string; displayName: string };
|
||||||
|
|
||||||
@@ -114,15 +112,20 @@ export class NotebookClientV2 {
|
|||||||
host: jupyterHostRecord
|
host: jupyterHostRecord
|
||||||
// TODO: tamitta: notificationSystem.addNotification was removed, do we need a substitute?
|
// TODO: tamitta: notificationSystem.addNotification was removed, do we need a substitute?
|
||||||
}),
|
}),
|
||||||
|
comms: makeCommsRecord(),
|
||||||
|
config: Immutable.Map({
|
||||||
|
theme: "light",
|
||||||
|
editorType: params.cellEditorType || "codemirror",
|
||||||
|
autoSaveInterval: params.autoSaveInterval || Constants.Notebook.autoSaveIntervalMs
|
||||||
|
}),
|
||||||
core: makeStateRecord({
|
core: makeStateRecord({
|
||||||
currentKernelspecsRef: kernelspecsRef,
|
currentKernelspecsRef: kernelspecsRef,
|
||||||
entities: makeEntitiesRecord({
|
entities: makeEntitiesRecord({
|
||||||
editors: makeEditorsRecord({}),
|
|
||||||
hosts: makeHostsRecord({
|
hosts: makeHostsRecord({
|
||||||
byRef: Immutable.Map<string, HostRecord>().set(this.contentHostRef, jupyterHostRecord)
|
byRef: Immutable.Map<string, HostRecord>().set(this.contentHostRef, jupyterHostRecord)
|
||||||
}),
|
}),
|
||||||
comms: makeCommsRecord(),
|
|
||||||
contents: makeContentsRecord({
|
contents: makeContentsRecord({
|
||||||
|
// byRef: Immutable.Map<string, ContentRecord>().set(this.contentRef, record)
|
||||||
byRef: Immutable.Map<string, ContentRecord>()
|
byRef: Immutable.Map<string, ContentRecord>()
|
||||||
}),
|
}),
|
||||||
transforms: makeTransformsRecord({
|
transforms: makeTransformsRecord({
|
||||||
@@ -235,24 +238,6 @@ export class NotebookClientV2 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.store = configureStore(initialState, params.contentProvider, traceErrorFct, [cacheKernelSpecsMiddleware]);
|
this.store = configureStore(initialState, params.contentProvider, traceErrorFct, [cacheKernelSpecsMiddleware]);
|
||||||
|
|
||||||
// Additional configuration
|
|
||||||
this.store.dispatch(configOption("editorType").action(params.cellEditorType ?? "monaco"));
|
|
||||||
this.store.dispatch(
|
|
||||||
configOption("autoSaveInterval").action(params.autoSaveInterval ?? Constants.Notebook.autoSaveIntervalMs)
|
|
||||||
);
|
|
||||||
createConfigCollection({
|
|
||||||
key: "monaco"
|
|
||||||
});
|
|
||||||
defineConfigOption({
|
|
||||||
label: "Show Line numbers",
|
|
||||||
key: "monaco.lineNumbers",
|
|
||||||
values: [
|
|
||||||
{ label: "Yes", value: true },
|
|
||||||
{ label: "No", value: false }
|
|
||||||
],
|
|
||||||
defaultValue: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ export class NotebookComponentBootstrapper {
|
|||||||
this.getStore().dispatch(
|
this.getStore().dispatch(
|
||||||
actions.createCellBelow({
|
actions.createCellBelow({
|
||||||
cellType: "code",
|
cellType: "code",
|
||||||
|
source: "",
|
||||||
contentRef: this.contentRef
|
contentRef: this.contentRef
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { StringUtils } from "../../../../../Utils/StringUtils";
|
import { StringUtils } from "../../../../../Utils/StringUtils";
|
||||||
import { actions, AppState, ContentRef, selectors } from "@nteract/core";
|
import { actions, AppState, ContentRef, selectors } from "@nteract/core";
|
||||||
import { IMonacoProps as MonacoEditorProps } from "@nteract/monaco-editor";
|
import { MonacoEditorProps } from "@nteract/monaco-editor";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { Dispatch } from "redux";
|
import { Dispatch } from "redux";
|
||||||
@@ -21,7 +21,7 @@ interface MappedStateProps {
|
|||||||
mimetype: string;
|
mimetype: string;
|
||||||
text: string;
|
text: string;
|
||||||
contentRef: ContentRef;
|
contentRef: ContentRef;
|
||||||
theme?: "light" | "dark";
|
theme: string; // "light" | "dark";
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MappedDispatchProps {
|
interface MappedDispatchProps {
|
||||||
@@ -65,10 +65,8 @@ export class TextFile extends React.PureComponent<TextFileProps, TextFileState>
|
|||||||
return (
|
return (
|
||||||
<EditorContainer className="nteract-editor" style={{ position: "static" }}>
|
<EditorContainer className="nteract-editor" style={{ position: "static" }}>
|
||||||
<Editor
|
<Editor
|
||||||
id={"no-cell-id-for-single-editor"}
|
|
||||||
contentRef={this.props.contentRef}
|
|
||||||
theme={this.props.theme === "dark" ? "vs-dark" : "vs"}
|
theme={this.props.theme === "dark" ? "vs-dark" : "vs"}
|
||||||
language={"plaintext"}
|
mode={this.props.mimetype}
|
||||||
editorFocused
|
editorFocused
|
||||||
value={this.props.text}
|
value={this.props.text}
|
||||||
onChange={this.handleChange.bind(this)}
|
onChange={this.handleChange.bind(this)}
|
||||||
@@ -99,7 +97,8 @@ function makeMapStateToTextFileProps(
|
|||||||
return {
|
return {
|
||||||
contentRef,
|
contentRef,
|
||||||
mimetype: content.mimetype != null ? content.mimetype : "text/plain",
|
mimetype: content.mimetype != null ? content.mimetype : "text/plain",
|
||||||
text
|
text,
|
||||||
|
theme: selectors.currentTheme(state)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return mapStateToTextFileProps;
|
return mapStateToTextFileProps;
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ const mapDispatchToProps = (dispatch: Dispatch, ownProps: ContentsProps): object
|
|||||||
},
|
},
|
||||||
COPY_CELL: () => dispatch(actions.copyCell({ contentRef })),
|
COPY_CELL: () => dispatch(actions.copyCell({ contentRef })),
|
||||||
CREATE_CELL_ABOVE: () => dispatch(actions.createCellAbove({ cellType: "code", contentRef })),
|
CREATE_CELL_ABOVE: () => dispatch(actions.createCellAbove({ cellType: "code", contentRef })),
|
||||||
CREATE_CELL_BELOW: () => dispatch(actions.createCellBelow({ cellType: "code", contentRef })),
|
CREATE_CELL_BELOW: () => dispatch(actions.createCellBelow({ cellType: "code", source: "", contentRef })),
|
||||||
CUT_CELL: () => dispatch(actions.cutCell({ contentRef })),
|
CUT_CELL: () => dispatch(actions.cutCell({ contentRef })),
|
||||||
DELETE_CELL: () => dispatch(actions.deleteCell({ contentRef })),
|
DELETE_CELL: () => dispatch(actions.deleteCell({ contentRef })),
|
||||||
EXECUTE_ALL_CELLS: () => dispatch(actions.executeAllCells({ contentRef })),
|
EXECUTE_ALL_CELLS: () => dispatch(actions.executeAllCells({ contentRef })),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as Immutable from "immutable";
|
import * as Immutable from "immutable";
|
||||||
import { StateObservable } from "redux-observable";
|
import { ActionsObservable, StateObservable } from "redux-observable";
|
||||||
import { Subject, of } from "rxjs";
|
import { Subject, empty } from "rxjs";
|
||||||
import { toArray } from "rxjs/operators";
|
import { toArray } from "rxjs/operators";
|
||||||
import { makeNotebookRecord } from "@nteract/commutable";
|
import { makeNotebookRecord } from "@nteract/commutable";
|
||||||
import { actions, state } from "@nteract/core";
|
import { actions, state } from "@nteract/core";
|
||||||
@@ -124,7 +124,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
const kernelSpecName = "kernelspecname";
|
const kernelSpecName = "kernelspecname";
|
||||||
const sessionId = "sessionId";
|
const sessionId = "sessionId";
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -192,7 +192,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
const kernelSpecName = "kernelspecname";
|
const kernelSpecName = "kernelspecname";
|
||||||
const sessionId = "sessionId";
|
const sessionId = "sessionId";
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -247,7 +247,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
const kernelSpecName = "kernelspecname";
|
const kernelSpecName = "kernelspecname";
|
||||||
const sessionId = "sessionId";
|
const sessionId = "sessionId";
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -298,7 +298,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||||
|
|
||||||
const cwd = "/";
|
const cwd = "/";
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -398,7 +398,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
it("launches supported kernel in kernelspecs", async () => {
|
it("launches supported kernel in kernelspecs", async () => {
|
||||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -421,7 +421,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
it("launches undefined kernel uses default kernel from kernelspecs", async () => {
|
it("launches undefined kernel uses default kernel from kernelspecs", async () => {
|
||||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -445,7 +445,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
it("launches unsupported kernel uses default kernel from kernelspecs", async () => {
|
it("launches unsupported kernel uses default kernel from kernelspecs", async () => {
|
||||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -469,7 +469,7 @@ describe("launchWebSocketKernelEpic", () => {
|
|||||||
it("launches unsupported kernel uses kernelspecs with similar name", async () => {
|
it("launches unsupported kernel uses kernelspecs with similar name", async () => {
|
||||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.launchKernelByName({
|
actions.launchKernelByName({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -499,7 +499,7 @@ describe("autoStartKernelEpic", () => {
|
|||||||
it("automatically starts kernel when content fetch is successful if kernelRef is defined", async () => {
|
it("automatically starts kernel when content fetch is successful if kernelRef is defined", async () => {
|
||||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.fetchContentFulfilled({
|
actions.fetchContentFulfilled({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef,
|
kernelRef,
|
||||||
@@ -527,7 +527,7 @@ describe("autoStartKernelEpic", () => {
|
|||||||
it("Don't start kernel when content fetch is successful if kernelRef is not defined", async () => {
|
it("Don't start kernel when content fetch is successful if kernelRef is not defined", async () => {
|
||||||
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
const state$ = new StateObservable(new Subject<CdbAppState>(), initialState);
|
||||||
|
|
||||||
const action$ = of(
|
const action$ = ActionsObservable.of(
|
||||||
actions.fetchContentFulfilled({
|
actions.fetchContentFulfilled({
|
||||||
contentRef,
|
contentRef,
|
||||||
kernelRef: undefined,
|
kernelRef: undefined,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EMPTY, merge, of, timer, concat, Subject, Subscriber, Observable, Observer } from "rxjs";
|
import { EMPTY, merge, of, timer, concat, Subject, Subscriber, Observable, Observer } from "rxjs";
|
||||||
import { webSocket } from "rxjs/webSocket";
|
import { webSocket } from "rxjs/webSocket";
|
||||||
import { StateObservable } from "redux-observable";
|
import { ActionsObservable, StateObservable } from "redux-observable";
|
||||||
import { ofType } from "redux-observable";
|
import { ofType } from "redux-observable";
|
||||||
import {
|
import {
|
||||||
mergeMap,
|
mergeMap,
|
||||||
@@ -65,7 +65,7 @@ const logToTelemetry = (state: CdbAppState, title: string, error?: string) => {
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const addInitialCodeCellEpic = (
|
const addInitialCodeCellEpic = (
|
||||||
action$: Observable<actions.FetchContentFulfilled>,
|
action$: ActionsObservable<actions.FetchContentFulfilled>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
): Observable<{} | actions.CreateCellBelow> => {
|
): Observable<{} | actions.CreateCellBelow> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -104,7 +104,7 @@ const addInitialCodeCellEpic = (
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
export const autoStartKernelEpic = (
|
export const autoStartKernelEpic = (
|
||||||
action$: Observable<actions.FetchContentFulfilled>,
|
action$: ActionsObservable<actions.FetchContentFulfilled>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
): Observable<{} | actions.CreateCellBelow> => {
|
): Observable<{} | actions.CreateCellBelow> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -157,7 +157,7 @@ const formWebSocketURL = (serverConfig: NotebookServiceConfig, kernelId: string,
|
|||||||
* Override from kernel-lifecycle to improve code mirror language intellisense
|
* Override from kernel-lifecycle to improve code mirror language intellisense
|
||||||
* @param action$
|
* @param action$
|
||||||
*/
|
*/
|
||||||
export const acquireKernelInfoEpic = (action$: Observable<actions.NewKernelAction>) => {
|
export const acquireKernelInfoEpic = (action$: ActionsObservable<actions.NewKernelAction>) => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
ofType(actions.LAUNCH_KERNEL_SUCCESSFUL),
|
ofType(actions.LAUNCH_KERNEL_SUCCESSFUL),
|
||||||
switchMap((action: actions.NewKernelAction) => {
|
switchMap((action: actions.NewKernelAction) => {
|
||||||
@@ -310,7 +310,7 @@ const connect = (serverConfig: NotebookServiceConfig, kernelID: string, sessionI
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
export const launchWebSocketKernelEpic = (
|
export const launchWebSocketKernelEpic = (
|
||||||
action$: Observable<actions.LaunchKernelByNameAction>,
|
action$: ActionsObservable<actions.LaunchKernelByNameAction>,
|
||||||
state$: StateObservable<CdbAppState>
|
state$: StateObservable<CdbAppState>
|
||||||
) => {
|
) => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -422,7 +422,7 @@ export const launchWebSocketKernelEpic = (
|
|||||||
* TODO: Remove this epic once the /restart endpoint is implemented.
|
* TODO: Remove this epic once the /restart endpoint is implemented.
|
||||||
*/
|
*/
|
||||||
export const restartWebSocketKernelEpic = (
|
export const restartWebSocketKernelEpic = (
|
||||||
action$: Observable<actions.RestartKernel | actions.NewKernelAction>,
|
action$: ActionsObservable<actions.RestartKernel | actions.NewKernelAction>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
) =>
|
) =>
|
||||||
action$.pipe(
|
action$.pipe(
|
||||||
@@ -532,7 +532,7 @@ export const restartWebSocketKernelEpic = (
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const changeWebSocketKernelEpic = (
|
const changeWebSocketKernelEpic = (
|
||||||
action$: Observable<actions.ChangeKernelByName>,
|
action$: ActionsObservable<actions.ChangeKernelByName>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
) => {
|
) => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -614,7 +614,7 @@ const changeWebSocketKernelEpic = (
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const focusInitialCodeCellEpic = (
|
const focusInitialCodeCellEpic = (
|
||||||
action$: Observable<actions.CreateCellAppend>,
|
action$: ActionsObservable<actions.CreateCellAppend>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
): Observable<{} | actions.FocusCell> => {
|
): Observable<{} | actions.FocusCell> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -652,7 +652,10 @@ const focusInitialCodeCellEpic = (
|
|||||||
* @param action$
|
* @param action$
|
||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const notificationsToUserEpic = (action$: Observable<any>, state$: StateObservable<CdbAppState>): Observable<{}> => {
|
const notificationsToUserEpic = (
|
||||||
|
action$: ActionsObservable<any>,
|
||||||
|
state$: StateObservable<CdbAppState>
|
||||||
|
): Observable<{}> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
ofType(
|
ofType(
|
||||||
actions.RESTART_KERNEL_SUCCESSFUL,
|
actions.RESTART_KERNEL_SUCCESSFUL,
|
||||||
@@ -702,7 +705,7 @@ const notificationsToUserEpic = (action$: Observable<any>, state$: StateObservab
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const handleKernelConnectionLostEpic = (
|
const handleKernelConnectionLostEpic = (
|
||||||
action$: Observable<actions.UpdateDisplayFailed>,
|
action$: ActionsObservable<actions.UpdateDisplayFailed>,
|
||||||
state$: StateObservable<CdbAppState>
|
state$: StateObservable<CdbAppState>
|
||||||
): Observable<CdbActions.UpdateKernelRestartDelayAction | actions.RestartKernel | {}> => {
|
): Observable<CdbActions.UpdateKernelRestartDelayAction | actions.RestartKernel | {}> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -763,7 +766,7 @@ const handleKernelConnectionLostEpic = (
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
export const cleanKernelOnConnectionLostEpic = (
|
export const cleanKernelOnConnectionLostEpic = (
|
||||||
action$: Observable<actions.UpdateDisplayFailed>,
|
action$: ActionsObservable<actions.UpdateDisplayFailed>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
): Observable<actions.KillKernelSuccessful> => {
|
): Observable<actions.KillKernelSuccessful> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -786,7 +789,7 @@ export const cleanKernelOnConnectionLostEpic = (
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const executeFocusedCellAndFocusNextEpic = (
|
const executeFocusedCellAndFocusNextEpic = (
|
||||||
action$: Observable<CdbActions.ExecuteFocusedCellAndFocusNextAction>,
|
action$: ActionsObservable<CdbActions.ExecuteFocusedCellAndFocusNextAction>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
): Observable<{} | actions.FocusNextCellEditor> => {
|
): Observable<{} | actions.FocusNextCellEditor> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -826,7 +829,7 @@ function getUserPuid(): string {
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const closeUnsupportedMimetypesEpic = (
|
const closeUnsupportedMimetypesEpic = (
|
||||||
action$: Observable<actions.FetchContentFulfilled>,
|
action$: ActionsObservable<actions.FetchContentFulfilled>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
): Observable<{}> => {
|
): Observable<{}> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
@@ -855,7 +858,7 @@ const closeUnsupportedMimetypesEpic = (
|
|||||||
* @param state$
|
* @param state$
|
||||||
*/
|
*/
|
||||||
const closeContentFailedToFetchEpic = (
|
const closeContentFailedToFetchEpic = (
|
||||||
action$: Observable<actions.FetchContentFailed>,
|
action$: ActionsObservable<actions.FetchContentFailed>,
|
||||||
state$: StateObservable<AppState>
|
state$: StateObservable<AppState>
|
||||||
): Observable<{}> => {
|
): Observable<{}> => {
|
||||||
return action$.pipe(
|
return action$.pipe(
|
||||||
|
|||||||
@@ -1,22 +1,36 @@
|
|||||||
import { AppState, epics as coreEpics, reducers, IContentProvider } from "@nteract/core";
|
import { AppState, epics as coreEpics, reducers, IContentProvider } from "@nteract/core";
|
||||||
import { compose, Store, AnyAction, Middleware, Dispatch, MiddlewareAPI } from "redux";
|
import {
|
||||||
import { createEpicMiddleware, Epic } from "redux-observable";
|
applyMiddleware,
|
||||||
|
combineReducers,
|
||||||
|
compose,
|
||||||
|
createStore,
|
||||||
|
Store,
|
||||||
|
AnyAction,
|
||||||
|
Middleware,
|
||||||
|
Dispatch,
|
||||||
|
MiddlewareAPI
|
||||||
|
} from "redux";
|
||||||
|
import { combineEpics, createEpicMiddleware, Epic, ActionsObservable } from "redux-observable";
|
||||||
import { allEpics } from "./epics";
|
import { allEpics } from "./epics";
|
||||||
import { coreReducer, cdbReducer } from "./reducers";
|
import { coreReducer, cdbReducer } from "./reducers";
|
||||||
import { catchError } from "rxjs/operators";
|
import { catchError } from "rxjs/operators";
|
||||||
import { Observable } from "rxjs";
|
|
||||||
import { configuration } from "@nteract/mythic-configuration";
|
|
||||||
import { makeConfigureStore } from "@nteract/myths";
|
|
||||||
import { CdbAppState } from "./types";
|
|
||||||
|
|
||||||
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||||
|
|
||||||
export default function configureStore(
|
export default function configureStore(
|
||||||
initialState: Partial<CdbAppState>,
|
initialState: Partial<AppState>,
|
||||||
contentProvider: IContentProvider,
|
contentProvider: IContentProvider,
|
||||||
onTraceFailure: (title: string, message: string) => void,
|
onTraceFailure: (title: string, message: string) => void,
|
||||||
customMiddlewares?: Middleware<{}, any, Dispatch<AnyAction>>[]
|
customMiddlewares?: Middleware<{}, any, Dispatch<AnyAction>>[]
|
||||||
): Store<CdbAppState, AnyAction> {
|
): Store<AppState, AnyAction> {
|
||||||
|
const rootReducer = combineReducers({
|
||||||
|
app: reducers.app,
|
||||||
|
comms: reducers.comms,
|
||||||
|
config: reducers.config,
|
||||||
|
core: coreReducer,
|
||||||
|
cdb: cdbReducer
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Catches errors in reducers
|
* Catches errors in reducers
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +46,7 @@ export default function configureStore(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const protect = (epic: Epic) => {
|
const protect = (epic: Epic) => {
|
||||||
return (action$: Observable<any>, state$: any, dependencies: any) =>
|
return (action$: ActionsObservable<any>, state$: any, dependencies: any) =>
|
||||||
epic(action$, state$, dependencies).pipe(
|
epic(action$, state$, dependencies).pipe(
|
||||||
catchError((error, caught) => {
|
catchError((error, caught) => {
|
||||||
traceFailure("Epic failure", error);
|
traceFailure("Epic failure", error);
|
||||||
@@ -50,8 +64,9 @@ export default function configureStore(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const protectEpics = (epics: Epic[]): Epic[] => {
|
const combineAndProtectEpics = (epics: Epic[]): Epic => {
|
||||||
return epics.map(epic => protect(epic));
|
const protectedEpics = epics.map(epic => protect(epic));
|
||||||
|
return combineEpics<Epic>(...protectedEpics);
|
||||||
};
|
};
|
||||||
|
|
||||||
// This list needs to be consistent and in sync with core.allEpics until we figure
|
// This list needs to be consistent and in sync with core.allEpics until we figure
|
||||||
@@ -78,23 +93,20 @@ export default function configureStore(
|
|||||||
coreEpics.publishToBookstoreAfterSave,
|
coreEpics.publishToBookstoreAfterSave,
|
||||||
coreEpics.sendInputReplyEpic
|
coreEpics.sendInputReplyEpic
|
||||||
];
|
];
|
||||||
|
const rootEpic = combineAndProtectEpics([...filteredCoreEpics, ...allEpics]);
|
||||||
|
const epicMiddleware = createEpicMiddleware({ dependencies: { contentProvider } });
|
||||||
|
let middlewares: Middleware[] = [epicMiddleware];
|
||||||
|
// TODO: tamitta: errorMiddleware was removed, do we need a substitute?
|
||||||
|
|
||||||
const mythConfigureStore = makeConfigureStore<CdbAppState>()({
|
if (customMiddlewares) {
|
||||||
packages: [configuration],
|
middlewares = middlewares.concat(customMiddlewares);
|
||||||
reducers: {
|
}
|
||||||
app: reducers.app,
|
middlewares.push(catchErrorMiddleware);
|
||||||
core: coreReducer as any,
|
|
||||||
cdb: cdbReducer
|
|
||||||
},
|
|
||||||
epics: protectEpics([...filteredCoreEpics, ...allEpics]),
|
|
||||||
epicDependencies: { contentProvider },
|
|
||||||
epicMiddleware: [catchErrorMiddleware],
|
|
||||||
enhancer: composeEnhancers
|
|
||||||
});
|
|
||||||
|
|
||||||
const store = mythConfigureStore(initialState as any);
|
const store = createStore(rootReducer, initialState, composeEnhancers(applyMiddleware(...middlewares)));
|
||||||
|
|
||||||
|
epicMiddleware.run(rootEpic);
|
||||||
|
|
||||||
// TODO Fix typing issue here: createStore() output type doesn't quite match AppState
|
// TODO Fix typing issue here: createStore() output type doesn't quite match AppState
|
||||||
// return store as Store<AppState, AnyAction>;
|
return store as Store<AppState, AnyAction>;
|
||||||
return store as any;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import { connect } from "react-redux";
|
|||||||
import { Dispatch } from "redux";
|
import { Dispatch } from "redux";
|
||||||
import { actions, ContentRef } from "@nteract/core";
|
import { actions, ContentRef } from "@nteract/core";
|
||||||
import loadTransform from "../NotebookComponent/loadTransform";
|
import loadTransform from "../NotebookComponent/loadTransform";
|
||||||
import MonacoEditor from "@nteract/stateful-components/lib/inputs/connected-editors/monacoEditor";
|
import CodeMirrorEditor from "@nteract/stateful-components/lib/inputs/connected-editors/codemirror";
|
||||||
import { PassedEditorProps } from "@nteract/stateful-components/lib/inputs/editor";
|
|
||||||
import "./NotebookReadOnlyRenderer.less";
|
import "./NotebookReadOnlyRenderer.less";
|
||||||
|
|
||||||
export interface NotebookRendererProps {
|
export interface NotebookRendererProps {
|
||||||
@@ -20,6 +19,19 @@ export interface NotebookRendererProps {
|
|||||||
hidePrompts?: boolean;
|
hidePrompts?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PassedEditorProps {
|
||||||
|
id: string;
|
||||||
|
contentRef: ContentRef;
|
||||||
|
editorFocused: boolean;
|
||||||
|
value: string;
|
||||||
|
channels: any;
|
||||||
|
kernelStatus: string;
|
||||||
|
theme: string;
|
||||||
|
onChange: (text: string) => void;
|
||||||
|
onFocusChange: (focused: boolean) => void;
|
||||||
|
className: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the class that uses nteract to render a read-only notebook.
|
* This is the class that uses nteract to render a read-only notebook.
|
||||||
*/
|
*/
|
||||||
@@ -61,8 +73,8 @@ class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
|||||||
{{
|
{{
|
||||||
prompt: (props: { id: string; contentRef: string }) => this.renderPrompt(props.id, props.contentRef),
|
prompt: (props: { id: string; contentRef: string }) => this.renderPrompt(props.id, props.contentRef),
|
||||||
editor: {
|
editor: {
|
||||||
monaco: (props: PassedEditorProps) =>
|
codemirror: (props: PassedEditorProps) =>
|
||||||
this.props.hideInputs ? <></> : <MonacoEditor readOnly={true} {...props} editorType={"monaco"} />
|
this.props.hideInputs ? <></> : <CodeMirrorEditor {...props} readOnly={"nocursor"} />
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
</CodeCell>
|
</CodeCell>
|
||||||
@@ -78,8 +90,8 @@ class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
|||||||
<RawCell id={id} contentRef={contentRef} cell_type="raw">
|
<RawCell id={id} contentRef={contentRef} cell_type="raw">
|
||||||
{{
|
{{
|
||||||
editor: {
|
editor: {
|
||||||
monaco: (props: PassedEditorProps) =>
|
codemirror: (props: PassedEditorProps) =>
|
||||||
this.props.hideInputs ? <></> : <MonacoEditor {...props} readOnly={true} editorType={"monaco"} />
|
this.props.hideInputs ? <></> : <CodeMirrorEditor {...props} readOnly={"nocursor"} />
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
</RawCell>
|
</RawCell>
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import "./base.css";
|
|||||||
import "./default.css";
|
import "./default.css";
|
||||||
|
|
||||||
import { RawCell, Cells, CodeCell, MarkdownCell } from "@nteract/stateful-components";
|
import { RawCell, Cells, CodeCell, MarkdownCell } from "@nteract/stateful-components";
|
||||||
import MonacoEditor from "@nteract/stateful-components/lib/inputs/connected-editors/monacoEditor";
|
import CodeMirrorEditor from "@nteract/stateful-components/lib/inputs/connected-editors/codemirror";
|
||||||
import { PassedEditorProps } from "@nteract/stateful-components/lib/inputs/editor";
|
|
||||||
|
|
||||||
import Prompt from "./Prompt";
|
import Prompt from "./Prompt";
|
||||||
import { promptContent } from "./PromptContent";
|
import { promptContent } from "./PromptContent";
|
||||||
@@ -43,6 +42,19 @@ interface NotebookRendererDispatchProps {
|
|||||||
|
|
||||||
type NotebookRendererProps = NotebookRendererBaseProps & NotebookRendererDispatchProps;
|
type NotebookRendererProps = NotebookRendererBaseProps & NotebookRendererDispatchProps;
|
||||||
|
|
||||||
|
interface PassedEditorProps {
|
||||||
|
id: string;
|
||||||
|
contentRef: ContentRef;
|
||||||
|
editorFocused: boolean;
|
||||||
|
value: string;
|
||||||
|
channels: any;
|
||||||
|
kernelStatus: string;
|
||||||
|
theme: string;
|
||||||
|
onChange: (text: string) => void;
|
||||||
|
onFocusChange: (focused: boolean) => void;
|
||||||
|
className: string;
|
||||||
|
}
|
||||||
|
|
||||||
const decorate = (id: string, contentRef: ContentRef, cell_type: CellType, children: React.ReactNode) => {
|
const decorate = (id: string, contentRef: ContentRef, cell_type: CellType, children: React.ReactNode) => {
|
||||||
const Cell = () => (
|
const Cell = () => (
|
||||||
<DraggableCell id={id} contentRef={contentRef}>
|
<DraggableCell id={id} contentRef={contentRef}>
|
||||||
@@ -103,7 +115,9 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
|||||||
<CodeCell id={id} contentRef={contentRef} cell_type="code">
|
<CodeCell id={id} contentRef={contentRef} cell_type="code">
|
||||||
{{
|
{{
|
||||||
editor: {
|
editor: {
|
||||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />
|
codemirror: (props: PassedEditorProps) => (
|
||||||
|
<CodeMirrorEditor {...props} lineNumbers={true} />
|
||||||
|
)
|
||||||
},
|
},
|
||||||
prompt: ({ id, contentRef }: { id: CellId; contentRef: ContentRef }) => (
|
prompt: ({ id, contentRef }: { id: CellId; contentRef: ContentRef }) => (
|
||||||
<Prompt id={id} contentRef={contentRef} isHovered={false}>
|
<Prompt id={id} contentRef={contentRef} isHovered={false}>
|
||||||
@@ -121,9 +135,6 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
|||||||
"markdown",
|
"markdown",
|
||||||
<MarkdownCell id={id} contentRef={contentRef} cell_type="markdown">
|
<MarkdownCell id={id} contentRef={contentRef} cell_type="markdown">
|
||||||
{{
|
{{
|
||||||
editor: {
|
|
||||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />
|
|
||||||
},
|
|
||||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />
|
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />
|
||||||
}}
|
}}
|
||||||
</MarkdownCell>
|
</MarkdownCell>
|
||||||
@@ -136,9 +147,6 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
|||||||
"raw",
|
"raw",
|
||||||
<RawCell id={id} contentRef={contentRef} cell_type="raw">
|
<RawCell id={id} contentRef={contentRef} cell_type="raw">
|
||||||
{{
|
{{
|
||||||
editor: {
|
|
||||||
monaco: (props: PassedEditorProps) => <MonacoEditor {...props} editorType={"monaco"} />
|
|
||||||
},
|
|
||||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />
|
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />
|
||||||
}}
|
}}
|
||||||
</RawCell>
|
</RawCell>
|
||||||
|
|||||||
@@ -150,9 +150,9 @@ const mapDispatchToProps = (
|
|||||||
): DispatchProps => ({
|
): DispatchProps => ({
|
||||||
executeCell: () => dispatch(actions.executeCell({ id, contentRef })),
|
executeCell: () => dispatch(actions.executeCell({ id, contentRef })),
|
||||||
insertCodeCellAbove: () => dispatch(actions.createCellAbove({ id, contentRef, cellType: "code" })),
|
insertCodeCellAbove: () => dispatch(actions.createCellAbove({ id, contentRef, cellType: "code" })),
|
||||||
insertCodeCellBelow: () => dispatch(actions.createCellBelow({ id, contentRef, cellType: "code" })),
|
insertCodeCellBelow: () => dispatch(actions.createCellBelow({ id, contentRef, cellType: "code", source: "" })),
|
||||||
insertTextCellAbove: () => dispatch(actions.createCellAbove({ id, contentRef, cellType: "markdown" })),
|
insertTextCellAbove: () => dispatch(actions.createCellAbove({ id, contentRef, cellType: "markdown" })),
|
||||||
insertTextCellBelow: () => dispatch(actions.createCellBelow({ id, contentRef, cellType: "markdown" })),
|
insertTextCellBelow: () => dispatch(actions.createCellBelow({ id, contentRef, cellType: "markdown", source: "" })),
|
||||||
moveCell: (destinationId: CellId, above: boolean) =>
|
moveCell: (destinationId: CellId, above: boolean) =>
|
||||||
dispatch(actions.moveCell({ id, contentRef, destinationId, above })),
|
dispatch(actions.moveCell({ id, contentRef, destinationId, above })),
|
||||||
clearOutputs: () => dispatch(actions.clearOutputs({ id, contentRef })),
|
clearOutputs: () => dispatch(actions.clearOutputs({ id, contentRef })),
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import UploadFilePaneTemplate from "./UploadFilePane.html";
|
|||||||
import StringInputPaneTemplate from "./StringInputPane.html";
|
import StringInputPaneTemplate from "./StringInputPane.html";
|
||||||
import SetupNotebooksPaneTemplate from "./SetupNotebooksPane.html";
|
import SetupNotebooksPaneTemplate from "./SetupNotebooksPane.html";
|
||||||
import GitHubReposPaneTemplate from "./GitHubReposPane.html";
|
import GitHubReposPaneTemplate from "./GitHubReposPane.html";
|
||||||
|
import SupportPaneTemplate from "./SupportPane.html";
|
||||||
|
|
||||||
export class PaneComponent {
|
export class PaneComponent {
|
||||||
constructor(data: any) {
|
constructor(data: any) {
|
||||||
@@ -224,3 +225,12 @@ export class GitHubReposPaneComponent {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SupportPaneComponent {
|
||||||
|
constructor() {
|
||||||
|
return {
|
||||||
|
viewModel: PaneComponent,
|
||||||
|
template: SupportPaneTemplate
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
35
src/Explorer/Panes/SupportPane.html
Normal file
35
src/Explorer/Panes/SupportPane.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<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="supportpane">
|
||||||
|
<!-- Save Query form -- Start -->
|
||||||
|
<div class="contextual-pane-in">
|
||||||
|
<div class="paneContentContainer">
|
||||||
|
<!-- Save Query 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>
|
||||||
|
<!-- Save Query header - End -->
|
||||||
|
|
||||||
|
<!-- Save Query inputs - Start -->
|
||||||
|
<div class="paneMainContent">
|
||||||
|
<div class="pkPadding" style="height: 100%;" data-bind="react: supportPaneComponentAdapter"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Save Query form - Start -->
|
||||||
|
<!-- Loader - Start -->
|
||||||
|
<div class="dataExplorerLoaderContainer dataExplorerPaneLoaderContainer" data-bind="visible: isExecuting">
|
||||||
|
<img class="dataExplorerLoader" src="/LoadingIndicator_3Squares.gif" />
|
||||||
|
</div>
|
||||||
|
<!-- Loader - End -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
28
src/Explorer/Panes/SupportPane.ts
Normal file
28
src/Explorer/Panes/SupportPane.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
|
import { ContextualPaneBase } from "./ContextualPaneBase";
|
||||||
|
import { SupportPaneComponentAdapter } from "../Controls/SupportPaneComponent/SupportPaneComponentAdapter";
|
||||||
|
|
||||||
|
export class SupportPane extends ContextualPaneBase {
|
||||||
|
public supportPaneComponentAdapter: SupportPaneComponentAdapter;
|
||||||
|
|
||||||
|
constructor(options: ViewModels.PaneOptions) {
|
||||||
|
super(options);
|
||||||
|
this.title("Cosmos DB Chat Assistant");
|
||||||
|
this.resetData();
|
||||||
|
this.supportPaneComponentAdapter = new SupportPaneComponentAdapter(this.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
public open() {
|
||||||
|
super.open();
|
||||||
|
this.supportPaneComponentAdapter.forceRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
public close() {
|
||||||
|
super.close();
|
||||||
|
this.supportPaneComponentAdapter.forceRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
public submit() {
|
||||||
|
// override default behavior because this is not a form
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -516,10 +516,6 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.container.isServerlessEnabled()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const numPartitions = this.collection.quotaInfo().numPartitions;
|
const numPartitions = this.collection.quotaInfo().numPartitions;
|
||||||
return !!this.collection.partitionKeyProperty || numPartitions > 1;
|
return !!this.collection.partitionKeyProperty || numPartitions > 1;
|
||||||
});
|
});
|
||||||
@@ -529,7 +525,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.minRUs = ko.computed<number>(() => {
|
this.minRUs = ko.computed<number>(() => {
|
||||||
if (this.isTryCosmosDBSubscription() || this.container.isServerlessEnabled()) {
|
if (this.isTryCosmosDBSubscription()) {
|
||||||
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
return SharedConstants.CollectionCreation.DefaultCollectionRUs400;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,7 +572,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
|
|
||||||
this.maxRUs = ko.computed<number>(() => {
|
this.maxRUs = ko.computed<number>(() => {
|
||||||
const isTryCosmosDBSubscription = this.isTryCosmosDBSubscription();
|
const isTryCosmosDBSubscription = this.isTryCosmosDBSubscription();
|
||||||
if (isTryCosmosDBSubscription || this.container.isServerlessEnabled()) {
|
if (isTryCosmosDBSubscription) {
|
||||||
return Constants.TryCosmosExperience.maxRU;
|
return Constants.TryCosmosExperience.maxRU;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,7 +748,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
|
|||||||
if (
|
if (
|
||||||
this.rupm() === Constants.RUPMStates.on &&
|
this.rupm() === Constants.RUPMStates.on &&
|
||||||
this.throughput() >
|
this.throughput() >
|
||||||
SharedConstants.CollectionCreation.MaxRUPMPerPartition * this.collection.quotaInfo()?.numPartitions
|
SharedConstants.CollectionCreation.MaxRUPMPerPartition * this.collection.quotaInfo().numPartitions
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
/**
|
/**
|
||||||
* JupyterLab applications based on jupyterLab components
|
* JupyterLab applications based on jupyterLab components
|
||||||
*/
|
*/
|
||||||
import { ServerConnection, TerminalManager } from "@jupyterlab/services";
|
import { ServerConnection, TerminalSession } from "@jupyterlab/services";
|
||||||
import { Terminal } from "@jupyterlab/terminal";
|
import { Terminal } from "@jupyterlab/terminal";
|
||||||
import { Panel, Widget } from "@phosphor/widgets";
|
import { Panel, Widget } from "@phosphor/widgets";
|
||||||
|
|
||||||
export class JupyterLabAppFactory {
|
export class JupyterLabAppFactory {
|
||||||
public static async createTerminalApp(serverSettings: ServerConnection.ISettings) {
|
public static async createTerminalApp(serverSettings: ServerConnection.ISettings) {
|
||||||
const manager = new TerminalManager({
|
const session = await TerminalSession.startNew({
|
||||||
serverSettings: serverSettings
|
serverSettings: serverSettings
|
||||||
});
|
});
|
||||||
const session = await manager.startNew();
|
|
||||||
const term = new Terminal(session, { theme: "dark", shutdownOnClose: true });
|
const term = new Terminal(session, { theme: "dark", shutdownOnClose: true });
|
||||||
|
|
||||||
if (!term) {
|
if (!term) {
|
||||||
@@ -22,7 +21,7 @@ export class JupyterLabAppFactory {
|
|||||||
term.addClass("terminalWidget");
|
term.addClass("terminalWidget");
|
||||||
|
|
||||||
let panel = new Panel();
|
let panel = new Panel();
|
||||||
panel.addWidget(term as any);
|
panel.addWidget(term);
|
||||||
panel.id = "main";
|
panel.id = "main";
|
||||||
|
|
||||||
// Attach the widget to the dom.
|
// Attach the widget to the dom.
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ const createServerSettings = (urlVars: { [key: string]: string }): ServerConnect
|
|||||||
options = {
|
options = {
|
||||||
baseUrl: server,
|
baseUrl: server,
|
||||||
token: urlVars[TerminalQueryParams.Token],
|
token: urlVars[TerminalQueryParams.Token],
|
||||||
appendToken: true,
|
|
||||||
init: { body },
|
init: { body },
|
||||||
fetch: window.parent.fetch
|
fetch: window.parent.fetch
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
import { armRequest } from "./request";
|
import { armRequest } from "./request";
|
||||||
import fetch from "node-fetch";
|
|
||||||
|
|
||||||
interface Global {
|
|
||||||
Headers: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
((global as unknown) as Global).Headers = ((fetch as unknown) as Global).Headers;
|
|
||||||
|
|
||||||
describe("ARM request", () => {
|
describe("ARM request", () => {
|
||||||
it("should call window.fetch", async () => {
|
it("should call window.fetch", async () => {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ Instead, generate ARM clients that consume this function with stricter typing.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import promiseRetry, { AbortError } from "p-retry";
|
import promiseRetry, { AbortError } from "p-retry";
|
||||||
import { configContext } from "../../ConfigContext";
|
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
|
|
||||||
interface ErrorResponse {
|
interface ErrorResponse {
|
||||||
@@ -44,7 +43,7 @@ interface Options {
|
|||||||
// TODO: This is very similar to what is happening in ResourceProviderClient.ts. Should probably merge them.
|
// TODO: This is very similar to what is happening in ResourceProviderClient.ts. Should probably merge them.
|
||||||
export async function armRequest<T>({ host, path, apiVersion, method, body: requestBody }: Options): Promise<T> {
|
export async function armRequest<T>({ host, path, apiVersion, method, body: requestBody }: Options): Promise<T> {
|
||||||
const url = new URL(path, host);
|
const url = new URL(path, host);
|
||||||
url.searchParams.append("api-version", configContext.armAPIVersion || apiVersion);
|
url.searchParams.append("api-version", apiVersion);
|
||||||
const response = await window.fetch(url.href, {
|
const response = await window.fetch(url.href, {
|
||||||
method,
|
method,
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -7,8 +7,10 @@
|
|||||||
<title>Azure Cosmos DB</title>
|
<title>Azure Cosmos DB</title>
|
||||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="flexContainer">
|
<div class="flexContainer">
|
||||||
<div id="divExplorer" class="flexContainer hideOverflows" style="display: none">
|
<div id="divExplorer" class="flexContainer hideOverflows" style="display: none">
|
||||||
<!-- Main Command Bar - Start -->
|
<!-- Main Command Bar - Start -->
|
||||||
@@ -289,6 +291,7 @@
|
|||||||
<upload-file-pane params="{data: uploadFilePane}"></upload-file-pane>
|
<upload-file-pane params="{data: uploadFilePane}"></upload-file-pane>
|
||||||
<string-input-pane params="{data: stringInputPane}"></string-input-pane>
|
<string-input-pane params="{data: stringInputPane}"></string-input-pane>
|
||||||
<setup-notebooks-pane params="{data: setupNotebooksPane}"></setup-notebooks-pane>
|
<setup-notebooks-pane params="{data: setupNotebooksPane}"></setup-notebooks-pane>
|
||||||
|
<support-pane params="{data: supportPane}"></support-pane>
|
||||||
|
|
||||||
<!-- ko if: isGitHubPaneEnabled -->
|
<!-- ko if: isGitHubPaneEnabled -->
|
||||||
<github-repos-pane params="{data: gitHubReposPane}"></github-repos-pane>
|
<github-repos-pane params="{data: gitHubReposPane}"></github-repos-pane>
|
||||||
|
|||||||
Reference in New Issue
Block a user