Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
0db8ac271b Bump path-parse from 1.0.6 to 1.0.7
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-13 00:54:01 +00:00
36 changed files with 2986 additions and 2157 deletions

View File

@@ -21,8 +21,16 @@ src/Common/MongoUtility.ts
src/Common/NotificationsClientBase.ts
src/Common/QueriesClient.ts
src/Common/Splitter.ts
src/Config.ts
src/Contracts/ActionContracts.ts
src/Contracts/DataModels.ts
src/Contracts/Diagnostics.ts
src/Contracts/ExplorerContracts.ts
src/Contracts/Versions.ts
src/Contracts/ViewModels.ts
src/Controls/Heatmap/Heatmap.test.ts
src/Controls/Heatmap/Heatmap.ts
src/Controls/Heatmap/HeatmapDatatypes.ts
src/Definitions/datatables.d.ts
src/Definitions/gif.d.ts
src/Definitions/globals.d.ts
@@ -36,10 +44,29 @@ src/Definitions/png.d.ts
src/Definitions/svg.d.ts
src/Explorer/ComponentRegisterer.test.ts
src/Explorer/ComponentRegisterer.ts
src/Explorer/Controls/CollapsiblePanel/CollapsiblePanelComponent.ts
src/Explorer/Controls/DiffEditor/DiffEditorComponent.ts
src/Explorer/Controls/DynamicList/DynamicList.test.ts
src/Explorer/Controls/DynamicList/DynamicListComponent.ts
src/Explorer/Controls/Editor/EditorComponent.ts
src/Explorer/Controls/ErrorDisplayComponent/ErrorDisplayComponent.ts
src/Explorer/Controls/InputTypeahead/InputTypeahead.ts
src/Explorer/Controls/JsonEditor/JsonEditorComponent.ts
src/Explorer/Controls/Notebook/NotebookAppMessageHandler.ts
src/Explorer/Controls/ThroughputInput/ThroughputInputComponent.ts
src/Explorer/Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3.ts
src/Explorer/Controls/Toolbar/IToolbarAction.ts
src/Explorer/Controls/Toolbar/IToolbarDisplayable.ts
src/Explorer/Controls/Toolbar/IToolbarDropDown.ts
src/Explorer/Controls/Toolbar/IToolbarItem.ts
src/Explorer/Controls/Toolbar/IToolbarSeperator.ts
src/Explorer/Controls/Toolbar/IToolbarToggle.ts
src/Explorer/Controls/Toolbar/KeyCodes.ts
src/Explorer/Controls/Toolbar/Toolbar.ts
src/Explorer/Controls/Toolbar/ToolbarAction.ts
src/Explorer/Controls/Toolbar/ToolbarDropDown.ts
src/Explorer/Controls/Toolbar/ToolbarToggle.ts
src/Explorer/Controls/Toolbar/Utilities.ts
src/Explorer/DataSamples/ContainerSampleGenerator.test.ts
src/Explorer/DataSamples/ContainerSampleGenerator.ts
src/Explorer/DataSamples/DataSamplesUtil.test.ts

View File

@@ -143,7 +143,7 @@ jobs:
- ./test/mongo/container.spec.ts
- ./test/mongo/container32.spec.ts
- ./test/selfServe/selfServeExample.spec.ts
# - ./test/notebooks/upload.spec.ts // TEMP disabled since notebooks service is off
- ./test/notebooks/upload.spec.ts
- ./test/sql/resourceToken.spec.ts
- ./test/tables/container.spec.ts
steps:

View File

Before

Width:  |  Height:  |  Size: 842 B

After

Width:  |  Height:  |  Size: 842 B

View File

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 371 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -9,7 +9,6 @@
@DataExplorerFont: wf_segoe-ui_normal, "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif;
@SemiboldFont: "Segoe UI Semibold", "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif;
@GrayScale: "grayscale()";
@xSmallFontSize: 4px;
@smallFontSize: 8px;

View File

@@ -19,10 +19,6 @@
.notebookHeader {
font-size: 12px;
}
.clickDisabled {
pointer-events: none;
}
}

