Merge branch 'master' into users/languy/save-documentstab-prefs
This commit is contained in:
commit
1795b8e2e9
|
@ -1906,8 +1906,14 @@ input::-webkit-calendar-picker-indicator::after {
|
|||
}
|
||||
|
||||
.nav-tabs-margin {
|
||||
padding-top: 5px;
|
||||
height: 32px;
|
||||
background-color: #f2f2f2;
|
||||
|
||||
.nav-tabs {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.navTabHeight {
|
||||
|
|
|
@ -134,6 +134,8 @@ export class BackendApi {
|
|||
public static readonly GenerateToken: string = "GenerateToken";
|
||||
public static readonly PortalSettings: string = "PortalSettings";
|
||||
public static readonly AccountRestrictions: string = "AccountRestrictions";
|
||||
public static readonly RuntimeProxy: string = "RuntimeProxy";
|
||||
public static readonly DisallowedLocations: string = "DisallowedLocations";
|
||||
}
|
||||
|
||||
export class PortalBackendEndpoints {
|
||||
|
@ -183,6 +185,12 @@ export class CassandraProxyAPIs {
|
|||
public static readonly connectionStringSchemaApi: string = "api/connectionstring/cassandra/schema";
|
||||
}
|
||||
|
||||
export class AadEndpoints {
|
||||
public static readonly Prod: string = "https://login.microsoftonline.com/";
|
||||
public static readonly Fairfax: string = "https://login.microsoftonline.us/";
|
||||
public static readonly Mooncake: string = "https://login.partner.microsoftonline.cn/";
|
||||
}
|
||||
|
||||
export class Queries {
|
||||
public static CustomPageOption: string = "custom";
|
||||
public static UnlimitedPageOption: string = "unlimited";
|
||||
|
|
|
@ -3,15 +3,16 @@ import { getAuthorizationTokenUsingResourceTokens } from "Common/getAuthorizatio
|
|||
import { AuthorizationToken } from "Contracts/FabricMessageTypes";
|
||||
import { checkDatabaseResourceTokensValidity } from "Platform/Fabric/FabricUtil";
|
||||
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||
import { useNewPortalBackendEndpoint } from "Utils/EndpointUtils";
|
||||
import { AuthType } from "../AuthType";
|
||||
import { PriorityLevel } from "../Common/Constants";
|
||||
import { BackendApi, PriorityLevel } from "../Common/Constants";
|
||||
import * as Logger from "../Common/Logger";
|
||||
import { Platform, configContext } from "../ConfigContext";
|
||||
import { userContext } from "../UserContext";
|
||||
import { logConsoleError } from "../Utils/NotificationConsoleUtils";
|
||||
import * as PriorityBasedExecutionUtils from "../Utils/PriorityBasedExecutionUtils";
|
||||
import { EmulatorMasterKey, HttpHeaders } from "./Constants";
|
||||
import { getErrorMessage } from "./ErrorHandlingUtils";
|
||||
import * as Logger from "../Common/Logger";
|
||||
|
||||
const _global = typeof self === "undefined" ? window : self;
|
||||
|
||||
|
@ -123,6 +124,37 @@ export async function getTokenFromAuthService(
|
|||
verb: string,
|
||||
resourceType: string,
|
||||
resourceId?: string,
|
||||
): Promise<AuthorizationToken> {
|
||||
if (!useNewPortalBackendEndpoint(BackendApi.RuntimeProxy)) {
|
||||
return getTokenFromAuthService_ToBeDeprecated(verb, resourceType, resourceId);
|
||||
}
|
||||
|
||||
try {
|
||||
const host: string = configContext.PORTAL_BACKEND_ENDPOINT;
|
||||
const response: Response = await _global.fetch(host + "/api/connectionstring/runtimeproxy/authorizationtokens", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
"x-ms-encrypted-auth-token": userContext.accessToken,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
verb,
|
||||
resourceType,
|
||||
resourceId,
|
||||
}),
|
||||
});
|
||||
const result: AuthorizationToken = await response.json();
|
||||
return result;
|
||||
} catch (error) {
|
||||
logConsoleError(`Failed to get authorization headers for ${resourceType}: ${getErrorMessage(error)}`);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getTokenFromAuthService_ToBeDeprecated(
|
||||
verb: string,
|
||||
resourceType: string,
|
||||
resourceId?: string,
|
||||
): Promise<AuthorizationToken> {
|
||||
try {
|
||||
const host = configContext.BACKEND_ENDPOINT;
|
||||
|
|
|
@ -720,7 +720,8 @@ export function useMongoProxyEndpoint(api: string): boolean {
|
|||
MongoProxyEndpoints.Local,
|
||||
MongoProxyEndpoints.Mpac,
|
||||
MongoProxyEndpoints.Prod,
|
||||
// MongoProxyEndpoints.Fairfax,
|
||||
MongoProxyEndpoints.Fairfax,
|
||||
MongoProxyEndpoints.Mooncake,
|
||||
];
|
||||
let canAccessMongoProxy: boolean = userContext.databaseAccount.properties.publicNetworkAccess === "Enabled";
|
||||
if (
|
||||
|
|
|
@ -87,7 +87,7 @@ let configContext: Readonly<ConfigContext> = {
|
|||
`^https:\\/\\/.*\\.analysis-df\\.net$`,
|
||||
`^https:\\/\\/.*\\.analysis-df\\.windows\\.net$`,
|
||||
`^https:\\/\\/.*\\.azure-test\\.net$`,
|
||||
`^https:\\/\\/cosmos-explorer-preview\\.azurewebsites\\.net`,
|
||||
`^https:\\/\\/cosmos-explorer-preview\\.azurewebsites\\.net$`,
|
||||
], // Webpack injects this at build time
|
||||
gitSha: process.env.GIT_SHA,
|
||||
hostedExplorerURL: "https://cosmos.azure.com/",
|
||||
|
|
|
@ -17,7 +17,7 @@ export const useTreeStyles = makeStyles({
|
|||
minWidth: "100%",
|
||||
rowGap: "0px",
|
||||
paddingTop: "0px",
|
||||
[treeIconWidth]: "20px",
|
||||
[treeIconWidth]: "16px",
|
||||
[leafNodeSpacing]: "24px",
|
||||
},
|
||||
nodeIcon: {
|
||||
|
@ -32,7 +32,6 @@ export const useTreeStyles = makeStyles({
|
|||
fontSize: tokens.fontSizeBase300,
|
||||
height: tokens.layoutRowHeight,
|
||||
...cosmosShorthands.borderBottom(),
|
||||
paddingLeft: `calc(var(${treeItemLevelToken}, 1) * ${tokens.spacingHorizontalXXL})`,
|
||||
|
||||
// Some sneaky CSS variables stuff to change the background color of the action button on hover.
|
||||
[actionButtonBackground]: tokens.colorNeutralBackground1,
|
||||
|
|
|
@ -149,15 +149,16 @@ export const TreeNodeComponent: React.FC<TreeNodeComponentProps> = ({
|
|||
|
||||
// We use the expandIcon slot to hold the node icon too.
|
||||
// We only show a node icon for leaf nodes, even if a branch node has an iconSrc.
|
||||
const expandIcon = isLoading ? (
|
||||
<Spinner size="extra-tiny" />
|
||||
) : !isBranch ? (
|
||||
typeof node.iconSrc === "string" ? (
|
||||
const treeIcon =
|
||||
node.iconSrc === undefined ? undefined : typeof node.iconSrc === "string" ? (
|
||||
<img src={node.iconSrc} className={treeStyles.nodeIcon} alt="" />
|
||||
) : (
|
||||
node.iconSrc
|
||||
)
|
||||
) : openItems.includes(treeNodeId) ? (
|
||||
);
|
||||
|
||||
const expandIcon = isLoading ? (
|
||||
<Spinner size="extra-tiny" />
|
||||
) : !isBranch ? undefined : openItems.includes(treeNodeId) ? (
|
||||
<ChevronDown20Regular data-test="TreeNode/CollapseIcon" />
|
||||
) : (
|
||||
<ChevronRight20Regular data-text="TreeNode/ExpandIcon" />
|
||||
|
@ -174,7 +175,6 @@ export const TreeNodeComponent: React.FC<TreeNodeComponentProps> = ({
|
|||
<TreeItemLayout
|
||||
className={mergeClasses(
|
||||
treeStyles.treeItemLayout,
|
||||
expandIcon ? undefined : treeStyles.treeItemLayoutNoIcon,
|
||||
shouldShowAsSelected && treeStyles.selectedItem,
|
||||
node.className && treeStyles[node.className],
|
||||
)}
|
||||
|
@ -200,6 +200,7 @@ export const TreeNodeComponent: React.FC<TreeNodeComponentProps> = ({
|
|||
),
|
||||
}
|
||||
}
|
||||
iconBefore={treeIcon}
|
||||
expandIcon={expandIcon}
|
||||
>
|
||||
<span className={treeStyles.nodeLabel}>{node.label}</span>
|
||||
|
|
|
@ -10,13 +10,20 @@ exports[`TreeNodeComponent does not render children if the node is loading 1`] =
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
<ChevronRight20Regular
|
||||
data-text="TreeNode/ExpandIcon"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<span
|
||||
className="___1h29e9h_0000000 fz5stix"
|
||||
|
@ -156,7 +163,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
"itemType": "branch",
|
||||
"layoutRef": {
|
||||
"current": <div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
>
|
||||
<div
|
||||
|
@ -179,6 +186,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -208,7 +225,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
>
|
||||
<div
|
||||
|
@ -231,6 +248,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -242,7 +269,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="fui-Tree rnv2ez3 ___jy13a00_lpffjy0 f1acs6jw f11qra4b fepn2xe f1nbblvp fhxm7u5 fzz4f4n"
|
||||
class="fui-Tree rnv2ez3 ___17a32do_7zrvj80 f1acs6jw f11qra4b fepn2xe f1nbblvp f19d5ny4 fzz4f4n"
|
||||
data-test="Tree:root"
|
||||
role="tree"
|
||||
>
|
||||
|
@ -256,7 +283,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child1Label"
|
||||
>
|
||||
<div
|
||||
|
@ -279,6 +306,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child1Icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -300,7 +337,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child2LoadingLabel"
|
||||
>
|
||||
<div
|
||||
|
@ -323,6 +360,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child2LoadingIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -343,7 +390,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vrg09j fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_vz3p260 fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child3ExpandingLabel"
|
||||
>
|
||||
<div
|
||||
|
@ -363,6 +410,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child3ExpandingIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -383,16 +440,23 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
<ChevronRight20Regular
|
||||
data-text="TreeNode/ExpandIcon"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
>
|
||||
<div
|
||||
|
@ -419,6 +483,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</svg>
|
||||
</ChevronRight20Regular>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden={true}
|
||||
className="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -431,7 +505,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</div>
|
||||
</TreeItemLayout>
|
||||
<Tree
|
||||
className="___jy13a00_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp fhxm7u5 fzz4f4n"
|
||||
className="___17a32do_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp f19d5ny4 fzz4f4n"
|
||||
data-test="Tree:root"
|
||||
>
|
||||
<TreeProvider
|
||||
|
@ -499,7 +573,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
}
|
||||
>
|
||||
<div
|
||||
className="fui-Tree rnv2ez3 ___jy13a00_lpffjy0 f1acs6jw f11qra4b fepn2xe f1nbblvp fhxm7u5 fzz4f4n"
|
||||
className="fui-Tree rnv2ez3 ___17a32do_7zrvj80 f1acs6jw f11qra4b fepn2xe f1nbblvp f19d5ny4 fzz4f4n"
|
||||
data-test="Tree:root"
|
||||
role="tree"
|
||||
>
|
||||
|
@ -587,7 +661,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
"itemType": "branch",
|
||||
"layoutRef": {
|
||||
"current": <div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child1Label"
|
||||
>
|
||||
<div
|
||||
|
@ -610,6 +684,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child1Icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -639,7 +723,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child1Label"
|
||||
>
|
||||
<div
|
||||
|
@ -662,6 +746,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child1Icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -680,16 +774,23 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child1Label"
|
||||
expandIcon={
|
||||
<ChevronRight20Regular
|
||||
data-text="TreeNode/ExpandIcon"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child1Icon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child1Label"
|
||||
>
|
||||
<div
|
||||
|
@ -716,6 +817,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</svg>
|
||||
</ChevronRight20Regular>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden={true}
|
||||
className="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child1Icon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -728,7 +839,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</div>
|
||||
</TreeItemLayout>
|
||||
<Tree
|
||||
className="___jy13a00_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp fhxm7u5 fzz4f4n"
|
||||
className="___17a32do_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp f19d5ny4 fzz4f4n"
|
||||
data-test="Tree:root/child1Label"
|
||||
>
|
||||
<TreeProvider
|
||||
|
@ -821,7 +932,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
"itemType": "branch",
|
||||
"layoutRef": {
|
||||
"current": <div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child2LoadingLabel"
|
||||
>
|
||||
<div
|
||||
|
@ -844,6 +955,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child2LoadingIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -873,7 +994,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child2LoadingLabel"
|
||||
>
|
||||
<div
|
||||
|
@ -896,6 +1017,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child2LoadingIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -914,16 +1045,23 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child2LoadingLabel"
|
||||
expandIcon={
|
||||
<ChevronRight20Regular
|
||||
data-text="TreeNode/ExpandIcon"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child2LoadingIcon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vtp8mg fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="fui-TreeItemLayout r1bx0xiv ___9uolwu0_9b0r4g0 fk6fouc fkhj508 figsok6 f1i3iumi fo100m9 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child2LoadingLabel"
|
||||
>
|
||||
<div
|
||||
|
@ -950,6 +1088,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</svg>
|
||||
</ChevronRight20Regular>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden={true}
|
||||
className="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child2LoadingIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -1039,7 +1187,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
"itemType": "leaf",
|
||||
"layoutRef": {
|
||||
"current": <div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vrg09j fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_vz3p260 fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child3ExpandingLabel"
|
||||
>
|
||||
<div
|
||||
|
@ -1059,6 +1207,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child3ExpandingIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -1087,7 +1245,7 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vrg09j fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
class="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_vz3p260 fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child3ExpandingLabel"
|
||||
>
|
||||
<div
|
||||
|
@ -1107,6 +1265,16 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
class="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="child3ExpandingIcon"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="fui-TreeItemLayout__main rklbe47"
|
||||
>
|
||||
|
@ -1125,9 +1293,9 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child3ExpandingLabel"
|
||||
expandIcon={
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
|
@ -1136,12 +1304,12 @@ exports[`TreeNodeComponent fully renders a tree 1`] = `
|
|||
}
|
||||
>
|
||||
<div
|
||||
className="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_1vrg09j fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="fui-TreeItemLayout r1bx0xiv ___dxcrnh0_vz3p260 fk6fouc fkhj508 figsok6 f1i3iumi f1k1erfc fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root/child3ExpandingLabel"
|
||||
>
|
||||
<div
|
||||
aria-hidden={true}
|
||||
className="fui-TreeItemLayout__expandIcon rh4pu5o"
|
||||
className="fui-TreeItemLayout__iconBefore rphzgg1 ___1lqnc2u_1hdcey2 f7x41pl"
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
|
@ -1184,9 +1352,9 @@ exports[`TreeNodeComponent renders a loading spinner if the node is loading: loa
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
|
@ -1213,13 +1381,20 @@ exports[`TreeNodeComponent renders a loading spinner if the node is loading: loa
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
<Spinner
|
||||
size="extra-tiny"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<span
|
||||
className="___1h29e9h_0000000 fz5stix"
|
||||
|
@ -1240,13 +1415,20 @@ exports[`TreeNodeComponent renders a node as expandable if it has empty, but def
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
<ChevronRight20Regular
|
||||
data-text="TreeNode/ExpandIcon"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<span
|
||||
className="___1h29e9h_0000000 fz5stix"
|
||||
|
@ -1313,9 +1495,9 @@ exports[`TreeNodeComponent renders a node with a menu 1`] = `
|
|||
"className": "___1r8p62d_0000000 f1xg1ack f1e31b4d",
|
||||
}
|
||||
}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
|
@ -1363,9 +1545,9 @@ exports[`TreeNodeComponent renders a single node 1`] = `
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
|
@ -1392,9 +1574,9 @@ exports[`TreeNodeComponent renders an icon if the node has one 1`] = `
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
|
@ -1421,13 +1603,20 @@ exports[`TreeNodeComponent renders selected parent node as selected if no descen
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___kqkdor0_ihxn0o0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1nfm20t f1do9gdl"
|
||||
className="___rq9vxg0_1ykn2d2 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1nfm20t f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
<ChevronRight20Regular
|
||||
data-text="TreeNode/ExpandIcon"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<span
|
||||
className="___1h29e9h_0000000 fz5stix"
|
||||
|
@ -1436,7 +1625,7 @@ exports[`TreeNodeComponent renders selected parent node as selected if no descen
|
|||
</span>
|
||||
</TreeItemLayout>
|
||||
<Tree
|
||||
className="___jy13a00_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp fhxm7u5 fzz4f4n"
|
||||
className="___17a32do_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp f19d5ny4 fzz4f4n"
|
||||
data-test="Tree:root"
|
||||
>
|
||||
<TreeNodeComponent
|
||||
|
@ -1497,13 +1686,20 @@ exports[`TreeNodeComponent renders selected parent node as unselected if any des
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___1kqyw53_iy2icj0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
className="___z7owk70_14ep1pe fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
<ChevronRight20Regular
|
||||
data-text="TreeNode/ExpandIcon"
|
||||
/>
|
||||
}
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
src="rootIcon"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<span
|
||||
className="___1h29e9h_0000000 fz5stix"
|
||||
|
@ -1512,7 +1708,7 @@ exports[`TreeNodeComponent renders selected parent node as unselected if any des
|
|||
</span>
|
||||
</TreeItemLayout>
|
||||
<Tree
|
||||
className="___jy13a00_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp fhxm7u5 fzz4f4n"
|
||||
className="___17a32do_0000000 f1acs6jw f11qra4b fepn2xe f1nbblvp f19d5ny4 fzz4f4n"
|
||||
data-test="Tree:root"
|
||||
>
|
||||
<TreeNodeComponent
|
||||
|
@ -1574,9 +1770,9 @@ exports[`TreeNodeComponent renders single selected leaf node as selected 1`] = `
|
|||
>
|
||||
<TreeItemLayout
|
||||
actions={false}
|
||||
className="___kqkdor0_ihxn0o0 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1k1erfc f1n8cmsf f1ktbui8 f1nfm20t f1do9gdl"
|
||||
className="___rq9vxg0_1ykn2d2 fkhj508 fbv8p0b f1f09k3d fg706s2 frpde29 f1n8cmsf f1ktbui8 f1nfm20t f1do9gdl"
|
||||
data-test="TreeNode:root"
|
||||
expandIcon={
|
||||
iconBefore={
|
||||
<img
|
||||
alt=""
|
||||
className="___i3nbrx0_0000000 f1do9gdl fbv8p0b"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { isPublicInternetAccessAllowed } from "Common/DatabaseAccountUtility";
|
||||
import { PhoenixClient } from "Phoenix/PhoenixClient";
|
||||
import { useNewPortalBackendEndpoint } from "Utils/EndpointUtils";
|
||||
import { cloneDeep } from "lodash";
|
||||
import create, { UseStore } from "zustand";
|
||||
import { AuthType } from "../../AuthType";
|
||||
|
@ -127,7 +128,9 @@ export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
|
|||
userContext.apiType === "Postgres" || userContext.apiType === "VCoreMongo"
|
||||
? databaseAccount?.location
|
||||
: databaseAccount?.properties?.writeLocations?.[0]?.locationName.toLowerCase();
|
||||
const disallowedLocationsUri = `${configContext.BACKEND_ENDPOINT}/api/disallowedLocations`;
|
||||
const disallowedLocationsUri: string = useNewPortalBackendEndpoint(Constants.BackendApi.DisallowedLocations)
|
||||
? `${configContext.PORTAL_BACKEND_ENDPOINT}/api/disallowedlocations`
|
||||
: `${configContext.BACKEND_ENDPOINT}/api/disallowedLocations`;
|
||||
const authorizationHeader = getAuthorizationHeader();
|
||||
try {
|
||||
const response = await fetch(disallowedLocationsUri, {
|
||||
|
|
|
@ -238,7 +238,7 @@ exports[`Settings Pane should render Default properly 1`] = `
|
|||
},
|
||||
]
|
||||
}
|
||||
selectedKey="vertical"
|
||||
selectedKey="horizontal"
|
||||
styles={
|
||||
{
|
||||
"flexContainer": [
|
||||
|
|
|
@ -86,7 +86,7 @@ const useSidebarStyles = makeStyles({
|
|||
},
|
||||
},
|
||||
globalCommandsMenuButton: {
|
||||
display: "initial",
|
||||
display: "inline-flex",
|
||||
"@container (min-width: 250px)": {
|
||||
display: "none",
|
||||
},
|
||||
|
@ -280,7 +280,7 @@ export const SidebarContainer: React.FC<SidebarProps> = ({ explorer }) => {
|
|||
{/* Collections Tree - Start */}
|
||||
{hasSidebar && (
|
||||
// When collapsed, we force the pane to 24 pixels wide and make it non-resizable.
|
||||
<Allotment.Pane minSize={24} preferredSize={300}>
|
||||
<Allotment.Pane minSize={24} preferredSize={250}>
|
||||
<CosmosFluentProvider className={mergeClasses(styles.sidebar)}>
|
||||
<div className={styles.sidebarContainer}>
|
||||
{loading && (
|
||||
|
|
|
@ -523,7 +523,10 @@ export interface IDocumentsTabComponentProps {
|
|||
|
||||
const getUniqueId = (collection: ViewModels.CollectionBase): string => `${collection.databaseId}-${collection.id()}`;
|
||||
|
||||
const defaultSqlFilters = ['WHERE c.id = "foo"', "ORDER BY c._ts DESC", 'WHERE c.id = "foo" ORDER BY c._ts DESC'];
|
||||
const getDefaultSqlFilters = (partitionKeys: string[]) =>
|
||||
['WHERE c.id = "foo"', "ORDER BY c._ts DESC", 'WHERE c.id = "foo" ORDER BY c._ts DESC', "ORDER BY c._ts ASC"].concat(
|
||||
partitionKeys.map((partitionKey) => `WHERE c.${partitionKey} = "foo"`),
|
||||
);
|
||||
const defaultMongoFilters = ['{"id":"foo"}', "{ qty: { $gte: 20 } }"];
|
||||
|
||||
// Extend DocumentId to include fields displayed in the table
|
||||
|
@ -1934,7 +1937,7 @@ export const DocumentsTabComponent: React.FunctionComponent<IDocumentsTabCompone
|
|||
<datalist id={`filtersList-${getUniqueId(_collection)}`}>
|
||||
{addStringsNoDuplicate(
|
||||
lastFilterContents,
|
||||
isPreferredApiMongoDB ? defaultMongoFilters : defaultSqlFilters,
|
||||
isPreferredApiMongoDB ? defaultMongoFilters : getDefaultSqlFilters(partitionKeyProperties),
|
||||
).map((filter) => (
|
||||
<option key={filter} value={filter} />
|
||||
))}
|
||||
|
|
|
@ -107,7 +107,7 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
>
|
||||
<List
|
||||
direction="ltr"
|
||||
height={-36}
|
||||
height={-32}
|
||||
itemCount={3}
|
||||
itemData={
|
||||
[
|
||||
|
@ -146,7 +146,7 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
},
|
||||
]
|
||||
}
|
||||
itemSize={36}
|
||||
itemSize={32}
|
||||
layout="vertical"
|
||||
overscanCount={2}
|
||||
style={
|
||||
|
@ -163,7 +163,7 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
{
|
||||
"WebkitOverflowScrolling": "touch",
|
||||
"direction": "ltr",
|
||||
"height": -36,
|
||||
"height": -32,
|
||||
"overflow": "auto",
|
||||
"overflowY": "scroll",
|
||||
"position": "relative",
|
||||
|
@ -175,7 +175,7 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
<div
|
||||
style={
|
||||
{
|
||||
"height": 108,
|
||||
"height": 96,
|
||||
"pointerEvents": undefined,
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
key="0"
|
||||
style={
|
||||
{
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
|
@ -241,7 +241,7 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
|
@ -259,7 +259,7 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
|
@ -313,11 +313,11 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
key="1"
|
||||
style={
|
||||
{
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 36,
|
||||
"top": 32,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
|
@ -331,11 +331,11 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 36,
|
||||
"top": 32,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -349,11 +349,11 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 36,
|
||||
"top": 32,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -403,11 +403,11 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
key="2"
|
||||
style={
|
||||
{
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 72,
|
||||
"top": 64,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
|
@ -421,11 +421,11 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 72,
|
||||
"top": 64,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -439,11 +439,11 @@ exports[`DocumentsTableComponent should not render selection column when isSelec
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 72,
|
||||
"top": 64,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -610,7 +610,7 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
>
|
||||
<List
|
||||
direction="ltr"
|
||||
height={-36}
|
||||
height={-32}
|
||||
itemCount={3}
|
||||
itemData={
|
||||
[
|
||||
|
@ -649,7 +649,7 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
},
|
||||
]
|
||||
}
|
||||
itemSize={36}
|
||||
itemSize={32}
|
||||
layout="vertical"
|
||||
overscanCount={2}
|
||||
style={
|
||||
|
@ -666,7 +666,7 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
{
|
||||
"WebkitOverflowScrolling": "touch",
|
||||
"direction": "ltr",
|
||||
"height": -36,
|
||||
"height": -32,
|
||||
"overflow": "auto",
|
||||
"overflowY": "scroll",
|
||||
"position": "relative",
|
||||
|
@ -678,7 +678,7 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
<div
|
||||
style={
|
||||
{
|
||||
"height": 108,
|
||||
"height": 96,
|
||||
"pointerEvents": undefined,
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -726,7 +726,7 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
key="0"
|
||||
style={
|
||||
{
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
|
@ -744,7 +744,7 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
|
@ -762,7 +762,7 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
|
@ -857,11 +857,11 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
key="1"
|
||||
style={
|
||||
{
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 36,
|
||||
"top": 32,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
|
@ -875,11 +875,11 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 36,
|
||||
"top": 32,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -893,11 +893,11 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 36,
|
||||
"top": 32,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -988,11 +988,11 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
key="2"
|
||||
style={
|
||||
{
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 72,
|
||||
"top": 64,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
|
@ -1006,11 +1006,11 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 72,
|
||||
"top": 64,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
@ -1024,11 +1024,11 @@ exports[`DocumentsTableComponent should render documents and partition keys in h
|
|||
style={
|
||||
{
|
||||
"cursor": "pointer",
|
||||
"height": 36,
|
||||
"height": 32,
|
||||
"left": 0,
|
||||
"position": "absolute",
|
||||
"right": undefined,
|
||||
"top": 72,
|
||||
"top": 64,
|
||||
"userSelect": "none",
|
||||
"width": "100%",
|
||||
}
|
||||
|
|
|
@ -100,8 +100,7 @@ export const Tabs = ({ explorer }: TabsProps): JSX.Element => {
|
|||
},
|
||||
}}
|
||||
>
|
||||
{`To prevent queries from using excessive RUs, Data Explorer has a 5,000 RU default limit. To modify or remove
|
||||
the limit, go to the Settings cog on the right and find "RU Threshold".`}
|
||||
{`Data Explorer has a 5,000 RU default limit. To adjust the limit, go to the Settings page and find "RU Threshold".`}
|
||||
<Link
|
||||
className="underlinedLink"
|
||||
href="https://review.learn.microsoft.com/en-us/azure/cosmos-db/data-explorer?branch=main#configure-request-unit-threshold"
|
||||
|
|
|
@ -16,7 +16,7 @@ import React from "react";
|
|||
import { appThemeFabricTealBrandRamp } from "../../Platform/Fabric/FabricTheme";
|
||||
|
||||
export const LayoutConstants = {
|
||||
rowHeight: 36,
|
||||
rowHeight: 32,
|
||||
};
|
||||
|
||||
// Our CosmosFluentProvider has the same props as a FluentProvider.
|
||||
|
@ -91,15 +91,30 @@ const appThemePortalBrandRamp: BrandVariants = {
|
|||
160: "#CDD8EF",
|
||||
};
|
||||
|
||||
const cosmosThemeElements = {
|
||||
layoutRowHeight: `${LayoutConstants.rowHeight}px`,
|
||||
export enum LayoutSize {
|
||||
Compact,
|
||||
// TODO: Cozy and Roomy layouts.
|
||||
}
|
||||
|
||||
interface CosmosThemeElements {
|
||||
layoutRowHeight: string;
|
||||
}
|
||||
|
||||
export type CosmosTheme = Theme & CosmosThemeElements;
|
||||
|
||||
const sizeMappings: Record<LayoutSize, Partial<Theme> & CosmosThemeElements> = {
|
||||
[LayoutSize.Compact]: {
|
||||
layoutRowHeight: "32px",
|
||||
fontSizeBase300: "13px",
|
||||
},
|
||||
};
|
||||
|
||||
const cosmosTheme = {
|
||||
sidebarMinimumWidth: "200px",
|
||||
sidebarInitialWidth: "300px",
|
||||
};
|
||||
|
||||
export type CosmosTheme = Theme & typeof cosmosThemeElements;
|
||||
|
||||
export const tokens = themeToTokensObject({ ...webLightTheme, ...cosmosThemeElements });
|
||||
export const tokens = themeToTokensObject({ ...webLightTheme, ...cosmosTheme, ...sizeMappings[LayoutSize.Compact] });
|
||||
|
||||
export const cosmosShorthands = {
|
||||
border: () => shorthands.border("1px", "solid", tokens.colorNeutralStroke2),
|
||||
|
@ -117,6 +132,7 @@ export function getPlatformTheme(platform: Platform): CosmosTheme {
|
|||
|
||||
return {
|
||||
...baseTheme,
|
||||
...cosmosThemeElements,
|
||||
...cosmosTheme,
|
||||
...sizeMappings[LayoutSize.Compact], // TODO: Allow for different layout sizes.
|
||||
};
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardCollection",
|
||||
|
@ -69,6 +72,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "conflictsCollection",
|
||||
|
@ -92,6 +98,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardDb",
|
||||
|
@ -102,6 +111,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
{
|
||||
"children": [
|
||||
{
|
||||
"iconSrc": <SettingsRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"id": "",
|
||||
"isSelected": [Function],
|
||||
"label": "Scale",
|
||||
|
@ -133,6 +145,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sampleItemsCollection",
|
||||
|
@ -156,6 +171,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sharedDatabase",
|
||||
|
@ -246,6 +264,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "schemaCollection",
|
||||
|
@ -274,6 +295,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Ca
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "giganticDatabase",
|
||||
|
@ -345,6 +369,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardCollection",
|
||||
|
@ -415,6 +442,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "conflictsCollection",
|
||||
|
@ -438,6 +468,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardDb",
|
||||
|
@ -448,6 +481,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
{
|
||||
"children": [
|
||||
{
|
||||
"iconSrc": <SettingsRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"id": "",
|
||||
"isSelected": [Function],
|
||||
"label": "Scale",
|
||||
|
@ -510,6 +546,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sampleItemsCollection",
|
||||
|
@ -533,6 +572,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sharedDatabase",
|
||||
|
@ -654,6 +696,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "schemaCollection",
|
||||
|
@ -682,6 +727,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "giganticDatabase",
|
||||
|
@ -706,6 +754,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardCollection",
|
||||
|
@ -724,6 +775,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "conflictsCollection",
|
||||
|
@ -747,6 +801,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardDb",
|
||||
|
@ -766,6 +823,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sampleItemsCollection",
|
||||
|
@ -789,6 +849,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sharedDatabase",
|
||||
|
@ -808,6 +871,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "schemaCollection",
|
||||
|
@ -836,6 +902,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "giganticDatabase",
|
||||
|
@ -976,6 +1045,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardCollection",
|
||||
|
@ -1076,6 +1148,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "conflictsCollection",
|
||||
|
@ -1099,6 +1174,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardDb",
|
||||
|
@ -1109,6 +1187,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
{
|
||||
"children": [
|
||||
{
|
||||
"iconSrc": <SettingsRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"id": "",
|
||||
"isSelected": [Function],
|
||||
"label": "Scale",
|
||||
|
@ -1201,6 +1282,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sampleItemsCollection",
|
||||
|
@ -1224,6 +1308,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sharedDatabase",
|
||||
|
@ -1375,6 +1462,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "schemaCollection",
|
||||
|
@ -1403,6 +1493,9 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the SQ
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "giganticDatabase",
|
||||
|
@ -1543,6 +1636,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardCollection",
|
||||
|
@ -1638,6 +1734,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "conflictsCollection",
|
||||
|
@ -1661,6 +1760,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "standardDb",
|
||||
|
@ -1671,6 +1773,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
{
|
||||
"children": [
|
||||
{
|
||||
"iconSrc": <SettingsRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"id": "",
|
||||
"isSelected": [Function],
|
||||
"label": "Scale",
|
||||
|
@ -1763,6 +1868,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sampleItemsCollection",
|
||||
|
@ -1786,6 +1894,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "sharedDatabase",
|
||||
|
@ -1937,6 +2048,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
"styleClass": "deleteCollectionMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "schemaCollection",
|
||||
|
@ -1965,6 +2079,9 @@ exports[`createDatabaseTreeNodes using NoSQL API on Hosted Platform creates expe
|
|||
"styleClass": "deleteDatabaseMenuItem",
|
||||
},
|
||||
],
|
||||
"iconSrc": <DatabaseRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "giganticDatabase",
|
||||
|
@ -1986,6 +2103,9 @@ exports[`createResourceTokenTreeNodes creates the expected tree nodes 1`] = `
|
|||
},
|
||||
],
|
||||
"className": "collectionNode",
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": true,
|
||||
"isSelected": [Function],
|
||||
"label": "testCollection",
|
||||
|
@ -2021,6 +2141,9 @@ exports[`createSampleDataTreeNodes creates the expected tree nodes 1`] = `
|
|||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"iconSrc": <DocumentMultipleRegular
|
||||
fontSize={16}
|
||||
/>,
|
||||
"isExpanded": false,
|
||||
"isSelected": [Function],
|
||||
"label": "testCollection",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { DatabaseRegular, DocumentMultipleRegular, SettingsRegular } from "@fluentui/react-icons";
|
||||
import { TreeNode } from "Explorer/Controls/TreeComponent/TreeNodeComponent";
|
||||
import TabsBase from "Explorer/Tabs/TabsBase";
|
||||
import StoredProcedure from "Explorer/Tree/StoredProcedure";
|
||||
|
@ -7,6 +8,7 @@ import { useDatabases } from "Explorer/useDatabases";
|
|||
import { getItemName } from "Utils/APITypeUtils";
|
||||
import { isServerlessAccount } from "Utils/CapabilityUtils";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import React from "react";
|
||||
import { isPublicInternetAccessAllowed } from "../../Common/DatabaseAccountUtility";
|
||||
import { Platform, configContext } from "../../ConfigContext";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
|
@ -25,6 +27,10 @@ export const shouldShowScriptNodes = (): boolean => {
|
|||
);
|
||||
};
|
||||
|
||||
const TreeDatabaseIcon = <DatabaseRegular fontSize={16} />;
|
||||
const TreeSettingsIcon = <SettingsRegular fontSize={16} />;
|
||||
const TreeCollectionIcon = <DocumentMultipleRegular fontSize={16} />;
|
||||
|
||||
export const createSampleDataTreeNodes = (sampleDataResourceTokenCollection: ViewModels.CollectionBase): TreeNode[] => {
|
||||
const updatedSampleTree: TreeNode = {
|
||||
label: sampleDataResourceTokenCollection.databaseId,
|
||||
|
@ -36,6 +42,7 @@ export const createSampleDataTreeNodes = (sampleDataResourceTokenCollection: Vie
|
|||
isExpanded: false,
|
||||
className: "collectionNode",
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createSampleCollectionContextMenuButton(),
|
||||
iconSrc: TreeCollectionIcon,
|
||||
onClick: () => {
|
||||
useSelectedNode.getState().setSelectedNode(sampleDataResourceTokenCollection);
|
||||
useCommandBar.getState().setContextButtons([]);
|
||||
|
@ -104,6 +111,7 @@ export const createResourceTokenTreeNodes = (collection: ViewModels.CollectionBa
|
|||
isExpanded: true,
|
||||
children,
|
||||
className: "collectionNode",
|
||||
iconSrc: TreeCollectionIcon,
|
||||
onClick: () => {
|
||||
// Rewritten version of expandCollapseCollection
|
||||
useSelectedNode.getState().setSelectedNode(collection);
|
||||
|
@ -133,6 +141,7 @@ export const createDatabaseTreeNodes = (
|
|||
databaseNode.children.push({
|
||||
id: database.isSampleDB ? "sampleScaleSettings" : "",
|
||||
label: "Scale",
|
||||
iconSrc: TreeSettingsIcon,
|
||||
isSelected: () =>
|
||||
useSelectedNode
|
||||
.getState()
|
||||
|
@ -169,6 +178,7 @@ export const createDatabaseTreeNodes = (
|
|||
children: [],
|
||||
isSelected: () => useSelectedNode.getState().isDataNodeSelected(database.id()),
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createDatabaseContextMenu(container, database.id()),
|
||||
iconSrc: TreeDatabaseIcon,
|
||||
onExpanded: async () => {
|
||||
useSelectedNode.getState().setSelectedNode(database);
|
||||
if (!databaseNode.children || databaseNode.children?.length === 0) {
|
||||
|
@ -219,6 +229,7 @@ export const buildCollectionNode = (
|
|||
children: children,
|
||||
className: "collectionNode",
|
||||
contextMenu: ResourceTreeContextMenuButtonFactory.createCollectionContextMenuButton(container, collection),
|
||||
iconSrc: TreeCollectionIcon,
|
||||
onClick: () => {
|
||||
useSelectedNode.getState().setSelectedNode(collection);
|
||||
collection.openTab();
|
|
@ -52,7 +52,7 @@ export const isAccountRestrictedForConnectionStringLogin = async (connectionStri
|
|||
const headers = new Headers();
|
||||
headers.append(HttpHeaders.connectionString, connectionString);
|
||||
|
||||
const backendEndpoint: string = useNewPortalBackendEndpoint(BackendApi.PortalSettings)
|
||||
const backendEndpoint: string = useNewPortalBackendEndpoint(BackendApi.AccountRestrictions)
|
||||
? configContext.PORTAL_BACKEND_ENDPOINT
|
||||
: configContext.BACKEND_ENDPOINT;
|
||||
|
||||
|
|
|
@ -58,10 +58,10 @@ export const getRUThreshold = (): number => {
|
|||
|
||||
export const getDefaultQueryResultsView = (): SplitterDirection => {
|
||||
const defaultQueryResultsViewRaw = LocalStorageUtility.getEntryString(StorageKey.DefaultQueryResultsView);
|
||||
if (defaultQueryResultsViewRaw === SplitterDirection.Horizontal) {
|
||||
return SplitterDirection.Horizontal;
|
||||
if (defaultQueryResultsViewRaw === SplitterDirection.Vertical) {
|
||||
return SplitterDirection.Vertical;
|
||||
}
|
||||
return SplitterDirection.Vertical;
|
||||
return SplitterDirection.Horizontal;
|
||||
};
|
||||
|
||||
export const DefaultRUThreshold = 5000;
|
||||
|
|
|
@ -52,7 +52,11 @@ export const defaultAllowedArmEndpoints: ReadonlyArray<string> = [
|
|||
"https://management.chinacloudapi.cn",
|
||||
];
|
||||
|
||||
export const allowedAadEndpoints: ReadonlyArray<string> = ["https://login.microsoftonline.com/"];
|
||||
export const allowedAadEndpoints: ReadonlyArray<string> = [
|
||||
"https://login.microsoftonline.com/",
|
||||
"https://login.microsoftonline.us/",
|
||||
"https://login.partner.microsoftonline.cn/",
|
||||
];
|
||||
|
||||
export const defaultAllowedBackendEndpoints: ReadonlyArray<string> = [
|
||||
"https://main.documentdb.ext.azure.com",
|
||||
|
@ -74,6 +78,13 @@ export const PortalBackendIPs: { [key: string]: string[] } = {
|
|||
//usnat: ["7.28.202.68"],
|
||||
};
|
||||
|
||||
export const PortalBackendOutboundIPs: { [key: string]: string[] } = {
|
||||
[PortalBackendEndpoints.Mpac]: ["13.91.105.215", "4.210.172.107"],
|
||||
[PortalBackendEndpoints.Prod]: ["13.88.56.148", "40.91.218.243"],
|
||||
[PortalBackendEndpoints.Fairfax]: ["52.247.163.6", "52.244.134.181"],
|
||||
[PortalBackendEndpoints.Mooncake]: ["163.228.137.6", "143.64.170.142"],
|
||||
};
|
||||
|
||||
export const MongoProxyOutboundIPs: { [key: string]: string[] } = {
|
||||
[MongoProxyEndpoints.Mpac]: ["20.245.81.54", "40.118.23.126"],
|
||||
[MongoProxyEndpoints.Prod]: ["40.80.152.199", "13.95.130.121"],
|
||||
|
@ -164,7 +175,23 @@ export function useNewPortalBackendEndpoint(backendApi: string): boolean {
|
|||
PortalBackendEndpoints.Mpac,
|
||||
PortalBackendEndpoints.Prod,
|
||||
],
|
||||
[BackendApi.AccountRestrictions]: [PortalBackendEndpoints.Development, PortalBackendEndpoints.Mpac],
|
||||
[BackendApi.AccountRestrictions]: [
|
||||
PortalBackendEndpoints.Development,
|
||||
PortalBackendEndpoints.Mpac,
|
||||
PortalBackendEndpoints.Prod,
|
||||
],
|
||||
[BackendApi.RuntimeProxy]: [
|
||||
PortalBackendEndpoints.Development,
|
||||
PortalBackendEndpoints.Mpac,
|
||||
PortalBackendEndpoints.Prod,
|
||||
],
|
||||
[BackendApi.DisallowedLocations]: [
|
||||
PortalBackendEndpoints.Development,
|
||||
PortalBackendEndpoints.Mpac,
|
||||
PortalBackendEndpoints.Prod,
|
||||
PortalBackendEndpoints.Fairfax,
|
||||
PortalBackendEndpoints.Mooncake,
|
||||
],
|
||||
};
|
||||
|
||||
if (!newBackendApiEnvironmentMap[backendApi] || !configContext.PORTAL_BACKEND_ENDPOINT) {
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
import { MongoProxyEndpoints, PortalBackendEndpoints } from "Common/Constants";
|
||||
import { resetConfigContext, updateConfigContext } from "ConfigContext";
|
||||
import { DatabaseAccount, IpRule } from "Contracts/DataModels";
|
||||
import { updateUserContext } from "UserContext";
|
||||
import { PortalBackendIPs } from "Utils/EndpointUtils";
|
||||
import { MongoProxyOutboundIPs, PortalBackendIPs, PortalBackendOutboundIPs } from "Utils/EndpointUtils";
|
||||
import { getNetworkSettingsWarningMessage } from "./NetworkUtility";
|
||||
|
||||
describe("NetworkUtility tests", () => {
|
||||
describe("getNetworkSettingsWarningMessage", () => {
|
||||
const legacyBackendEndpoint: string = "https://main.documentdb.ext.azure.com";
|
||||
const publicAccessMessagePart = "Please enable public access to proceed";
|
||||
const accessMessagePart = "Please allow access from Azure Portal to proceed";
|
||||
// validEnpoints are a subset of those from Utils/EndpointValidation/PortalBackendIPs
|
||||
const validEndpoints = [
|
||||
"https://main.documentdb.ext.azure.com",
|
||||
"https://main.documentdb.ext.azure.cn",
|
||||
"https://main.documentdb.ext.azure.us",
|
||||
];
|
||||
|
||||
let warningMessageResult: string;
|
||||
const warningMessageFunc = (msg: string) => (warningMessageResult = msg);
|
||||
|
||||
|
@ -52,52 +47,59 @@ describe("NetworkUtility tests", () => {
|
|||
expect(warningMessageResult).toContain(publicAccessMessagePart);
|
||||
});
|
||||
|
||||
it(`should return no message when the appropriate ip rules are added to mongo/cassandra account per endpoint`, () => {
|
||||
validEndpoints.forEach(async (endpoint) => {
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
kind: "MongoDB",
|
||||
properties: {
|
||||
ipRules: PortalBackendIPs[endpoint].map((ip: string) => ({ ipAddressOrRange: ip }) as IpRule),
|
||||
publicNetworkAccess: "Enabled",
|
||||
},
|
||||
} as DatabaseAccount,
|
||||
});
|
||||
|
||||
updateConfigContext({
|
||||
BACKEND_ENDPOINT: endpoint,
|
||||
});
|
||||
|
||||
let asyncWarningMessageResult: string;
|
||||
const asyncWarningMessageFunc = (msg: string) => (asyncWarningMessageResult = msg);
|
||||
|
||||
await getNetworkSettingsWarningMessage(asyncWarningMessageFunc);
|
||||
expect(asyncWarningMessageResult).toBeUndefined();
|
||||
it(`should return no message when the appropriate ip rules are added to mongo/cassandra account per endpoint`, async () => {
|
||||
const portalBackendOutboundIPsWithLegacyIPs: string[] = [
|
||||
...PortalBackendOutboundIPs[PortalBackendEndpoints.Mpac],
|
||||
...PortalBackendOutboundIPs[PortalBackendEndpoints.Prod],
|
||||
...MongoProxyOutboundIPs[MongoProxyEndpoints.Mpac],
|
||||
...MongoProxyOutboundIPs[MongoProxyEndpoints.Prod],
|
||||
...PortalBackendIPs["https://main.documentdb.ext.azure.com"],
|
||||
];
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
kind: "MongoDB",
|
||||
properties: {
|
||||
ipRules: portalBackendOutboundIPsWithLegacyIPs.map((ip: string) => ({ ipAddressOrRange: ip }) as IpRule),
|
||||
publicNetworkAccess: "Enabled",
|
||||
},
|
||||
} as DatabaseAccount,
|
||||
});
|
||||
|
||||
updateConfigContext({
|
||||
BACKEND_ENDPOINT: legacyBackendEndpoint,
|
||||
PORTAL_BACKEND_ENDPOINT: PortalBackendEndpoints.Mpac,
|
||||
MONGO_PROXY_ENDPOINT: MongoProxyEndpoints.Mpac,
|
||||
});
|
||||
|
||||
let asyncWarningMessageResult: string;
|
||||
const asyncWarningMessageFunc = (msg: string) => (asyncWarningMessageResult = msg);
|
||||
|
||||
await getNetworkSettingsWarningMessage(asyncWarningMessageFunc);
|
||||
expect(asyncWarningMessageResult).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should return accessMessage when incorrent ip rule is added to mongo/cassandra account per endpoint", () => {
|
||||
validEndpoints.forEach(async (endpoint) => {
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
kind: "MongoDB",
|
||||
properties: {
|
||||
ipRules: [{ ipAddressOrRange: "1.1.1.1" }],
|
||||
publicNetworkAccess: "Enabled",
|
||||
},
|
||||
} as DatabaseAccount,
|
||||
});
|
||||
|
||||
updateConfigContext({
|
||||
BACKEND_ENDPOINT: endpoint,
|
||||
});
|
||||
|
||||
let asyncWarningMessageResult: string;
|
||||
const asyncWarningMessageFunc = (msg: string) => (asyncWarningMessageResult = msg);
|
||||
|
||||
await getNetworkSettingsWarningMessage(asyncWarningMessageFunc);
|
||||
expect(asyncWarningMessageResult).toContain(accessMessagePart);
|
||||
it("should return accessMessage when incorrent ip rule is added to mongo/cassandra account per endpoint", async () => {
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
kind: "MongoDB",
|
||||
properties: {
|
||||
ipRules: [{ ipAddressOrRange: "1.1.1.1" }],
|
||||
publicNetworkAccess: "Enabled",
|
||||
},
|
||||
} as DatabaseAccount,
|
||||
});
|
||||
|
||||
updateConfigContext({
|
||||
BACKEND_ENDPOINT: legacyBackendEndpoint,
|
||||
PORTAL_BACKEND_ENDPOINT: PortalBackendEndpoints.Mpac,
|
||||
MONGO_PROXY_ENDPOINT: MongoProxyEndpoints.Mpac,
|
||||
});
|
||||
|
||||
let asyncWarningMessageResult: string;
|
||||
const asyncWarningMessageFunc = (msg: string) => (asyncWarningMessageResult = msg);
|
||||
|
||||
await getNetworkSettingsWarningMessage(asyncWarningMessageFunc);
|
||||
expect(asyncWarningMessageResult).toContain(accessMessagePart);
|
||||
});
|
||||
|
||||
// Postgres and vcore mongo account checks basically pass through to CheckFirewallRules so those
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import { CassandraProxyEndpoints, MongoProxyEndpoints, PortalBackendEndpoints } from "Common/Constants";
|
||||
import { configContext } from "ConfigContext";
|
||||
import { checkFirewallRules } from "Explorer/Tabs/Shared/CheckFirewallRules";
|
||||
import { userContext } from "UserContext";
|
||||
import { PortalBackendIPs } from "Utils/EndpointUtils";
|
||||
import {
|
||||
CassandraProxyOutboundIPs,
|
||||
MongoProxyOutboundIPs,
|
||||
PortalBackendIPs,
|
||||
PortalBackendOutboundIPs,
|
||||
} from "Utils/EndpointUtils";
|
||||
|
||||
export const getNetworkSettingsWarningMessage = async (
|
||||
setStateFunc: (warningMessage: string) => void,
|
||||
|
@ -45,18 +51,53 @@ export const getNetworkSettingsWarningMessage = async (
|
|||
const ipRules = accountProperties.ipRules;
|
||||
// public network access is NOT set to "All networks"
|
||||
if (ipRules?.length > 0) {
|
||||
if (userContext.apiType === "Cassandra" || userContext.apiType === "Mongo") {
|
||||
const portalIPs = PortalBackendIPs[configContext.BACKEND_ENDPOINT];
|
||||
let numberOfMatches = 0;
|
||||
ipRules.forEach((ipRule) => {
|
||||
if (portalIPs.indexOf(ipRule.ipAddressOrRange) !== -1) {
|
||||
numberOfMatches++;
|
||||
}
|
||||
});
|
||||
const isProdOrMpacPortalBackendEndpoint: boolean = [
|
||||
PortalBackendEndpoints.Mpac,
|
||||
PortalBackendEndpoints.Prod,
|
||||
].includes(configContext.PORTAL_BACKEND_ENDPOINT);
|
||||
const portalBackendOutboundIPs: string[] = isProdOrMpacPortalBackendEndpoint
|
||||
? [
|
||||
...PortalBackendOutboundIPs[PortalBackendEndpoints.Mpac],
|
||||
...PortalBackendOutboundIPs[PortalBackendEndpoints.Prod],
|
||||
]
|
||||
: PortalBackendOutboundIPs[configContext.PORTAL_BACKEND_ENDPOINT];
|
||||
let portalIPs: string[] = [...portalBackendOutboundIPs, ...PortalBackendIPs[configContext.BACKEND_ENDPOINT]];
|
||||
|
||||
if (numberOfMatches !== portalIPs.length) {
|
||||
setStateFunc(accessMessage);
|
||||
if (userContext.apiType === "Mongo") {
|
||||
const isProdOrMpacMongoProxyEndpoint: boolean = [MongoProxyEndpoints.Mpac, MongoProxyEndpoints.Prod].includes(
|
||||
configContext.MONGO_PROXY_ENDPOINT,
|
||||
);
|
||||
|
||||
const mongoProxyOutboundIPs: string[] = isProdOrMpacMongoProxyEndpoint
|
||||
? [...MongoProxyOutboundIPs[MongoProxyEndpoints.Mpac], ...MongoProxyOutboundIPs[MongoProxyEndpoints.Prod]]
|
||||
: MongoProxyOutboundIPs[configContext.MONGO_PROXY_ENDPOINT];
|
||||
|
||||
portalIPs = [...portalIPs, ...mongoProxyOutboundIPs];
|
||||
} else if (userContext.apiType === "Cassandra") {
|
||||
const isProdOrMpacCassandraProxyEndpoint: boolean = [
|
||||
CassandraProxyEndpoints.Mpac,
|
||||
CassandraProxyEndpoints.Prod,
|
||||
].includes(configContext.CASSANDRA_PROXY_ENDPOINT);
|
||||
|
||||
const cassandraProxyOutboundIPs: string[] = isProdOrMpacCassandraProxyEndpoint
|
||||
? [
|
||||
...CassandraProxyOutboundIPs[CassandraProxyEndpoints.Mpac],
|
||||
...CassandraProxyOutboundIPs[CassandraProxyEndpoints.Prod],
|
||||
]
|
||||
: CassandraProxyOutboundIPs[configContext.CASSANDRA_PROXY_ENDPOINT];
|
||||
|
||||
portalIPs = [...portalIPs, ...cassandraProxyOutboundIPs];
|
||||
}
|
||||
|
||||
let numberOfMatches = 0;
|
||||
ipRules.forEach((ipRule) => {
|
||||
if (portalIPs.indexOf(ipRule.ipAddressOrRange) !== -1) {
|
||||
numberOfMatches++;
|
||||
}
|
||||
});
|
||||
|
||||
if (numberOfMatches !== portalIPs.length) {
|
||||
setStateFunc(accessMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,5 +147,33 @@ describe("Query Utils", () => {
|
|||
expect(expectedPartitionKeyValues).toContain(documentContent["Type"]);
|
||||
expect(expectedPartitionKeyValues).toContain(documentContent["Status"]);
|
||||
});
|
||||
|
||||
it("should extract three partition key values even if one is empty", () => {
|
||||
const multiPartitionKeyDefinition: PartitionKeyDefinition = {
|
||||
kind: PartitionKeyKind.MultiHash,
|
||||
paths: ["/Country", "/Region", "/Category"],
|
||||
};
|
||||
const expectedPartitionKeyValues: string[] = ["United States", "US-Washington", ""];
|
||||
const partitioinKeyValues: PartitionKey[] = extractPartitionKeyValues(
|
||||
documentContent,
|
||||
multiPartitionKeyDefinition,
|
||||
);
|
||||
expect(partitioinKeyValues.length).toBe(3);
|
||||
expect(expectedPartitionKeyValues).toContain(documentContent["Country"]);
|
||||
expect(expectedPartitionKeyValues).toContain(documentContent["Region"]);
|
||||
expect(expectedPartitionKeyValues).toContain(documentContent["Category"]);
|
||||
});
|
||||
|
||||
it("should extract no partition key values in the case nested partition key", () => {
|
||||
const singlePartitionKeyDefinition: PartitionKeyDefinition = {
|
||||
kind: PartitionKeyKind.Hash,
|
||||
paths: ["/Location.type"],
|
||||
};
|
||||
const partitionKeyValues: PartitionKey[] = extractPartitionKeyValues(
|
||||
documentContent,
|
||||
singlePartitionKeyDefinition,
|
||||
);
|
||||
expect(partitionKeyValues.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -106,7 +106,7 @@ export const extractPartitionKeyValues = (
|
|||
const partitionKeyValues: PartitionKey[] = [];
|
||||
partitionKeyDefinition.paths.forEach((partitionKeyPath: string) => {
|
||||
const partitionKeyPathWithoutSlash: string = partitionKeyPath.substring(1);
|
||||
if (documentContent[partitionKeyPathWithoutSlash]) {
|
||||
if (documentContent[partitionKeyPathWithoutSlash] !== undefined) {
|
||||
partitionKeyValues.push(documentContent[partitionKeyPathWithoutSlash]);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -619,6 +619,31 @@ function shouldForwardMessage(message: PortalMessage, messageOrigin: string) {
|
|||
return messageOrigin === window.document.location.origin && message.type === MessageTypes.TelemetryInfo;
|
||||
}
|
||||
|
||||
function updateAADEndpoints(portalEnv: PortalEnv) {
|
||||
switch (portalEnv) {
|
||||
case "prod1":
|
||||
case "prod":
|
||||
updateConfigContext({
|
||||
AAD_ENDPOINT: Constants.AadEndpoints.Prod,
|
||||
});
|
||||
break;
|
||||
case "fairfax":
|
||||
updateConfigContext({
|
||||
AAD_ENDPOINT: Constants.AadEndpoints.Fairfax,
|
||||
});
|
||||
break;
|
||||
case "mooncake":
|
||||
updateConfigContext({
|
||||
AAD_ENDPOINT: Constants.AadEndpoints.Mooncake,
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn(`Unknown portal environment: ${portalEnv}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) {
|
||||
if (
|
||||
configContext.BACKEND_ENDPOINT &&
|
||||
|
@ -639,6 +664,8 @@ function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) {
|
|||
PORTAL_BACKEND_ENDPOINT: inputs.portalBackendEndpoint,
|
||||
});
|
||||
|
||||
updateAADEndpoints(inputs.serverId as PortalEnv);
|
||||
|
||||
updateUserContext({
|
||||
authorizationToken,
|
||||
databaseAccount,
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { ApiEndpoints } from "../Common/Constants";
|
||||
import { useNewPortalBackendEndpoint } from "Utils/EndpointUtils";
|
||||
import { ApiEndpoints, BackendApi, HttpHeaders } from "../Common/Constants";
|
||||
import { configContext } from "../ConfigContext";
|
||||
import { AccessInputMetadata } from "../Contracts/DataModels";
|
||||
|
||||
const url = `${configContext.BACKEND_ENDPOINT}${ApiEndpoints.guestRuntimeProxy}/accessinputmetadata?_=1609359229955`;
|
||||
|
||||
export async function fetchAccessData(portalToken: string): Promise<AccessInputMetadata> {
|
||||
if (!useNewPortalBackendEndpoint(BackendApi.RuntimeProxy)) {
|
||||
return fetchAccessData_ToBeDeprecated(portalToken);
|
||||
}
|
||||
|
||||
const headers = new Headers();
|
||||
// Portal encrypted token API quirk: The token header must be URL encoded
|
||||
headers.append("x-ms-encrypted-auth-token", encodeURIComponent(portalToken));
|
||||
headers.append(HttpHeaders.guestAccessToken, encodeURIComponent(portalToken));
|
||||
const url: string = `${configContext.PORTAL_BACKEND_ENDPOINT}/api/connectionstring/runtimeproxy/accessinputmetadata`;
|
||||
const options = {
|
||||
method: "GET",
|
||||
headers: headers,
|
||||
};
|
||||
|
||||
return fetch(url, options)
|
||||
.then((response) => response.json())
|
||||
.catch((error) => console.error(error));
|
||||
}
|
||||
|
||||
export async function fetchAccessData_ToBeDeprecated(portalToken: string): Promise<AccessInputMetadata> {
|
||||
const headers = new Headers();
|
||||
// Portal encrypted token API quirk: The token header must be URL encoded
|
||||
headers.append(HttpHeaders.guestAccessToken, encodeURIComponent(portalToken));
|
||||
|
||||
const options = {
|
||||
method: "GET",
|
||||
|
|
Loading…
Reference in New Issue