mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-20 18:23:34 +00:00
Compare commits
17 Commits
release/ma
...
users/aisa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
228f412406 | ||
|
|
cad718acc4 | ||
|
|
0559ec5cb1 | ||
|
|
ca641b2ff5 | ||
|
|
53836a93cd | ||
|
|
c38e42e44b | ||
|
|
6032b39058 | ||
|
|
23852dcd69 | ||
|
|
81bd0f635e | ||
|
|
3efbc57617 | ||
|
|
aee8249ffa | ||
|
|
14db9e819a | ||
|
|
f9e18cf28c | ||
|
|
4708722d1a | ||
|
|
777e411f4f | ||
|
|
63d4b4f4ef | ||
|
|
eaf9a14e7d |
@@ -1914,13 +1914,20 @@ input::-webkit-calendar-picker-indicator::after {
|
||||
}
|
||||
|
||||
.nav-tabs-margin {
|
||||
height: 32px;
|
||||
background-color: #f2f2f2;
|
||||
|
||||
.nav-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
height: 100%;
|
||||
margin-bottom: -0.5px;
|
||||
|
||||
li {
|
||||
// Override the bootstrap defaults here to align with our layout constants.
|
||||
margin-bottom: 0px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
51
package-lock.json
generated
51
package-lock.json
generated
@@ -86,7 +86,7 @@
|
||||
"mkdirp": "1.0.4",
|
||||
"monaco-editor": "0.44.0",
|
||||
"ms": "2.1.3",
|
||||
"p-retry": "4.6.2",
|
||||
"p-retry": "6.2.1",
|
||||
"patch-package": "8.0.0",
|
||||
"plotly.js-cartesian-dist-min": "1.52.3",
|
||||
"post-robot": "10.0.42",
|
||||
@@ -12662,7 +12662,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/retry": {
|
||||
"version": "0.12.0",
|
||||
"version": "0.12.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz",
|
||||
"integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/sanitize-html": {
|
||||
@@ -21799,6 +21801,18 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-network-error": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz",
|
||||
"integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
"version": "3.0.0",
|
||||
"license": "MIT",
|
||||
@@ -30243,14 +30257,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/p-retry": {
|
||||
"version": "4.6.2",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz",
|
||||
"integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/retry": "0.12.0",
|
||||
"@types/retry": "0.12.2",
|
||||
"is-network-error": "^1.0.0",
|
||||
"retry": "^0.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=16.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-try": {
|
||||
@@ -35997,6 +36017,13 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-server/node_modules/@types/retry": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
|
||||
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/webpack-dev-server/node_modules/ajv": {
|
||||
"version": "8.12.0",
|
||||
"dev": true,
|
||||
@@ -36044,6 +36071,20 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-server/node_modules/p-retry": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
|
||||
"integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/retry": "0.12.0",
|
||||
"retry": "^0.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-server/node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"dev": true,
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
"mkdirp": "1.0.4",
|
||||
"monaco-editor": "0.44.0",
|
||||
"ms": "2.1.3",
|
||||
"p-retry": "4.6.2",
|
||||
"p-retry": "6.2.1",
|
||||
"patch-package": "8.0.0",
|
||||
"plotly.js-cartesian-dist-min": "1.52.3",
|
||||
"post-robot": "10.0.42",
|
||||
|
||||
37913
preview/package-lock.json
generated
37913
preview/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
* Notebook container related stuff
|
||||
*/
|
||||
import { useDialog } from "Explorer/Controls/Dialog";
|
||||
import promiseRetry, { AbortError } from "p-retry";
|
||||
import promiseRetry, { AbortError, Options } from "p-retry";
|
||||
import { PhoenixClient } from "Phoenix/PhoenixClient";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { ConnectionStatusType, HttpHeaders, HttpStatusCodes, Notebook, PoolIdType } from "../../Common/Constants";
|
||||
@@ -19,7 +19,7 @@ export class NotebookContainerClient {
|
||||
private clearReconnectionAttemptMessage? = () => {};
|
||||
private isResettingWorkspace: boolean;
|
||||
private phoenixClient: PhoenixClient;
|
||||
private retryOptions: promiseRetry.Options;
|
||||
private retryOptions: Options;
|
||||
private scheduleTimerId: NodeJS.Timeout;
|
||||
|
||||
constructor(private onConnectionLost: () => void) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { checkFirewallRules } from "Explorer/Tabs/Shared/CheckFirewallRules";
|
||||
import * as ko from "knockout";
|
||||
import * as React from "react";
|
||||
import FirewallRuleScreenshot from "../../../images/firewallRule.png";
|
||||
import VcoreFirewallRuleScreenshot from "../../../images/vcoreMongoFirewallRule.png";
|
||||
import { ReactAdapter } from "../../Bindings/ReactBindingHandler";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
@@ -42,7 +43,11 @@ class NotebookTerminalComponentAdapter implements ReactAdapter {
|
||||
return (
|
||||
<QuickstartFirewallNotification
|
||||
messageType={MessageTypes.OpenPostgresNetworkingBlade}
|
||||
screenshot={FirewallRuleScreenshot}
|
||||
screenshot={
|
||||
this.kind === ViewModels.TerminalKind.Mongo || this.kind === ViewModels.TerminalKind.VCoreMongo
|
||||
? VcoreFirewallRuleScreenshot
|
||||
: FirewallRuleScreenshot
|
||||
}
|
||||
shellName={this.getShellNameForDisplay(this.kind)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||
import { userContext } from "UserContext";
|
||||
import { allowedJunoOrigins, validateEndpoint } from "Utils/EndpointUtils";
|
||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||
import promiseRetry, { AbortError } from "p-retry";
|
||||
import promiseRetry, { AbortError, Options } from "p-retry";
|
||||
import {
|
||||
Areas,
|
||||
ConnectionStatusType,
|
||||
@@ -35,21 +35,26 @@ import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||
export class PhoenixClient {
|
||||
private armResourceId: string;
|
||||
private containerHealthHandler: NodeJS.Timeout;
|
||||
private retryOptions: promiseRetry.Options = {
|
||||
private retryOptions: Options = {
|
||||
retries: Notebook.retryAttempts,
|
||||
maxTimeout: Notebook.retryAttemptDelayMs,
|
||||
minTimeout: Notebook.retryAttemptDelayMs,
|
||||
};
|
||||
private abortController: AbortController;
|
||||
private abortSignal: AbortSignal;
|
||||
|
||||
constructor(armResourceId: string) {
|
||||
this.armResourceId = armResourceId;
|
||||
}
|
||||
|
||||
public async allocateContainer(provisionData: IProvisionData): Promise<IResponse<IPhoenixServiceInfo>> {
|
||||
this.initializeCancelEventListener();
|
||||
|
||||
return promiseRetry(() => this.executeContainerAssignmentOperation(provisionData, "allocate"), {
|
||||
retries: 4,
|
||||
maxTimeout: 20000,
|
||||
minTimeout: 20000,
|
||||
signal: this.abortSignal,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -270,6 +275,17 @@ export class PhoenixClient {
|
||||
};
|
||||
}
|
||||
|
||||
private initializeCancelEventListener(): void {
|
||||
this.abortController = new AbortController();
|
||||
this.abortSignal = this.abortController.signal;
|
||||
|
||||
document.addEventListener("keydown", (event: KeyboardEvent) => {
|
||||
if (event.ctrlKey && (event.key === "c" || event.key === "z")) {
|
||||
this.abortController.abort(new AbortError("Request canceled"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ConvertToForbiddenErrorString(jsonData: IPhoenixError): string {
|
||||
const errInfo = jsonData;
|
||||
switch (errInfo?.type) {
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
* @module SelfServe/Decorators
|
||||
*/
|
||||
|
||||
import { TFunction } from "i18next";
|
||||
import { ChoiceItem, Description, Info, NumberUiType, OnChangeCallback, RefreshParams } from "./SelfServeTypes";
|
||||
import { addPropertyToMap, buildSmartUiDescriptor, DecoratorProperties } from "./SelfServeUtils";
|
||||
import { addPropertyToMap, buildSmartUiDescriptor, DecoratorProperties, SelfServeType } from "./SelfServeUtils";
|
||||
|
||||
type ValueOf<T> = T[keyof T];
|
||||
interface Decorator {
|
||||
@@ -128,8 +129,9 @@ const isDescriptionDisplayOptions = (inputOptions: InputOptions): inputOptions i
|
||||
};
|
||||
|
||||
const addToMap = (...decorators: Decorator[]): PropertyDecorator => {
|
||||
return (target, property) => {
|
||||
let className = target.constructor.name;
|
||||
console.log(decorators);
|
||||
return async (target, property) => {
|
||||
let className: string = getTargetName(target);
|
||||
const propertyName = property.toString();
|
||||
if (className === "Function") {
|
||||
//eslint-disable-next-line @typescript-eslint/ban-types
|
||||
@@ -138,6 +140,7 @@ const addToMap = (...decorators: Decorator[]): PropertyDecorator => {
|
||||
}
|
||||
|
||||
const propertyType = (Reflect.getMetadata("design:type", target, property)?.name as string)?.toLowerCase();
|
||||
console.log(propertyType);
|
||||
addPropertyToMap(target, propertyName, className, "type", propertyType);
|
||||
addPropertyToMap(target, propertyName, className, "dataFieldName", propertyName);
|
||||
|
||||
@@ -205,7 +208,8 @@ export const Values = (inputOptions: InputOptions): PropertyDecorator => {
|
||||
*/
|
||||
export const IsDisplayable = (): ClassDecorator => {
|
||||
return (target) => {
|
||||
buildSmartUiDescriptor(target.name, target.prototype);
|
||||
let targetName: string = getTargetName(target);
|
||||
buildSmartUiDescriptor(targetName, target.prototype);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -215,7 +219,26 @@ export const IsDisplayable = (): ClassDecorator => {
|
||||
* how often the auto refresh of the page occurs.
|
||||
*/
|
||||
export const RefreshOptions = (refreshParams: RefreshParams): ClassDecorator => {
|
||||
console.log(refreshParams);
|
||||
return (target) => {
|
||||
addPropertyToMap(target.prototype, "root", target.name, "refreshParams", refreshParams);
|
||||
let targetName: string = getTargetName(target);
|
||||
addPropertyToMap(target.prototype, "root", targetName, "refreshParams", refreshParams);
|
||||
};
|
||||
};
|
||||
|
||||
const getTargetName = (target: TFunction | Object): string => {
|
||||
const targetString: string = target.toString();
|
||||
let targetName: string;
|
||||
if (targetString.includes(SelfServeType.example)) {
|
||||
targetName = SelfServeType.example;
|
||||
} else if (targetString.includes(SelfServeType.graphapicompute)) {
|
||||
targetName = SelfServeType.graphapicompute;
|
||||
} else if (targetString.includes(SelfServeType.materializedviewsbuilder)) {
|
||||
targetName = SelfServeType.materializedviewsbuilder;
|
||||
} else if (targetString.includes(SelfServeType.sqlx)) {
|
||||
targetName = SelfServeType.sqlx;
|
||||
} else {
|
||||
targetName = target.constructor.name;
|
||||
}
|
||||
return targetName;
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SelfServeType } from "SelfServe/SelfServeUtils";
|
||||
import { IsDisplayable, OnChange, PropertyInfo, RefreshOptions, Values } from "../Decorators";
|
||||
import { selfServeTraceStart, selfServeTraceSuccess } from "../SelfServeTelemetryProcessor";
|
||||
import {
|
||||
@@ -168,6 +169,10 @@ export default class SelfServeExample extends SelfServeBaseClass {
|
||||
return defaults;
|
||||
};
|
||||
|
||||
public getSelfServeType = (): SelfServeType => {
|
||||
return SelfServeType.example;
|
||||
};
|
||||
|
||||
@Values({
|
||||
labelTKey: "DescriptionLabel",
|
||||
description: {
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
|
||||
import type { ChoiceItem } from "../SelfServeTypes";
|
||||
|
||||
import { BladeType, generateBladeLink } from "../SelfServeUtils";
|
||||
import { BladeType, generateBladeLink, SelfServeType } from "../SelfServeUtils";
|
||||
import {
|
||||
deleteComputeResource,
|
||||
getCurrentProvisioningState,
|
||||
@@ -360,6 +360,10 @@ export default class GraphAPICompute extends SelfServeBaseClass {
|
||||
return defaults;
|
||||
};
|
||||
|
||||
public getSelfServeType = (): SelfServeType => {
|
||||
return SelfServeType.graphapicompute;
|
||||
};
|
||||
|
||||
@Values({
|
||||
isDynamicDescription: true,
|
||||
})
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
|
||||
import type { ChoiceItem } from "../SelfServeTypes";
|
||||
|
||||
import { BladeType, generateBladeLink } from "../SelfServeUtils";
|
||||
import { BladeType, generateBladeLink, SelfServeType } from "../SelfServeUtils";
|
||||
import {
|
||||
deleteMaterializedViewsBuilderResource,
|
||||
getCurrentProvisioningState,
|
||||
@@ -359,6 +359,10 @@ export default class MaterializedViewsBuilder extends SelfServeBaseClass {
|
||||
return defaults;
|
||||
};
|
||||
|
||||
public getSelfServeType = (): SelfServeType => {
|
||||
return SelfServeType.materializedviewsbuilder;
|
||||
};
|
||||
|
||||
@Values({
|
||||
isDynamicDescription: true,
|
||||
})
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
Text,
|
||||
} from "@fluentui/react";
|
||||
import { TFunction } from "i18next";
|
||||
import promiseRetry, { AbortError } from "p-retry";
|
||||
import promiseRetry, { AbortError, Options } from "p-retry";
|
||||
import React from "react";
|
||||
import { WithTranslation } from "react-i18next";
|
||||
import * as _ from "underscore";
|
||||
@@ -80,7 +80,7 @@ export class SelfServeComponent extends React.Component<SelfServeComponentProps,
|
||||
private static readonly defaultRetryIntervalInMs = 30000;
|
||||
private smartUiGeneratorClassName: string;
|
||||
private retryIntervalInMs: number;
|
||||
private retryOptions: promiseRetry.Options;
|
||||
private retryOptions: Options;
|
||||
private translationFunction: TFunction;
|
||||
|
||||
componentDidMount(): void {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* @module SelfServe/SelfServeTypes
|
||||
*/
|
||||
|
||||
import { SelfServeType } from "SelfServe/SelfServeUtils";
|
||||
import { TelemetryData } from "../Shared/Telemetry/TelemetryProcessor";
|
||||
|
||||
interface BaseInput {
|
||||
@@ -120,9 +121,11 @@ export abstract class SelfServeBaseClass {
|
||||
*/
|
||||
public abstract onRefresh: () => Promise<RefreshResult>;
|
||||
|
||||
public abstract getSelfServeType: () => SelfServeType;
|
||||
public test: string = "hello";
|
||||
/**@internal */
|
||||
public toSelfServeDescriptor(): SelfServeDescriptor {
|
||||
const className = this.constructor.name;
|
||||
const className: string = this.getSelfServeType();
|
||||
const selfServeDescriptor = Reflect.getMetadata(className, this) as SelfServeDescriptor;
|
||||
|
||||
if (!this.initialize) {
|
||||
|
||||
@@ -1,42 +1,60 @@
|
||||
import { NumberUiType, OnSaveResult, RefreshResult, SelfServeBaseClass, SmartUiInput } from "./SelfServeTypes";
|
||||
import { DecoratorProperties, mapToSmartUiDescriptor, updateContextWithDecorator } from "./SelfServeUtils";
|
||||
import {
|
||||
DecoratorProperties,
|
||||
mapToSmartUiDescriptor,
|
||||
SelfServeType,
|
||||
updateContextWithDecorator,
|
||||
} from "./SelfServeUtils";
|
||||
|
||||
describe("SelfServeUtils", () => {
|
||||
const getSelfServeTypeExample = (): SelfServeType => {
|
||||
return SelfServeType.example;
|
||||
};
|
||||
|
||||
it("initialize should be declared for self serve classes", () => {
|
||||
class Test extends SelfServeBaseClass {
|
||||
class SelfServeExample extends SelfServeBaseClass {
|
||||
public initialize: () => Promise<Map<string, SmartUiInput>>;
|
||||
public onSave: (currentValues: Map<string, SmartUiInput>) => Promise<OnSaveResult>;
|
||||
public onRefresh: () => Promise<RefreshResult>;
|
||||
public getSelfServeType = (): SelfServeType => getSelfServeTypeExample();
|
||||
}
|
||||
expect(() => new Test().toSelfServeDescriptor()).toThrow("initialize() was not declared for the class 'Test'");
|
||||
expect(() => new SelfServeExample().toSelfServeDescriptor()).toThrow(
|
||||
"initialize() was not declared for the class 'SelfServeExample'",
|
||||
);
|
||||
});
|
||||
|
||||
it("onSave should be declared for self serve classes", () => {
|
||||
class Test extends SelfServeBaseClass {
|
||||
class SelfServeExample extends SelfServeBaseClass {
|
||||
public initialize = jest.fn();
|
||||
public onSave: () => Promise<OnSaveResult>;
|
||||
public onRefresh: () => Promise<RefreshResult>;
|
||||
public getSelfServeType = (): SelfServeType => getSelfServeTypeExample();
|
||||
}
|
||||
expect(() => new Test().toSelfServeDescriptor()).toThrow("onSave() was not declared for the class 'Test'");
|
||||
expect(() => new SelfServeExample().toSelfServeDescriptor()).toThrow(
|
||||
"onSave() was not declared for the class 'SelfServeExample'",
|
||||
);
|
||||
});
|
||||
|
||||
it("onRefresh should be declared for self serve classes", () => {
|
||||
class Test extends SelfServeBaseClass {
|
||||
class SelfServeExample extends SelfServeBaseClass {
|
||||
public initialize = jest.fn();
|
||||
public onSave = jest.fn();
|
||||
public onRefresh: () => Promise<RefreshResult>;
|
||||
public getSelfServeType = (): SelfServeType => getSelfServeTypeExample();
|
||||
}
|
||||
expect(() => new Test().toSelfServeDescriptor()).toThrow("onRefresh() was not declared for the class 'Test'");
|
||||
expect(() => new SelfServeExample().toSelfServeDescriptor()).toThrow(
|
||||
"onRefresh() was not declared for the class 'SelfServeExample'",
|
||||
);
|
||||
});
|
||||
|
||||
it("@IsDisplayable decorator must be present for self serve classes", () => {
|
||||
class Test extends SelfServeBaseClass {
|
||||
class SelfServeExample extends SelfServeBaseClass {
|
||||
public initialize = jest.fn();
|
||||
public onSave = jest.fn();
|
||||
public onRefresh = jest.fn();
|
||||
public getSelfServeType = (): SelfServeType => getSelfServeTypeExample();
|
||||
}
|
||||
expect(() => new Test().toSelfServeDescriptor()).toThrow(
|
||||
"@IsDisplayable decorator was not declared for the class 'Test'",
|
||||
expect(() => new SelfServeExample().toSelfServeDescriptor()).toThrow(
|
||||
"@IsDisplayable decorator was not declared for the class 'SelfServeExample'",
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -141,6 +141,9 @@ export const updateContextWithDecorator = <T extends keyof DecoratorProperties,
|
||||
descriptorName: keyof DecoratorProperties,
|
||||
descriptorValue: K,
|
||||
): void => {
|
||||
console.log(context);
|
||||
console.log(propertyName);
|
||||
console.log(className);
|
||||
if (!(context instanceof Map)) {
|
||||
throw new Error(`@IsDisplayable should be the first decorator for the class '${className}'.`);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
|
||||
import type { ChoiceItem } from "../SelfServeTypes";
|
||||
|
||||
import { BladeType, generateBladeLink } from "../SelfServeUtils";
|
||||
import { BladeType, generateBladeLink, SelfServeType } from "../SelfServeUtils";
|
||||
import {
|
||||
deleteDedicatedGatewayResource,
|
||||
getCurrentProvisioningState,
|
||||
@@ -396,6 +396,10 @@ export default class SqlX extends SelfServeBaseClass {
|
||||
return defaults;
|
||||
};
|
||||
|
||||
public getSelfServeType = (): SelfServeType => {
|
||||
return SelfServeType.sqlx;
|
||||
};
|
||||
|
||||
@Values({
|
||||
isDynamicDescription: true,
|
||||
})
|
||||
|
||||
@@ -17,7 +17,7 @@ export class JupyterLabAppFactory {
|
||||
if (userContext.apiType === "VCoreMongo" && content?.includes("MongoServerError: Invalid key")) {
|
||||
this.restartShell = true;
|
||||
}
|
||||
return content?.includes("cosmosuser@");
|
||||
return content?.includes("cosmosshelluser@");
|
||||
}
|
||||
|
||||
private isMongoShellStarted(content: string | undefined) {
|
||||
@@ -68,7 +68,6 @@ export class JupyterLabAppFactory {
|
||||
const session = await manager.startNew();
|
||||
session.messageReceived.connect(async (_, message: IMessage) => {
|
||||
const content = message.content && message.content[0]?.toString();
|
||||
|
||||
if (this.checkShellStarted && message.type == "stdout") {
|
||||
//Close the terminal tab once the shell closed messages are received
|
||||
if (!this.isShellStarted) {
|
||||
@@ -114,6 +113,13 @@ export class JupyterLabAppFactory {
|
||||
panel.dispose();
|
||||
});
|
||||
|
||||
// Close terminal when Ctrl key is pressed
|
||||
term.node.addEventListener("keydown", (event: KeyboardEvent) => {
|
||||
if (event.ctrlKey) {
|
||||
this.onShellExited(false);
|
||||
}
|
||||
});
|
||||
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user