4647
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -48,9 +48,9 @@
"applicationinsights": "1.8.0",
"bootstrap": "3.4.1",
"canvas": "file:./canvas",
"clean-webpack-plugin": "3.0.0",
"clean-webpack-plugin": "0.1.19",
"clipboard-copy": "4.0.1",
"copy-webpack-plugin": "9.0.1",
"copy-webpack-plugin": "6.0.2",
"crossroads": "0.12.2",
"css-element-queries": "1.1.1",
"d3": "6.1.1",
@@ -81,10 +81,10 @@
"plotly.js-cartesian-dist-min": "1.52.3",
"post-robot": "10.0.42",
"q": "1.5.1",
"react": "16.14.0",
"react": "16.13.1",
"react-animate-height": "2.0.8",
"react-dnd": "14.0.2",
"react-dnd-html5-backend": "14.0.0",
"react-dnd": "9.4.0",
"react-dnd-html5-backend": "9.4.0",
"react-dom": "16.13.1",
"react-hotkeys": "2.0.0",
"react-i18next": "11.8.5",
@@ -98,7 +98,7 @@
"sanitize-html": "2.3.3",
"styled-components": "4.3.2",
"swr": "0.4.0",
"terser-webpack-plugin": "5.1.4",
"terser-webpack-plugin": "3.1.0",
"underscore": "1.9.1",
"utility-types": "3.10.0",
"zustand": "3.5.0"
@@ -132,7 +132,6 @@
"@types/underscore": "1.7.36",
"@typescript-eslint/eslint-plugin": "4.22.0",
"@typescript-eslint/parser": "4.22.0",
"@webpack-cli/serve": "1.5.2",
"babel-jest": "24.9.0",
"babel-loader": "8.1.0",
"buffer": "5.1.0",
@@ -154,45 +153,44 @@
"html-inline-css-webpack-plugin": "1.11.0",
"html-loader": "0.5.5",
"html-loader-jest": "0.2.1",
"html-webpack-plugin": "5.3.2",
"jest": "26.6.3",
"jest-canvas-mock": "2.3.1",
"html-webpack-plugin": "4.5.2",
"jest": "25.5.4",
"jest-canvas-mock": "2.1.0",
"jest-playwright-preset": "1.5.1",
"jest-trx-results-processor": "0.0.7",
"less": "3.8.1",
"less-loader": "4.1.0",
"less-vars-loader": "1.1.0",
"mini-css-extract-plugin": "2.1.0",
"mini-css-extract-plugin": "0.4.3",
"monaco-editor-webpack-plugin": "1.7.0",
"node-fetch": "2.6.1",
"playwright": "1.13.0",
"prettier": "2.2.1",
"process": "0.11.10",
"raw-loader": "0.5.1",
"react-dev-utils": "11.0.4",
"rimraf": "3.0.0",
"sinon": "3.2.1",
"style-loader": "0.23.0",
"ts-loader": "9.2.4",
"ts-loader": "6.2.2",
"tslint": "5.11.0",
"tslint-microsoft-contrib": "6.0.0",
"typedoc": "0.20.36",
"typescript": "4.3.4",
"url-loader": "1.1.1",
"wait-on": "4.0.2",
"webpack": "5.47.0",
"webpack-bundle-analyzer": "4.4.2",
"webpack-cli": "4.7.2",
"webpack-dev-server": "3.11.2"
"webpack": "4.46.0",
"webpack-bundle-analyzer": "3.6.1",
"webpack-cli": "3.3.10",
"webpack-dev-server": "3.11.0"
},
"scripts": {
"start": "webpack serve --mode development",
"start": "node --max-old-space-size=10196 node_modules/webpack-dev-server/bin/webpack-dev-server.js",
"dev": "echo \"WARNING: npm run dev has been deprecated\" && npm run build",
"build:dataExplorer:ci": "npm run build:ci",
"build": "npm run format:check && npm run lint && npm run compile && npm run compile:strict && npm run pack:prod && npm run copyToConsumers",
"build:ci": "npm run format:check && npm run lint && npm run compile && npm run compile:strict && npm run pack:fast",
"pack:prod": "webpack --mode production",
"pack:fast": "webpack --mode development --progress",
"pack:prod": "node --max_old_space_size=10196 ./node_modules/webpack/bin/webpack.js --mode production",
"pack:fast": "node --max_old_space_size=10196 ./node_modules/webpack/bin/webpack.js --mode development --progress",
"copyToConsumers": "node copyToConsumers",
"test": "rimraf coverage && jest",
"test:e2e": "jest -c ./jest.config.playwright.js --detectOpenHandles",

View File

@@ -350,11 +350,6 @@ export class Notebook {
public static readonly kernelRestartInitialDelayMs = 1000;
public static readonly kernelRestartMaxDelayMs = 20000;
public static readonly autoSaveIntervalMs = 120000;
public static readonly temporarilyDownMsg = "Notebooks is currently not available. We are working on it.";
public static readonly mongoShellTemporarilyDownMsg =
"We have identified an issue with the Mongo Shell and it is unavailable right now. We are actively working on the mitigation.";
public static readonly cassandraShellTemporarilyDownMsg =
"We have identified an issue with the Cassandra Shell and it is unavailable right now. We are actively working on the mitigation.";
}
export class SparkLibrary {

View File

@@ -22,8 +22,8 @@ describe("The Heatmap Control", () => {
};
let heatmap: Heatmap;
const theme: PortalTheme = 1;
const divElement = `<div id="${Heatmap.elementId}"></div>`;
let theme: PortalTheme = 1;
const divElement: string = `<div id="${Heatmap.elementId}"></div>`;
describe("drawHeatmap rendering", () => {
beforeEach(() => {
@@ -100,7 +100,7 @@ describe("iframe rendering when there is no data", () => {
});
it("should show a no data message with a dark theme", () => {
const data = {
let data = {
data: {
signature: "pcIframe",
data: {
@@ -111,7 +111,7 @@ describe("iframe rendering when there is no data", () => {
},
};
const divElement = `<div id="${Heatmap.elementId}"></div>`;
const divElement: string = `<div id="${Heatmap.elementId}"></div>`;
document.body.innerHTML = divElement;
handleMessage(data as MessageEvent);
@@ -120,7 +120,7 @@ describe("iframe rendering when there is no data", () => {
});
it("should show a no data message with a white theme", () => {
const data = {
let data = {
data: {
signature: "pcIframe",
data: {
@@ -131,7 +131,7 @@ describe("iframe rendering when there is no data", () => {
},
};
const divElement = `<div id="${Heatmap.elementId}"></div>`;
const divElement: string = `<div id="${Heatmap.elementId}"></div>`;
document.body.innerHTML = divElement;
handleMessage(data as MessageEvent);

View File

@@ -39,7 +39,7 @@ export class Heatmap {
}
}
private _getFontStyles(size: number = StyleConstants.MediumFontSize, color = "#838383"): FontSettings {
private _getFontStyles(size: number = StyleConstants.MediumFontSize, color: string = "#838383"): FontSettings {
return {
family: StyleConstants.DataExplorerFont,
size,
@@ -78,9 +78,9 @@ export class Heatmap {
// go thru all rows and create 2d matrix for heatmap...
for (let i = 0; i < rows.length; i++) {
output.yAxisPoints.push(rows[i]);
const dataPoints: number[] = [];
let dataPoints: number[] = [];
for (let a = 0; a < output.xAxisPoints.length; a++) {
const row: PartitionTimeStampToData = data[rows[i]];
let row: PartitionTimeStampToData = data[rows[i]];
dataPoints.push(row[output.xAxisPoints[a]]["Normalized Throughput"]);
}
output.dataPoints.push(dataPoints);
@@ -193,7 +193,7 @@ export class Heatmap {
this._getLayoutSettings(),
this._getChartDisplaySettings()
);
const plotDiv: any = document.getElementById(Heatmap.elementId);
let plotDiv: any = document.getElementById(Heatmap.elementId);
plotDiv.on("plotly_click", (data: any) => {
let timeSelected: string = data.points[0].x;
timeSelected = timeSelected.replace(" ", "T");
@@ -205,7 +205,7 @@ export class Heatmap {
break;
}
}
const output = [];
let output = [];
for (let i = 0; i < this._chartData.dataPoints.length; i++) {
output.push(this._chartData.dataPoints[i][xAxisIndex]);
}

View File

@@ -83,7 +83,6 @@ export const createCollectionContextMenuButton = (
items.push({
iconSrc: HostedTerminalIcon,
isDisabled: useNotebook.getState().isShellEnabled && userContext.features.notebooksTemporarilyDown,
onClick: () => {
const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection();
if (useNotebook.getState().isShellEnabled) {

View File

@@ -1084,13 +1084,11 @@ export default class Explorer {
dataExplorerArea: Constants.Areas.Notebook,
});
if (!userContext.features.notebooksTemporarilyDown) {
if (isNotebookEnabled) {
await this.initNotebooks(userContext.databaseAccount);
} else if (this.notebookToImport) {
// if notebooks is not enabled but the user is trying to do a quickstart setup with notebooks, open the SetupNotebooksPane
this._openSetupNotebooksPaneForQuickstart();
}
if (isNotebookEnabled) {
await this.initNotebooks(userContext.databaseAccount);
} else if (this.notebookToImport) {
// if notebooks is not enabled but the user is trying to do a quickstart setup with notebooks, open the SetupNotebooksPane
this._openSetupNotebooksPaneForQuickstart();
}
}
}

View File

@@ -6,9 +6,9 @@
import * as React from "react";
import CancelIcon from "../../../../images/cancel.svg";
import CheckIcon from "../../../../images/check-1.svg";
import CheckIcon from "../../../../images/check.svg";
import DeleteIcon from "../../../../images/delete.svg";
import EditIcon from "../../../../images/edit-1.svg";
import EditIcon from "../../../../images/edit.svg";
import * as ViewModels from "../../../Contracts/ViewModels";
import { AccessibleElement } from "../../Controls/AccessibleElement/AccessibleElement";
import { CollapsiblePanel } from "../../Controls/CollapsiblePanel/CollapsiblePanel";

View File

@@ -103,25 +103,19 @@ describe("CommandBarComponentButtonFactory tests", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel);
//TODO: modify once notebooks are available
expect(enableNotebookBtn).toBeUndefined();
//expect(enableNotebookBtn).toBeDefined();
//expect(enableNotebookBtn.disabled).toBe(false);
//expect(enableNotebookBtn.tooltipText).toBe("");
expect(enableNotebookBtn).toBeDefined();
expect(enableNotebookBtn.disabled).toBe(false);
expect(enableNotebookBtn.tooltipText).toBe("");
});
it("Notebooks is not enabled and is unavailable - button should be shown and disabled", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const enableNotebookBtn = buttons.find((button) => button.commandButtonLabel === enableNotebookBtnLabel);
//TODO: modify once notebooks are available
expect(enableNotebookBtn).toBeUndefined();
//expect(enableNotebookBtn).toBeDefined();
//expect(enableNotebookBtn.disabled).toBe(true);
//expect(enableNotebookBtn.tooltipText).toBe(
// "Notebooks are not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks."
//);
expect(enableNotebookBtn).toBeDefined();
expect(enableNotebookBtn.disabled).toBe(true);
expect(enableNotebookBtn.tooltipText).toBe(
"Notebooks are not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks."
);
});
});
@@ -198,11 +192,8 @@ describe("CommandBarComponentButtonFactory tests", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openMongoShellBtn.disabled).toBe(true);
//expect(openMongoShellBtn.disabled).toBe(false);
//expect(openMongoShellBtn.tooltipText).toBe("");
expect(openMongoShellBtn.disabled).toBe(false);
expect(openMongoShellBtn.tooltipText).toBe("");
});
it("Notebooks is enabled and is available - button should be shown and enabled", () => {
@@ -212,11 +203,8 @@ describe("CommandBarComponentButtonFactory tests", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openMongoShellBtn.disabled).toBe(true);
//expect(openMongoShellBtn.disabled).toBe(false);
//expect(openMongoShellBtn.tooltipText).toBe("");
expect(openMongoShellBtn.disabled).toBe(false);
expect(openMongoShellBtn.tooltipText).toBe("");
});
it("Notebooks is enabled and is available, terminal is unavailable due to ipRules - button should be hidden", () => {
@@ -302,13 +290,9 @@ describe("CommandBarComponentButtonFactory tests", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openCassandraShellBtn.disabled).toBe(true);
//expect(openCassandraShellBtn.disabled).toBe(false);
//expect(openCassandraShellBtn.tooltipText).toBe("");
expect(openCassandraShellBtn.disabled).toBe(false);
expect(openCassandraShellBtn.tooltipText).toBe("");
});
it("Notebooks is enabled and is available - button should be shown and enabled", () => {
@@ -318,11 +302,8 @@ describe("CommandBarComponentButtonFactory tests", () => {
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeDefined();
//TODO: modify once notebooks are available
expect(openCassandraShellBtn.disabled).toBe(true);
//expect(openCassandraShellBtn.disabled).toBe(false);
//expect(openCassandraShellBtn.tooltipText).toBe("");
expect(openCassandraShellBtn.disabled).toBe(false);
expect(openCassandraShellBtn.tooltipText).toBe("");
});
});

View File

@@ -67,50 +67,35 @@ export function createStaticCommandBarButtons(
newCollectionBtn.children.push(newDatabaseBtn);
}
if (useNotebook.getState().isNotebookEnabled) {
buttons.push(createDivider());
const notebookButtons: CommandButtonComponentProps[] = [];
buttons.push(createDivider());
if (useNotebook.getState().isNotebookEnabled) {
const newNotebookButton = createNewNotebookButton(container);
newNotebookButton.children = [createNewNotebookButton(container), createuploadNotebookButton(container)];
notebookButtons.push(newNotebookButton);
buttons.push(newNotebookButton);
if (container.notebookManager?.gitHubOAuthService) {
notebookButtons.push(createManageGitHubAccountButton(container));
buttons.push(createManageGitHubAccountButton(container));
}
notebookButtons.push(createOpenTerminalButton(container));
buttons.push(createOpenTerminalButton(container));
notebookButtons.push(createNotebookWorkspaceResetButton(container));
buttons.push(createNotebookWorkspaceResetButton(container));
if (
(userContext.apiType === "Mongo" &&
useNotebook.getState().isShellEnabled &&
selectedNodeState.isDatabaseNodeOrNoneSelected()) ||
userContext.apiType === "Cassandra"
) {
notebookButtons.push(createDivider());
buttons.push(createDivider());
if (userContext.apiType === "Cassandra") {
notebookButtons.push(createOpenCassandraTerminalButton(container));
buttons.push(createOpenCassandraTerminalButton(container));
} else {
notebookButtons.push(createOpenMongoTerminalButton(container));
buttons.push(createOpenMongoTerminalButton(container));
}
}
notebookButtons.forEach((btn) => {
if (userContext.features.notebooksTemporarilyDown) {
if (btn.commandButtonLabel.indexOf("Cassandra") !== -1) {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.cassandraShellTemporarilyDownMsg);
} else if (btn.commandButtonLabel.indexOf("Mongo") !== -1) {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.mongoShellTemporarilyDownMsg);
} else {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.temporarilyDownMsg);
}
}
buttons.push(btn);
});
} else {
if (!isRunningOnNationalCloud() && !userContext.features.notebooksTemporarilyDown) {
buttons.push(createDivider());
if (!isRunningOnNationalCloud()) {
buttons.push(createEnableNotebooksButton(container));
}
}
@@ -167,9 +152,7 @@ export function createContextCommandBarButtons(
onCommandClick: () => {
const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection();
if (useNotebook.getState().isShellEnabled) {
if (!userContext.features.notebooksTemporarilyDown) {
container.openNotebookTerminal(ViewModels.TerminalKind.Mongo);
}
container.openNotebookTerminal(ViewModels.TerminalKind.Mongo);
} else {
selectedCollection && selectedCollection.onNewMongoShellClick();
}
@@ -177,13 +160,7 @@ export function createContextCommandBarButtons(
commandButtonLabel: label,
ariaLabel: label,
hasPopup: true,
tooltipText:
useNotebook.getState().isShellEnabled && userContext.features.notebooksTemporarilyDown
? Constants.Notebook.mongoShellTemporarilyDownMsg
: undefined,
disabled:
(selectedNodeState.isDatabaseNodeOrNoneSelected() && userContext.apiType === "Mongo") ||
(useNotebook.getState().isShellEnabled && userContext.features.notebooksTemporarilyDown),
disabled: selectedNodeState.isDatabaseNodeOrNoneSelected() && userContext.apiType === "Mongo",
};
buttons.push(newMongoShellBtn);
}
@@ -411,13 +388,6 @@ export function createScriptCommandButtons(selectedNodeState: SelectedNodeState)
return buttons;
}
function applyNotebooksTemporarilyDownStyle(buttonProps: CommandButtonComponentProps, tooltip: string): void {
if (!buttonProps.isDivider) {
buttonProps.disabled = true;
buttonProps.tooltipText = tooltip;
}
}
function createNewNotebookButton(container: Explorer): CommandButtonComponentProps {
const label = "New Notebook";
return {

View File

@@ -22,13 +22,6 @@ import { MemoryTracker } from "./MemoryTrackerComponent";
export const convertButton = (btns: CommandButtonComponentProps[], backgroundColor: string): ICommandBarItemProps[] => {
const buttonHeightPx = StyleConstants.CommandBarButtonHeight;
const getFilter = (isDisabled: boolean): string => {
if (isDisabled) {
return StyleConstants.GrayScale;
}
return undefined;
};
return btns
.filter((btn) => btn)
.map(
@@ -44,7 +37,6 @@ export const convertButton = (btns: CommandButtonComponentProps[], backgroundCol
style: {
width: StyleConstants.CommandBarIconWidth, // 16
alignSelf: btn.iconName ? "baseline" : undefined,
filter: getFilter(btn.disabled),
},
imageProps: btn.iconSrc ? { src: btn.iconSrc, alt: btn.iconAlt } : undefined,
iconName: btn.iconName,
@@ -131,12 +123,8 @@ export const convertButton = (btns: CommandButtonComponentProps[], backgroundCol
width: 12,
paddingLeft: 1,
paddingTop: 6,
filter: getFilter(btn.disabled),
},
imageProps: {
src: ChevronDownIcon,
alt: btn.iconAlt,
},
imageProps: { src: ChevronDownIcon, alt: btn.iconAlt },
};
}

View File

@@ -6,7 +6,7 @@ import { Dropdown, IDropdownOption } from "@fluentui/react";
import * as React from "react";
import AnimateHeight from "react-animate-height";
import LoaderIcon from "../../../../images/circular_loader_black_16x16.gif";
import ClearIcon from "../../../../images/Clear-1.svg";
import ClearIcon from "../../../../images/Clear.svg";
import ErrorBlackIcon from "../../../../images/error_black.svg";
import ErrorRedIcon from "../../../../images/error_red.svg";
import infoBubbleIcon from "../../../../images/info-bubble-9x9.svg";

View File

@@ -18,7 +18,7 @@ const EditorContainer = styled.div`
`;
interface MappedStateProps {
mimetype: string | null;
mimetype: string;
text: string;
contentRef: ContentRef;
theme?: "light" | "dark";
@@ -37,7 +37,7 @@ interface TextFileState {
class EditorPlaceholder extends React.PureComponent<MonacoEditorProps> {
render(): JSX.Element {
// TODO: Show a little blocky placeholder
return <div />;
return undefined;
}
}
@@ -83,7 +83,7 @@ interface InitialProps {
}
function makeMapStateToTextFileProps(
_initialState: AppState,
initialState: AppState,
initialProps: InitialProps
): (state: AppState) => MappedStateProps {
const { contentRef } = initialProps;
@@ -106,7 +106,7 @@ function makeMapStateToTextFileProps(
}
const makeMapDispatchToTextFileProps = (
_initialDispatch: Dispatch,
initialDispatch: Dispatch,
initialProps: InitialProps
): ((dispatch: Dispatch) => MappedDispatchProps) => {
const { contentRef } = initialProps;

View File

@@ -6,7 +6,7 @@ import CodeMirrorEditor from "@nteract/stateful-components/lib/inputs/connected-
import { PassedEditorProps } from "@nteract/stateful-components/lib/inputs/editor";
import * as React from "react";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import HTML5Backend from "react-dnd-html5-backend";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import { userContext } from "../../../UserContext";

View File

@@ -11,6 +11,7 @@ import {
DropTargetConnector,
DropTargetMonitor,
} from "react-dnd";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import styled, { StyledComponent } from "styled-components";
@@ -122,10 +123,9 @@ export const cellTarget = {
drop(props: Props, monitor: DropTargetMonitor, component: any): void {
if (monitor) {
const hoverUpperHalf = isDragUpper(props, monitor, component.el);
const item: Props = monitor.getItem();
// DropTargetSpec monitor definition could be undefined. we'll need a check for monitor in order to pass validation.
props.moveCell({
id: item.id,
id: monitor.getItem().id,
destinationId: props.id,
above: hoverUpperHalf,
contentRef: props.contentRef,

View File

@@ -99,7 +99,7 @@ export class PureMarkdownCell extends React.Component<ComponentProps & DispatchP
}
export const makeMapStateToProps = (
_initialState: AppState,
initialState: AppState,
ownProps: ComponentProps
): ((state: AppState) => StateProps) => {
const { id, contentRef } = ownProps;
@@ -134,7 +134,7 @@ export const makeMapStateToProps = (
};
const makeMapDispatchToProps = (
_initialDispatch: Dispatch,
initialDispatch: Dispatch,
ownProps: ComponentProps
): ((dispatch: Dispatch) => DispatchProps) => {
const { id, contentRef } = ownProps;

View File

@@ -550,72 +550,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
</Stack>
)}
{this.shouldShowAnalyticalStoreOptions() && (
<Stack className="panelGroupSpacing">
<Stack horizontal>
<Text className="panelTextBold" variant="small">
Analytical store
</Text>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content={this.getAnalyticalStorageTooltipContent()}
>
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
<Stack horizontal verticalAlign="center">
<input
className="panelRadioBtn"
checked={this.state.enableAnalyticalStore}
disabled={!this.isSynapseLinkEnabled()}
aria-label="Enable analytical store"
aria-checked={this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
role="radio"
id="enableAnalyticalStoreBtn"
tabIndex={0}
onChange={this.onEnableAnalyticalStoreRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">On</span>
<input
className="panelRadioBtn"
checked={!this.state.enableAnalyticalStore}
disabled={!this.isSynapseLinkEnabled()}
aria-label="Disable analytical store"
aria-checked={!this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
role="radio"
id="disableAnalyticalStoreBtn"
tabIndex={0}
onChange={this.onDisableAnalyticalStoreRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">Off</span>
</Stack>
{!this.isSynapseLinkEnabled() && (
<Stack className="panelGroupSpacing">
<Text variant="small">
Azure Synapse Link is required for creating an analytical store{" "}
{getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account.{" "}
<Link href="https://aka.ms/cosmosdb-synapselink" target="_blank">
Learn more
</Link>
</Text>
<DefaultButton
text="Enable"
onClick={() => this.props.explorer.openEnableSynapseLinkDialog()}
style={{ height: 27, width: 80 }}
styles={{ label: { fontSize: 12 } }}
/>
</Stack>
)}
</Stack>
)}
{userContext.apiType !== "Tables" && (
<CollapsibleSectionComponent
title="Advanced"
@@ -670,6 +604,72 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
}
/>
)}
{this.shouldShowAnalyticalStoreOptions() && (
<Stack className="panelGroupSpacing">
<Stack horizontal>
<Text className="panelTextBold" variant="small">
Analytical store
</Text>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content={this.getAnalyticalStorageTooltipContent()}
>
<Icon iconName="Info" className="panelInfoIcon" />
</TooltipHost>
</Stack>
<Stack horizontal verticalAlign="center">
<input
className="panelRadioBtn"
checked={this.state.enableAnalyticalStore}
disabled={!this.isSynapseLinkEnabled()}
aria-label="Enable analytical store"
aria-checked={this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
role="radio"
id="enableAnalyticalStoreBtn"
tabIndex={0}
onChange={this.onEnableAnalyticalStoreRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">On</span>
<input
className="panelRadioBtn"
checked={!this.state.enableAnalyticalStore}
disabled={!this.isSynapseLinkEnabled()}
aria-label="Disable analytical store"
aria-checked={!this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
role="radio"
id="disableAnalyticalStoreBtn"
tabIndex={0}
onChange={this.onDisableAnalyticalStoreRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">Off</span>
</Stack>
{!this.isSynapseLinkEnabled() && (
<Stack className="panelGroupSpacing">
<Text variant="small">
Azure Synapse Link is required for creating an analytical store{" "}
{getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account.{" "}
<Link href="https://aka.ms/cosmosdb-synapselink" target="_blank">
Learn more
</Link>
</Text>
<DefaultButton
text="Enable"
onClick={() => this.props.explorer.openEnableSynapseLinkDialog()}
style={{ height: 27, width: 80 }}
styles={{ label: { fontSize: 12 } }}
/>
</Stack>
)}
</Stack>
)}
</Stack>
</CollapsibleSectionComponent>
)}

View File

@@ -105,6 +105,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
notebookName,
notebookDescription,
notebookTags?.split(","),
author,
imageSrc,
content
);

View File

@@ -91,7 +91,9 @@ export const UploadItemsPane: FunctionComponent = () => {
accept="application/json"
multiple
tabIndex={0}
tooltip="Select one or more JSON files to upload. Each file can contain a single JSON document or an array of JSON documents. The combined size of all files in an individual upload operation must be less than 2 MB. You can perform multiple upload operations for larger data sets."
tooltip="Select one or more JSON files to upload. Each file can contain a single JSON document or an array of JSON
documents. The combined size of all files in an individual upload operation must be less than 2 MB. You
can perform multiple upload operations for larger data sets."
/>
{uploadFileData?.length > 0 && (
<div className="fileUploadSummaryContainer">

View File

@@ -83,11 +83,7 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
public render(): JSX.Element {
const mainItems = this.createMainItems();
const commonTaskItems = this.createCommonTaskItems();
let recentItems = this.createRecentItems();
if (userContext.features.notebooksTemporarilyDown) {
recentItems = recentItems.filter((item) => item.description !== "Notebook");
}
const recentItems = this.createRecentItems();
const tipsItems = this.createTipsItems();
const onClearRecent = this.clearMostRecent;
@@ -223,7 +219,7 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
});
}
if (useNotebook.getState().isNotebookEnabled && !userContext.features.notebooksTemporarilyDown) {
if (useNotebook.getState().isNotebookEnabled) {
heroes.push({
iconSrc: NewNotebookIcon,
title: "New Notebook",

View File

@@ -11,7 +11,7 @@ import NotebookIcon from "../../../images/notebook/Notebook-resource.svg";
import PublishIcon from "../../../images/notebook/publish_content.svg";
import RefreshIcon from "../../../images/refresh-cosmos.svg";
import CollectionIcon from "../../../images/tree-collection.svg";
import { Areas, Notebook } from "../../Common/Constants";
import { Areas } from "../../Common/Constants";
import { isPublicInternetAccessAllowed } from "../../Common/DatabaseAccountUtility";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
@@ -121,34 +121,23 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
children: [],
};
if (userContext.features.notebooksTemporarilyDown) {
notebooksTree.children.push(buildNotebooksTemporarilyDownTree());
} else {
if (galleryContentRoot) {
notebooksTree.children.push(buildGalleryNotebooksTree());
}
if (galleryContentRoot) {
notebooksTree.children.push(buildGalleryNotebooksTree());
}
if (myNotebooksContentRoot) {
notebooksTree.children.push(buildMyNotebooksTree());
}
if (myNotebooksContentRoot) {
notebooksTree.children.push(buildMyNotebooksTree());
}
if (container.notebookManager?.gitHubOAuthService.isLoggedIn()) {
// collapse all other notebook nodes
notebooksTree.children.forEach((node) => (node.isExpanded = false));
notebooksTree.children.push(buildGitHubNotebooksTree());
}
if (container.notebookManager?.gitHubOAuthService.isLoggedIn()) {
// collapse all other notebook nodes
notebooksTree.children.forEach((node) => (node.isExpanded = false));
notebooksTree.children.push(buildGitHubNotebooksTree());
}
return notebooksTree;
};
const buildNotebooksTemporarilyDownTree = (): TreeNode => {
return {
label: Notebook.temporarilyDownMsg,
className: "clickDisabled",
};
};
const buildGalleryNotebooksTree = (): TreeNode => {
return {
label: "Gallery",
@@ -514,12 +503,7 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
contextMenu: ResourceTreeContextMenuButtonFactory.createCollectionContextMenuButton(container, collection),
});
if (
isNotebookEnabled &&
userContext.apiType === "Mongo" &&
isPublicInternetAccessAllowed() &&
!userContext.features.notebooksTemporarilyDown
) {
if (isNotebookEnabled && userContext.apiType === "Mongo" && isPublicInternetAccessAllowed()) {
children.push({
label: "Schema (Preview)",
onClick: collection.onSchemaAnalyzerClick.bind(collection),

View File

@@ -364,6 +364,7 @@ describe("Gallery", () => {
const name = "name";
const description = "description";
const tags = ["tag"];
const author = "author";
const thumbnailUrl = "thumbnailUrl";
const content = `{ "key": "value" }`;
const addLinkToNotebookViewer = true;
@@ -372,7 +373,7 @@ describe("Gallery", () => {
json: () => undefined as any,
});
const response = await junoClient.publishNotebook(name, description, tags, thumbnailUrl, content);
const response = await junoClient.publishNotebook(name, description, tags, author, thumbnailUrl, content);
const authorizationHeader = getAuthorizationHeader();
expect(response.status).toBe(HttpStatusCodes.OK);
@@ -390,6 +391,7 @@ describe("Gallery", () => {
name,
description,
tags,
author,
thumbnailUrl,
content: JSON.parse(content),
addLinkToNotebookViewer,

View File

@@ -61,6 +61,7 @@ export interface IPublishNotebookRequest {
name: string;
description: string;
tags: string[];
author: string;
thumbnailUrl: string;
content: any;
addLinkToNotebookViewer: boolean;
@@ -358,6 +359,7 @@ export class JunoClient {
name: string,
description: string,
tags: string[],
author: string,
thumbnailUrl: string,
content: string
): Promise<IJunoResponse<IGalleryItem>> {
@@ -368,6 +370,7 @@ export class JunoClient {
name,
description,
tags,
author,
thumbnailUrl,
content: JSON.parse(content),
addLinkToNotebookViewer: true,

View File

@@ -28,7 +28,6 @@ export type Features = {
readonly pr?: string;
readonly showMinRUSurvey: boolean;
readonly ttl90Days: boolean;
readonly notebooksTemporarilyDown: boolean;
};
export function extractFeatures(given = new URLSearchParams(window.location.search)): Features {
@@ -75,6 +74,5 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
autoscaleDefault: "true" === get("autoscaledefault"),
partitionKeyDefault: "true" === get("partitionkeytest"),
partitionKeyDefault2: "true" === get("pkpartitionkeytest"),
notebooksTemporarilyDown: "true" === get("notebookstemporarilydown", "true"),
};
}

View File

@@ -32,9 +32,8 @@ export async function fetchDatabaseAccounts(subscriptionId: string, accessToken:
export function useDatabaseAccounts(subscriptionId: string, armToken: string): DatabaseAccount[] | undefined {
const { data } = useSWR(
// eslint-disable-next-line no-null/no-null
() => (armToken && subscriptionId ? ["databaseAccounts", subscriptionId, armToken] : null),
(_: string, subscriptionId: string, armToken: string) => fetchDatabaseAccounts(subscriptionId, armToken)
() => (armToken && subscriptionId ? ["databaseAccounts", subscriptionId, armToken] : undefined),
(_, subscriptionId, armToken) => fetchDatabaseAccounts(subscriptionId, armToken)
);
return data;
}

View File

@@ -34,9 +34,8 @@ export async function fetchSubscriptions(accessToken: string): Promise<Subscript
export function useSubscriptions(armToken: string): Subscription[] | undefined {
const { data } = useSWR(
// eslint-disable-next-line no-null/no-null
() => (armToken ? ["subscriptions", armToken] : null),
(_: string, armToken: string) => fetchSubscriptions(armToken)
() => (armToken ? ["subscriptions", armToken] : undefined),
(_, armToken) => fetchSubscriptions(armToken)
);
return data;
}

View File

@@ -16,7 +16,7 @@ test("Mongo CRUD", async () => {
await explorer.click('[data-test="New Collection"]');
await explorer.fill('[aria-label="New database id"]', databaseId);
await explorer.fill('[aria-label="Collection id"]', containerId);
await explorer.fill('[aria-label="Shard key"]', "pk");
await explorer.fill('[aria-label="Shard key"]', "/pk");
await explorer.click("#sidePanelOkButton");
await explorer.click(`.nodeItem >> text=${databaseId}`);
await explorer.click(`.nodeItem >> text=${containerId}`);

View File

@@ -8,9 +8,6 @@
"noUnusedParameters": true
},
"files": [
"./src/hooks/useDatabaseAccounts.tsx",
"./src/hooks/useSubscriptions.tsx",
"./src/Explorer/Notebook/NotebookComponent/contents/file/text-file.tsx",
"./src/AuthType.ts",
"./src/Bindings/ReactBindingHandler.ts",
"./src/Common/ArrayHashMap.ts",
@@ -168,4 +165,4 @@
"src/Terminal/**/*",
"src/Utils/arm/**/*"
]
}
}

View File

@@ -9,13 +9,12 @@ const HTMLInlineCSSWebpackPlugin = require("html-inline-css-webpack-plugin").def
const { EnvironmentPlugin } = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
const CreateFileWebpack = require("create-file-webpack");
const childProcess = require("child_process");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const TerserPlugin = require("terser-webpack-plugin");
const webpack = require("webpack");
const isCI = require("is-ci");
const gitSha = childProcess.execSync("git rev-parse HEAD").toString("utf8");
@@ -110,11 +109,7 @@ module.exports = function (_env = {}, argv = {}) {
}
const plugins = [
new CleanWebpackPlugin(),
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
}),
new CleanWebpackPlugin(["dist"]),
new CreateFileWebpack({
path: "./dist",
fileName: "version.txt",
@@ -215,26 +210,23 @@ module.exports = function (_env = {}, argv = {}) {
selfServe: "./src/SelfServe/SelfServe.tsx",
connectToGitHub: "./src/GitHub/GitHubConnector.ts",
},
node: {
util: true,
tls: "empty",
net: "empty",
fs: "empty",
},
output: {
chunkFilename: "[name].[chunkhash:6].js",
filename: "[name].[chunkhash:6].js",
path: path.resolve(__dirname, "dist"),
publicPath: "",
},
devtool: mode === "development" ? "eval-source-map" : "source-map",
devtool: mode === "development" ? "cheap-eval-source-map" : "source-map",
plugins,
module: {
rules,
},
resolve: {
alias: {
process: "process/browser",
},
fallback: {
crypto: false,
fs: false,
},
extensions: [".tsx", ".ts", ".js"],
},
optimization: {
@@ -252,7 +244,7 @@ module.exports = function (_env = {}, argv = {}) {
}),
],
},
watch: false,
watch: isCI || mode === "production" ? false : true,
// Hack since it is hard to disable watch entirely with webpack dev server https://github.com/webpack/webpack-dev-server/issues/1251#issuecomment-654240734
watchOptions: isCI ? { poll: 24 * 60 * 60 * 1000 } : {},
devServer: {