Compare commits

..

1 Commits

Author SHA1 Message Date
sunilyadav840
a10b61b8af migrate refreshNoteBookEnabledStateForAccount to react 2021-04-30 16:02:08 +05:30
306 changed files with 64412 additions and 32142 deletions

View File

@@ -1,5 +1,4 @@
**/node_modules/ **/node_modules/
src/**/__mocks__/**/*
dist/ dist/
Contracts/ Contracts/
src/Api/Apis.ts src/Api/Apis.ts
@@ -54,6 +53,7 @@ src/Explorer/Controls/ErrorDisplayComponent/ErrorDisplayComponent.ts
src/Explorer/Controls/InputTypeahead/InputTypeahead.ts src/Explorer/Controls/InputTypeahead/InputTypeahead.ts
src/Explorer/Controls/JsonEditor/JsonEditorComponent.ts src/Explorer/Controls/JsonEditor/JsonEditorComponent.ts
src/Explorer/Controls/Notebook/NotebookAppMessageHandler.ts src/Explorer/Controls/Notebook/NotebookAppMessageHandler.ts
src/Explorer/Controls/ThroughputInput/ThroughputInput.test.ts
src/Explorer/Controls/ThroughputInput/ThroughputInputComponent.ts src/Explorer/Controls/ThroughputInput/ThroughputInputComponent.ts
src/Explorer/Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3.ts src/Explorer/Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3.ts
src/Explorer/Controls/Toolbar/IToolbarAction.ts src/Explorer/Controls/Toolbar/IToolbarAction.ts
@@ -84,8 +84,8 @@ src/Explorer/Graph/GraphExplorerComponent/GremlinClient.test.ts
src/Explorer/Graph/GraphExplorerComponent/GremlinClient.ts src/Explorer/Graph/GraphExplorerComponent/GremlinClient.ts
src/Explorer/Graph/GraphExplorerComponent/GremlinSimpleClient.test.ts src/Explorer/Graph/GraphExplorerComponent/GremlinSimpleClient.test.ts
src/Explorer/Graph/GraphExplorerComponent/GremlinSimpleClient.ts src/Explorer/Graph/GraphExplorerComponent/GremlinSimpleClient.ts
# src/Explorer/Graph/GraphStyleComponent/GraphStyle.test.ts src/Explorer/Graph/GraphStyleComponent/GraphStyle.test.ts
# src/Explorer/Graph/GraphStyleComponent/GraphStyleComponent.ts src/Explorer/Graph/GraphStyleComponent/GraphStyleComponent.ts
src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.test.ts src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.test.ts
src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.ts src/Explorer/Menus/CommandBar/CommandBarComponentButtonFactory.ts
@@ -108,19 +108,24 @@ src/Explorer/Notebook/NotebookUtil.ts
src/Explorer/OpenActions.test.ts src/Explorer/OpenActions.test.ts
src/Explorer/OpenActions.ts src/Explorer/OpenActions.ts
src/Explorer/OpenActionsStubs.ts src/Explorer/OpenActionsStubs.ts
src/Explorer/Panes/AddDatabasePane.ts src/Explorer/Panes/AddCollectionPane.test.ts
src/Explorer/Panes/AddCollectionPane.ts
src/Explorer/Panes/AddDatabasePane.test.ts src/Explorer/Panes/AddDatabasePane.test.ts
src/Explorer/Panes/AddDatabasePane.ts
src/Explorer/Panes/BrowseQueriesPane.ts src/Explorer/Panes/BrowseQueriesPane.ts
src/Explorer/Panes/CassandraAddCollectionPane.ts src/Explorer/Panes/CassandraAddCollectionPane.ts
src/Explorer/Panes/ContextualPaneBase.ts src/Explorer/Panes/ContextualPaneBase.ts
src/Explorer/Panes/DeleteDatabaseConfirmationPane.test.ts src/Explorer/Panes/DeleteDatabaseConfirmationPane.test.ts
src/Explorer/Panes/DeleteDatabaseConfirmationPane.ts src/Explorer/Panes/DeleteDatabaseConfirmationPane.ts
# src/Explorer/Panes/GraphStylingPane.ts src/Explorer/Panes/GraphStylingPane.ts
# src/Explorer/Panes/NewVertexPane.ts # src/Explorer/Panes/NewVertexPane.ts
src/Explorer/Panes/PaneComponents.ts src/Explorer/Panes/PaneComponents.ts
src/Explorer/Panes/RenewAdHocAccessPane.ts src/Explorer/Panes/RenewAdHocAccessPane.ts
src/Explorer/Panes/SetupNotebooksPane.ts src/Explorer/Panes/SetupNotebooksPane.ts
src/Explorer/Panes/SwitchDirectoryPane.ts src/Explorer/Panes/SwitchDirectoryPane.ts
src/Explorer/Panes/Tables/EditTableEntityPane.ts
src/Explorer/Panes/Tables/EntityPropertyViewModel.ts
src/Explorer/Panes/Tables/TableEntityPane.ts
src/Explorer/Panes/Tables/Validators/EntityPropertyNameValidator.ts src/Explorer/Panes/Tables/Validators/EntityPropertyNameValidator.ts
src/Explorer/Panes/Tables/Validators/EntityPropertyValidationCommon.ts src/Explorer/Panes/Tables/Validators/EntityPropertyValidationCommon.ts
src/Explorer/Panes/Tables/Validators/EntityPropertyValueValidator.ts src/Explorer/Panes/Tables/Validators/EntityPropertyValueValidator.ts

View File

