mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-05-04 07:24:52 +01:00
Merge branch 'master' into users/kcheekuri/updatePhoenixEndpoints
This commit is contained in:
commit
a9e1c2fba8
@ -2077,7 +2077,7 @@ a:link {
|
|||||||
.resourceTreeAndTabs {
|
.resourceTreeAndTabs {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
overflow-x: auto;
|
overflow-x: clip;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@ -2245,7 +2245,7 @@ a:link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.refreshColHeader {
|
.refreshColHeader {
|
||||||
padding: 3px 6px 6px 6px;
|
padding: 3px 6px 10px 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.refreshColHeader:hover {
|
.refreshColHeader:hover {
|
||||||
@ -2869,31 +2869,31 @@ a:link {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
settings-pane {
|
.settingsSection {
|
||||||
.settingsSection {
|
border-bottom: 1px solid @BaseMedium;
|
||||||
border-bottom: 1px solid @BaseMedium;
|
margin-right: 24px;
|
||||||
margin-right: 24px;
|
padding: @MediumSpace 0px;
|
||||||
padding: @MediumSpace 0px;
|
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
}
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingsSectionPart {
|
.settingsSectionPart {
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingsSectionLabel {
|
.settingsSectionLabel {
|
||||||
margin-bottom: @DefaultSpace;
|
margin-bottom: @DefaultSpace;
|
||||||
}
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.pageOptionsPart {
|
.pageOptionsPart {
|
||||||
padding-bottom: @MediumSpace;
|
padding-bottom: @MediumSpace;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,3 +412,11 @@ export class TerminalQueryParams {
|
|||||||
public static readonly SubscriptionId = "subscriptionId";
|
public static readonly SubscriptionId = "subscriptionId";
|
||||||
public static readonly TerminalEndpoint = "terminalEndpoint";
|
public static readonly TerminalEndpoint = "terminalEndpoint";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class JunoEndpoints {
|
||||||
|
public static readonly Test = "https://juno-test.documents-dev.windows-int.net";
|
||||||
|
public static readonly Test2 = "https://juno-test2.documents-dev.windows-int.net";
|
||||||
|
public static readonly Test3 = "https://juno-test3.documents-dev.windows-int.net";
|
||||||
|
public static readonly Prod = "https://tools.cosmos.azure.com";
|
||||||
|
public static readonly Stage = "https://tools-staging.cosmos.azure.com";
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { JunoEndpoints } from "Common/Constants";
|
||||||
|
|
||||||
export enum Platform {
|
export enum Platform {
|
||||||
Portal = "Portal",
|
Portal = "Portal",
|
||||||
Hosted = "Hosted",
|
Hosted = "Hosted",
|
||||||
@ -23,6 +25,7 @@ export interface ConfigContext {
|
|||||||
PROXY_PATH?: string;
|
PROXY_PATH?: string;
|
||||||
JUNO_ENDPOINT: string;
|
JUNO_ENDPOINT: string;
|
||||||
GITHUB_CLIENT_ID: string;
|
GITHUB_CLIENT_ID: string;
|
||||||
|
GITHUB_TEST_ENV_CLIENT_ID: string;
|
||||||
GITHUB_CLIENT_SECRET?: string; // No need to inject secret for prod. Juno already knows it.
|
GITHUB_CLIENT_SECRET?: string; // No need to inject secret for prod. Juno already knows it.
|
||||||
IS_MPAC: boolean;
|
IS_MPAC: boolean;
|
||||||
hostedExplorerURL: string;
|
hostedExplorerURL: string;
|
||||||
@ -53,16 +56,17 @@ let configContext: Readonly<ConfigContext> = {
|
|||||||
GRAPH_API_VERSION: "1.6",
|
GRAPH_API_VERSION: "1.6",
|
||||||
ARCADIA_ENDPOINT: "https://workspaceartifacts.projectarcadia.net",
|
ARCADIA_ENDPOINT: "https://workspaceartifacts.projectarcadia.net",
|
||||||
ARCADIA_LIVY_ENDPOINT_DNS_ZONE: "dev.azuresynapse.net",
|
ARCADIA_LIVY_ENDPOINT_DNS_ZONE: "dev.azuresynapse.net",
|
||||||
GITHUB_CLIENT_ID: "6cb2f63cf6f7b5cbdeca", // Registered OAuth app: https://github.com/settings/applications/1189306
|
GITHUB_CLIENT_ID: "6cb2f63cf6f7b5cbdeca", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1189306
|
||||||
|
GITHUB_TEST_ENV_CLIENT_ID: "b63fc8cbf87fd3c6e2eb", // Registered OAuth app: https://github.com/organizations/AzureCosmosDBNotebooks/settings/applications/1777772
|
||||||
IS_MPAC: false,
|
IS_MPAC: false,
|
||||||
JUNO_ENDPOINT: "https://tools.cosmos.azure.com",
|
JUNO_ENDPOINT: "https://tools.cosmos.azure.com",
|
||||||
BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com",
|
BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com",
|
||||||
allowedJunoOrigins: [
|
allowedJunoOrigins: [
|
||||||
"https://juno-test.documents-dev.windows-int.net",
|
JunoEndpoints.Test,
|
||||||
"https://juno-test2.documents-dev.windows-int.net",
|
JunoEndpoints.Test2,
|
||||||
"https://juno-test3.documents-dev.windows-int.net",
|
JunoEndpoints.Test3,
|
||||||
"https://tools.cosmos.azure.com",
|
JunoEndpoints.Prod,
|
||||||
"https://tools-staging.cosmos.azure.com",
|
JunoEndpoints.Stage,
|
||||||
"https://localhost",
|
"https://localhost",
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@ -148,3 +152,4 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export { configContext };
|
export { configContext };
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import shallow from "zustand/shallow";
|
|||||||
import { AuthType } from "../AuthType";
|
import { AuthType } from "../AuthType";
|
||||||
import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer";
|
import { BindingHandlersRegisterer } from "../Bindings/BindingHandlersRegisterer";
|
||||||
import * as Constants from "../Common/Constants";
|
import * as Constants from "../Common/Constants";
|
||||||
import { ConnectionStatusType, HttpStatusCodes, Notebook } from "../Common/Constants";
|
import { Areas, ConnectionStatusType, HttpStatusCodes, Notebook } from "../Common/Constants";
|
||||||
import { readCollection } from "../Common/dataAccess/readCollection";
|
import { readCollection } from "../Common/dataAccess/readCollection";
|
||||||
import { readDatabases } from "../Common/dataAccess/readDatabases";
|
import { readDatabases } from "../Common/dataAccess/readDatabases";
|
||||||
import { getErrorMessage, getErrorStack, handleError } from "../Common/ErrorHandlingUtils";
|
import { getErrorMessage, getErrorStack, handleError } from "../Common/ErrorHandlingUtils";
|
||||||
@ -16,7 +16,6 @@ import { QueriesClient } from "../Common/QueriesClient";
|
|||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
import {
|
import {
|
||||||
ContainerConnectionInfo,
|
ContainerConnectionInfo,
|
||||||
IContainerData,
|
|
||||||
IPhoenixConnectionInfoResult,
|
IPhoenixConnectionInfoResult,
|
||||||
IProvisionData,
|
IProvisionData,
|
||||||
IResponse,
|
IResponse,
|
||||||
@ -377,18 +376,36 @@ export default class Explorer {
|
|||||||
};
|
};
|
||||||
useNotebook.getState().setConnectionInfo(connectionStatus);
|
useNotebook.getState().setConnectionInfo(connectionStatus);
|
||||||
try {
|
try {
|
||||||
|
TelemetryProcessor.traceStart(Action.PhoenixConnection, {
|
||||||
|
dataExplorerArea: Areas.Notebook,
|
||||||
|
});
|
||||||
useNotebook.getState().setIsAllocating(true);
|
useNotebook.getState().setIsAllocating(true);
|
||||||
const connectionInfo = await this.phoenixClient.allocateContainer(provisionData);
|
const connectionInfo = await this.phoenixClient.allocateContainer(provisionData);
|
||||||
|
if (connectionInfo.status !== HttpStatusCodes.OK) {
|
||||||
|
throw new Error(`Received status code: ${connectionInfo?.status}`);
|
||||||
|
}
|
||||||
|
if (!connectionInfo?.data?.notebookServerUrl) {
|
||||||
|
throw new Error(`NotebookServerUrl is invalid!`);
|
||||||
|
}
|
||||||
await this.setNotebookInfo(connectionInfo, connectionStatus);
|
await this.setNotebookInfo(connectionInfo, connectionStatus);
|
||||||
|
TelemetryProcessor.traceSuccess(Action.PhoenixConnection, {
|
||||||
|
dataExplorerArea: Areas.Notebook,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
TelemetryProcessor.traceFailure(Action.PhoenixConnection, {
|
||||||
|
dataExplorerArea: Areas.Notebook,
|
||||||
|
error: getErrorMessage(error),
|
||||||
|
errorStack: getErrorStack(error),
|
||||||
|
});
|
||||||
connectionStatus.status = ConnectionStatusType.Failed;
|
connectionStatus.status = ConnectionStatusType.Failed;
|
||||||
useNotebook.getState().resetContainerConnection(connectionStatus);
|
useNotebook.getState().resetContainerConnection(connectionStatus);
|
||||||
throw error;
|
throw error;
|
||||||
|
} finally {
|
||||||
|
useNotebook.getState().setIsAllocating(false);
|
||||||
|
this.refreshCommandBarButtons();
|
||||||
|
this.refreshNotebookList();
|
||||||
|
this._isInitializingNotebooks = false;
|
||||||
}
|
}
|
||||||
this.refreshCommandBarButtons();
|
|
||||||
this.refreshNotebookList();
|
|
||||||
|
|
||||||
this._isInitializingNotebooks = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,27 +413,22 @@ export default class Explorer {
|
|||||||
connectionInfo: IResponse<IPhoenixConnectionInfoResult>,
|
connectionInfo: IResponse<IPhoenixConnectionInfoResult>,
|
||||||
connectionStatus: DataModels.ContainerConnectionInfo
|
connectionStatus: DataModels.ContainerConnectionInfo
|
||||||
) {
|
) {
|
||||||
if (connectionInfo.status === HttpStatusCodes.OK && connectionInfo.data && connectionInfo.data.notebookServerUrl) {
|
const containerData = {
|
||||||
const containerData: IContainerData = {
|
forwardingId: connectionInfo.data.forwardingId,
|
||||||
forwardingId: connectionInfo.data.forwardingId,
|
dbAccountName: userContext.databaseAccount.name,
|
||||||
};
|
};
|
||||||
await this.phoenixClient.initiateContainerHeartBeat(containerData);
|
await this.phoenixClient.initiateContainerHeartBeat(containerData);
|
||||||
|
|
||||||
connectionStatus.status = ConnectionStatusType.Connected;
|
connectionStatus.status = ConnectionStatusType.Connected;
|
||||||
useNotebook.getState().setConnectionInfo(connectionStatus);
|
useNotebook.getState().setConnectionInfo(connectionStatus);
|
||||||
useNotebook.getState().setNotebookServerInfo({
|
useNotebook.getState().setNotebookServerInfo({
|
||||||
notebookServerEndpoint: userContext.features.notebookServerUrl || connectionInfo.data.notebookServerUrl,
|
notebookServerEndpoint: userContext.features.notebookServerUrl || connectionInfo.data.notebookServerUrl,
|
||||||
authToken: userContext.features.notebookServerToken || connectionInfo.data.notebookAuthToken,
|
authToken: userContext.features.notebookServerToken || connectionInfo.data.notebookAuthToken,
|
||||||
forwardingId: connectionInfo.data.forwardingId,
|
forwardingId: connectionInfo.data.forwardingId,
|
||||||
});
|
});
|
||||||
this.notebookManager?.notebookClient
|
this.notebookManager?.notebookClient
|
||||||
.getMemoryUsage()
|
.getMemoryUsage()
|
||||||
.then((memoryUsageInfo) => useNotebook.getState().setMemoryUsageInfo(memoryUsageInfo));
|
.then((memoryUsageInfo) => useNotebook.getState().setMemoryUsageInfo(memoryUsageInfo));
|
||||||
} else {
|
|
||||||
connectionStatus.status = ConnectionStatusType.Failed;
|
|
||||||
useNotebook.getState().resetContainerConnection(connectionStatus);
|
|
||||||
}
|
|
||||||
useNotebook.getState().setIsAllocating(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetNotebookWorkspace(): void {
|
public resetNotebookWorkspace(): void {
|
||||||
@ -501,7 +513,9 @@ export default class Explorer {
|
|||||||
logConsoleError(error);
|
logConsoleError(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TelemetryProcessor.traceStart(Action.PhoenixResetWorkspace, {
|
||||||
|
dataExplorerArea: Areas.Notebook,
|
||||||
|
});
|
||||||
if (useNotebook.getState().isPhoenix) {
|
if (useNotebook.getState().isPhoenix) {
|
||||||
useTabs.getState().closeAllNotebookTabs(true);
|
useTabs.getState().closeAllNotebookTabs(true);
|
||||||
connectionStatus = {
|
connectionStatus = {
|
||||||
@ -510,27 +524,24 @@ export default class Explorer {
|
|||||||
useNotebook.getState().setConnectionInfo(connectionStatus);
|
useNotebook.getState().setConnectionInfo(connectionStatus);
|
||||||
}
|
}
|
||||||
const connectionInfo = await this.notebookManager?.notebookClient.resetWorkspace();
|
const connectionInfo = await this.notebookManager?.notebookClient.resetWorkspace();
|
||||||
if (connectionInfo && connectionInfo.status && connectionInfo.status === HttpStatusCodes.OK) {
|
if (connectionInfo?.status !== HttpStatusCodes.OK) {
|
||||||
if (useNotebook.getState().isPhoenix && connectionInfo.data && connectionInfo.data.notebookServerUrl) {
|
throw new Error(`Reset Workspace: Received status code- ${connectionInfo?.status}`);
|
||||||
await this.setNotebookInfo(connectionInfo, connectionStatus);
|
|
||||||
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
|
|
||||||
}
|
|
||||||
logConsoleInfo("Successfully reset notebook workspace");
|
|
||||||
TelemetryProcessor.traceSuccess(Action.ResetNotebookWorkspace);
|
|
||||||
} else {
|
|
||||||
logConsoleError(`Failed to reset notebook workspace`);
|
|
||||||
TelemetryProcessor.traceFailure(Action.ResetNotebookWorkspace);
|
|
||||||
if (useNotebook.getState().isPhoenix) {
|
|
||||||
connectionStatus = {
|
|
||||||
status: ConnectionStatusType.Reconnect,
|
|
||||||
};
|
|
||||||
useNotebook.getState().resetContainerConnection(connectionStatus);
|
|
||||||
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!connectionInfo?.data?.notebookServerUrl) {
|
||||||
|
throw new Error(`Reset Workspace: NotebookServerUrl is invalid!`);
|
||||||
|
}
|
||||||
|
if (useNotebook.getState().isPhoenix) {
|
||||||
|
await this.setNotebookInfo(connectionInfo, connectionStatus);
|
||||||
|
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
|
||||||
|
}
|
||||||
|
logConsoleInfo("Successfully reset notebook workspace");
|
||||||
|
TelemetryProcessor.traceSuccess(Action.PhoenixResetWorkspace, {
|
||||||
|
dataExplorerArea: Areas.Notebook,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logConsoleError(`Failed to reset notebook workspace: ${error}`);
|
logConsoleError(`Failed to reset notebook workspace: ${error}`);
|
||||||
TelemetryProcessor.traceFailure(Action.ResetNotebookWorkspace, {
|
TelemetryProcessor.traceFailure(Action.PhoenixResetWorkspace, {
|
||||||
|
dataExplorerArea: Areas.Notebook,
|
||||||
error: getErrorMessage(error),
|
error: getErrorMessage(error),
|
||||||
errorStack: getErrorStack(error),
|
errorStack: getErrorStack(error),
|
||||||
});
|
});
|
||||||
@ -538,7 +549,7 @@ export default class Explorer {
|
|||||||
connectionStatus = {
|
connectionStatus = {
|
||||||
status: ConnectionStatusType.Failed,
|
status: ConnectionStatusType.Failed,
|
||||||
};
|
};
|
||||||
useNotebook.getState().setConnectionInfo(connectionStatus);
|
useNotebook.getState().resetContainerConnection(connectionStatus);
|
||||||
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
|
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -23,10 +23,12 @@ import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneFor
|
|||||||
|
|
||||||
export interface AddDatabasePaneProps {
|
export interface AddDatabasePaneProps {
|
||||||
explorer: Explorer;
|
explorer: Explorer;
|
||||||
|
buttonElement?: HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||||
explorer: container,
|
explorer: container,
|
||||||
|
buttonElement,
|
||||||
}: AddDatabasePaneProps) => {
|
}: AddDatabasePaneProps) => {
|
||||||
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
|
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
|
||||||
let throughput: number;
|
let throughput: number;
|
||||||
@ -78,6 +80,9 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
|||||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||||
};
|
};
|
||||||
TelemetryProcessor.trace(Action.CreateDatabase, ActionModifiers.Open, addDatabasePaneOpenMessage);
|
TelemetryProcessor.trace(Action.CreateDatabase, ActionModifiers.Open, addDatabasePaneOpenMessage);
|
||||||
|
if (buttonElement) {
|
||||||
|
buttonElement.focus();
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { IDropdownOption, IImageProps, Image, Stack, Text } from "@fluentui/react";
|
import { IDropdownOption, IImageProps, Image, Stack, Text } from "@fluentui/react";
|
||||||
import { useBoolean } from "@fluentui/react-hooks";
|
import { useBoolean } from "@fluentui/react-hooks";
|
||||||
import React, { FunctionComponent, useState } from "react";
|
import React, { FunctionComponent, useRef, useState } from "react";
|
||||||
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
||||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||||
import { logConsoleError } from "../../../Utils/NotificationConsoleUtils";
|
import { logConsoleError } from "../../../Utils/NotificationConsoleUtils";
|
||||||
@ -25,19 +25,16 @@ interface UnwrappedExecuteSprocParam {
|
|||||||
export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPaneProps> = ({
|
export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPaneProps> = ({
|
||||||
storedProcedure,
|
storedProcedure,
|
||||||
}: ExecuteSprocParamsPaneProps): JSX.Element => {
|
}: ExecuteSprocParamsPaneProps): JSX.Element => {
|
||||||
|
const paramKeyValuesRef = useRef<UnwrappedExecuteSprocParam[]>([{ key: "string", text: "" }]);
|
||||||
|
const partitionValueRef = useRef<string>();
|
||||||
|
const partitionKeyRef = useRef<string>("string");
|
||||||
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
|
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
|
||||||
|
const [numberOfParams, setNumberOfParams] = useState<number>(1);
|
||||||
const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false);
|
const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false);
|
||||||
const [paramKeyValues, setParamKeyValues] = useState<UnwrappedExecuteSprocParam[]>([{ key: "string", text: "" }]);
|
|
||||||
const [partitionValue, setPartitionValue] = useState<string>(); // Defaulting to undefined here is important. It is not the same partition key as ""
|
|
||||||
const [selectedKey, setSelectedKey] = React.useState<IDropdownOption>({ key: "string", text: "" });
|
|
||||||
const [formError, setFormError] = useState<string>("");
|
const [formError, setFormError] = useState<string>("");
|
||||||
|
|
||||||
const onPartitionKeyChange = (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): void => {
|
|
||||||
setSelectedKey(item);
|
|
||||||
};
|
|
||||||
|
|
||||||
const validateUnwrappedParams = (): boolean => {
|
const validateUnwrappedParams = (): boolean => {
|
||||||
const unwrappedParams: UnwrappedExecuteSprocParam[] = paramKeyValues;
|
const unwrappedParams: UnwrappedExecuteSprocParam[] = paramKeyValuesRef.current;
|
||||||
for (let i = 0; i < unwrappedParams.length; i++) {
|
for (let i = 0; i < unwrappedParams.length; i++) {
|
||||||
const { key: paramType, text: paramValue } = unwrappedParams[i];
|
const { key: paramType, text: paramValue } = unwrappedParams[i];
|
||||||
if (paramType === "custom" && (paramValue === "" || paramValue === undefined)) {
|
if (paramType === "custom" && (paramValue === "" || paramValue === undefined)) {
|
||||||
@ -53,8 +50,9 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
|
|||||||
};
|
};
|
||||||
|
|
||||||
const submit = (): void => {
|
const submit = (): void => {
|
||||||
const wrappedSprocParams: UnwrappedExecuteSprocParam[] = paramKeyValues;
|
const wrappedSprocParams: UnwrappedExecuteSprocParam[] = paramKeyValuesRef.current;
|
||||||
const { key: partitionKey } = selectedKey;
|
const partitionValue: string = partitionValueRef.current;
|
||||||
|
const partitionKey: string = partitionKeyRef.current;
|
||||||
if (partitionKey === "custom" && (partitionValue === "" || partitionValue === undefined)) {
|
if (partitionKey === "custom" && (partitionValue === "" || partitionValue === undefined)) {
|
||||||
setInvalidParamError(partitionValue);
|
setInvalidParamError(partitionValue);
|
||||||
return;
|
return;
|
||||||
@ -78,37 +76,21 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
|
|||||||
};
|
};
|
||||||
|
|
||||||
const deleteParamAtIndex = (indexToRemove: number): void => {
|
const deleteParamAtIndex = (indexToRemove: number): void => {
|
||||||
const cloneParamKeyValue = [...paramKeyValues];
|
paramKeyValuesRef.current.splice(indexToRemove, 1);
|
||||||
cloneParamKeyValue.splice(indexToRemove, 1);
|
setNumberOfParams(numberOfParams - 1);
|
||||||
setParamKeyValues(cloneParamKeyValue);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const addNewParamAtIndex = (indexToAdd: number): void => {
|
const addNewParamAtIndex = (indexToAdd: number): void => {
|
||||||
const cloneParamKeyValue = [...paramKeyValues];
|
paramKeyValuesRef.current.splice(indexToAdd, 0, { key: "string", text: "" });
|
||||||
cloneParamKeyValue.splice(indexToAdd, 0, { key: "string", text: "" });
|
setNumberOfParams(numberOfParams + 1);
|
||||||
setParamKeyValues(cloneParamKeyValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
const paramValueChange = (value: string, indexOfInput: number): void => {
|
|
||||||
const cloneParamKeyValue = [...paramKeyValues];
|
|
||||||
cloneParamKeyValue[indexOfInput].text = value;
|
|
||||||
setParamKeyValues(cloneParamKeyValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
const paramKeyChange = (
|
|
||||||
_event: React.FormEvent<HTMLDivElement>,
|
|
||||||
selectedParam: IDropdownOption,
|
|
||||||
indexOfParam: number
|
|
||||||
): void => {
|
|
||||||
const cloneParamKeyValue = [...paramKeyValues];
|
|
||||||
cloneParamKeyValue[indexOfParam].key = selectedParam.key.toString();
|
|
||||||
setParamKeyValues(cloneParamKeyValue);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const addNewParamAtLastIndex = (): void => {
|
const addNewParamAtLastIndex = (): void => {
|
||||||
const cloneParamKeyValue = [...paramKeyValues];
|
paramKeyValuesRef.current.push({
|
||||||
cloneParamKeyValue.splice(cloneParamKeyValue.length, 0, { key: "string", text: "" });
|
key: "string",
|
||||||
setParamKeyValues(cloneParamKeyValue);
|
text: "",
|
||||||
|
});
|
||||||
|
setNumberOfParams(numberOfParams + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const props: RightPaneFormProps = {
|
const props: RightPaneFormProps = {
|
||||||
@ -118,46 +100,52 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
|
|||||||
onSubmit: () => submit(),
|
onSubmit: () => submit(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getInputParameterComponent = (): JSX.Element[] => {
|
||||||
|
const inputParameters: JSX.Element[] = [];
|
||||||
|
for (let i = 0; i < numberOfParams; i++) {
|
||||||
|
const paramKeyValue = paramKeyValuesRef.current[i];
|
||||||
|
inputParameters.push(
|
||||||
|
<InputParameter
|
||||||
|
key={paramKeyValue.text + i}
|
||||||
|
dropdownLabel={i === 0 ? "Key" : ""}
|
||||||
|
inputParameterTitle={i === 0 ? "Enter input parameters (if any)" : ""}
|
||||||
|
inputLabel={i === 0 ? "Param" : ""}
|
||||||
|
isAddRemoveVisible={true}
|
||||||
|
onDeleteParamKeyPress={() => deleteParamAtIndex(i)}
|
||||||
|
onAddNewParamKeyPress={() => addNewParamAtIndex(i + 1)}
|
||||||
|
onParamValueChange={(_event, newInput?: string) => (paramKeyValuesRef.current[i].text = newInput)}
|
||||||
|
onParamKeyChange={(_event, selectedParam: IDropdownOption) =>
|
||||||
|
(paramKeyValuesRef.current[i].key = selectedParam.key.toString())
|
||||||
|
}
|
||||||
|
paramValue={paramKeyValue.text}
|
||||||
|
selectedKey={paramKeyValue.key}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputParameters;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RightPaneForm {...props}>
|
<RightPaneForm {...props}>
|
||||||
<div className="panelFormWrapper">
|
<div className="panelMainContent">
|
||||||
<div className="panelMainContent">
|
<InputParameter
|
||||||
<InputParameter
|
dropdownLabel="Key"
|
||||||
dropdownLabel="Key"
|
inputParameterTitle="Partition key value"
|
||||||
inputParameterTitle="Partition key value"
|
inputLabel="Value"
|
||||||
inputLabel="Value"
|
isAddRemoveVisible={false}
|
||||||
isAddRemoveVisible={false}
|
onParamValueChange={(_event, newInput?: string) => (partitionValueRef.current = newInput)}
|
||||||
onParamValueChange={(_event, newInput?: string) => {
|
onParamKeyChange={(_event: React.FormEvent<HTMLDivElement>, item: IDropdownOption) =>
|
||||||
setPartitionValue(newInput);
|
(partitionKeyRef.current = item.key.toString())
|
||||||
}}
|
}
|
||||||
onParamKeyChange={onPartitionKeyChange}
|
paramValue={partitionValueRef.current}
|
||||||
paramValue={partitionValue}
|
selectedKey={partitionKeyRef.current}
|
||||||
selectedKey={selectedKey.key}
|
/>
|
||||||
/>
|
{getInputParameterComponent()}
|
||||||
{paramKeyValues.map((paramKeyValue, index) => (
|
<Stack horizontal onClick={() => addNewParamAtLastIndex()} tabIndex={0}>
|
||||||
<InputParameter
|
<Image {...imageProps} src={AddPropertyIcon} alt="Add param" />
|
||||||
key={paramKeyValue && paramKeyValue.text + index}
|
<Text className="addNewParamStyle">Add New Param</Text>
|
||||||
dropdownLabel={!index && "Key"}
|
</Stack>
|
||||||
inputParameterTitle={!index && "Enter input parameters (if any)"}
|
|
||||||
inputLabel={!index && "Param"}
|
|
||||||
isAddRemoveVisible={true}
|
|
||||||
onDeleteParamKeyPress={() => deleteParamAtIndex(index)}
|
|
||||||
onAddNewParamKeyPress={() => addNewParamAtIndex(index + 1)}
|
|
||||||
onParamValueChange={(event, newInput?: string) => {
|
|
||||||
paramValueChange(newInput, index);
|
|
||||||
}}
|
|
||||||
onParamKeyChange={(event: React.FormEvent<HTMLDivElement>, selectedParam: IDropdownOption) => {
|
|
||||||
paramKeyChange(event, selectedParam, index);
|
|
||||||
}}
|
|
||||||
paramValue={paramKeyValue && paramKeyValue.text}
|
|
||||||
selectedKey={paramKeyValue && paramKeyValue.key}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
<Stack horizontal onClick={addNewParamAtLastIndex} tabIndex={0}>
|
|
||||||
<Image {...imageProps} src={AddPropertyIcon} alt="Add param" />
|
|
||||||
<Text className="addNewParamStyle">Add New Param</Text>
|
|
||||||
</Stack>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</RightPaneForm>
|
</RightPaneForm>
|
||||||
);
|
);
|
||||||
|
@ -55,7 +55,7 @@ export const InputParameter: FunctionComponent<InputParameterProps> = ({
|
|||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
label={dropdownLabel && dropdownLabel}
|
label={dropdownLabel && dropdownLabel}
|
||||||
selectedKey={selectedKey}
|
defaultSelectedKey={selectedKey}
|
||||||
onChange={onParamKeyChange}
|
onChange={onParamKeyChange}
|
||||||
options={options}
|
options={options}
|
||||||
styles={dropdownStyles}
|
styles={dropdownStyles}
|
||||||
@ -64,8 +64,9 @@ export const InputParameter: FunctionComponent<InputParameterProps> = ({
|
|||||||
<TextField
|
<TextField
|
||||||
label={inputLabel && inputLabel}
|
label={inputLabel && inputLabel}
|
||||||
id="confirmCollectionId"
|
id="confirmCollectionId"
|
||||||
value={paramValue}
|
defaultValue={paramValue}
|
||||||
onChange={onParamValueChange}
|
onChange={onParamValueChange}
|
||||||
|
tabIndex={0}
|
||||||
/>
|
/>
|
||||||
{isAddRemoveVisible && (
|
{isAddRemoveVisible && (
|
||||||
<>
|
<>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
import { Checkbox, ChoiceGroup, IChoiceGroupOption, SpinButton } from "@fluentui/react";
|
import { Checkbox, ChoiceGroup, IChoiceGroupOption, SpinButton, Stack, Text } from "@fluentui/react";
|
||||||
import * as Constants from "Common/Constants";
|
import * as Constants from "Common/Constants";
|
||||||
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
|
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
|
||||||
import { configContext } from "ConfigContext";
|
import { configContext } from "ConfigContext";
|
||||||
@ -113,20 +113,44 @@ export const SettingsPane: FunctionComponent = () => {
|
|||||||
const handleOnPageOptionChange = (ev: React.FormEvent<HTMLInputElement>, option: IChoiceGroupOption): void => {
|
const handleOnPageOptionChange = (ev: React.FormEvent<HTMLInputElement>, option: IChoiceGroupOption): void => {
|
||||||
setPageOption(option.key);
|
setPageOption(option.key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const choiceButtonStyles = {
|
||||||
|
flexContainer: [
|
||||||
|
{
|
||||||
|
selectors: {
|
||||||
|
".ms-ChoiceField-wrapper label": {
|
||||||
|
fontSize: 12,
|
||||||
|
paddingTop: 0,
|
||||||
|
},
|
||||||
|
".ms-ChoiceField": {
|
||||||
|
marginTop: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<RightPaneForm {...genericPaneProps}>
|
<RightPaneForm {...genericPaneProps}>
|
||||||
<div className="paneMainContent">
|
<div className="paneMainContent">
|
||||||
{shouldShowQueryPageOptions && (
|
{shouldShowQueryPageOptions && (
|
||||||
<div className="settingsSection">
|
<div className="settingsSection">
|
||||||
<div className="settingsSectionPart pageOptionsPart">
|
<div className="settingsSectionPart">
|
||||||
<div className="settingsSectionLabel">
|
<Stack horizontal>
|
||||||
Page options
|
<Text id="pageOptions" className="settingsSectionLabel" variant="small">
|
||||||
|
Page options
|
||||||
|
</Text>
|
||||||
<InfoTooltip>
|
<InfoTooltip>
|
||||||
Choose Custom to specify a fixed amount of query results to show, or choose Unlimited to show as many
|
Choose Custom to specify a fixed amount of query results to show, or choose Unlimited to show as many
|
||||||
query results per page.
|
query results per page.
|
||||||
</InfoTooltip>
|
</InfoTooltip>
|
||||||
</div>
|
</Stack>
|
||||||
<ChoiceGroup selectedKey={pageOption} options={pageOptionList} onChange={handleOnPageOptionChange} />
|
<ChoiceGroup
|
||||||
|
ariaLabelledBy="pageOptions"
|
||||||
|
selectedKey={pageOption}
|
||||||
|
options={pageOptionList}
|
||||||
|
styles={choiceButtonStyles}
|
||||||
|
onChange={handleOnPageOptionChange}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="tabs settingsSectionPart">
|
<div className="tabs settingsSectionPart">
|
||||||
{isCustomPageOptionSelected() && (
|
{isCustomPageOptionSelected() && (
|
||||||
|
@ -14,17 +14,24 @@ exports[`Settings Pane should render Default properly 1`] = `
|
|||||||
className="settingsSection"
|
className="settingsSection"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="settingsSectionPart pageOptionsPart"
|
className="settingsSectionPart"
|
||||||
>
|
>
|
||||||
<div
|
<Stack
|
||||||
className="settingsSectionLabel"
|
horizontal={true}
|
||||||
>
|
>
|
||||||
Page options
|
<Text
|
||||||
|
className="settingsSectionLabel"
|
||||||
|
id="pageOptions"
|
||||||
|
variant="small"
|
||||||
|
>
|
||||||
|
Page options
|
||||||
|
</Text>
|
||||||
<InfoTooltip>
|
<InfoTooltip>
|
||||||
Choose Custom to specify a fixed amount of query results to show, or choose Unlimited to show as many query results per page.
|
Choose Custom to specify a fixed amount of query results to show, or choose Unlimited to show as many query results per page.
|
||||||
</InfoTooltip>
|
</InfoTooltip>
|
||||||
</div>
|
</Stack>
|
||||||
<StyledChoiceGroup
|
<StyledChoiceGroup
|
||||||
|
ariaLabelledBy="pageOptions"
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
options={
|
options={
|
||||||
Array [
|
Array [
|
||||||
@ -39,6 +46,23 @@ exports[`Settings Pane should render Default properly 1`] = `
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
selectedKey="custom"
|
selectedKey="custom"
|
||||||
|
styles={
|
||||||
|
Object {
|
||||||
|
"flexContainer": Array [
|
||||||
|
Object {
|
||||||
|
"selectors": Object {
|
||||||
|
".ms-ChoiceField": Object {
|
||||||
|
"marginTop": 0,
|
||||||
|
},
|
||||||
|
".ms-ChoiceField-wrapper label": Object {
|
||||||
|
"fontSize": 12,
|
||||||
|
"paddingTop": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -33,6 +33,7 @@ const {
|
|||||||
Inet,
|
Inet,
|
||||||
Smallint,
|
Smallint,
|
||||||
Tinyint,
|
Tinyint,
|
||||||
|
Timestamp,
|
||||||
} = TableConstants.CassandraType;
|
} = TableConstants.CassandraType;
|
||||||
export const cassandraOptions = [
|
export const cassandraOptions = [
|
||||||
{ key: Text, text: Text },
|
{ key: Text, text: Text },
|
||||||
@ -50,6 +51,7 @@ export const cassandraOptions = [
|
|||||||
{ key: Inet, text: Inet },
|
{ key: Inet, text: Inet },
|
||||||
{ key: Smallint, text: Smallint },
|
{ key: Smallint, text: Smallint },
|
||||||
{ key: Tinyint, text: Tinyint },
|
{ key: Tinyint, text: Tinyint },
|
||||||
|
{ key: Timestamp, text: Timestamp },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const imageProps: IImageProps = {
|
export const imageProps: IImageProps = {
|
||||||
|
@ -314,7 +314,10 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
}
|
}
|
||||||
useSidePanel
|
useSidePanel
|
||||||
.getState()
|
.getState()
|
||||||
.openSidePanel("New " + getDatabaseName(), <AddDatabasePanel explorer={this.container} />);
|
.openSidePanel(
|
||||||
|
"New " + getDatabaseName(),
|
||||||
|
<AddDatabasePanel explorer={this.container} buttonElement={document.activeElement as HTMLElement} />
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ export const CassandraType = {
|
|||||||
Float: "Float",
|
Float: "Float",
|
||||||
Int: "Int",
|
Int: "Int",
|
||||||
Text: "Text",
|
Text: "Text",
|
||||||
|
Timestamp: "Timestamp",
|
||||||
Uuid: "Uuid",
|
Uuid: "Uuid",
|
||||||
Varchar: "Varchar",
|
Varchar: "Varchar",
|
||||||
Varint: "Varint",
|
Varint: "Varint",
|
||||||
|
@ -431,7 +431,7 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
if (newHeaders.length > 0) {
|
if (newHeaders.length > 0) {
|
||||||
// Any new columns found will be added into headers array, which will trigger a re-render of the DataTable.
|
// Any new columns found will be added into headers array, which will trigger a re-render of the DataTable.
|
||||||
// So there is no need to call it here.
|
// So there is no need to call it here.
|
||||||
this.updateHeaders(newHeaders, /* notifyColumnChanges */ true);
|
this.updateHeaders(selectedHeadersUnion, /* notifyColumnChanges */ true);
|
||||||
} else {
|
} else {
|
||||||
if (columnSortOrder) {
|
if (columnSortOrder) {
|
||||||
this.sortColumns(columnSortOrder, oSettings);
|
this.sortColumns(columnSortOrder, oSettings);
|
||||||
|
@ -535,7 +535,8 @@ export class CassandraAPIDataClient extends TableDataClient {
|
|||||||
dataType === TableConstants.CassandraType.Text ||
|
dataType === TableConstants.CassandraType.Text ||
|
||||||
dataType === TableConstants.CassandraType.Inet ||
|
dataType === TableConstants.CassandraType.Inet ||
|
||||||
dataType === TableConstants.CassandraType.Ascii ||
|
dataType === TableConstants.CassandraType.Ascii ||
|
||||||
dataType === TableConstants.CassandraType.Varchar
|
dataType === TableConstants.CassandraType.Varchar ||
|
||||||
|
dataType === TableConstants.CassandraType.Timestamp
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
import postRobot from "post-robot";
|
import postRobot from "post-robot";
|
||||||
|
import { GetGithubClientId } from "Utils/GitHubUtils";
|
||||||
import { HttpStatusCodes } from "../Common/Constants";
|
import { HttpStatusCodes } from "../Common/Constants";
|
||||||
import { handleError } from "../Common/ErrorHandlingUtils";
|
import { handleError } from "../Common/ErrorHandlingUtils";
|
||||||
import { configContext } from "../ConfigContext";
|
|
||||||
import { AuthorizeAccessComponent } from "../Explorer/Controls/GitHub/AuthorizeAccessComponent";
|
import { AuthorizeAccessComponent } from "../Explorer/Controls/GitHub/AuthorizeAccessComponent";
|
||||||
import { JunoClient } from "../Juno/JunoClient";
|
import { JunoClient } from "../Juno/JunoClient";
|
||||||
import { logConsoleInfo } from "../Utils/NotificationConsoleUtils";
|
import { logConsoleInfo } from "../Utils/NotificationConsoleUtils";
|
||||||
@ -55,7 +55,7 @@ export class GitHubOAuthService {
|
|||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
scope,
|
scope,
|
||||||
client_id: configContext.GITHUB_CLIENT_ID,
|
client_id: GetGithubClientId(),
|
||||||
redirect_uri: new URL("./connectToGitHub.html", window.location.href).href,
|
redirect_uri: new URL("./connectToGitHub.html", window.location.href).href,
|
||||||
state: this.resetState(),
|
state: this.resetState(),
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import ko from "knockout";
|
import ko from "knockout";
|
||||||
|
import { GetGithubClientId } from "Utils/GitHubUtils";
|
||||||
import { HttpHeaders, HttpStatusCodes } from "../Common/Constants";
|
import { HttpHeaders, HttpStatusCodes } from "../Common/Constants";
|
||||||
import { configContext } from "../ConfigContext";
|
import { configContext } from "../ConfigContext";
|
||||||
import * as DataModels from "../Contracts/DataModels";
|
import * as DataModels from "../Contracts/DataModels";
|
||||||
@ -522,7 +523,7 @@ export class JunoClient {
|
|||||||
|
|
||||||
private static getGitHubClientParams(): URLSearchParams {
|
private static getGitHubClientParams(): URLSearchParams {
|
||||||
const githubParams = new URLSearchParams({
|
const githubParams = new URLSearchParams({
|
||||||
client_id: configContext.GITHUB_CLIENT_ID,
|
client_id: GetGithubClientId(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (configContext.GITHUB_CLIENT_SECRET) {
|
if (configContext.GITHUB_CLIENT_SECRET) {
|
||||||
|
@ -50,7 +50,6 @@ export enum Action {
|
|||||||
SubscriptionSwitch,
|
SubscriptionSwitch,
|
||||||
TenantSwitch,
|
TenantSwitch,
|
||||||
DefaultTenantSwitch,
|
DefaultTenantSwitch,
|
||||||
ResetNotebookWorkspace,
|
|
||||||
CreateNotebookWorkspace,
|
CreateNotebookWorkspace,
|
||||||
NotebookErrorNotification,
|
NotebookErrorNotification,
|
||||||
CreateSparkCluster,
|
CreateSparkCluster,
|
||||||
@ -82,6 +81,8 @@ export enum Action {
|
|||||||
NotebooksInsertTextCellBelowFromMenu,
|
NotebooksInsertTextCellBelowFromMenu,
|
||||||
NotebooksMoveCellUpFromMenu,
|
NotebooksMoveCellUpFromMenu,
|
||||||
NotebooksMoveCellDownFromMenu,
|
NotebooksMoveCellDownFromMenu,
|
||||||
|
PhoenixConnection,
|
||||||
|
PhoenixResetWorkspace,
|
||||||
DeleteCellFromMenu,
|
DeleteCellFromMenu,
|
||||||
OpenTerminal,
|
OpenTerminal,
|
||||||
CreateMongoCollectionWithWildcardIndex,
|
CreateMongoCollectionWithWildcardIndex,
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
// https://github.com/<owner>/<repo>/tree/<branch>
|
// https://github.com/<owner>/<repo>/tree/<branch>
|
||||||
|
|
||||||
|
import { JunoEndpoints } from "Common/Constants";
|
||||||
|
import { configContext } from "ConfigContext";
|
||||||
|
import { userContext } from "UserContext";
|
||||||
|
|
||||||
// The url when users visit a repo/branch on github.com
|
// The url when users visit a repo/branch on github.com
|
||||||
export const RepoUriPattern = /https:\/\/github.com\/([^/]*)\/([^/]*)\/tree\/([^?]*)/;
|
export const RepoUriPattern = /https:\/\/github.com\/([^/]*)\/([^/]*)\/tree\/([^?]*)/;
|
||||||
|
|
||||||
@ -60,3 +65,15 @@ export function toContentUri(owner: string, repo: string, branch: string, path:
|
|||||||
export function toRawContentUri(owner: string, repo: string, branch: string, path: string): string {
|
export function toRawContentUri(owner: string, repo: string, branch: string, path: string): string {
|
||||||
return `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${path}`;
|
return `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GetGithubClientId(): string {
|
||||||
|
const junoEndpoint = userContext.features.junoEndpoint ?? configContext.JUNO_ENDPOINT;
|
||||||
|
if (
|
||||||
|
junoEndpoint === JunoEndpoints.Test ||
|
||||||
|
junoEndpoint === JunoEndpoints.Test2 ||
|
||||||
|
junoEndpoint === JunoEndpoints.Test3
|
||||||
|
) {
|
||||||
|
return configContext.GITHUB_TEST_ENV_CLIENT_ID;
|
||||||
|
}
|
||||||
|
return configContext.GITHUB_CLIENT_ID;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user