@@ -11,7 +11,6 @@ module.exports = {
}, },
parser: "@typescript-eslint/parser", parser: "@typescript-eslint/parser",
parserOptions: { parserOptions: {
project: ["./tsconfig.json", "./tsconfig.test.json"],
ecmaFeatures: { ecmaFeatures: {
jsx: true, jsx: true,
}, },
@@ -36,7 +35,6 @@ module.exports = {
rules: { rules: {
"no-console": ["error", { allow: ["error", "warn", "dir"] }], "no-console": ["error", { allow: ["error", "warn", "dir"] }],
curly: "error", curly: "error",
"@typescript-eslint/switch-exhaustiveness-check": "error",
"@typescript-eslint/no-unused-vars": "error", "@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-extraneous-class": "error", "@typescript-eslint/no-extraneous-class": "error",
"no-null/no-null": "error", "no-null/no-null": "error",

View File

@@ -138,10 +138,8 @@ jobs:
matrix: matrix:
test-file: test-file:
- ./test/cassandra/container.spec.ts - ./test/cassandra/container.spec.ts
- ./test/graph/container.spec.ts
- ./test/sql/container.spec.ts - ./test/sql/container.spec.ts
- ./test/mongo/container.spec.ts - ./test/mongo/container.spec.ts
- ./test/mongo/container32.spec.ts
- ./test/selfServe/selfServeExample.spec.ts - ./test/selfServe/selfServeExample.spec.ts
- ./test/notebooks/upload.spec.ts - ./test/notebooks/upload.spec.ts
- ./test/sql/resourceToken.spec.ts - ./test/sql/resourceToken.spec.ts

View File

@@ -188,3 +188,7 @@ Cosmos Explorer has been under constant development for over 5 years. As a resul
✅ DO ✅ DO
- Support all [browsers supported by the Azure Portal](https://docs.microsoft.com/en-us/azure/azure-portal/azure-portal-supported-browsers-devices) - Support all [browsers supported by the Azure Portal](https://docs.microsoft.com/en-us/azure/azure-portal/azure-portal-supported-browsers-devices)
- Support IE11
- In practice, this should not need to be considered as part of a normal development workflow
- Polyfills and transpilation are already provided by our engineering systems.
- This requirement will be removed on March 30th, 2021 when Azure drops IE11 support.

View File

@@ -69,8 +69,7 @@ module.exports = {
moduleNameMapper: { moduleNameMapper: {
"^.*[.](svg|png|gif|less|css)$": "<rootDir>/mockModule", "^.*[.](svg|png|gif|less|css)$": "<rootDir>/mockModule",
"@nteract/stateful-components/(.*)$": "<rootDir>/mockModule", "@nteract/stateful-components/(.*)$": "<rootDir>/mockModule",
"@fluentui/react/lib/(.*)$": "@fluentui/react/lib-commonjs/$1", // https://github.com/microsoft/fluentui/wiki/Version-8-release-notes "office-ui-fabric-react/lib/(.*)$": "office-ui-fabric-react/lib-commonjs/$1", // https://github.com/OfficeDev/office-ui-fabric-react/wiki/Fabric-6-Release-Notes
"monaco-editor/(.*)$": "<rootDir>/__mocks__/monaco-editor",
"^dnd-core$": "dnd-core/dist/cjs", "^dnd-core$": "dnd-core/dist/cjs",
"^react-dnd$": "react-dnd/dist/cjs", "^react-dnd$": "react-dnd/dist/cjs",
"^react-dnd-html5-backend$": "react-dnd-html5-backend/dist/cjs", "^react-dnd-html5-backend$": "react-dnd-html5-backend/dist/cjs",

View File

@@ -4,7 +4,7 @@
@font-face { @font-face {
font-family: wf_segoe-ui_normal; font-family: wf_segoe-ui_normal;
src: local("Segoe UI"), url("../../fonts/segoe-ui/west-european/normal/latest.woff"); src: url("../../fonts/segoe-ui/west-european/normal/latest.woff");
} }
@DataExplorerFont: wf_segoe-ui_normal, "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif; @DataExplorerFont: wf_segoe-ui_normal, "Segoe UI", "Segoe WP", Tahoma, Arial, sans-serif;

View File

@@ -1757,7 +1757,7 @@ input::-webkit-calendar-picker-indicator {
cursor: pointer; cursor: pointer;
} }
.paneMainContent { .contextual-pane .paneMainContent {
flex: 1; flex: 1;
padding-left: 34px; padding-left: 34px;
padding-right: 34px; padding-right: 34px;
@@ -2099,7 +2099,7 @@ a:link {
display: flex; display: flex;
flex: 1 1 auto; flex: 1 1 auto;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: auto;
height: 100%; height: 100%;
} }
@@ -3085,7 +3085,3 @@ settings-pane {
padding-left: @SmallSpace; padding-left: @SmallSpace;
} }
} }
.hiddenMain {
visibility: hidden;
height: 0px;
}

View File

@@ -3,7 +3,6 @@
.resourceTree { .resourceTree {
height: 100%; height: 100%;
width: 20%;
flex: 0 0 auto; flex: 0 0 auto;
.main { .main {
height: 100%; height: 100%;

31521
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,6 @@
"@azure/ms-rest-nodeauth": "3.0.7", "@azure/ms-rest-nodeauth": "3.0.7",
"@babel/plugin-proposal-class-properties": "7.12.1", "@babel/plugin-proposal-class-properties": "7.12.1",
"@babel/plugin-proposal-decorators": "7.12.12", "@babel/plugin-proposal-decorators": "7.12.12",
"@fluentui/react": "8.14.3",
"@jupyterlab/services": "6.0.2", "@jupyterlab/services": "6.0.2",
"@jupyterlab/terminal": "3.0.3", "@jupyterlab/terminal": "3.0.3",
"@microsoft/applicationinsights-web": "2.6.1", "@microsoft/applicationinsights-web": "2.6.1",
@@ -43,6 +42,8 @@
"@testing-library/jest-dom": "5.11.9", "@testing-library/jest-dom": "5.11.9",
"@types/mkdirp": "1.0.1", "@types/mkdirp": "1.0.1",
"@types/node-fetch": "2.5.7", "@types/node-fetch": "2.5.7",
"@uifabric/react-cards": "0.109.110",
"@uifabric/styling": "7.13.7",
"applicationinsights": "1.8.0", "applicationinsights": "1.8.0",
"bootstrap": "3.4.1", "bootstrap": "3.4.1",
"canvas": "file:./canvas", "canvas": "file:./canvas",
@@ -56,7 +57,6 @@
"datatables.net-dt": "1.10.19", "datatables.net-dt": "1.10.19",
"date-fns": "1.29.0", "date-fns": "1.29.0",
"dayjs": "1.8.19", "dayjs": "1.8.19",
"dom-to-image": "2.6.0",
"dotenv": "8.2.0", "dotenv": "8.2.0",
"eslint-plugin-jest": "23.13.2", "eslint-plugin-jest": "23.13.2",
"eslint-plugin-react": "7.20.0", "eslint-plugin-react": "7.20.0",
@@ -76,6 +76,7 @@
"monaco-editor": "0.18.1", "monaco-editor": "0.18.1",
"ms": "2.1.3", "ms": "2.1.3",
"msal": "1.4.4", "msal": "1.4.4",
"office-ui-fabric-react": "7.164.2",
"p-retry": "4.2.0", "p-retry": "4.2.0",
"plotly.js-cartesian-dist-min": "1.52.3", "plotly.js-cartesian-dist-min": "1.52.3",
"post-robot": "10.0.42", "post-robot": "10.0.42",
@@ -98,8 +99,7 @@
"swr": "0.4.0", "swr": "0.4.0",
"terser-webpack-plugin": "3.1.0", "terser-webpack-plugin": "3.1.0",
"underscore": "1.9.1", "underscore": "1.9.1",
"utility-types": "3.10.0", "utility-types": "3.10.0"
"zustand": "3.5.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.9.0", "@babel/core": "7.9.0",
@@ -111,7 +111,6 @@
"@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": "5.9.2",
"@types/dom-to-image": "2.6.2",
"@types/enzyme": "3.10.7", "@types/enzyme": "3.10.7",
"@types/enzyme-adapter-react-16": "1.0.6", "@types/enzyme-adapter-react-16": "1.0.6",
"@types/hasher": "0.0.31", "@types/hasher": "0.0.31",
@@ -129,8 +128,8 @@
"@types/sinon": "2.3.3", "@types/sinon": "2.3.3",
"@types/styled-components": "5.1.1", "@types/styled-components": "5.1.1",
"@types/underscore": "1.7.36", "@types/underscore": "1.7.36",
"@typescript-eslint/eslint-plugin": "4.22.0", "@typescript-eslint/eslint-plugin": "4.0.1",
"@typescript-eslint/parser": "4.22.0", "@typescript-eslint/parser": "4.0.1",
"babel-jest": "24.9.0", "babel-jest": "24.9.0",
"babel-loader": "8.1.0", "babel-loader": "8.1.0",
"buffer": "5.1.0", "buffer": "5.1.0",
@@ -192,7 +191,7 @@
"pack:fast": "node --max_old_space_size=10196 ./node_modules/webpack/bin/webpack.js --mode development --progress", "pack:fast": "node --max_old_space_size=10196 ./node_modules/webpack/bin/webpack.js --mode development --progress",
"copyToConsumers": "node copyToConsumers", "copyToConsumers": "node copyToConsumers",
"test": "rimraf coverage && jest", "test": "rimraf coverage && jest",
"test:e2e": "jest -c ./jest.config.playwright.js --detectOpenHandles", "test:e2e": "jest -c ./jest.config.e2e.js --detectOpenHandles",
"watch": "npm run start", "watch": "npm run start",
"wait-for-server": "wait-on -t 240000 -i 5000 -v https-get://0.0.0.0:1234/", "wait-for-server": "wait-on -t 240000 -i 5000 -v https-get://0.0.0.0:1234/",
"build:ase": "gulp build:ase", "build:ase": "gulp build:ase",

View File

@@ -1,15 +0,0 @@
.schema-analyzer-cell-outputs {
padding: 10px 2px;
}
// Mimic FluentUI8's DocumentCard style
.schema-analyzer-cell-output {
margin-bottom: 20px;
padding: 14px 20px;
border: 1px solid rgb(237, 235, 233);
}
.schema-analyzer-cell-output:hover {
border-color: rgb(200, 198, 196);
box-shadow: inset 0 0 0 1px rgb(200, 198, 196)
}

View File

@@ -9,22 +9,15 @@ import postRobot from "post-robot";
import * as React from "react"; import * as React from "react";
import * as ReactDOM from "react-dom"; import * as ReactDOM from "react-dom";
import "../../externals/iframeResizer.contentWindow.min.js"; // Required for iFrameResizer to work import "../../externals/iframeResizer.contentWindow.min.js"; // Required for iFrameResizer to work
import { SnapshotRequest } from "../Explorer/Notebook/NotebookComponent/types";
import "../Explorer/Notebook/NotebookRenderer/base.css"; import "../Explorer/Notebook/NotebookRenderer/base.css";
import "../Explorer/Notebook/NotebookRenderer/default.css"; import "../Explorer/Notebook/NotebookRenderer/default.css";
import { NotebookUtil } from "../Explorer/Notebook/NotebookUtil";
import "./CellOutputViewer.less";
import { TransformMedia } from "./TransformMedia"; import { TransformMedia } from "./TransformMedia";
export interface SnapshotResponse {
imageSrc: string;
requestId: string;
}
export interface CellOutputViewerProps { export interface CellOutputViewerProps {
id: string; id: string;
contentRef: ContentRef; contentRef: ContentRef;
outputsContainerClassName: string; hidden: boolean;
outputClassName: string; expanded: boolean;
outputs: OnDiskOutput[]; outputs: OnDiskOutput[];
onMetadataChange: (metadata: JSONObject, mediaType: string, index?: number) => void; onMetadataChange: (metadata: JSONObject, mediaType: string, index?: number) => void;
} }
@@ -41,26 +34,27 @@ const onInit = async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const props = (event as any).data as CellOutputViewerProps; const props = (event as any).data as CellOutputViewerProps;
const outputs = ( const outputs = (
<div data-iframe-height className={props.outputsContainerClassName}> <div
data-iframe-height
className={`nteract-cell-outputs ${props.hidden ? "hidden" : ""} ${props.expanded ? "expanded" : ""}`}
>
{props.outputs?.map((output, index) => ( {props.outputs?.map((output, index) => (
<div className={props.outputClassName} key={index}> <Output output={createImmutableOutput(output)} key={index}>
<Output output={createImmutableOutput(output)} key={index}> <TransformMedia
<TransformMedia output_type={"display_data"}
output_type={"display_data"} id={props.id}
id={props.id} contentRef={props.contentRef}
contentRef={props.contentRef} onMetadataChange={(metadata, mediaType) => props.onMetadataChange(metadata, mediaType, index)}
onMetadataChange={(metadata, mediaType) => props.onMetadataChange(metadata, mediaType, index)} />
/> <TransformMedia
<TransformMedia output_type={"execute_result"}
output_type={"execute_result"} id={props.id}
id={props.id} contentRef={props.contentRef}
contentRef={props.contentRef} onMetadataChange={(metadata, mediaType) => props.onMetadataChange(metadata, mediaType, index)}
onMetadataChange={(metadata, mediaType) => props.onMetadataChange(metadata, mediaType, index)} />
/> <KernelOutputError />
<KernelOutputError /> <StreamText />
<StreamText /> </Output>
</Output>
</div>
))} ))}
</div> </div>
); );
@@ -68,36 +62,6 @@ const onInit = async () => {
ReactDOM.render(outputs, document.getElementById("cellOutput")); ReactDOM.render(outputs, document.getElementById("cellOutput"));
} }
); );
postRobot.on(
"snapshotRequest",
{
window: window.parent,
domain: window.location.origin,
},
async (event): Promise<SnapshotResponse> => {
const topNode = document.getElementById("cellOutput");
if (!topNode) {
const errorMsg = "No top node to snapshot";
return Promise.reject(new Error(errorMsg));
}
// Typescript definition for event is wrong. So read props by casting to <any>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const snapshotRequest = (event as any).data as SnapshotRequest;
const result = await NotebookUtil.takeScreenshotDomToImage(
topNode,
snapshotRequest.aspectRatio,
undefined,
snapshotRequest.downloadFilename
);
return {
imageSrc: result.imageSrc,
requestId: snapshotRequest.requestId,
};
}
);
}; };
// Entry point // Entry point

View File

@@ -1,35 +0,0 @@
import React, { FunctionComponent } from "react";
import arrowLeftImg from "../../images/imgarrowlefticon.svg";
export interface CollapsedResourceTreeProps {
toggleLeftPaneExpanded: () => void;
isLeftPaneExpanded: boolean;
}
export const CollapsedResourceTree: FunctionComponent<CollapsedResourceTreeProps> = ({
toggleLeftPaneExpanded,
isLeftPaneExpanded,
}: CollapsedResourceTreeProps): JSX.Element => {
return (
<div id="mini" className={!isLeftPaneExpanded ? "mini toggle-mini" : "hiddenMain"}>
<div className="main-nav nav">
<ul className="nav">
<li
className="resourceTreeCollapse"
id="collapseToggleLeftPaneButton"
role="button"
tabIndex={0}
aria-label="Expand Tree"
>
<span className="leftarrowCollapsed" onClick={toggleLeftPaneExpanded}>
<img className="arrowCollapsed" src={arrowLeftImg} alt="Expand" />
</span>
<span className="collectionCollapsed" onClick={toggleLeftPaneExpanded}>
<span data-bind="text: collectionTitle" />
</span>
</li>
</ul>
</div>
</div>
);
};

View File

@@ -65,18 +65,28 @@ export class ClientDefaults {
public static readonly arcadiaTokenRefreshIntervalPaddingMs: number = 2000; public static readonly arcadiaTokenRefreshIntervalPaddingMs: number = 2000;
} }
export enum AccountKind { export class AccountKind {
DocumentDB = "DocumentDB", public static DocumentDB: string = "DocumentDB";
MongoDB = "MongoDB", public static MongoDB: string = "MongoDB";
Parse = "Parse", public static Parse: string = "Parse";
GlobalDocumentDB = "GlobalDocumentDB", public static GlobalDocumentDB: string = "GlobalDocumentDB";
Default = "DocumentDB", public static Default: string = AccountKind.DocumentDB;
} }
export class CorrelationBackend { export class CorrelationBackend {
public static Url: string = "https://aka.ms/cosmosdbanalytics"; public static Url: string = "https://aka.ms/cosmosdbanalytics";
} }
export class DefaultAccountExperience {
public static DocumentDB: string = "DocumentDB";
public static Graph: string = "Graph";
public static MongoDB: string = "MongoDB";
public static ApiForMongoDB: string = "Azure Cosmos DB for MongoDB API";
public static Table: string = "Table";
public static Cassandra: string = "Cassandra";
public static Default: string = DefaultAccountExperience.DocumentDB;
}
export class CapabilityNames { export class CapabilityNames {
public static EnableTable: string = "EnableTable"; public static EnableTable: string = "EnableTable";
public static EnableGremlin: string = "EnableGremlin"; public static EnableGremlin: string = "EnableGremlin";
@@ -94,7 +104,6 @@ export class Flights {
public static readonly MongoIndexEditor = "mongoindexeditor"; public static readonly MongoIndexEditor = "mongoindexeditor";
public static readonly MongoIndexing = "mongoindexing"; public static readonly MongoIndexing = "mongoindexing";
public static readonly AutoscaleTest = "autoscaletest"; public static readonly AutoscaleTest = "autoscaletest";
public static readonly SchemaAnalyzer = "schemaanalyzer";
} }
export class AfecFeatures { export class AfecFeatures {

View File

@@ -1,5 +1,5 @@
import { ResourceType } from "@azure/cosmos/dist-esm/common/constants"; import { ResourceType } from "@azure/cosmos/dist-esm/common/constants";
import { Platform, resetConfigContext, updateConfigContext } from "../ConfigContext"; import { configContext, Platform, updateConfigContext, resetConfigContext } from "../ConfigContext";
import { updateUserContext } from "../UserContext"; import { updateUserContext } from "../UserContext";
import { endpoint, getTokenFromAuthService, requestPlugin, tokenProvider } from "./CosmosClient"; import { endpoint, getTokenFromAuthService, requestPlugin, tokenProvider } from "./CosmosClient";
@@ -91,6 +91,7 @@ describe("endpoint", () => {
location: "foo", location: "foo",
type: "foo", type: "foo",
kind: "foo", kind: "foo",
tags: [],
properties: { properties: {
documentEndpoint: "bar", documentEndpoint: "bar",
gremlinEndpoint: "foo", gremlinEndpoint: "foo",

View File

@@ -43,7 +43,12 @@ export const endpoint = () => {
const location = _global.parent ? _global.parent.location : _global.location; const location = _global.parent ? _global.parent.location : _global.location;
return configContext.EMULATOR_ENDPOINT || location.origin; return configContext.EMULATOR_ENDPOINT || location.origin;
} }
return userContext.endpoint || userContext?.databaseAccount?.properties?.documentEndpoint; return (
userContext.endpoint ||
(userContext.databaseAccount &&
userContext.databaseAccount.properties &&
userContext.databaseAccount.properties.documentEndpoint)
);
}; };
export async function getTokenFromAuthService(verb: string, resourceType: string, resourceId?: string): Promise<any> { export async function getTokenFromAuthService(verb: string, resourceType: string, resourceId?: string): Promise<any> {

View File

@@ -1,4 +1,4 @@
import { DatePicker, TextField } from "@fluentui/react"; import { DatePicker, TextField } from "office-ui-fabric-react";
import React, { FunctionComponent } from "react"; import React, { FunctionComponent } from "react";
export interface TableEntityProps { export interface TableEntityProps {

View File

@@ -61,7 +61,7 @@ export function queryDocuments(
query: string, query: string,
continuationToken?: string continuationToken?: string
): Promise<QueryResponse> { ): Promise<QueryResponse> {
const { databaseAccount } = userContext; const databaseAccount = userContext.databaseAccount;
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint; const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
const params = { const params = {
db: databaseId, db: databaseId,
@@ -121,7 +121,7 @@ export function readDocument(
collection: Collection, collection: Collection,
documentId: DocumentId documentId: DocumentId
): Promise<DataModels.DocumentId> { ): Promise<DataModels.DocumentId> {
const { databaseAccount } = userContext; const databaseAccount = userContext.databaseAccount;
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint; const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
const idComponents = documentId.self.split("/"); const idComponents = documentId.self.split("/");
const path = idComponents.slice(0, 4).join("/"); const path = idComponents.slice(0, 4).join("/");
@@ -167,7 +167,7 @@ export function createDocument(
partitionKeyProperty: string, partitionKeyProperty: string,
documentContent: unknown documentContent: unknown
): Promise<DataModels.DocumentId> { ): Promise<DataModels.DocumentId> {
const { databaseAccount } = userContext; const databaseAccount = userContext.databaseAccount;
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint; const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
const params = { const params = {
db: databaseId, db: databaseId,
@@ -206,7 +206,7 @@ export function updateDocument(
documentId: DocumentId, documentId: DocumentId,
documentContent: string documentContent: string
): Promise<DataModels.DocumentId> { ): Promise<DataModels.DocumentId> {
const { databaseAccount } = userContext; const databaseAccount = userContext.databaseAccount;
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint; const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
const idComponents = documentId.self.split("/"); const idComponents = documentId.self.split("/");
const path = idComponents.slice(0, 5).join("/"); const path = idComponents.slice(0, 5).join("/");
@@ -247,7 +247,7 @@ export function updateDocument(
} }
export function deleteDocument(databaseId: string, collection: Collection, documentId: DocumentId): Promise<void> { export function deleteDocument(databaseId: string, collection: Collection, documentId: DocumentId): Promise<void> {
const { databaseAccount } = userContext; const databaseAccount = userContext.databaseAccount;
const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint; const resourceEndpoint = databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint;
const idComponents = documentId.self.split("/"); const idComponents = documentId.self.split("/");
const path = idComponents.slice(0, 5).join("/"); const path = idComponents.slice(0, 5).join("/");
@@ -289,7 +289,7 @@ export function deleteDocument(databaseId: string, collection: Collection, docum
export function createMongoCollectionWithProxy( export function createMongoCollectionWithProxy(
params: DataModels.CreateCollectionParams params: DataModels.CreateCollectionParams
): Promise<DataModels.Collection> { ): Promise<DataModels.Collection> {
const { databaseAccount } = userContext; const databaseAccount = userContext.databaseAccount;
const shardKey: string = params.partitionKey?.paths[0]; const shardKey: string = params.partitionKey?.paths[0];
const mongoParams: DataModels.MongoParameters = { const mongoParams: DataModels.MongoParameters = {
resourceUrl: databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint, resourceUrl: databaseAccount.properties.mongoEndpoint || databaseAccount.properties.documentEndpoint,

View File

@@ -1,8 +1,8 @@
import { configContext, Platform } from "../ConfigContext";
import * as DataModels from "../Contracts/DataModels"; import * as DataModels from "../Contracts/DataModels";
import * as ViewModels from "../Contracts/ViewModels"; import * as ViewModels from "../Contracts/ViewModels";
import { userContext } from "../UserContext";
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils"; import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
import { userContext } from "../UserContext";
import { configContext, Platform } from "../ConfigContext";
const notificationsPath = () => { const notificationsPath = () => {
switch (configContext.platform) { switch (configContext.platform) {
@@ -20,7 +20,9 @@ export const fetchPortalNotifications = async (): Promise<DataModels.Notificatio
return []; return [];
} }
const { databaseAccount, resourceGroup, subscriptionId } = userContext; const databaseAccount = userContext.databaseAccount;
const subscriptionId = userContext.subscriptionId;
const resourceGroup = userContext.resourceGroup;
const url = `${configContext.BACKEND_ENDPOINT}${notificationsPath()}?accountName=${ const url = `${configContext.BACKEND_ENDPOINT}${notificationsPath()}?accountName=${
databaseAccount.name databaseAccount.name
}&subscriptionId=${subscriptionId}&resourceGroup=${resourceGroup}`; }&subscriptionId=${subscriptionId}&resourceGroup=${resourceGroup}`;

View File

@@ -182,8 +182,11 @@ export class QueriesClient {
} }
public getResourceId(): string { public getResourceId(): string {
const { databaseAccount, subscriptionId = "", resourceGroup = "" } = userContext; const databaseAccount = userContext.databaseAccount;
const databaseAccountName = databaseAccount?.name || ""; const databaseAccountName = (databaseAccount && databaseAccount.name) || "";
const subscriptionId = userContext.subscriptionId || "";
const resourceGroup = userContext.resourceGroup || "";
return `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DocumentDb/databaseAccounts/${databaseAccountName}`; return `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DocumentDb/databaseAccounts/${databaseAccountName}`;
} }

View File

@@ -1,59 +0,0 @@
import React, { FunctionComponent } from "react";
import arrowLeftImg from "../../images/imgarrowlefticon.svg";
import refreshImg from "../../images/refresh-cosmos.svg";
import { AuthType } from "../AuthType";
import { userContext } from "../UserContext";
export interface ResourceTreeProps {
toggleLeftPaneExpanded: () => void;
isLeftPaneExpanded: boolean;
}
export const ResourceTree: FunctionComponent<ResourceTreeProps> = ({
toggleLeftPaneExpanded,
isLeftPaneExpanded,
}: ResourceTreeProps): JSX.Element => {
return (
<div id="main" className={isLeftPaneExpanded ? "main" : "hiddenMain"}>
{/* Collections Window - - Start */}
<div id="mainslide" className="flexContainer">
{/* Collections Window Title/Command Bar - Start */}
<div className="collectiontitle">
<div className="coltitle">
<span className="titlepadcol" data-bind="text: collectionTitle" />
<div className="float-right">
<span
className="padimgcolrefresh"
data-test="refreshTree"
role="button"
data-bind="click: onRefreshResourcesClick, clickBubble: false, event: { keypress: onRefreshDatabasesKeyPress }"
tabIndex={0}
aria-label="Refresh tree"
title="Refresh tree"
>
<img className="refreshcol" src={refreshImg} alt="Refresh tree" />
</span>
<span
className="padimgcolrefresh1"
id="expandToggleLeftPaneButton"
role="button"
onClick={toggleLeftPaneExpanded}
tabIndex={0}
aria-label="Collapse Tree"
title="Collapse Tree"
>
<img className="refreshcol1" src={arrowLeftImg} alt="Hide" />
</span>
</div>
</div>
</div>
{userContext.authType === AuthType.ResourceToken ? (
<div style={{ overflowY: "auto" }} data-bind="react:resourceTreeForResourceToken" />
) : (
<div style={{ overflowY: "auto" }} data-bind="react:resourceTree" />
)}
</div>
{/* Collections Window - End */}
</div>
);
};

View File

@@ -8,7 +8,7 @@ import {
Stack, Stack,
TextField, TextField,
TooltipHost, TooltipHost,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import React, { FunctionComponent } from "react"; import React, { FunctionComponent } from "react";
import DeleteIcon from "../../images/delete.svg"; import DeleteIcon from "../../images/delete.svg";
import EditIcon from "../../images/Edit_entity.svg"; import EditIcon from "../../images/Edit_entity.svg";

View File

@@ -1,16 +0,0 @@
import { Icon, TooltipHost } from "@fluentui/react";
import * as React from "react";
export interface TooltipProps {
children: string;
}
export const InfoTooltip: React.FunctionComponent<TooltipProps> = ({ children }: TooltipProps) => {
return (
<span>
<TooltipHost content={children}>
<Icon iconName="Info" ariaLabel="Info" className="panelInfoIcon" />
</TooltipHost>
</span>
);
};

View File

@@ -0,0 +1,24 @@
import { useId } from "@uifabric/react-hooks";
import { ITooltipHostStyles, TooltipHost } from "office-ui-fabric-react/lib/Tooltip";
import * as React from "react";
import InfoBubble from "../../../images/info-bubble.svg";
const calloutProps = { gapSpace: 0 };
const hostStyles: Partial<ITooltipHostStyles> = { root: { display: "inline-block" } };
export interface TooltipProps {
children: string;
}
export const Tooltip: React.FunctionComponent = ({ children }: TooltipProps) => {
const tooltipId = useId("tooltip");
return children ? (
<span>
<TooltipHost content={children} id={tooltipId} calloutProps={calloutProps} styles={hostStyles}>
<img className="infoImg" src={InfoBubble} alt="More information" />
</TooltipHost>
</span>
) : (
<></>
);
};

View File

@@ -1,8 +1,8 @@
import { Image, Stack, TextField } from "@fluentui/react"; import { Image, Stack, TextField } from "office-ui-fabric-react";
import React, { ChangeEvent, FunctionComponent, KeyboardEvent, useRef, useState } from "react"; import React, { ChangeEvent, FunctionComponent, KeyboardEvent, useRef, useState } from "react";
import FolderIcon from "../../../images/folder_16x16.svg"; import FolderIcon from "../../../images/folder_16x16.svg";
import * as Constants from "../Constants"; import * as Constants from "../Constants";
import { InfoTooltip } from "../Tooltip/InfoTooltip"; import { Tooltip } from "../Tooltip/Tooltip";
interface UploadProps { interface UploadProps {
label: string; label: string;
@@ -51,7 +51,7 @@ export const Upload: FunctionComponent<UploadProps> = ({
return ( return (
<div> <div>
<span className="renewUploadItemsHeader">{label}</span> <span className="renewUploadItemsHeader">{label}</span>
{tooltip && <InfoTooltip>{tooltip}</InfoTooltip>} <Tooltip>{tooltip}</Tooltip>
<Stack horizontal> <Stack horizontal>
<TextField styles={{ fieldGroup: { width: 300 } }} readOnly value={selectedFilesTitle.toString()} /> <TextField styles={{ fieldGroup: { width: 300 } }} readOnly value={selectedFilesTitle.toString()} />
<input <input

View File

@@ -62,8 +62,8 @@ export const createCollection = async (params: DataModels.CreateCollectionParams
}; };
const createCollectionWithARM = async (params: DataModels.CreateCollectionParams): Promise<DataModels.Collection> => { const createCollectionWithARM = async (params: DataModels.CreateCollectionParams): Promise<DataModels.Collection> => {
const { apiType } = userContext; const defaultExperience = userContext.apiType;
switch (apiType) { switch (defaultExperience) {
case "SQL": case "SQL":
return createSqlContainer(params); return createSqlContainer(params);
case "Mongo": case "Mongo":
@@ -75,7 +75,7 @@ const createCollectionWithARM = async (params: DataModels.CreateCollectionParams
case "Tables": case "Tables":
return createTable(params); return createTable(params);
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
}; };

View File

@@ -48,9 +48,8 @@ export async function createDatabase(params: DataModels.CreateDatabaseParams): P
} }
async function createDatabaseWithARM(params: DataModels.CreateDatabaseParams): Promise<DataModels.Database> { async function createDatabaseWithARM(params: DataModels.CreateDatabaseParams): Promise<DataModels.Database> {
const { apiType } = userContext; const defaultExperience = userContext.apiType;
switch (defaultExperience) {
switch (apiType) {
case "SQL": case "SQL":
return createSqlDatabase(params); return createSqlDatabase(params);
case "Mongo": case "Mongo":
@@ -60,7 +59,7 @@ async function createDatabaseWithARM(params: DataModels.CreateDatabaseParams): P
case "Gremlin": case "Gremlin":
return createGremlineDatabase(params); return createGremlineDatabase(params);
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
} }

View File

@@ -27,10 +27,12 @@ export async function deleteCollection(databaseId: string, collectionId: string)
} }
function deleteCollectionWithARM(databaseId: string, collectionId: string): Promise<void> { function deleteCollectionWithARM(databaseId: string, collectionId: string): Promise<void> {
const { subscriptionId, resourceGroup, apiType, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const defaultExperience = userContext.apiType;
switch (apiType) { switch (defaultExperience) {
case "SQL": case "SQL":
return deleteSqlContainer(subscriptionId, resourceGroup, accountName, databaseId, collectionId); return deleteSqlContainer(subscriptionId, resourceGroup, accountName, databaseId, collectionId);
case "Mongo": case "Mongo":
@@ -42,6 +44,6 @@ function deleteCollectionWithARM(databaseId: string, collectionId: string): Prom
case "Tables": case "Tables":
return deleteTable(subscriptionId, resourceGroup, accountName, collectionId); return deleteTable(subscriptionId, resourceGroup, accountName, collectionId);
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
} }

View File

@@ -30,10 +30,12 @@ export async function deleteDatabase(databaseId: string): Promise<void> {
} }
function deleteDatabaseWithARM(databaseId: string): Promise<void> { function deleteDatabaseWithARM(databaseId: string): Promise<void> {
const { subscriptionId, resourceGroup, apiType, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const defaultExperience = userContext.apiType;
switch (apiType) { switch (defaultExperience) {
case "SQL": case "SQL":
return deleteSqlDatabase(subscriptionId, resourceGroup, accountName, databaseId); return deleteSqlDatabase(subscriptionId, resourceGroup, accountName, databaseId);
case "Mongo": case "Mongo":
@@ -43,6 +45,6 @@ function deleteDatabaseWithARM(databaseId: string): Promise<void> {
case "Gremlin": case "Gremlin":
return deleteGremlinDatabase(subscriptionId, resourceGroup, accountName, databaseId); return deleteGremlinDatabase(subscriptionId, resourceGroup, accountName, databaseId);
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
} }

View File

@@ -1,8 +1,8 @@
import { AuthType } from "../../AuthType"; import { AuthType } from "../../AuthType";
import { configContext } from "../../ConfigContext";
import { userContext } from "../../UserContext";
import { armRequest } from "../../Utils/arm/request"; import { armRequest } from "../../Utils/arm/request";
import { configContext } from "../../ConfigContext";
import { handleError } from "../ErrorHandlingUtils"; import { handleError } from "../ErrorHandlingUtils";
import { userContext } from "../../UserContext";
interface TimeSeriesData { interface TimeSeriesData {
data: { data: {
@@ -45,9 +45,9 @@ export const getCollectionUsageSizeInKB = async (databaseName: string, container
return undefined; return undefined;
} }
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const filter = `DatabaseName eq '${databaseName}' and CollectionName eq '${containerName}'`; const filter = `DatabaseName eq '${databaseName}' and CollectionName eq '${containerName}'`;
const metricNames = "DataUsage,IndexUsage"; const metricNames = "DataUsage,IndexUsage";
const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/providers/microsoft.insights/metrics`; const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/providers/microsoft.insights/metrics`;

View File

@@ -28,12 +28,14 @@ export const readCollectionOffer = async (params: ReadCollectionOfferParams): Pr
}; };
const readCollectionOfferWithARM = async (databaseId: string, collectionId: string): Promise<Offer> => { const readCollectionOfferWithARM = async (databaseId: string, collectionId: string): Promise<Offer> => {
const { subscriptionId, resourceGroup, apiType, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const defaultExperience = userContext.apiType;
let rpResponse; let rpResponse;
try { try {
switch (apiType) { switch (defaultExperience) {
case "SQL": case "SQL":
rpResponse = await getSqlContainerThroughput( rpResponse = await getSqlContainerThroughput(
subscriptionId, subscriptionId,
@@ -74,7 +76,7 @@ const readCollectionOfferWithARM = async (databaseId: string, collectionId: stri
rpResponse = await getTableThroughput(subscriptionId, resourceGroup, accountName, collectionId); rpResponse = await getTableThroughput(subscriptionId, resourceGroup, accountName, collectionId);
break; break;
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
} catch (error) { } catch (error) {
if (error.code !== "NotFound") { if (error.code !== "NotFound") {

View File

@@ -29,11 +29,12 @@ export async function readCollections(databaseId: string): Promise<DataModels.Co
async function readCollectionsWithARM(databaseId: string): Promise<DataModels.Collection[]> { async function readCollectionsWithARM(databaseId: string): Promise<DataModels.Collection[]> {
let rpResponse; let rpResponse;
const subscriptionId = userContext.subscriptionId;
const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const defaultExperience = userContext.apiType;
const { subscriptionId, resourceGroup, apiType, databaseAccount } = userContext; switch (defaultExperience) {
const accountName = databaseAccount.name;
switch (apiType) {
case "SQL": case "SQL":
rpResponse = await listSqlContainers(subscriptionId, resourceGroup, accountName, databaseId); rpResponse = await listSqlContainers(subscriptionId, resourceGroup, accountName, databaseId);
break; break;
@@ -50,7 +51,7 @@ async function readCollectionsWithARM(databaseId: string): Promise<DataModels.Co
rpResponse = await listTables(subscriptionId, resourceGroup, accountName); rpResponse = await listTables(subscriptionId, resourceGroup, accountName);
break; break;
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
return rpResponse?.value?.map((collection) => collection.properties?.resource as DataModels.Collection); return rpResponse?.value?.map((collection) => collection.properties?.resource as DataModels.Collection);

View File

@@ -27,12 +27,14 @@ export const readDatabaseOffer = async (params: ReadDatabaseOfferParams): Promis
}; };
const readDatabaseOfferWithARM = async (databaseId: string): Promise<Offer> => { const readDatabaseOfferWithARM = async (databaseId: string): Promise<Offer> => {
const { subscriptionId, resourceGroup, apiType, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const defaultExperience = userContext.apiType;
let rpResponse; let rpResponse;
try { try {
switch (apiType) { switch (defaultExperience) {
case "SQL": case "SQL":
rpResponse = await getSqlDatabaseThroughput(subscriptionId, resourceGroup, accountName, databaseId); rpResponse = await getSqlDatabaseThroughput(subscriptionId, resourceGroup, accountName, databaseId);
break; break;
@@ -46,7 +48,7 @@ const readDatabaseOfferWithARM = async (databaseId: string): Promise<Offer> => {
rpResponse = await getGremlinDatabaseThroughput(subscriptionId, resourceGroup, accountName, databaseId); rpResponse = await getGremlinDatabaseThroughput(subscriptionId, resourceGroup, accountName, databaseId);
break; break;
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
} catch (error) { } catch (error) {
if (error.code !== "NotFound") { if (error.code !== "NotFound") {

View File

@@ -29,10 +29,12 @@ export async function readDatabases(): Promise<DataModels.Database[]> {
async function readDatabasesWithARM(): Promise<DataModels.Database[]> { async function readDatabasesWithARM(): Promise<DataModels.Database[]> {
let rpResponse; let rpResponse;
const { subscriptionId, resourceGroup, apiType, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const defaultExperience = userContext.apiType;
switch (apiType) { switch (defaultExperience) {
case "SQL": case "SQL":
rpResponse = await listSqlDatabases(subscriptionId, resourceGroup, accountName); rpResponse = await listSqlDatabases(subscriptionId, resourceGroup, accountName);
break; break;
@@ -46,7 +48,7 @@ async function readDatabasesWithARM(): Promise<DataModels.Database[]> {
rpResponse = await listGremlinDatabases(subscriptionId, resourceGroup, accountName); rpResponse = await listGremlinDatabases(subscriptionId, resourceGroup, accountName);
break; break;
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
return rpResponse?.value?.map((database) => database.properties?.resource as DataModels.Database); return rpResponse?.value?.map((database) => database.properties?.resource as DataModels.Database);

View File

@@ -1,9 +1,9 @@
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
import { getMongoDBCollection } from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; import { getMongoDBCollection } from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources";
import { MongoDBCollectionResource } from "../../Utils/arm/generatedClients/2020-04-01/types"; import { MongoDBCollectionResource } from "../../Utils/arm/generatedClients/2020-04-01/types";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { handleError } from "../ErrorHandlingUtils"; import { handleError } from "../ErrorHandlingUtils";
import { AuthType } from "../../AuthType";
export async function readMongoDBCollectionThroughRP( export async function readMongoDBCollectionThroughRP(
databaseId: string, databaseId: string,
@@ -13,9 +13,9 @@ export async function readMongoDBCollectionThroughRP(
return undefined; return undefined;
} }
let collection: MongoDBCollectionResource; let collection: MongoDBCollectionResource;
const subscriptionId = userContext.subscriptionId;
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const resourceGroup = userContext.resourceGroup;
const accountName = databaseAccount.name; const accountName = userContext.databaseAccount.name;
const clearMessage = logConsoleProgress(`Reading container ${collectionId}`); const clearMessage = logConsoleProgress(`Reading container ${collectionId}`);
try { try {

View File

@@ -11,13 +11,12 @@ export async function readUserDefinedFunctions(
collectionId: string collectionId: string
): Promise<(UserDefinedFunctionDefinition & Resource)[]> { ): Promise<(UserDefinedFunctionDefinition & Resource)[]> {
const clearMessage = logConsoleProgress(`Querying user defined functions for container ${collectionId}`); const clearMessage = logConsoleProgress(`Querying user defined functions for container ${collectionId}`);
const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext;
try { try {
if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") { if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") {
const rpResponse = await listSqlUserDefinedFunctions( const rpResponse = await listSqlUserDefinedFunctions(
subscriptionId, userContext.subscriptionId,
resourceGroup, userContext.resourceGroup,
databaseAccount.name, userContext.databaseAccount.name,
databaseId, databaseId,
collectionId collectionId
); );

View File

@@ -63,10 +63,12 @@ async function updateCollectionWithARM(
collectionId: string, collectionId: string,
newCollection: Partial<Collection> newCollection: Partial<Collection>
): Promise<Collection> { ): Promise<Collection> {
const { subscriptionId, resourceGroup, apiType, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
const defaultExperience = userContext.apiType;
switch (apiType) { switch (defaultExperience) {
case "SQL": case "SQL":
return updateSqlContainer(databaseId, collectionId, subscriptionId, resourceGroup, accountName, newCollection); return updateSqlContainer(databaseId, collectionId, subscriptionId, resourceGroup, accountName, newCollection);
case "Cassandra": case "Cassandra":
@@ -85,7 +87,7 @@ async function updateCollectionWithARM(
newCollection newCollection
); );
default: default:
throw new Error(`Unsupported default experience type: ${apiType}`); throw new Error(`Unsupported default experience type: ${defaultExperience}`);
} }
} }

View File

@@ -144,8 +144,9 @@ const updateDatabaseOfferWithARM = async (params: UpdateOfferParams): Promise<Of
}; };
const updateSqlContainerOffer = async (params: UpdateOfferParams): Promise<void> => { const updateSqlContainerOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateSqlContainerToAutoscale( await migrateSqlContainerToAutoscale(
@@ -177,8 +178,9 @@ const updateSqlContainerOffer = async (params: UpdateOfferParams): Promise<void>
}; };
const updateMongoCollectionOffer = async (params: UpdateOfferParams): Promise<void> => { const updateMongoCollectionOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateMongoDBCollectionToAutoscale( await migrateMongoDBCollectionToAutoscale(
@@ -210,8 +212,9 @@ const updateMongoCollectionOffer = async (params: UpdateOfferParams): Promise<vo
}; };
const updateCassandraTableOffer = async (params: UpdateOfferParams): Promise<void> => { const updateCassandraTableOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateCassandraTableToAutoscale( await migrateCassandraTableToAutoscale(
@@ -243,8 +246,9 @@ const updateCassandraTableOffer = async (params: UpdateOfferParams): Promise<voi
}; };
const updateGremlinGraphOffer = async (params: UpdateOfferParams): Promise<void> => { const updateGremlinGraphOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateGremlinGraphToAutoscale( await migrateGremlinGraphToAutoscale(
@@ -276,8 +280,9 @@ const updateGremlinGraphOffer = async (params: UpdateOfferParams): Promise<void>
}; };
const updateTableOffer = async (params: UpdateOfferParams): Promise<void> => { const updateTableOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateTableToAutoscale(subscriptionId, resourceGroup, accountName, params.collectionId); await migrateTableToAutoscale(subscriptionId, resourceGroup, accountName, params.collectionId);
@@ -290,8 +295,9 @@ const updateTableOffer = async (params: UpdateOfferParams): Promise<void> => {
}; };
const updateSqlDatabaseOffer = async (params: UpdateOfferParams): Promise<void> => { const updateSqlDatabaseOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateSqlDatabaseToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId); await migrateSqlDatabaseToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId);
@@ -304,8 +310,9 @@ const updateSqlDatabaseOffer = async (params: UpdateOfferParams): Promise<void>
}; };
const updateMongoDatabaseOffer = async (params: UpdateOfferParams): Promise<void> => { const updateMongoDatabaseOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateMongoDBDatabaseToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId); await migrateMongoDBDatabaseToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId);
@@ -318,8 +325,9 @@ const updateMongoDatabaseOffer = async (params: UpdateOfferParams): Promise<void
}; };
const updateCassandraKeyspaceOffer = async (params: UpdateOfferParams): Promise<void> => { const updateCassandraKeyspaceOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateCassandraKeyspaceToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId); await migrateCassandraKeyspaceToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId);
@@ -332,8 +340,9 @@ const updateCassandraKeyspaceOffer = async (params: UpdateOfferParams): Promise<
}; };
const updateGremlinDatabaseOffer = async (params: UpdateOfferParams): Promise<void> => { const updateGremlinDatabaseOffer = async (params: UpdateOfferParams): Promise<void> => {
const { subscriptionId, resourceGroup, databaseAccount } = userContext; const subscriptionId = userContext.subscriptionId;
const accountName = databaseAccount.name; const resourceGroup = userContext.resourceGroup;
const accountName = userContext.databaseAccount.name;
if (params.migrateToAutoPilot) { if (params.migrateToAutoPilot) {
await migrateGremlinDatabaseToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId); await migrateGremlinDatabaseToAutoscale(subscriptionId, resourceGroup, accountName, params.databaseId);

View File

@@ -20,13 +20,11 @@ export async function updateStoredProcedure(
): Promise<StoredProcedureDefinition & Resource> { ): Promise<StoredProcedureDefinition & Resource> {
const clearMessage = logConsoleProgress(`Updating stored procedure ${storedProcedure.id}`); const clearMessage = logConsoleProgress(`Updating stored procedure ${storedProcedure.id}`);
try { try {
const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext; if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") {
if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") {
const getResponse = await getSqlStoredProcedure( const getResponse = await getSqlStoredProcedure(
subscriptionId, userContext.subscriptionId,
resourceGroup, userContext.resourceGroup,
databaseAccount.name, userContext.databaseAccount.name,
databaseId, databaseId,
collectionId, collectionId,
storedProcedure.id storedProcedure.id
@@ -40,9 +38,9 @@ export async function updateStoredProcedure(
}, },
}; };
const rpResponse = await createUpdateSqlStoredProcedure( const rpResponse = await createUpdateSqlStoredProcedure(
subscriptionId, userContext.subscriptionId,
resourceGroup, userContext.resourceGroup,
databaseAccount.name, userContext.databaseAccount.name,
databaseId, databaseId,
collectionId, collectionId,
storedProcedure.id, storedProcedure.id,

View File

@@ -16,13 +16,12 @@ export async function updateTrigger(
trigger: TriggerDefinition trigger: TriggerDefinition
): Promise<TriggerDefinition> { ): Promise<TriggerDefinition> {
const clearMessage = logConsoleProgress(`Updating trigger ${trigger.id}`); const clearMessage = logConsoleProgress(`Updating trigger ${trigger.id}`);
const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext;
try { try {
if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") { if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") {
const getResponse = await getSqlTrigger( const getResponse = await getSqlTrigger(
subscriptionId, userContext.subscriptionId,
resourceGroup, userContext.resourceGroup,
databaseAccount.name, userContext.databaseAccount.name,
databaseId, databaseId,
collectionId, collectionId,
trigger.id trigger.id
@@ -36,9 +35,9 @@ export async function updateTrigger(
}, },
}; };
const rpResponse = await createUpdateSqlTrigger( const rpResponse = await createUpdateSqlTrigger(
subscriptionId, userContext.subscriptionId,
resourceGroup, userContext.resourceGroup,
databaseAccount.name, userContext.databaseAccount.name,
databaseId, databaseId,
collectionId, collectionId,
trigger.id, trigger.id,

View File

@@ -19,13 +19,12 @@ export async function updateUserDefinedFunction(
userDefinedFunction: UserDefinedFunctionDefinition userDefinedFunction: UserDefinedFunctionDefinition
): Promise<UserDefinedFunctionDefinition & Resource> { ): Promise<UserDefinedFunctionDefinition & Resource> {
const clearMessage = logConsoleProgress(`Updating user defined function ${userDefinedFunction.id}`); const clearMessage = logConsoleProgress(`Updating user defined function ${userDefinedFunction.id}`);
const { authType, useSDKOperations, apiType, subscriptionId, resourceGroup, databaseAccount } = userContext;
try { try {
if (authType === AuthType.AAD && !useSDKOperations && apiType === "SQL") { if (userContext.authType === AuthType.AAD && !userContext.useSDKOperations && userContext.apiType === "SQL") {
const getResponse = await getSqlUserDefinedFunction( const getResponse = await getSqlUserDefinedFunction(
subscriptionId, userContext.subscriptionId,
resourceGroup, userContext.resourceGroup,
databaseAccount.name, userContext.databaseAccount.name,
databaseId, databaseId,
collectionId, collectionId,
userDefinedFunction.id userDefinedFunction.id
@@ -39,9 +38,9 @@ export async function updateUserDefinedFunction(
}, },
}; };
const rpResponse = await createUpdateSqlUserDefinedFunction( const rpResponse = await createUpdateSqlUserDefinedFunction(
subscriptionId, userContext.subscriptionId,
resourceGroup, userContext.resourceGroup,
databaseAccount.name, userContext.databaseAccount.name,
databaseId, databaseId,
collectionId, collectionId,
userDefinedFunction.id, userDefinedFunction.id,

View File

@@ -4,6 +4,7 @@ export interface DatabaseAccount {
location: string; location: string;
type: string; type: string;
kind: string; kind: string;
tags: any;
properties: DatabaseAccountExtendedProperties; properties: DatabaseAccountExtendedProperties;
} }

View File

@@ -206,14 +206,17 @@ export enum NeighborType {
BOTH, BOTH,
} }
export interface IGraphConfigUiData { /**
showNeighborType: NeighborType; * Set of observable related to graph configuration by user
nodeProperties: string[]; */
nodePropertiesWithNone: string[]; export interface GraphConfigUiData {
nodeCaptionChoice: string; showNeighborType: ko.Observable<NeighborType>;
nodeColorKeyChoice: string; nodeProperties: ko.ObservableArray<string>;
nodeIconChoice: string; nodePropertiesWithNone: ko.ObservableArray<string>;
nodeIconSet: string; nodeCaptionChoice: ko.Observable<string>;
nodeColorKeyChoice: ko.Observable<string>;
nodeIconChoice: ko.Observable<string>;
nodeIconSet: ko.Observable<string>;
} }
/** /**

View File

@@ -4,10 +4,30 @@ import * as ko from "knockout";
import "./ComponentRegisterer"; import "./ComponentRegisterer";
describe("Component Registerer", () => { describe("Component Registerer", () => {
it("should register input-typeahead component", () => {
expect(ko.components.isRegistered("input-typeahead")).toBe(true);
});
it("should register error-display component", () => {
expect(ko.components.isRegistered("error-display")).toBe(true);
});
it("should register graph-style component", () => {
expect(ko.components.isRegistered("graph-style")).toBe(true);
});
it("should register json-editor component", () => { it("should register json-editor component", () => {
expect(ko.components.isRegistered("json-editor")).toBe(true); expect(ko.components.isRegistered("json-editor")).toBe(true);
}); });
it("should registeradd-collection-pane component", () => {
expect(ko.components.isRegistered("add-collection-pane")).toBe(true);
});
it("should register graph-styling-pane component", () => {
expect(ko.components.isRegistered("graph-styling-pane")).toBe(true);
});
it("should register dynamic-list component", () => { it("should register dynamic-list component", () => {
expect(ko.components.isRegistered("dynamic-list")).toBe(true); expect(ko.components.isRegistered("dynamic-list")).toBe(true);
}); });

View File

@@ -2,10 +2,16 @@ import * as ko from "knockout";
import { DiffEditorComponent } from "./Controls/DiffEditor/DiffEditorComponent"; import { DiffEditorComponent } from "./Controls/DiffEditor/DiffEditorComponent";
import { DynamicListComponent } from "./Controls/DynamicList/DynamicListComponent"; import { DynamicListComponent } from "./Controls/DynamicList/DynamicListComponent";
import { EditorComponent } from "./Controls/Editor/EditorComponent"; import { EditorComponent } from "./Controls/Editor/EditorComponent";
import { ErrorDisplayComponent } from "./Controls/ErrorDisplayComponent/ErrorDisplayComponent";
import { InputTypeaheadComponent } from "./Controls/InputTypeahead/InputTypeahead";
import { JsonEditorComponent } from "./Controls/JsonEditor/JsonEditorComponent"; import { JsonEditorComponent } from "./Controls/JsonEditor/JsonEditorComponent";
import { ThroughputInputComponentAutoPilotV3 } from "./Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3"; import { ThroughputInputComponentAutoPilotV3 } from "./Controls/ThroughputInput/ThroughputInputComponentAutoPilotV3";
import { GraphStyleComponent } from "./Graph/GraphStyleComponent/GraphStyleComponent";
import * as PaneComponents from "./Panes/PaneComponents"; import * as PaneComponents from "./Panes/PaneComponents";
ko.components.register("input-typeahead", new InputTypeaheadComponent());
ko.components.register("error-display", new ErrorDisplayComponent());
ko.components.register("graph-style", GraphStyleComponent);
ko.components.register("editor", new EditorComponent()); ko.components.register("editor", new EditorComponent());
ko.components.register("json-editor", new JsonEditorComponent()); ko.components.register("json-editor", new JsonEditorComponent());
ko.components.register("diff-editor", new DiffEditorComponent()); ko.components.register("diff-editor", new DiffEditorComponent());
@@ -13,4 +19,10 @@ ko.components.register("dynamic-list", DynamicListComponent);
ko.components.register("throughput-input-autopilot-v3", ThroughputInputComponentAutoPilotV3); ko.components.register("throughput-input-autopilot-v3", ThroughputInputComponentAutoPilotV3);
// Panes // Panes
ko.components.register("add-database-pane", new PaneComponents.AddDatabasePaneComponent());
ko.components.register("add-collection-pane", new PaneComponents.AddCollectionPaneComponent());
ko.components.register("graph-styling-pane", new PaneComponents.GraphStylingPaneComponent());
ko.components.register("table-add-entity-pane", new PaneComponents.TableAddEntityPaneComponent());
ko.components.register("table-edit-entity-pane", new PaneComponents.TableEditEntityPaneComponent());
ko.components.register("cassandra-add-collection-pane", new PaneComponents.CassandraAddCollectionPaneComponent()); ko.components.register("cassandra-add-collection-pane", new PaneComponents.CassandraAddCollectionPaneComponent());
ko.components.register("github-repos-pane", new PaneComponents.GitHubReposPaneComponent());

View File

@@ -29,11 +29,11 @@ export interface DatabaseContextMenuButtonParams {
* New resource tree (in ReactJS) * New resource tree (in ReactJS)
*/ */
export class ResourceTreeContextMenuButtonFactory { export class ResourceTreeContextMenuButtonFactory {
public static createDatabaseContextMenu(container: Explorer, databaseId: string): TreeNodeMenuItem[] { public static createDatabaseContextMenu(container: Explorer): TreeNodeMenuItem[] {
const items: TreeNodeMenuItem[] = [ const items: TreeNodeMenuItem[] = [
{ {
iconSrc: AddCollectionIcon, iconSrc: AddCollectionIcon,
onClick: () => container.onNewCollectionClicked(databaseId), onClick: () => container.onNewCollectionClicked(),
label: container.addCollectionText(), label: container.addCollectionText(),
}, },
]; ];

View File

@@ -1,8 +1,9 @@
import { DefaultButton, IButtonStyles, IContextualMenuItem, IContextualMenuProps } from "@fluentui/react";
import * as React from "react"; import * as React from "react";
import { getErrorMessage } from "../../../Common/ErrorHandlingUtils";
import * as Logger from "../../../Common/Logger";
import { ArcadiaWorkspace, SparkPool } from "../../../Contracts/DataModels"; import { ArcadiaWorkspace, SparkPool } from "../../../Contracts/DataModels";
import { DefaultButton, IButtonStyles } from "office-ui-fabric-react/lib/Button";
import { IContextualMenuItem, IContextualMenuProps } from "office-ui-fabric-react/lib/ContextualMenu";
import * as Logger from "../../../Common/Logger";
import { getErrorMessage } from "../../../Common/ErrorHandlingUtils";
export interface ArcadiaMenuPickerProps { export interface ArcadiaMenuPickerProps {
selectText?: string; selectText?: string;

View File

@@ -1,11 +1,10 @@
import { Icon, Label, Stack } from "@fluentui/react"; import { Icon, Label, Stack } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import { accordionStackTokens } from "../Settings/SettingsRenderUtils"; import { accordionStackTokens } from "../Settings/SettingsRenderUtils";
export interface CollapsibleSectionProps { export interface CollapsibleSectionProps {
title: string; title: string;
isExpandedByDefault: boolean; isExpandedByDefault: boolean;
onExpand?: () => void;
} }
export interface CollapsibleSectionState { export interface CollapsibleSectionState {
@@ -24,12 +23,6 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
this.setState({ isExpanded: !this.state.isExpanded }); this.setState({ isExpanded: !this.state.isExpanded });
}; };
public componentDidUpdate(): void {
if (this.state.isExpanded && this.props.onExpand) {
this.props.onExpand();
}
}
public render(): JSX.Element { public render(): JSX.Element {
return ( return (
<> <>

View File

@@ -1,20 +1,14 @@
import { import {
ChoiceGroup, ChoiceGroup,
DefaultButton,
Dialog as FluentDialog,
DialogFooter,
DialogType,
FontIcon, FontIcon,
IButtonProps,
IChoiceGroupProps, IChoiceGroupProps,
IDialogProps,
IProgressIndicatorProps, IProgressIndicatorProps,
ITextFieldProps,
Link,
PrimaryButton,
ProgressIndicator, ProgressIndicator,
TextField, } from "office-ui-fabric-react";
} from "@fluentui/react"; import { DefaultButton, IButtonProps, PrimaryButton } from "office-ui-fabric-react/lib/Button";
import { Dialog as FluentDialog, DialogFooter, DialogType, IDialogProps } from "office-ui-fabric-react/lib/Dialog";
import { Link } from "office-ui-fabric-react/lib/Link";
import { ITextFieldProps, TextField } from "office-ui-fabric-react/lib/TextField";
import React, { FunctionComponent } from "react"; import React, { FunctionComponent } from "react";
export interface TextFieldProps extends ITextFieldProps { export interface TextFieldProps extends ITextFieldProps {
@@ -103,7 +97,7 @@ export const Dialog: FunctionComponent<DialogProps> = ({
text: secondaryButtonText, text: secondaryButtonText,
onClick: onSecondaryButtonClick, onClick: onSecondaryButtonClick,
} }
: {}; : undefined;
return ( return (
<FluentDialog {...dialogProps}> <FluentDialog {...dialogProps}>

View File

@@ -2,9 +2,9 @@
* React component for Switch Directory * React component for Switch Directory
*/ */
import { Dropdown, IDropdownOption, IDropdownProps } from "@fluentui/react";
import * as React from "react";
import _ from "underscore"; import _ from "underscore";
import * as React from "react";
import { Dropdown, IDropdownOption, IDropdownProps } from "office-ui-fabric-react/lib/Dropdown";
import { Tenant } from "../../../Contracts/DataModels"; import { Tenant } from "../../../Contracts/DataModels";
export interface DefaultDirectoryDropdownProps { export interface DefaultDirectoryDropdownProps {

View File

@@ -1,15 +1,11 @@
import {
DefaultButton,
IButtonProps,
ITextFieldProps,
List,
ScrollablePane,
Sticky,
StickyPositionType,
TextField,
} from "@fluentui/react";
import * as React from "react";
import _ from "underscore"; import _ from "underscore";
import * as React from "react";
import { DefaultButton, IButtonProps } from "office-ui-fabric-react/lib/Button";
import { List } from "office-ui-fabric-react/lib/List";
import { ScrollablePane } from "office-ui-fabric-react/lib/ScrollablePane";
import { Sticky, StickyPositionType } from "office-ui-fabric-react/lib/Sticky";
import { TextField, ITextFieldProps } from "office-ui-fabric-react/lib/TextField";
import { Tenant } from "../../../Contracts/DataModels"; import { Tenant } from "../../../Contracts/DataModels";
export interface DirectoryListProps { export interface DirectoryListProps {

View File

@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`test render renders with directories and default 1`] = ` exports[`test render renders with directories and default 1`] = `
<Dropdown <StyledWithResponsiveMode
className="defaultDirectoryDropdown" className="defaultDirectoryDropdown"
defaultSelectedKey="asdfghjklzxcvbnm9876543210" defaultSelectedKey="asdfghjklzxcvbnm9876543210"
label="Set your default directory" label="Set your default directory"
@@ -26,7 +26,7 @@ exports[`test render renders with directories and default 1`] = `
`; `;
exports[`test render renders with directories and last visit default 1`] = ` exports[`test render renders with directories and last visit default 1`] = `
<Dropdown <StyledWithResponsiveMode
className="defaultDirectoryDropdown" className="defaultDirectoryDropdown"
defaultSelectedKey="lastVisited" defaultSelectedKey="lastVisited"
label="Set your default directory" label="Set your default directory"
@@ -51,7 +51,7 @@ exports[`test render renders with directories and last visit default 1`] = `
`; `;
exports[`test render renders with directories but no default 1`] = ` exports[`test render renders with directories but no default 1`] = `
<Dropdown <StyledWithResponsiveMode
className="defaultDirectoryDropdown" className="defaultDirectoryDropdown"
defaultSelectedKey="lastVisited" defaultSelectedKey="lastVisited"
label="Set your default directory" label="Set your default directory"
@@ -76,7 +76,7 @@ exports[`test render renders with directories but no default 1`] = `
`; `;
exports[`test render renders with no directories 1`] = ` exports[`test render renders with no directories 1`] = `
<Dropdown <StyledWithResponsiveMode
className="defaultDirectoryDropdown" className="defaultDirectoryDropdown"
defaultSelectedKey="lastVisited" defaultSelectedKey="lastVisited"
label="Set your default directory" label="Set your default directory"

View File

@@ -350,11 +350,11 @@ exports[`test render renders with filters 1`] = `
} }
> >
<div <div
className="ms-ScrollablePane root-53" className="ms-ScrollablePane root-40"
data-is-scrollable="true" data-is-scrollable="true"
> >
<div <div
className="stickyAbove-55" className="stickyAbove-42"
style={ style={
Object { Object {
"height": 0, "height": 0,
@@ -365,7 +365,7 @@ exports[`test render renders with filters 1`] = `
} }
/> />
<div <div
className="ms-ScrollablePane--contentContainer contentContainer-54" className="ms-ScrollablePane--contentContainer contentContainer-41"
data-is-scrollable={true} data-is-scrollable={true}
> >
<Sticky <Sticky
@@ -408,6 +408,7 @@ exports[`test render renders with filters 1`] = `
> >
<TextFieldBase <TextFieldBase
ariaLabel="Directory filter text box" ariaLabel="Directory filter text box"
canRevealPassword={false}
className="directoryListFilterTextBox" className="directoryListFilterTextBox"
deferredValidationTime={200} deferredValidationTime={200}
onChange={[Function]} onChange={[Function]}
@@ -690,18 +691,18 @@ exports[`test render renders with filters 1`] = `
validateOnLoad={true} validateOnLoad={true}
> >
<div <div
className="ms-TextField directoryListFilterTextBox root-59" className="ms-TextField directoryListFilterTextBox root-46"
> >
<div <div
className="ms-TextField-wrapper" className="ms-TextField-wrapper"
> >
<div <div
className="ms-TextField-fieldGroup fieldGroup-60" className="ms-TextField-fieldGroup fieldGroup-47"
> >
<input <input
aria-invalid={false} aria-invalid={false}
aria-label="Directory filter text box" aria-label="Directory filter text box"
className="ms-TextField-field field-61" className="ms-TextField-field field-48"
id="TextField0" id="TextField0"
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@@ -1265,6 +1266,7 @@ exports[`test render renders with filters 1`] = `
"borderColor": "#f3f2f1", "borderColor": "#f3f2f1",
"color": "#a19f9d", "color": "#a19f9d",
"cursor": "default", "cursor": "default",
"pointerEvents": "none",
"selectors": Object { "selectors": Object {
":focus": Object { ":focus": Object {
"outline": 0, "outline": 0,
@@ -1609,35 +1611,6 @@ exports[`test render renders with filters 1`] = `
}, },
}, },
}, },
"splitButtonMenuFocused": Object {
"outline": "transparent",
"position": "relative",
"selectors": Object {
".ms-Fabric--isFocusVisible &:focus:after": Object {
"border": "1px solid #ffffff",
"bottom": 3,
"content": "\\"\\"",
"left": 3,
"outline": "1px solid #605e5c",
"position": "absolute",
"right": 3,
"selectors": Object {
"@media screen and (-ms-high-contrast: active), (forced-colors: active)": Object {
"border": "none",
"bottom": -2,
"left": -2,
"right": -2,
"top": -2,
},
},
"top": 3,
"zIndex": 1,
},
"::-moz-focus-inner": Object {
"border": "0",
},
},
},
"splitButtonMenuIcon": Object { "splitButtonMenuIcon": Object {
"color": "#323130", "color": "#323130",
}, },
@@ -1927,7 +1900,7 @@ exports[`test render renders with filters 1`] = `
> >
<button <button
aria-disabled={true} aria-disabled={true}
className="ms-Button ms-Button--default is-disabled directoryListButton root-70" className="ms-Button ms-Button--default is-disabled directoryListButton root-57"
data-is-focusable={false} data-is-focusable={false}
disabled={true} disabled={true}
onClick={[Function]} onClick={[Function]}
@@ -1939,7 +1912,7 @@ exports[`test render renders with filters 1`] = `
type="button" type="button"
> >
<span <span
className="ms-Button-flexContainer flexContainer-71" className="ms-Button-flexContainer flexContainer-58"
data-automationid="splitbuttonprimary" data-automationid="splitbuttonprimary"
> >
<div <div
@@ -1959,7 +1932,7 @@ exports[`test render renders with filters 1`] = `
</div> </div>
</span> </span>
</button> </button>
<FocusRects /> <Component />
</BaseButton> </BaseButton>
</DefaultButton> </DefaultButton>
</CustomizedDefaultButton> </CustomizedDefaultButton>
@@ -1970,7 +1943,7 @@ exports[`test render renders with filters 1`] = `
</List> </List>
</div> </div>
<div <div
className="stickyBelow-56" className="stickyBelow-43"
style={ style={
Object { Object {
"bottom": "0px", "bottom": "0px",
@@ -1981,7 +1954,7 @@ exports[`test render renders with filters 1`] = `
} }
> >
<div <div
className="stickyBelowItems-57" className="stickyBelowItems-44"
/> />
</div> </div>
</div> </div>

View File

@@ -0,0 +1,27 @@
import template from "./error-display-component.html";
/**
* Helper class for ko component registration
* This component displays an error as designed in:
* https://microsoft.sharepoint.com/teams/DPX/Modern/DocDB/_layouts/15/WopiFrame.aspx?sourcedoc={66864d4a-f925-4cbe-9eb4-79f8d191a115}&action=edit&wd=target%28DocumentDB%20emulator%2Eone%7CE617D0A7-F77C-4968-B75A-1451049F4FEA%2FError%20notification%7CAA1E4BC9-4D72-472C-B40C-2437FA217226%2F%29
* TODO: support "More details"
*/
export class ErrorDisplayComponent {
constructor() {
return {
viewModel: ErrorDisplayViewModel,
template,
};
}
}
/**
* Parameters for this component
*/
interface ErrorDisplayParams {
errorMsg: ko.Observable<string>; // Primary message
}
class ErrorDisplayViewModel {
public constructor(public params: ErrorDisplayParams) {}
}

View File

@@ -0,0 +1,6 @@
<div class="warningErrorContainer" data-bind="visible: !!params.errorMsg()">
<div class="warningErrorContent">
<span><img src="/error_red.svg" alt="Error" /></span>
<span class="settingErrorMsg warningErrorDetailsLinkContainer" data-bind="text: params.errorMsg()"></span>
</div>
</div>

View File

@@ -1,14 +1,9 @@
import {
Checkbox,
DefaultButton,
Dropdown,
IDropdownOption,
IDropdownStyles,
ITextFieldStyles,
Stack,
TextField,
} from "@fluentui/react";
import * as React from "react"; import * as React from "react";
import { Stack } from "office-ui-fabric-react/lib/Stack";
import { Dropdown, IDropdownOption, IDropdownStyles } from "office-ui-fabric-react/lib/Dropdown";
import { Checkbox } from "office-ui-fabric-react/lib/Checkbox";
import { TextField, ITextFieldStyles } from "office-ui-fabric-react/lib/TextField";
import { DefaultButton } from "office-ui-fabric-react";
import "./FeaturePanelComponent.less"; import "./FeaturePanelComponent.less";
export const FeaturePanelComponent: React.FunctionComponent = () => { export const FeaturePanelComponent: React.FunctionComponent = () => {

View File

@@ -1,6 +1,6 @@
import * as React from "react"; import * as React from "react";
import { FeaturePanelComponent } from "./FeaturePanelComponent"; import { FeaturePanelComponent } from "./FeaturePanelComponent";
import { getTheme, mergeStyleSets, FontWeights, Modal, IconButton, IIconProps } from "@fluentui/react"; import { getTheme, mergeStyleSets, FontWeights, Modal, IconButton, IIconProps } from "office-ui-fabric-react";
import "./FeaturePanelLauncher.less"; import "./FeaturePanelLauncher.less";
// Modal wrapper // Modal wrapper

View File

@@ -57,7 +57,7 @@ exports[`Feature panel renders all flags 1`] = `
} }
} }
> >
<Dropdown <StyledWithResponsiveMode
label="Base Url" label="Base Url"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -85,7 +85,7 @@ exports[`Feature panel renders all flags 1`] = `
} }
} }
/> />
<Dropdown <StyledWithResponsiveMode
label="Platform" label="Platform"
onChange={[Function]} onChange={[Function]}
options={ options={

View File

@@ -1,4 +1,4 @@
import { DefaultButton, IButtonProps, ITextFieldProps, TextField } from "@fluentui/react"; import { DefaultButton, IButtonProps, ITextFieldProps, TextField } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import * as Constants from "../../../Common/Constants"; import * as Constants from "../../../Common/Constants";
import { Action } from "../../../Shared/Telemetry/TelemetryConstants"; import { Action } from "../../../Shared/Telemetry/TelemetryConstants";

View File

@@ -1,4 +1,10 @@
import { ChoiceGroup, IButtonProps, IChoiceGroupProps, PrimaryButton, IChoiceGroupOption } from "@fluentui/react"; import {
ChoiceGroup,
IButtonProps,
IChoiceGroupProps,
PrimaryButton,
IChoiceGroupOption,
} from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import { ChildrenMargin } from "./GitHubStyleConstants"; import { ChildrenMargin } from "./GitHubStyleConstants";

View File

@@ -1,4 +1,4 @@
import { DefaultButton, IButtonProps, Link, PrimaryButton } from "@fluentui/react"; import { DefaultButton, IButtonProps, Link, PrimaryButton } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import { IGitHubBranch, IGitHubRepo } from "../../../GitHub/GitHubClient"; import { IGitHubBranch, IGitHubRepo } from "../../../GitHub/GitHubClient";
import { AddRepoComponent, AddRepoComponentProps } from "./AddRepoComponent"; import { AddRepoComponent, AddRepoComponentProps } from "./AddRepoComponent";
@@ -23,6 +23,8 @@ export interface RepoListItem {
} }
export class GitHubReposComponent extends React.Component<GitHubReposComponentProps> { export class GitHubReposComponent extends React.Component<GitHubReposComponentProps> {
public static readonly ConnectToGitHubTitle = "Connect to GitHub";
public static readonly ManageGitHubRepoTitle = "Manage GitHub settings";
private static readonly ManageGitHubRepoDescription = private static readonly ManageGitHubRepoDescription =
"Select your GitHub repos and branch(es) to pin to your notebooks workspace."; "Select your GitHub repos and branch(es) to pin to your notebooks workspace.";
private static readonly ManageGitHubRepoResetConnection = "View or change your GitHub authorization settings."; private static readonly ManageGitHubRepoResetConnection = "View or change your GitHub authorization settings.";
@@ -30,6 +32,14 @@ export class GitHubReposComponent extends React.Component<GitHubReposComponentPr
private static readonly CancelButtonText = "Cancel"; private static readonly CancelButtonText = "Cancel";
public render(): JSX.Element { public render(): JSX.Element {
const header: JSX.Element = (
<p>
{this.props.showAuthorizeAccess
? GitHubReposComponent.ConnectToGitHubTitle
: GitHubReposComponent.ManageGitHubRepoTitle}
</p>
);
const content: JSX.Element = this.props.showAuthorizeAccess ? ( const content: JSX.Element = this.props.showAuthorizeAccess ? (
<AuthorizeAccessComponent {...this.props.authorizeAccessProps} /> <AuthorizeAccessComponent {...this.props.authorizeAccessProps} />
) : ( ) : (
@@ -56,6 +66,9 @@ export class GitHubReposComponent extends React.Component<GitHubReposComponentPr
return ( return (
<> <>
<div className={"firstdivbg headerline"} role="heading" aria-level={2}>
{header}
</div>
<div className={"paneMainContent"}>{content}</div> <div className={"paneMainContent"}>{content}</div>
{!this.props.showAuthorizeAccess && ( {!this.props.showAuthorizeAccess && (
<> <>

View File

@@ -1,21 +1,19 @@
import { import {
IStyleFunctionOrObject,
ICheckboxStyleProps, ICheckboxStyleProps,
ICheckboxStyles, ICheckboxStyles,
IDropdownStyleProps,
IDropdownStyles, IDropdownStyles,
IStyleFunctionOrObject, IDropdownStyleProps,
} from "@fluentui/react"; } from "office-ui-fabric-react";
export const ButtonsFooterStyle: React.CSSProperties = { export const ButtonsFooterStyle: React.CSSProperties = {
paddingTop: 14, padding: 14,
height: "auto", height: "auto",
borderTop: "2px solid lightGray",
}; };
export const ContentFooterStyle: React.CSSProperties = { export const ContentFooterStyle: React.CSSProperties = {
paddingTop: "10px", padding: "10px 24px 10px 24px",
height: "auto", height: "auto",
borderTop: "2px solid lightGray",
}; };
export const ChildrenMargin = 10; export const ChildrenMargin = 10;
@@ -55,11 +53,6 @@ export const BranchesDropdownOptionContainerStyle: React.CSSProperties = {
padding: 8, padding: 8,
}; };
export const ContentMainStyle: React.CSSProperties = {
display: "flex",
flexDirection: "column",
};
export const ReposListRepoColumnMinWidth = 192; export const ReposListRepoColumnMinWidth = 192;
export const ReposListBranchesColumnWidth = 116; export const ReposListBranchesColumnWidth = 116;
export const BranchesDropdownWidth = 200; export const BranchesDropdownWidth = 200;

View File

@@ -16,7 +16,7 @@ import {
ResponsiveMode, ResponsiveMode,
SelectionMode, SelectionMode,
Text, Text,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import { IGitHubBranch, IGitHubPageInfo } from "../../../GitHub/GitHubClient"; import { IGitHubBranch, IGitHubPageInfo } from "../../../GitHub/GitHubClient";
import * as GitHubUtils from "../../../Utils/GitHubUtils"; import * as GitHubUtils from "../../../Utils/GitHubUtils";

View File

@@ -1,5 +1,5 @@
import { CommandButton, FontIcon, FontWeights, ITextProps, Separator, Stack, Text } from "@fluentui/react";
import * as React from "react"; import * as React from "react";
import { Stack, Text, Separator, FontIcon, CommandButton, FontWeights, ITextProps } from "office-ui-fabric-react";
export class GalleryHeaderComponent extends React.Component { export class GalleryHeaderComponent extends React.Component {
private static readonly azureText = "Microsoft Azure"; private static readonly azureText = "Microsoft Azure";
@@ -61,7 +61,7 @@ export class GalleryHeaderComponent extends React.Component {
<Stack.Item> <Stack.Item>
{this.renderHeaderItem( {this.renderHeaderItem(
GalleryHeaderComponent.galleryText, GalleryHeaderComponent.galleryText,
() => "", undefined,
GalleryHeaderComponent.headerItemTextProps GalleryHeaderComponent.headerItemTextProps
)} )}
</Stack.Item> </Stack.Item>

View File

@@ -0,0 +1,186 @@
/**
* How to use this component:
*
* In your html markup, use:
* <input-typeahead params="{
choices:choices,
selection:selection,
inputValue:inputValue,
placeholder:'Enter source',
typeaheadOverrideOptions:typeaheadOverrideOptions
}"></input-typeahead>
* The parameters are documented below.
*
* Notes:
* - dynamic:true by default, this allows choices to change after initialization.
* To turn it off, use:
* typeaheadOverrideOptions: { dynamic:false }
*
*/
import "jquery-typeahead";
import template from "./input-typeahead.html";
/**
* Helper class for ko component registration
*/
export class InputTypeaheadComponent {
constructor() {
return {
viewModel: InputTypeaheadViewModel,
template,
};
}
}
export interface Item {
caption: string;
value: any;
}
/**
* Parameters for this component
*/
interface InputTypeaheadParams {
/**
* List of choices available in the dropdown.
*/
choices: ko.ObservableArray<Item>;
/**
* Gets updated when user clicks on the choice in the dropdown
*/
selection?: ko.Observable<Item>;
/**
* The current string value of <input>
*/
inputValue?: ko.Observable<string>;
/**
* Define what text you want as the input placeholder
*/
placeholder: string;
/**
* Override default jquery-typeahead options
* WARNING: do not override input, source or callback to avoid breaking the components behavior.
*/
typeaheadOverrideOptions?: any;
/**
* This function gets called when pressing ENTER on the input box
*/
submitFct?: (inputValue: string | null, selection: Item | null) => void;
/**
* Typehead comes with a Search button that we normally remove.
* If you want to use it, turn this on
*/
showSearchButton?: boolean;
}
interface OnClickItem {
matchedKey: string;
value: any;
caption: string;
group: string;
}
interface Cache {
inputValue: string | null;
selection: Item | null;
}
class InputTypeaheadViewModel {
private static instanceCount = 0; // Generate unique id for each component's typeahead instance
private instanceNumber: number;
private params: InputTypeaheadParams;
private cache: Cache;
public constructor(params: InputTypeaheadParams) {
this.instanceNumber = InputTypeaheadViewModel.instanceCount++;
this.params = params;
this.params.choices.subscribe(this.initializeTypeahead.bind(this));
this.cache = {
inputValue: null,
selection: null,
};
}
/**
* Must execute once ko is rendered, so that it can find the input element by id
*/
private initializeTypeahead() {
let params = this.params;
let cache = this.cache;
let options: any = {
input: `#${this.getComponentId()}`, //'.input-typeahead',
order: "asc",
minLength: 0,
searchOnFocus: true,
source: {
display: "caption",
data: () => {
return this.params.choices();
},
},
callback: {
onClick: (_node: unknown, _a: unknown, item: OnClickItem) => {
cache.selection = item;
if (params.selection) {
params.selection(item);
}
},
onResult(_node: unknown, query: any) {
cache.inputValue = query;
if (params.inputValue) {
params.inputValue(query);
}
},
},
template: (_query: string, item: any) => {
// Don't display id if caption *IS* the id
return item.caption === item.value
? "<span>{{caption}}</span>"
: "<span><div>{{caption}}</div><div><small>{{value}}</small></div></span>";
},
dynamic: true,
};
// Override options
if (params.typeaheadOverrideOptions) {
for (let p in params.typeaheadOverrideOptions) {
options[p] = params.typeaheadOverrideOptions[p];
}
}
($ as any).typeahead(options);
}
/**
* Get this component id
* @return unique id per instance
*/
private getComponentId(): string {
return `input-typeahead${this.instanceNumber}`;
}
/**
* Executed once ko is done rendering bindings
* Use ko's "template: afterRender" callback to do that without actually using any template.
* Another way is to call it within setTimeout() in constructor.
*/
public afterRender(): void {
this.initializeTypeahead();
}
public submit(): void {
if (this.params.submitFct) {
this.params.submitFct(this.cache.inputValue, this.cache.selection);
}
}
}

View File

@@ -0,0 +1,19 @@
<span class="input-typeahead-container">
<form class="input-typehead" data-bind="submit:submit">
<div class="typeahead__container">
<div class="typeahead__field">
<span class="typeahead__query">
<input
name="q"
type="search"
autocomplete="off"
data-bind="attr: { placeholder: params.placeholder, id:getComponentId() }, value:params.inputValue, template: { afterRender:afterRender() }"
/>
</span>
<span class="typeahead__button" data-bind="visible:params.showSearchButton">
<button type="submit"><span class="typeahead__search-icon"></span></button>
</span>
</div>
</div>
</form>
</span>

View File

@@ -13,6 +13,7 @@ const createTestDatabaseAccount = (): DataModels.DatabaseAccount => {
gremlinEndpoint: null, gremlinEndpoint: null,
tableEndpoint: null, tableEndpoint: null,
}, },
tags: "testTags",
type: "testType", type: "testType",
}; };
}; };
@@ -29,6 +30,7 @@ const createTestMongo32DatabaseAccount = (): DataModels.DatabaseAccount => {
gremlinEndpoint: null, gremlinEndpoint: null,
tableEndpoint: null, tableEndpoint: null,
}, },
tags: "testTags",
type: "testType", type: "testType",
}; };
}; };
@@ -46,6 +48,7 @@ const createTestMongo36DatabaseAccount = (): DataModels.DatabaseAccount => {
tableEndpoint: null, tableEndpoint: null,
mongoEndpoint: "https://testMongoEndpoint.azure.com/", mongoEndpoint: "https://testMongoEndpoint.azure.com/",
}, },
tags: "testTags",
type: "testType", type: "testType",
}; };
}; };
@@ -62,6 +65,7 @@ const createTestCassandraDatabaseAccount = (): DataModels.DatabaseAccount => {
gremlinEndpoint: null, gremlinEndpoint: null,
tableEndpoint: null, tableEndpoint: null,
}, },
tags: "testTags",
type: "testType", type: "testType",
}; };
}; };

View File

@@ -1,23 +1,21 @@
import { Card } from "@uifabric/react-cards";
import { import {
BaseButton, BaseButton,
Button, Button,
DocumentCard, FontWeights,
DocumentCardActivity,
DocumentCardDetails,
DocumentCardPreview,
DocumentCardTitle,
Icon, Icon,
IconButton, IconButton,
IDocumentCardPreviewProps, Image,
IDocumentCardStyles,
ImageFit, ImageFit,
Link, Link,
LinkBase,
Persona,
Separator, Separator,
Spinner, Spinner,
SpinnerSize, SpinnerSize,
Text, Text,
TooltipHost, TooltipHost,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import React, { FunctionComponent, useState } from "react"; import React, { FunctionComponent, useState } from "react";
import CosmosDBLogo from "../../../../../images/CosmosDB-logo.svg"; import CosmosDBLogo from "../../../../../images/CosmosDB-logo.svg";
import { IGalleryItem } from "../../../../Juno/JunoClient"; import { IGalleryItem } from "../../../../Juno/JunoClient";
@@ -51,6 +49,7 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
const CARD_WIDTH = 256; const CARD_WIDTH = 256;
const cardImageHeight = 144; const cardImageHeight = 144;
const cardDescriptionMaxChars = 80; const cardDescriptionMaxChars = 80;
const cardItemGapBig = 10;
const cardItemGapSmall = 8; const cardItemGapSmall = 8;
const cardDeleteSpinnerHeight = 360; const cardDeleteSpinnerHeight = 360;
const smallTextLineHeight = 18; const smallTextLineHeight = 18;
@@ -66,9 +65,9 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
const dateString = new Date(data.created).toLocaleString("default", options); const dateString = new Date(data.created).toLocaleString("default", options);
const cardTitle = FileSystemUtil.stripExtension(data.name, "ipynb"); const cardTitle = FileSystemUtil.stripExtension(data.name, "ipynb");
const renderTruncated = (text: string, totalLength: number): string => { const renderTruncatedDescription = (): string => {
let truncatedDescription = text.substr(0, totalLength); let truncatedDescription = data.description.substr(0, cardDescriptionMaxChars);
if (text.length > totalLength) { if (data.description.length > cardDescriptionMaxChars) {
truncatedDescription = `${truncatedDescription} ...`; truncatedDescription = `${truncatedDescription} ...`;
} }
return truncatedDescription; return truncatedDescription;
@@ -111,7 +110,7 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
const handlerOnClick = ( const handlerOnClick = (
event: event:
| React.MouseEvent<HTMLElement | HTMLAnchorElement | HTMLButtonElement | MouseEvent> | React.MouseEvent<HTMLElement | HTMLAnchorElement | HTMLButtonElement | LinkBase, MouseEvent>
| React.MouseEvent< | React.MouseEvent<
HTMLAnchorElement | HTMLButtonElement | HTMLDivElement | BaseButton | Button | HTMLSpanElement, HTMLAnchorElement | HTMLButtonElement | HTMLDivElement | BaseButton | Button | HTMLSpanElement,
MouseEvent MouseEvent
@@ -122,35 +121,42 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
event.preventDefault(); event.preventDefault();
activate(); activate();
}; };
const DocumentCardActivityPeople = [{ name: data.author, profileImageSrc: data.isSample && CosmosDBLogo }];
const previewProps: IDocumentCardPreviewProps = {
previewImages: [
{
previewImageSrc: data.thumbnailUrl,
imageFit: ImageFit.cover,
width: CARD_WIDTH,
height: cardImageHeight,
},
],
};
const cardStyles: IDocumentCardStyles = {
root: { display: "inline-block", marginRight: 20, width: CARD_WIDTH },
};
return ( return (
<DocumentCard aria-label={cardTitle} styles={cardStyles} onClick={onClick}> <Card
style={{ background: "white" }}
aria-label={cardTitle}
data-is-focusable="true"
tokens={{ width: CARD_WIDTH, childrenGap: 0 }}
onClick={(event) => handlerOnClick(event, onClick)}
>
{isDeletingPublishedNotebook && ( {isDeletingPublishedNotebook && (
<Spinner <Card.Item tokens={{ padding: cardItemGapBig }}>
size={SpinnerSize.large} <Spinner
label={`Deleting '${cardTitle}'`} size={SpinnerSize.large}
styles={{ root: { height: cardDeleteSpinnerHeight } }} label={`Deleting '${cardTitle}'`}
/> styles={{ root: { height: cardDeleteSpinnerHeight } }}
/>
</Card.Item>
)} )}
{!isDeletingPublishedNotebook && ( {!isDeletingPublishedNotebook && (
<> <>
<DocumentCardActivity activity={dateString} people={DocumentCardActivityPeople} /> <Card.Item tokens={{ padding: cardItemGapBig }}>
<DocumentCardPreview {...previewProps} /> <Persona imageUrl={data.isSample && CosmosDBLogo} text={data.author} secondaryText={dateString} />
<DocumentCardDetails> </Card.Item>
<Text variant="small" nowrap styles={{ root: { height: smallTextLineHeight, padding: "2px 16px" } }}>
<Card.Item>
<Image
src={data.thumbnailUrl}
width={CARD_WIDTH}
height={cardImageHeight}
imageFit={ImageFit.cover}
alt={`${cardTitle} cover image`}
/>
</Card.Item>
<Card.Section styles={{ root: { padding: cardItemGapBig } }}>
<Text variant="small" nowrap styles={{ root: { height: smallTextLineHeight } }}>
{data.tags ? ( {data.tags ? (
data.tags.map((tag, index, array) => ( data.tags.map((tag, index, array) => (
<span key={tag}> <span key={tag}>
@@ -162,22 +168,43 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
<br /> <br />
)} )}
</Text> </Text>
<DocumentCardTitle title={renderTruncated(cardTitle, 20)} shouldTruncate />
<DocumentCardTitle <Text
title={renderTruncated(data.description, cardDescriptionMaxChars)} styles={{
showAsSecondaryTitle root: {
/> fontWeight: FontWeights.semibold,
<span style={{ padding: "8px 16px" }}> paddingTop: cardItemGapSmall,
paddingBottom: cardItemGapSmall,
},
}}
nowrap
>
{cardTitle}
</Text>
<Text variant="small" styles={{ root: { height: smallTextLineHeight * 2 } }}>
{renderTruncatedDescription()}
</Text>
<span>
{data.views !== undefined && generateIconText("RedEye", data.views.toString())} {data.views !== undefined && generateIconText("RedEye", data.views.toString())}
{data.downloads !== undefined && generateIconText("Download", data.downloads.toString())} {data.downloads !== undefined && generateIconText("Download", data.downloads.toString())}
{data.favorites !== undefined && generateIconText("Heart", data.favorites.toString())} {data.favorites !== undefined && generateIconText("Heart", data.favorites.toString())}
</span> </span>
</DocumentCardDetails> </Card.Section>
{cardButtonsVisible && ( {cardButtonsVisible && (
<DocumentCardDetails> <Card.Section
styles={{
root: {
marginLeft: cardItemGapBig,
marginRight: cardItemGapBig,
},
}}
>
<Separator styles={{ root: { padding: 0, height: 1 } }} /> <Separator styles={{ root: { padding: 0, height: 1 } }} />
<span style={{ padding: "0px 16px" }}> <span>
{isFavorite !== undefined && {isFavorite !== undefined &&
generateIconButtonWithTooltip( generateIconButtonWithTooltip(
isFavorite ? "HeartFill" : "Heart", isFavorite ? "HeartFill" : "Heart",
@@ -196,10 +223,10 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
) )
)} )}
</span> </span>
</DocumentCardDetails> </Card.Section>
)} )}
</> </>
)} )}
</DocumentCard> </Card>
); );
}; };

View File

@@ -1,49 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`GalleryCardComponent renders 1`] = ` exports[`GalleryCardComponent renders 1`] = `
<StyledDocumentCardBase <Card
aria-label="name" aria-label="name"
styles={ data-is-focusable="true"
onClick={[Function]}
style={
Object { Object {
"root": Object { "background": "white",
"display": "inline-block", }
"marginRight": 20, }
"width": 256, tokens={
}, Object {
"childrenGap": 0,
"width": 256,
} }
} }
> >
<StyledDocumentCardActivityBase <CardItem
activity="Invalid Date" tokens={
people={ Object {
Array [ "padding": 10,
Object { }
"name": "author",
"profileImageSrc": false,
},
]
} }
/> >
<StyledDocumentCardPreviewBase <StyledPersonaBase
previewImages={ imageUrl={false}
Array [ secondaryText="Invalid Date"
Object { text="author"
"height": 144, />
"imageFit": 2, </CardItem>
"previewImageSrc": "thumbnailUrl", <CardItem>
"width": 256, <StyledImageBase
alt="name cover image"
height={144}
imageFit={2}
src="thumbnailUrl"
width={256}
/>
</CardItem>
<CardSection
styles={
Object {
"root": Object {
"padding": 10,
}, },
] }
} }
/> >
<StyledDocumentCardDetailsBase>
<Text <Text
nowrap={true} nowrap={true}
styles={ styles={
Object { Object {
"root": Object { "root": Object {
"height": 18, "height": 18,
"padding": "2px 16px",
}, },
} }
} }
@@ -59,21 +69,33 @@ exports[`GalleryCardComponent renders 1`] = `
</StyledLinkBase> </StyledLinkBase>
</span> </span>
</Text> </Text>
<StyledDocumentCardTitleBase <Text
shouldTruncate={true} nowrap={true}
title="name" styles={
/>
<StyledDocumentCardTitleBase
showAsSecondaryTitle={true}
title="description"
/>
<span
style={
Object { Object {
"padding": "8px 16px", "root": Object {
"fontWeight": 600,
"paddingBottom": 8,
"paddingTop": 8,
},
} }
} }
> >
name
</Text>
<Text
styles={
Object {
"root": Object {
"height": 36,
},
}
}
variant="small"
>
description
</Text>
<span>
<Text <Text
styles={ styles={
Object { Object {
@@ -147,8 +169,17 @@ exports[`GalleryCardComponent renders 1`] = `
0 0
</Text> </Text>
</span> </span>
</StyledDocumentCardDetailsBase> </CardSection>
<StyledDocumentCardDetailsBase> <CardSection
styles={
Object {
"root": Object {
"marginLeft": 10,
"marginRight": 10,
},
}
}
>
<Separator <Separator
styles={ styles={
Object { Object {
@@ -159,13 +190,7 @@ exports[`GalleryCardComponent renders 1`] = `
} }
} }
/> />
<span <span>
style={
Object {
"padding": "0px 16px",
}
}
>
<StyledTooltipHostBase <StyledTooltipHostBase
calloutProps={ calloutProps={
Object { Object {
@@ -251,6 +276,6 @@ exports[`GalleryCardComponent renders 1`] = `
/> />
</StyledTooltipHostBase> </StyledTooltipHostBase>
</span> </span>
</StyledDocumentCardDetailsBase> </CardSection>
</StyledDocumentCardBase> </Card>
`; `;

View File

@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CodeOfConduct renders 1`] = ` exports[`CodeOfConductComponent renders 1`] = `
<Stack <Stack
tokens={ tokens={
Object { Object {

View File

@@ -1,15 +1,15 @@
jest.mock("../../../../Juno/JunoClient"); jest.mock("../../../../Juno/JunoClient");
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import React from "react"; import React from "react";
import { CodeOfConductComponent, CodeOfConductComponentProps } from ".";
import { HttpStatusCodes } from "../../../../Common/Constants"; import { HttpStatusCodes } from "../../../../Common/Constants";
import { JunoClient } from "../../../../Juno/JunoClient"; import { JunoClient } from "../../../../Juno/JunoClient";
import { CodeOfConduct, CodeOfConductProps } from "./CodeOfConduct";
describe("CodeOfConduct", () => { describe("CodeOfConductComponent", () => {
let codeOfConductProps: CodeOfConductProps; let codeOfConductProps: CodeOfConductComponentProps;
beforeEach(() => { beforeEach(() => {
const junoClient = new JunoClient(); const junoClient = new JunoClient(undefined);
junoClient.acceptCodeOfConduct = jest.fn().mockReturnValue({ junoClient.acceptCodeOfConduct = jest.fn().mockReturnValue({
status: HttpStatusCodes.OK, status: HttpStatusCodes.OK,
data: true, data: true,
@@ -21,12 +21,12 @@ describe("CodeOfConduct", () => {
}); });
it("renders", () => { it("renders", () => {
const wrapper = shallow(<CodeOfConduct {...codeOfConductProps} />); const wrapper = shallow(<CodeOfConductComponent {...codeOfConductProps} />);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it("onAcceptedCodeOfConductCalled", async () => { it("onAcceptedCodeOfConductCalled", async () => {
const wrapper = shallow(<CodeOfConduct {...codeOfConductProps} />); const wrapper = shallow(<CodeOfConductComponent {...codeOfConductProps} />);
wrapper.find(".genericPaneSubmitBtn").first().simulate("click"); wrapper.find(".genericPaneSubmitBtn").first().simulate("click");
await Promise.resolve(); await Promise.resolve();
expect(codeOfConductProps.onAcceptCodeOfConduct).toBeCalled(); expect(codeOfConductProps.onAcceptCodeOfConduct).toBeCalled();

View File

@@ -1,4 +1,4 @@
import { Checkbox, Link, PrimaryButton, Stack, Text } from "@fluentui/react"; import { Checkbox, Link, PrimaryButton, Stack, Text } from "office-ui-fabric-react";
import React, { FunctionComponent, useEffect, useState } from "react"; import React, { FunctionComponent, useEffect, useState } from "react";
import { CodeOfConductEndpoints, HttpStatusCodes } from "../../../../Common/Constants"; import { CodeOfConductEndpoints, HttpStatusCodes } from "../../../../Common/Constants";
import { getErrorMessage, getErrorStack, handleError } from "../../../../Common/ErrorHandlingUtils"; import { getErrorMessage, getErrorStack, handleError } from "../../../../Common/ErrorHandlingUtils";
@@ -6,15 +6,15 @@ import { JunoClient } from "../../../../Juno/JunoClient";
import { Action } from "../../../../Shared/Telemetry/TelemetryConstants"; import { Action } from "../../../../Shared/Telemetry/TelemetryConstants";
import { trace, traceFailure, traceStart, traceSuccess } from "../../../../Shared/Telemetry/TelemetryProcessor"; import { trace, traceFailure, traceStart, traceSuccess } from "../../../../Shared/Telemetry/TelemetryProcessor";
export interface CodeOfConductProps { export interface CodeOfConductComponentProps {
junoClient: JunoClient; junoClient: JunoClient;
onAcceptCodeOfConduct: (result: boolean) => void; onAcceptCodeOfConduct: (result: boolean) => void;
} }
export const CodeOfConduct: FunctionComponent<CodeOfConductProps> = ({ export const CodeOfConductComponent: FunctionComponent<CodeOfConductComponentProps> = ({
junoClient, junoClient,
onAcceptCodeOfConduct, onAcceptCodeOfConduct,
}: CodeOfConductProps) => { }: CodeOfConductComponentProps) => {
const descriptionPara1 = "Azure Cosmos DB Notebook Gallery - Code of Conduct"; const descriptionPara1 = "Azure Cosmos DB Notebook Gallery - Code of Conduct";
const descriptionPara2 = "The notebook public gallery contains notebook samples shared by users of Azure Cosmos DB."; const descriptionPara2 = "The notebook public gallery contains notebook samples shared by users of Azure Cosmos DB.";
const descriptionPara3 = "In order to view and publish your samples to the gallery, you must accept the "; const descriptionPara3 = "In order to view and publish your samples to the gallery, you must accept the ";
@@ -47,7 +47,7 @@ export const CodeOfConduct: FunctionComponent<CodeOfConductProps> = ({
startKey startKey
); );
handleError(error, "CodeOfConduct/acceptCodeOfConduct", "Failed to accept code of conduct"); handleError(error, "CodeOfConductComponent/acceptCodeOfConduct", "Failed to accept code of conduct");
} }
}; };

View File

@@ -19,7 +19,7 @@ import {
SpinnerSize, SpinnerSize,
Stack, Stack,
Text, Text,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import { HttpStatusCodes } from "../../../Common/Constants"; import { HttpStatusCodes } from "../../../Common/Constants";
import { handleError } from "../../../Common/ErrorHandlingUtils"; import { handleError } from "../../../Common/ErrorHandlingUtils";
@@ -30,10 +30,11 @@ import * as GalleryUtils from "../../../Utils/GalleryUtils";
import Explorer from "../../Explorer"; import Explorer from "../../Explorer";
import { Dialog, DialogProps } from "../Dialog"; import { Dialog, DialogProps } from "../Dialog";
import { GalleryCardComponent, GalleryCardComponentProps } from "./Cards/GalleryCardComponent"; import { GalleryCardComponent, GalleryCardComponentProps } from "./Cards/GalleryCardComponent";
import { CodeOfConduct } from "./CodeOfConduct/CodeOfConduct"; import { CodeOfConductComponent } from "./CodeOfConductComponent";
import "./GalleryViewerComponent.less"; import "./GalleryViewerComponent.less";
import { InfoComponent } from "./InfoComponent/InfoComponent"; import { InfoComponent } from "./InfoComponent/InfoComponent";
const CARD_WIDTH = 256;
export interface GalleryViewerComponentProps { export interface GalleryViewerComponentProps {
container?: Explorer; container?: Explorer;
junoClient: JunoClient; junoClient: JunoClient;
@@ -86,7 +87,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
public static readonly PublishedTitle = "My published work"; public static readonly PublishedTitle = "My published work";
private static readonly rowsPerPage = 5; private static readonly rowsPerPage = 5;
private static readonly CARD_WIDTH = 256;
private static readonly mostViewedText = "Most viewed"; private static readonly mostViewedText = "Most viewed";
private static readonly mostDownloadedText = "Most downloaded"; private static readonly mostDownloadedText = "Most downloaded";
private static readonly mostFavoritedText = "Most favorited"; private static readonly mostFavoritedText = "Most favorited";
@@ -372,7 +373,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
{acceptedCodeOfConduct === false && ( {acceptedCodeOfConduct === false && (
<Overlay isDarkThemed> <Overlay isDarkThemed>
<div className="publicGalleryTabOverlayContent"> <div className="publicGalleryTabOverlayContent">
<CodeOfConduct <CodeOfConductComponent
junoClient={this.props.junoClient} junoClient={this.props.junoClient}
onAcceptCodeOfConduct={(result: boolean) => { onAcceptCodeOfConduct={(result: boolean) => {
this.setState({ isCodeOfConductAccepted: result }); this.setState({ isCodeOfConductAccepted: result });
@@ -643,7 +644,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
private getPageSpecification = (itemIndex?: number, visibleRect?: IRectangle): IPageSpecification => { private getPageSpecification = (itemIndex?: number, visibleRect?: IRectangle): IPageSpecification => {
if (itemIndex === 0) { if (itemIndex === 0) {
this.columnCount = Math.floor(visibleRect.width / GalleryViewerComponent.CARD_WIDTH) || this.columnCount; this.columnCount = Math.floor(visibleRect.width / CARD_WIDTH) || this.columnCount;
this.rowCount = GalleryViewerComponent.rowsPerPage; this.rowCount = GalleryViewerComponent.rowsPerPage;
} }
@@ -671,7 +672,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
}; };
return ( return (
<div style={{ float: "left", padding: 5 }}> <div style={{ float: "left", padding: 10 }}>
<GalleryCardComponent {...props} /> <GalleryCardComponent {...props} />
</div> </div>
); );

View File

@@ -1,5 +1,5 @@
import * as React from "react"; import * as React from "react";
import { Icon, Label, Stack, HoverCard, HoverCardType, Link } from "@fluentui/react"; import { Icon, Label, Stack, HoverCard, HoverCardType, Link } from "office-ui-fabric-react";
import { CodeOfConductEndpoints } from "../../../../Common/Constants"; import { CodeOfConductEndpoints } from "../../../../Common/Constants";
import "./InfoComponent.less"; import "./InfoComponent.less";

View File

@@ -4,7 +4,7 @@ exports[`GalleryViewerComponent renders 1`] = `
<div <div
className="galleryContainer" className="galleryContainer"
> >
<StyledPivot <StyledPivotBase
onLinkClick={[Function]} onLinkClick={[Function]}
selectedKey="OfficialSamples" selectedKey="OfficialSamples"
> >
@@ -41,7 +41,7 @@ exports[`GalleryViewerComponent renders 1`] = `
<StackItem <StackItem
grow={true} grow={true}
> >
<StyledSearchBox <StyledSearchBoxBase
onChange={[Function]} onChange={[Function]}
placeholder="Search" placeholder="Search"
/> />
@@ -60,7 +60,7 @@ exports[`GalleryViewerComponent renders 1`] = `
} }
} }
> >
<Dropdown <StyledWithResponsiveMode
onChange={[Function]} onChange={[Function]}
options={ options={
Array [ Array [
@@ -127,7 +127,7 @@ exports[`GalleryViewerComponent renders 1`] = `
<StackItem <StackItem
grow={true} grow={true}
> >
<StyledSearchBox <StyledSearchBoxBase
onChange={[Function]} onChange={[Function]}
placeholder="Search" placeholder="Search"
/> />
@@ -146,7 +146,7 @@ exports[`GalleryViewerComponent renders 1`] = `
} }
} }
> >
<Dropdown <StyledWithResponsiveMode
onChange={[Function]} onChange={[Function]}
options={ options={
Array [ Array [
@@ -182,6 +182,6 @@ exports[`GalleryViewerComponent renders 1`] = `
</StackItem> </StackItem>
</Stack> </Stack>
</PivotItem> </PivotItem>
</StyledPivot> </StyledPivotBase>
</div> </div>
`; `;

View File

@@ -1,7 +1,17 @@
/** /**
* Wrapper around Notebook metadata * Wrapper around Notebook metadata
*/ */
import { FontWeights, Icon, IconButton, Link, Persona, PersonaSize, PrimaryButton, Stack, Text } from "@fluentui/react"; import {
FontWeights,
Icon,
IconButton,
Link,
Persona,
PersonaSize,
PrimaryButton,
Stack,
Text,
} from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import { IGalleryItem } from "../../../Juno/JunoClient"; import { IGalleryItem } from "../../../Juno/JunoClient";
import * as FileSystemUtil from "../../Notebook/FileSystemUtil"; import * as FileSystemUtil from "../../Notebook/FileSystemUtil";

View File

@@ -3,7 +3,7 @@
*/ */
import { Notebook } from "@nteract/commutable"; import { Notebook } from "@nteract/commutable";
import { createContentRef } from "@nteract/core"; import { createContentRef } from "@nteract/core";
import { IChoiceGroupProps, Icon, IProgressIndicatorProps, Link, ProgressIndicator } from "@fluentui/react"; import { IChoiceGroupProps, Icon, IProgressIndicatorProps, Link, ProgressIndicator } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import { contents } from "rx-jupyter"; import { contents } from "rx-jupyter";
import { IGalleryItem, JunoClient } from "../../../Juno/JunoClient"; import { IGalleryItem, JunoClient } from "../../../Juno/JunoClient";

View File

@@ -1,24 +1,22 @@
import { IButtonProps, IconButton } from "office-ui-fabric-react/lib/Button";
import { ContextualMenu, IContextualMenuProps } from "office-ui-fabric-react/lib/ContextualMenu";
import { import {
ContextualMenu,
DetailsList, DetailsList,
DetailsListLayoutMode, DetailsListLayoutMode,
DetailsRow, DetailsRow,
FocusZone,
IButtonProps,
IColumn, IColumn,
IconButton,
IContextualMenuProps,
IDetailsListProps, IDetailsListProps,
IDetailsRowProps, IDetailsRowProps,
} from "office-ui-fabric-react/lib/DetailsList";
import { FocusZone } from "office-ui-fabric-react/lib/FocusZone";
import { ITextField, ITextFieldProps, TextField } from "office-ui-fabric-react/lib/TextField";
import {
IObjectWithKey, IObjectWithKey,
ISelectionZoneProps, ISelectionZoneProps,
ITextField,
ITextFieldProps,
Selection, Selection,
SelectionMode, SelectionMode,
SelectionZone, SelectionZone,
TextField, } from "office-ui-fabric-react/lib/utilities/selection/index";
} from "@fluentui/react";
import * as React from "react"; import * as React from "react";
import * as _ from "underscore"; import * as _ from "underscore";
import SaveQueryBannerIcon from "../../../../images/save_query_banner.png"; import SaveQueryBannerIcon from "../../../../images/save_query_banner.png";

View File

@@ -2,10 +2,10 @@
* Horizontal switch component * Horizontal switch component
*/ */
import { Icon } from "@fluentui/react";
import * as React from "react"; import * as React from "react";
import { NormalizedEventKey } from "../../../Common/Constants";
import "./RadioSwitchComponent.less"; import "./RadioSwitchComponent.less";
import { Icon } from "office-ui-fabric-react/lib/Icon";
import { NormalizedEventKey } from "../../../Common/Constants";
export interface Choice { export interface Choice {
key: string; key: string;

View File

@@ -154,20 +154,19 @@ describe("SettingsComponent", () => {
expect(settingsComponentInstance.hasConflictResolution()).toEqual(undefined); expect(settingsComponentInstance.hasConflictResolution()).toEqual(undefined);
const newContainer = new Explorer(); const newContainer = new Explorer();
updateUserContext({ newContainer.databaseAccount = ko.observable({
databaseAccount: { id: undefined,
id: undefined, name: undefined,
name: undefined, location: undefined,
location: undefined, type: undefined,
type: undefined, kind: undefined,
kind: undefined, tags: undefined,
properties: { properties: {
documentEndpoint: undefined, documentEndpoint: undefined,
tableEndpoint: undefined, tableEndpoint: undefined,
gremlinEndpoint: undefined, gremlinEndpoint: undefined,
cassandraEndpoint: undefined, cassandraEndpoint: undefined,
enableMultipleWriteLocations: true, enableMultipleWriteLocations: true,
},
}, },
}); });
const newCollection = { ...collection }; const newCollection = { ...collection };

View File

@@ -1,4 +1,4 @@
import { IPivotItemProps, IPivotProps, Pivot, PivotItem } from "@fluentui/react"; import { IPivotItemProps, IPivotProps, Pivot, PivotItem } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import DiscardIcon from "../../../../images/discard.svg"; import DiscardIcon from "../../../../images/discard.svg";
import SaveIcon from "../../../../images/save-cosmos.svg"; import SaveIcon from "../../../../images/save-cosmos.svg";
@@ -233,7 +233,11 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
} }
public loadMongoIndexes = async (): Promise<void> => { public loadMongoIndexes = async (): Promise<void> => {
if (userContext.apiType === "Mongo" && userContext?.databaseAccount) { if (
userContext.apiType === "Mongo" &&
this.container.isEnableMongoCapabilityPresent() &&
this.container.databaseAccount()
) {
this.mongoDBCollectionResource = await readMongoDBCollectionThroughRP( this.mongoDBCollectionResource = await readMongoDBCollectionThroughRP(
this.collection.databaseId, this.collection.databaseId,
this.collection.id() this.collection.id()
@@ -296,7 +300,8 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
this.container && userContext.apiType === "Cassandra" && hasDatabaseSharedThroughput(this.collection); this.container && userContext.apiType === "Cassandra" && hasDatabaseSharedThroughput(this.collection);
public hasConflictResolution = (): boolean => public hasConflictResolution = (): boolean =>
userContext?.databaseAccount?.properties?.enableMultipleWriteLocations && this.container?.databaseAccount &&
this.container.databaseAccount()?.properties?.enableMultipleWriteLocations &&
this.collection.conflictResolutionPolicy && this.collection.conflictResolutionPolicy &&
!!this.collection.conflictResolutionPolicy(); !!this.collection.conflictResolutionPolicy();
@@ -871,7 +876,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
mongoIndexingPolicyComponentProps: MongoIndexingPolicyComponentProps mongoIndexingPolicyComponentProps: MongoIndexingPolicyComponentProps
): JSX.Element => { ): JSX.Element => {
if (userContext.authType === AuthType.AAD) { if (userContext.authType === AuthType.AAD) {
if (userContext.apiType === "Mongo") { if (this.container.isEnableMongoCapabilityPresent()) {
return <MongoIndexingPolicyComponent {...mongoIndexingPolicyComponentProps} />; return <MongoIndexingPolicyComponent {...mongoIndexingPolicyComponentProps} />;
} }
return undefined; return undefined;

View File

@@ -1,6 +1,6 @@
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import React from "react"; import React from "react";
import { IColumn, Text } from "@fluentui/react"; import { IColumn, Text } from "office-ui-fabric-react";
import { import {
getAutoPilotV3SpendElement, getAutoPilotV3SpendElement,
getEstimatedSpendingElement, getEstimatedSpendingElement,

View File

@@ -38,7 +38,7 @@ import {
IDetailsRowProps, IDetailsRowProps,
DetailsRow, DetailsRow,
IDetailsColumnStyles, IDetailsColumnStyles,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import { isDirtyTypes, isDirty } from "./SettingsUtils"; import { isDirtyTypes, isDirty } from "./SettingsUtils";
export interface EstimatedSpendingDisplayProps { export interface EstimatedSpendingDisplayProps {

View File

@@ -9,7 +9,7 @@ import {
subComponentStackProps, subComponentStackProps,
getChoiceGroupStyles, getChoiceGroupStyles,
} from "../SettingsRenderUtils"; } from "../SettingsRenderUtils";
import { TextField, ITextFieldProps, Stack, IChoiceGroupOption, ChoiceGroup } from "@fluentui/react"; import { TextField, ITextFieldProps, Stack, IChoiceGroupOption, ChoiceGroup } from "office-ui-fabric-react";
import { ToolTipLabelComponent } from "./ToolTipLabelComponent"; import { ToolTipLabelComponent } from "./ToolTipLabelComponent";
import { isDirty } from "../SettingsUtils"; import { isDirty } from "../SettingsUtils";

View File

@@ -1,8 +1,7 @@
import { MessageBar, MessageBarType, Stack } from "@fluentui/react"; import { MessageBar, MessageBarType, Stack } from "office-ui-fabric-react";
import * as monaco from "monaco-editor";
import * as React from "react"; import * as React from "react";
import * as DataModels from "../../../../Contracts/DataModels"; import * as DataModels from "../../../../Contracts/DataModels";
import { loadMonaco } from "../../../LazyMonaco"; import { loadMonaco, monaco } from "../../../LazyMonaco";
import { indexingPolicynUnsavedWarningMessage, titleAndInputStackProps } from "../SettingsRenderUtils"; import { indexingPolicynUnsavedWarningMessage, titleAndInputStackProps } from "../SettingsRenderUtils";
import { isDirty, isIndexTransforming } from "../SettingsUtils"; import { isDirty, isIndexTransforming } from "../SettingsUtils";
import { IndexingPolicyRefreshComponent } from "./IndexingPolicyRefresh/IndexingPolicyRefreshComponent"; import { IndexingPolicyRefreshComponent } from "./IndexingPolicyRefresh/IndexingPolicyRefreshComponent";

View File

@@ -1,5 +1,5 @@
import * as React from "react"; import * as React from "react";
import { MessageBar, MessageBarType } from "@fluentui/react"; import { MessageBar, MessageBarType } from "office-ui-fabric-react";
import { import {
mongoIndexTransformationRefreshingMessage, mongoIndexTransformationRefreshingMessage,
renderMongoIndexTransformationRefreshMessage, renderMongoIndexTransformationRefreshMessage,

View File

@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`IndexingPolicyRefreshComponent renders 1`] = ` exports[`IndexingPolicyRefreshComponent renders 1`] = `
<StyledMessageBar <StyledMessageBarBase
messageBarType={5} messageBarType={5}
> >
<Text <Text
@@ -20,5 +20,5 @@ exports[`IndexingPolicyRefreshComponent renders 1`] = `
Refresh to check the progress. Refresh to check the progress.
</StyledLinkBase> </StyledLinkBase>
</Text> </Text>
</StyledMessageBar> </StyledMessageBarBase>
`; `;

View File

@@ -8,7 +8,7 @@ import {
Dropdown, Dropdown,
IDropdownOption, IDropdownOption,
ITextField, ITextField,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import { import {
addMongoIndexSubElementsTokens, addMongoIndexSubElementsTokens,
mongoErrorMessageStyles, mongoErrorMessageStyles,

View File

@@ -12,7 +12,7 @@ import {
Spinner, Spinner,
SpinnerSize, SpinnerSize,
Separator, Separator,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import { import {
addMongoIndexStackProps, addMongoIndexStackProps,
customDetailsListStyles, customDetailsListStyles,

View File

@@ -30,7 +30,7 @@ exports[`AddMongoIndexComponent renders 1`] = `
} }
value="sample_key" value="sample_key"
/> />
<Dropdown <StyledWithResponsiveMode
ariaLabel="Index Type 1" ariaLabel="Index Type 1"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -67,7 +67,7 @@ exports[`AddMongoIndexComponent renders 1`] = `
onClick={[Function]} onClick={[Function]}
/> />
</Stack> </Stack>
<StyledMessageBar <StyledMessageBarBase
messageBarType={1} messageBarType={1}
styles={ styles={
Object { Object {
@@ -78,6 +78,6 @@ exports[`AddMongoIndexComponent renders 1`] = `
} }
> >
sample error sample error
</StyledMessageBar> </StyledMessageBarBase>
</Stack> </Stack>
`; `;

View File

@@ -1,15 +1,14 @@
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import ko from "knockout";
import React from "react"; import React from "react";
import { ScaleComponent, ScaleComponentProps } from "./ScaleComponent";
import { container, collection } from "../TestUtils";
import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents/ThroughputInputAutoPilotV3Component";
import Explorer from "../../../Explorer";
import * as Constants from "../../../../Common/Constants"; import * as Constants from "../../../../Common/Constants";
import * as DataModels from "../../../../Contracts/DataModels"; import * as DataModels from "../../../../Contracts/DataModels";
import * as SharedConstants from "../../../../Shared/Constants";
import { updateUserContext } from "../../../../UserContext";
import Explorer from "../../../Explorer";
import { throughputUnit } from "../SettingsRenderUtils"; import { throughputUnit } from "../SettingsRenderUtils";
import { collection, container } from "../TestUtils"; import * as SharedConstants from "../../../../Shared/Constants";
import { ScaleComponent, ScaleComponentProps } from "./ScaleComponent"; import ko from "knockout";
import { ThroughputInputAutoPilotV3Component } from "./ThroughputInputComponents/ThroughputInputAutoPilotV3Component";
describe("ScaleComponent", () => { describe("ScaleComponent", () => {
const nonNationalCloudContainer = new Explorer(); const nonNationalCloudContainer = new Explorer();
@@ -81,25 +80,25 @@ describe("ScaleComponent", () => {
it("autoScale enabled", () => { it("autoScale enabled", () => {
const newContainer = new Explorer(); const newContainer = new Explorer();
updateUserContext({
databaseAccount: { newContainer.databaseAccount({
id: undefined, id: undefined,
name: undefined, name: undefined,
location: undefined, location: undefined,
type: undefined, type: undefined,
kind: "documentdb", kind: "documentdb",
properties: { tags: undefined,
documentEndpoint: undefined, properties: {
tableEndpoint: undefined, documentEndpoint: undefined,
gremlinEndpoint: undefined, tableEndpoint: undefined,
cassandraEndpoint: undefined, gremlinEndpoint: undefined,
capabilities: [ cassandraEndpoint: undefined,
{ capabilities: [
name: Constants.CapabilityNames.EnableAutoScale.toLowerCase(), {
description: undefined, name: Constants.CapabilityNames.EnableAutoScale.toLowerCase(),
}, description: undefined,
], },
}, ],
}, },
}); });
const props = { ...baseProps, container: newContainer }; const props = { ...baseProps, container: newContainer };

View File

@@ -1,4 +1,4 @@
import { Label, Link, MessageBar, MessageBarType, Stack, Text, TextField } from "@fluentui/react"; import { Label, Link, MessageBar, MessageBarType, Stack, Text, TextField } from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import * as Constants from "../../../../Common/Constants"; import * as Constants from "../../../../Common/Constants";
import { configContext, Platform } from "../../../../ConfigContext"; import { configContext, Platform } from "../../../../ConfigContext";
@@ -54,7 +54,8 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
} }
public isAutoScaleEnabled = (): boolean => { public isAutoScaleEnabled = (): boolean => {
const accountCapabilities: DataModels.Capability[] = userContext?.databaseAccount?.properties?.capabilities; const accountCapabilities: DataModels.Capability[] = this.props.container?.databaseAccount()?.properties
?.capabilities;
const enableAutoScaleCapability = const enableAutoScaleCapability =
accountCapabilities && accountCapabilities &&
accountCapabilities.find((capability: DataModels.Capability) => { accountCapabilities.find((capability: DataModels.Capability) => {
@@ -169,7 +170,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
private getThroughputInputComponent = (): JSX.Element => ( private getThroughputInputComponent = (): JSX.Element => (
<ThroughputInputAutoPilotV3Component <ThroughputInputAutoPilotV3Component
databaseAccount={userContext?.databaseAccount} databaseAccount={this.props.container.databaseAccount()}
databaseName={this.databaseId} databaseName={this.databaseId}
collectionName={this.collectionId} collectionName={this.collectionId}
throughput={this.props.throughput} throughput={this.props.throughput}
@@ -198,7 +199,8 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
); );
private isFreeTierAccount(): boolean { private isFreeTierAccount(): boolean {
return userContext?.databaseAccount?.properties?.enableFreeTier; const databaseAccount = this.props.container?.databaseAccount();
return databaseAccount?.properties?.enableFreeTier;
} }
private getFreeTierInfoMessage(): JSX.Element { private getFreeTierInfoMessage(): JSX.Element {

View File

@@ -1,4 +1,13 @@
import { ChoiceGroup, IChoiceGroupOption, Label, Link, MessageBar, Stack, Text, TextField } from "@fluentui/react"; import {
ChoiceGroup,
IChoiceGroupOption,
Label,
Link,
MessageBar,
Stack,
Text,
TextField,
} from "office-ui-fabric-react";
import * as React from "react"; import * as React from "react";
import * as ViewModels from "../../../../Contracts/ViewModels"; import * as ViewModels from "../../../../Contracts/ViewModels";
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";

View File

@@ -10,7 +10,7 @@ import {
Stack, Stack,
Text, Text,
TextField, TextField,
} from "@fluentui/react"; } from "office-ui-fabric-react";
import React from "react"; import React from "react";
import * as DataModels from "../../../../../Contracts/DataModels"; import * as DataModels from "../../../../../Contracts/DataModels";
import { SubscriptionType } from "../../../../../Contracts/SubscriptionType"; import { SubscriptionType } from "../../../../../Contracts/SubscriptionType";

View File

@@ -8,7 +8,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
} }
} }
> >
<StyledMessageBar <StyledMessageBarBase
messageBarIconProps={ messageBarIconProps={
Object { Object {
"className": "messageBarWarningIcon", "className": "messageBarWarningIcon",
@@ -27,7 +27,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
> >
Your bill will be affected as you update your throughput settings. Please review the updated cost estimate below before saving your changes Your bill will be affected as you update your throughput settings. Please review the updated cost estimate below before saving your changes
</Text> </Text>
</StyledMessageBar> </StyledMessageBarBase>
<Stack> <Stack>
<StyledLabelBase <StyledLabelBase
id="settingsV2RadioButtonLabelId" id="settingsV2RadioButtonLabelId"
@@ -49,7 +49,7 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
} }
/> />
</StyledLabelBase> </StyledLabelBase>
<StyledMessageBar <StyledMessageBarBase
messageBarIconProps={ messageBarIconProps={
Object { Object {
"className": "messageBarInfoIcon", "className": "messageBarInfoIcon",
@@ -86,8 +86,8 @@ exports[`ThroughputInputAutoPilotV3Component autopilot input visible 1`] = `
Learn more Learn more
</a> </a>
</Text> </Text>
</StyledMessageBar> </StyledMessageBarBase>
<StyledChoiceGroup <StyledChoiceGroupBase
ariaLabelledBy="settingsV2RadioButtonLabelId" ariaLabelledBy="settingsV2RadioButtonLabelId"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -196,7 +196,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
} }
/> />
</StyledLabelBase> </StyledLabelBase>
<StyledChoiceGroup <StyledChoiceGroupBase
ariaLabelledBy="settingsV2RadioButtonLabelId" ariaLabelledBy="settingsV2RadioButtonLabelId"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -252,7 +252,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
> >
capacity calculator capacity calculator
<FontIcon <Component
iconName="NavigateExternalInline" iconName="NavigateExternalInline"
/> />
</StyledLinkBase> </StyledLinkBase>
@@ -415,7 +415,7 @@ exports[`ThroughputInputAutoPilotV3Component spendAck checkbox visible 1`] = `
</Text> </Text>
<Text> <Text>
<em> <em>
This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account *This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
</em> </em>
</Text> </Text>
</Stack> </Stack>
@@ -470,7 +470,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
} }
/> />
</StyledLabelBase> </StyledLabelBase>
<StyledChoiceGroup <StyledChoiceGroupBase
ariaLabelledBy="settingsV2RadioButtonLabelId" ariaLabelledBy="settingsV2RadioButtonLabelId"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -526,7 +526,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
> >
capacity calculator capacity calculator
<FontIcon <Component
iconName="NavigateExternalInline" iconName="NavigateExternalInline"
/> />
</StyledLinkBase> </StyledLinkBase>
@@ -689,7 +689,7 @@ exports[`ThroughputInputAutoPilotV3Component throughput input visible 1`] = `
</Text> </Text>
<Text> <Text>
<em> <em>
This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account *This cost is an estimate and may vary based on the regions where your account is deployed and potential discounts applied to your account
</em> </em>
</Text> </Text>
</Stack> </Stack>

View File

@@ -1,5 +1,5 @@
import * as React from "react"; import * as React from "react";
import { Stack, Text, IIconStyles, Icon, TooltipHost, DirectionalHint } from "@fluentui/react"; import { Stack, Text, IIconStyles, Icon, TooltipHost, DirectionalHint } from "office-ui-fabric-react";
import { toolTipLabelStackTokens } from "../SettingsRenderUtils"; import { toolTipLabelStackTokens } from "../SettingsRenderUtils";
export interface ToolTipLabelComponentProps { export interface ToolTipLabelComponentProps {

View File

@@ -8,7 +8,7 @@ exports[`ConflictResolutionComponent Path text field displayed 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
label="Mode" label="Mode"
onChange={[Function]} onChange={[Function]}
options={ options={
@@ -80,7 +80,7 @@ exports[`ConflictResolutionComponent Sproc text field displayed 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
label="Mode" label="Mode"
onChange={[Function]} onChange={[Function]}
options={ options={

View File

@@ -8,7 +8,7 @@ exports[`ScaleComponent renders with correct initial notification 1`] = `
} }
} }
> >
<StyledMessageBar <StyledMessageBarBase
messageBarType={5} messageBarType={5}
> >
<Text <Text
@@ -26,7 +26,7 @@ exports[`ScaleComponent renders with correct initial notification 1`] = `
Database: test, Container: test Database: test, Container: test
, Current autoscale throughput: 100 - 1000 RU/s, Target autoscale throughput: 600 - 6000 RU/s , Current autoscale throughput: 100 - 1000 RU/s, Target autoscale throughput: 600 - 6000 RU/s
</Text> </Text>
</StyledMessageBar> </StyledMessageBarBase>
<Stack <Stack
tokens={ tokens={
Object { Object {

View File

@@ -15,7 +15,7 @@ exports[`SubSettingsComponent analyticalTimeToLive hidden 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="timeToLive" id="timeToLive"
label="Time to Live" label="Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -85,7 +85,7 @@ exports[`SubSettingsComponent analyticalTimeToLive hidden 1`] = `
value="1000" value="1000"
/> />
</Stack> </Stack>
<StyledChoiceGroup <StyledChoiceGroupBase
id="geoSpatialConfig" id="geoSpatialConfig"
label="Geospatial Configuration" label="Geospatial Configuration"
onChange={[Function]} onChange={[Function]}
@@ -146,7 +146,7 @@ exports[`SubSettingsComponent analyticalTimeToLive hidden 1`] = `
} }
/> />
</StyledLabelBase> </StyledLabelBase>
<StyledChoiceGroup <StyledChoiceGroupBase
aria-labelledby="settingsV2ChangeFeedLabelId" aria-labelledby="settingsV2ChangeFeedLabelId"
id="changeFeedPolicy" id="changeFeedPolicy"
onChange={[Function]} onChange={[Function]}
@@ -238,7 +238,7 @@ exports[`SubSettingsComponent analyticalTimeToLiveSeconds hidden 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="timeToLive" id="timeToLive"
label="Time to Live" label="Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -308,7 +308,7 @@ exports[`SubSettingsComponent analyticalTimeToLiveSeconds hidden 1`] = `
value="1000" value="1000"
/> />
</Stack> </Stack>
<StyledChoiceGroup <StyledChoiceGroupBase
id="geoSpatialConfig" id="geoSpatialConfig"
label="Geospatial Configuration" label="Geospatial Configuration"
onChange={[Function]} onChange={[Function]}
@@ -355,7 +355,7 @@ exports[`SubSettingsComponent analyticalTimeToLiveSeconds hidden 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="analyticalStorageTimeToLive" id="analyticalStorageTimeToLive"
label="Analytical Storage Time to Live" label="Analytical Storage Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -422,7 +422,7 @@ exports[`SubSettingsComponent analyticalTimeToLiveSeconds hidden 1`] = `
} }
/> />
</StyledLabelBase> </StyledLabelBase>
<StyledChoiceGroup <StyledChoiceGroupBase
aria-labelledby="settingsV2ChangeFeedLabelId" aria-labelledby="settingsV2ChangeFeedLabelId"
id="changeFeedPolicy" id="changeFeedPolicy"
onChange={[Function]} onChange={[Function]}
@@ -514,7 +514,7 @@ exports[`SubSettingsComponent changeFeedPolicy hidden 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="timeToLive" id="timeToLive"
label="Time to Live" label="Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -584,7 +584,7 @@ exports[`SubSettingsComponent changeFeedPolicy hidden 1`] = `
value="1000" value="1000"
/> />
</Stack> </Stack>
<StyledChoiceGroup <StyledChoiceGroupBase
id="geoSpatialConfig" id="geoSpatialConfig"
label="Geospatial Configuration" label="Geospatial Configuration"
onChange={[Function]} onChange={[Function]}
@@ -631,7 +631,7 @@ exports[`SubSettingsComponent changeFeedPolicy hidden 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="analyticalStorageTimeToLive" id="analyticalStorageTimeToLive"
label="Analytical Storage Time to Live" label="Analytical Storage Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -753,7 +753,7 @@ exports[`SubSettingsComponent renders 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="timeToLive" id="timeToLive"
label="Time to Live" label="Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -823,7 +823,7 @@ exports[`SubSettingsComponent renders 1`] = `
value="1000" value="1000"
/> />
</Stack> </Stack>
<StyledChoiceGroup <StyledChoiceGroupBase
id="geoSpatialConfig" id="geoSpatialConfig"
label="Geospatial Configuration" label="Geospatial Configuration"
onChange={[Function]} onChange={[Function]}
@@ -870,7 +870,7 @@ exports[`SubSettingsComponent renders 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="analyticalStorageTimeToLive" id="analyticalStorageTimeToLive"
label="Analytical Storage Time to Live" label="Analytical Storage Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -962,7 +962,7 @@ exports[`SubSettingsComponent renders 1`] = `
} }
/> />
</StyledLabelBase> </StyledLabelBase>
<StyledChoiceGroup <StyledChoiceGroupBase
aria-labelledby="settingsV2ChangeFeedLabelId" aria-labelledby="settingsV2ChangeFeedLabelId"
id="changeFeedPolicy" id="changeFeedPolicy"
onChange={[Function]} onChange={[Function]}
@@ -1054,7 +1054,7 @@ exports[`SubSettingsComponent timeToLiveSeconds hidden 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="timeToLive" id="timeToLive"
label="Time to Live" label="Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -1099,7 +1099,7 @@ exports[`SubSettingsComponent timeToLiveSeconds hidden 1`] = `
} }
/> />
</Stack> </Stack>
<StyledChoiceGroup <StyledChoiceGroupBase
id="geoSpatialConfig" id="geoSpatialConfig"
label="Geospatial Configuration" label="Geospatial Configuration"
onChange={[Function]} onChange={[Function]}
@@ -1146,7 +1146,7 @@ exports[`SubSettingsComponent timeToLiveSeconds hidden 1`] = `
} }
} }
> >
<StyledChoiceGroup <StyledChoiceGroupBase
id="analyticalStorageTimeToLive" id="analyticalStorageTimeToLive"
label="Analytical Storage Time to Live" label="Analytical Storage Time to Live"
onChange={[Function]} onChange={[Function]}
@@ -1238,7 +1238,7 @@ exports[`SubSettingsComponent timeToLiveSeconds hidden 1`] = `
} }
/> />
</StyledLabelBase> </StyledLabelBase>
<StyledChoiceGroup <StyledChoiceGroupBase
aria-labelledby="settingsV2ChangeFeedLabelId" aria-labelledby="settingsV2ChangeFeedLabelId"
id="changeFeedPolicy" id="changeFeedPolicy"
onChange={[Function]} onChange={[Function]}

Some files were not shown because too many files have changed in this diff Show More