mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-05-10 18:33:52 +01:00
Fabric native improvements: Settings pane, Partition Key settings tab, sample data and message contract (#2119)
* Hide entire Accordion of options in Settings Pane * In PartitionKeyComponent hide "Change partition key" label when read-only. * Create sample data container with correct pkey * Add unit tests to PartitionKeyComponent * Fix format * fix unit test snapshot * Add Fabric message to open Settings to given tab id * Improve syntax on message contract * Remove "(preview)" in partition key tab title in Settings Tab
This commit is contained in:
parent
274c85d2de
commit
2f858ecf9b
@ -18,10 +18,13 @@ export type DataExploreMessageV3 =
|
|||||||
| {
|
| {
|
||||||
type: FabricMessageTypes.GetAllResourceTokens;
|
type: FabricMessageTypes.GetAllResourceTokens;
|
||||||
id: string;
|
id: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: FabricMessageTypes.OpenSettings;
|
||||||
|
settingsId: string;
|
||||||
};
|
};
|
||||||
|
export interface GetCosmosTokenMessageOptions {
|
||||||
export type GetCosmosTokenMessageOptions = {
|
|
||||||
verb: "connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put" | "trace";
|
verb: "connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put" | "trace";
|
||||||
resourceType: "" | "dbs" | "colls" | "docs" | "sprocs" | "pkranges";
|
resourceType: "" | "dbs" | "colls" | "docs" | "sprocs" | "pkranges";
|
||||||
resourceId: string;
|
resourceId: string;
|
||||||
};
|
}
|
||||||
|
@ -6,6 +6,7 @@ export enum FabricMessageTypes {
|
|||||||
GetAllResourceTokens = "GetAllResourceTokens",
|
GetAllResourceTokens = "GetAllResourceTokens",
|
||||||
GetAccessToken = "GetAccessToken",
|
GetAccessToken = "GetAccessToken",
|
||||||
Ready = "Ready",
|
Ready = "Ready",
|
||||||
|
OpenSettings = "OpenSettings",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AuthorizationToken {
|
export interface AuthorizationToken {
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
import { shallow } from "enzyme";
|
||||||
|
import {
|
||||||
|
PartitionKeyComponent,
|
||||||
|
PartitionKeyComponentProps,
|
||||||
|
} from "Explorer/Controls/Settings/SettingsSubComponents/PartitionKeyComponent";
|
||||||
|
import Explorer from "Explorer/Explorer";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
describe("PartitionKeyComponent", () => {
|
||||||
|
// Create a test setup function to get fresh instances for each test
|
||||||
|
const setupTest = () => {
|
||||||
|
// Create an instance of the mocked Explorer
|
||||||
|
const explorer = new Explorer();
|
||||||
|
// Create minimal mock objects for database and collection
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const mockDatabase = {} as any as import("../../../../Contracts/ViewModels").Database;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const mockCollection = {} as any as import("../../../../Contracts/ViewModels").Collection;
|
||||||
|
|
||||||
|
// Create props with the mocked Explorer instance
|
||||||
|
const props: PartitionKeyComponentProps = {
|
||||||
|
database: mockDatabase,
|
||||||
|
collection: mockCollection,
|
||||||
|
explorer,
|
||||||
|
};
|
||||||
|
|
||||||
|
return { explorer, props };
|
||||||
|
};
|
||||||
|
|
||||||
|
it("renders default component and matches snapshot", () => {
|
||||||
|
const { props } = setupTest();
|
||||||
|
const wrapper = shallow(<PartitionKeyComponent {...props} />);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders read-only component and matches snapshot", () => {
|
||||||
|
const { props } = setupTest();
|
||||||
|
const wrapper = shallow(<PartitionKeyComponent {...props} isReadOnly={true} />);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
@ -161,7 +161,7 @@ export const PartitionKeyComponent: React.FC<PartitionKeyComponentProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Stack tokens={{ childrenGap: 20 }} styles={{ root: { maxWidth: 600 } }}>
|
<Stack tokens={{ childrenGap: 20 }} styles={{ root: { maxWidth: 600 } }}>
|
||||||
<Stack tokens={{ childrenGap: 10 }}>
|
<Stack tokens={{ childrenGap: 10 }}>
|
||||||
<Text styles={textHeadingStyle}>Change {partitionKeyName.toLowerCase()}</Text>
|
{!isReadOnly && <Text styles={textHeadingStyle}>Change {partitionKeyName.toLowerCase()}</Text>}
|
||||||
<Stack horizontal tokens={{ childrenGap: 20 }}>
|
<Stack horizontal tokens={{ childrenGap: 20 }}>
|
||||||
<Stack tokens={{ childrenGap: 5 }}>
|
<Stack tokens={{ childrenGap: 5 }}>
|
||||||
<Text styles={textSubHeadingStyle}>Current {partitionKeyName.toLowerCase()}</Text>
|
<Text styles={textSubHeadingStyle}>Current {partitionKeyName.toLowerCase()}</Text>
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`PartitionKeyComponent renders default component and matches snapshot 1`] = `
|
||||||
|
<Stack
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"maxWidth": 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Change
|
||||||
|
partition key
|
||||||
|
</Text>
|
||||||
|
<Stack
|
||||||
|
horizontal={true}
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"fontWeight": 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Current
|
||||||
|
partition key
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"fontWeight": 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Partitioning
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text />
|
||||||
|
<Text>
|
||||||
|
Non-hierarchical
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
<StyledMessageBar
|
||||||
|
messageBarType={5}
|
||||||
|
>
|
||||||
|
To safeguard the integrity of the data being copied to the new container, ensure that no updates are made to the source container for the entire duration of the partition key change process.
|
||||||
|
<StyledLinkBase
|
||||||
|
href="https://learn.microsoft.com/azure/cosmos-db/container-copy#how-does-container-copy-work"
|
||||||
|
target="_blank"
|
||||||
|
underline={true}
|
||||||
|
>
|
||||||
|
Learn more
|
||||||
|
</StyledLinkBase>
|
||||||
|
</StyledMessageBar>
|
||||||
|
<Text>
|
||||||
|
To change the partition key, a new destination container must be created or an existing destination container selected. Data will then be copied to the destination container.
|
||||||
|
</Text>
|
||||||
|
<CustomizedPrimaryButton
|
||||||
|
onClick={[Function]}
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"width": "fit-content",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text="Change"
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`PartitionKeyComponent renders read-only component and matches snapshot 1`] = `
|
||||||
|
<Stack
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"maxWidth": 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
horizontal={true}
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Stack
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"fontWeight": 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Current
|
||||||
|
partition key
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"root": {
|
||||||
|
"fontWeight": 600,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Partitioning
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
tokens={
|
||||||
|
{
|
||||||
|
"childrenGap": 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text />
|
||||||
|
<Text>
|
||||||
|
Non-hierarchical
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
`;
|
@ -1,6 +1,7 @@
|
|||||||
import * as Constants from "../../../Common/Constants";
|
import * as Constants from "../../../Common/Constants";
|
||||||
import * as DataModels from "../../../Contracts/DataModels";
|
import * as DataModels from "../../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||||
|
import { isFabricNative } from "../../../Platform/Fabric/FabricUtil";
|
||||||
import { MongoIndex } from "../../../Utils/arm/generatedClients/cosmos/types";
|
import { MongoIndex } from "../../../Utils/arm/generatedClients/cosmos/types";
|
||||||
|
|
||||||
const zeroValue = 0;
|
const zeroValue = 0;
|
||||||
@ -165,7 +166,7 @@ export const getTabTitle = (tab: SettingsV2TabTypes): string => {
|
|||||||
case SettingsV2TabTypes.IndexingPolicyTab:
|
case SettingsV2TabTypes.IndexingPolicyTab:
|
||||||
return "Indexing Policy";
|
return "Indexing Policy";
|
||||||
case SettingsV2TabTypes.PartitionKeyTab:
|
case SettingsV2TabTypes.PartitionKeyTab:
|
||||||
return "Partition Keys (preview)";
|
return isFabricNative() ? "Partition Keys" : "Partition Keys (preview)";
|
||||||
case SettingsV2TabTypes.ComputedPropertiesTab:
|
case SettingsV2TabTypes.ComputedPropertiesTab:
|
||||||
return "Computed Properties";
|
return "Computed Properties";
|
||||||
case SettingsV2TabTypes.ContainerVectorPolicyTab:
|
case SettingsV2TabTypes.ContainerVectorPolicyTab:
|
||||||
|
@ -23,7 +23,7 @@ import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
|
|||||||
import { Platform, configContext } from "ConfigContext";
|
import { Platform, configContext } from "ConfigContext";
|
||||||
import { useDialog } from "Explorer/Controls/Dialog";
|
import { useDialog } from "Explorer/Controls/Dialog";
|
||||||
import { useDatabases } from "Explorer/useDatabases";
|
import { useDatabases } from "Explorer/useDatabases";
|
||||||
import { isFabric } from "Platform/Fabric/FabricUtil";
|
import { isFabric, isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||||
import {
|
import {
|
||||||
AppStateComponentNames,
|
AppStateComponentNames,
|
||||||
deleteAllStates,
|
deleteAllStates,
|
||||||
@ -607,441 +607,447 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
return (
|
return (
|
||||||
<RightPaneForm {...genericPaneProps}>
|
<RightPaneForm {...genericPaneProps}>
|
||||||
<div className={`paneMainContent ${styles.container}`}>
|
<div className={`paneMainContent ${styles.container}`}>
|
||||||
<Accordion className={`customAccordion ${styles.firstItem}`}>
|
{!isFabricNative() && (
|
||||||
{shouldShowQueryPageOptions && (
|
<Accordion className={`customAccordion ${styles.firstItem}`}>
|
||||||
<AccordionItem value="1">
|
{shouldShowQueryPageOptions && (
|
||||||
<AccordionHeader>
|
<AccordionItem value="1">
|
||||||
<div className={styles.header}>Page Options</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Choose Custom to specify a fixed amount of query results to show, or choose Unlimited to show as
|
|
||||||
many query results per page.
|
|
||||||
</div>
|
|
||||||
<ChoiceGroup
|
|
||||||
ariaLabelledBy="pageOptions"
|
|
||||||
selectedKey={pageOption}
|
|
||||||
options={pageOptionList}
|
|
||||||
styles={choiceButtonStyles}
|
|
||||||
onChange={handleOnPageOptionChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={`tabs ${styles.settingsSectionContainer}`}>
|
|
||||||
{isCustomPageOptionSelected() && (
|
|
||||||
<div className="tabcontent">
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Query results per page{" "}
|
|
||||||
<InfoTooltip className={styles.headerIcon}>
|
|
||||||
Enter the number of query results that should be shown per page.
|
|
||||||
</InfoTooltip>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<SpinButton
|
|
||||||
ariaLabel="Custom query items per page"
|
|
||||||
value={"" + customItemPerPage}
|
|
||||||
onIncrement={(newValue) => {
|
|
||||||
setCustomItemPerPage(parseInt(newValue) + 1 || customItemPerPage);
|
|
||||||
}}
|
|
||||||
onDecrement={(newValue) => setCustomItemPerPage(parseInt(newValue) - 1 || customItemPerPage)}
|
|
||||||
onValidate={(newValue) => setCustomItemPerPage(parseInt(newValue) || customItemPerPage)}
|
|
||||||
min={1}
|
|
||||||
step={1}
|
|
||||||
className="textfontclr"
|
|
||||||
incrementButtonAriaLabel="Increase value by 1"
|
|
||||||
decrementButtonAriaLabel="Decrease value by 1"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
{showEnableEntraIdRbac && (
|
|
||||||
<AccordionItem value="2">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>Enable Entra ID RBAC</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Choose Automatic to enable Entra ID RBAC automatically. True/False to force enable/disable Entra ID
|
|
||||||
RBAC.
|
|
||||||
<a
|
|
||||||
href="https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac#use-data-explorer"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{" "}
|
|
||||||
Learn more{" "}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<ChoiceGroup
|
|
||||||
ariaLabelledBy="enableDataPlaneRBACOptions"
|
|
||||||
options={dataPlaneRBACOptionsList}
|
|
||||||
styles={choiceButtonStyles}
|
|
||||||
selectedKey={enableDataPlaneRBACOption}
|
|
||||||
onChange={handleOnDataPlaneRBACOptionChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
{userContext.apiType === "SQL" && userContext.authType === AuthType.AAD && !isFabric() && (
|
|
||||||
<AccordionItem value="3">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>Region Selection</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Changes region the Cosmos Client uses to access account.
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span className={styles.subHeader}>Select Region</span>
|
|
||||||
<InfoTooltip className={styles.headerIcon}>
|
|
||||||
Changes the account endpoint used to perform client operations.
|
|
||||||
</InfoTooltip>
|
|
||||||
</div>
|
|
||||||
<Dropdown
|
|
||||||
placeholder={
|
|
||||||
selectedRegionalEndpoint
|
|
||||||
? regionOptions.find((option) => option.key === selectedRegionalEndpoint)?.text
|
|
||||||
: regionOptions[0]?.text
|
|
||||||
}
|
|
||||||
onChange={handleOnSelectedRegionOptionChange}
|
|
||||||
options={regionOptions}
|
|
||||||
styles={{ root: { marginBottom: "10px" } }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
{userContext.apiType === "SQL" && !isEmulator && (
|
|
||||||
<>
|
|
||||||
<AccordionItem value="4">
|
|
||||||
<AccordionHeader>
|
<AccordionHeader>
|
||||||
<div className={styles.header}>Query Timeout</div>
|
<div className={styles.header}>Page Options</div>
|
||||||
</AccordionHeader>
|
</AccordionHeader>
|
||||||
<AccordionPanel>
|
<AccordionPanel>
|
||||||
<div className={styles.settingsSectionContainer}>
|
<div className={styles.settingsSectionContainer}>
|
||||||
<div className={styles.settingsSectionDescription}>
|
<div className={styles.settingsSectionDescription}>
|
||||||
When a query reaches a specified time limit, a popup with an option to cancel the query will show
|
Choose Custom to specify a fixed amount of query results to show, or choose Unlimited to show as
|
||||||
unless automatic cancellation has been enabled.
|
many query results per page.
|
||||||
</div>
|
|
||||||
<Toggle
|
|
||||||
styles={toggleStyles}
|
|
||||||
label="Enable query timeout"
|
|
||||||
onChange={handleOnQueryTimeoutToggleChange}
|
|
||||||
defaultChecked={queryTimeoutEnabled}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{queryTimeoutEnabled && (
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<SpinButton
|
|
||||||
label="Query timeout (ms)"
|
|
||||||
labelPosition={Position.top}
|
|
||||||
defaultValue={(queryTimeout || 5000).toString()}
|
|
||||||
min={100}
|
|
||||||
step={1000}
|
|
||||||
onChange={handleOnQueryTimeoutSpinButtonChange}
|
|
||||||
incrementButtonAriaLabel="Increase value by 1000"
|
|
||||||
decrementButtonAriaLabel="Decrease value by 1000"
|
|
||||||
styles={spinButtonStyles}
|
|
||||||
/>
|
|
||||||
<Toggle
|
|
||||||
label="Automatically cancel query after timeout"
|
|
||||||
styles={toggleStyles}
|
|
||||||
onChange={handleOnAutomaticallyCancelQueryToggleChange}
|
|
||||||
defaultChecked={automaticallyCancelQueryAfterTimeout}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
|
|
||||||
<AccordionItem value="5">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>RU Limit</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
If a query exceeds a configured RU limit, the query will be aborted.
|
|
||||||
</div>
|
|
||||||
<Toggle
|
|
||||||
styles={toggleStyles}
|
|
||||||
label="Enable RU limit"
|
|
||||||
onChange={handleOnRUThresholdToggleChange}
|
|
||||||
defaultChecked={ruThresholdEnabled}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{ruThresholdEnabled && (
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<SpinButton
|
|
||||||
label="RU Limit (RU)"
|
|
||||||
labelPosition={Position.top}
|
|
||||||
defaultValue={(ruThreshold || DefaultRUThreshold).toString()}
|
|
||||||
min={1}
|
|
||||||
step={1000}
|
|
||||||
onChange={handleOnRUThresholdSpinButtonChange}
|
|
||||||
incrementButtonAriaLabel="Increase value by 1000"
|
|
||||||
decrementButtonAriaLabel="Decrease value by 1000"
|
|
||||||
styles={spinButtonStyles}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
|
|
||||||
<AccordionItem value="6">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>Default Query Results View</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Select the default view to use when displaying query results.
|
|
||||||
</div>
|
</div>
|
||||||
<ChoiceGroup
|
<ChoiceGroup
|
||||||
ariaLabelledBy="defaultQueryResultsView"
|
ariaLabelledBy="pageOptions"
|
||||||
selectedKey={defaultQueryResultsView}
|
selectedKey={pageOption}
|
||||||
options={defaultQueryResultsViewOptionList}
|
options={pageOptionList}
|
||||||
styles={choiceButtonStyles}
|
styles={choiceButtonStyles}
|
||||||
onChange={handleOnDefaultQueryResultsViewChange}
|
onChange={handleOnPageOptionChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className={`tabs ${styles.settingsSectionContainer}`}>
|
||||||
|
{isCustomPageOptionSelected() && (
|
||||||
|
<div className="tabcontent">
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
Query results per page{" "}
|
||||||
|
<InfoTooltip className={styles.headerIcon}>
|
||||||
|
Enter the number of query results that should be shown per page.
|
||||||
|
</InfoTooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SpinButton
|
||||||
|
ariaLabel="Custom query items per page"
|
||||||
|
value={"" + customItemPerPage}
|
||||||
|
onIncrement={(newValue) => {
|
||||||
|
setCustomItemPerPage(parseInt(newValue) + 1 || customItemPerPage);
|
||||||
|
}}
|
||||||
|
onDecrement={(newValue) => setCustomItemPerPage(parseInt(newValue) - 1 || customItemPerPage)}
|
||||||
|
onValidate={(newValue) => setCustomItemPerPage(parseInt(newValue) || customItemPerPage)}
|
||||||
|
min={1}
|
||||||
|
step={1}
|
||||||
|
className="textfontclr"
|
||||||
|
incrementButtonAriaLabel="Increase value by 1"
|
||||||
|
decrementButtonAriaLabel="Decrease value by 1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
)}
|
||||||
|
{showEnableEntraIdRbac && (
|
||||||
|
<AccordionItem value="2">
|
||||||
|
<AccordionHeader>
|
||||||
|
<div className={styles.header}>Enable Entra ID RBAC</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
Choose Automatic to enable Entra ID RBAC automatically. True/False to force enable/disable Entra
|
||||||
|
ID RBAC.
|
||||||
|
<a
|
||||||
|
href="https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac#use-data-explorer"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
Learn more{" "}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<ChoiceGroup
|
||||||
|
ariaLabelledBy="enableDataPlaneRBACOptions"
|
||||||
|
options={dataPlaneRBACOptionsList}
|
||||||
|
styles={choiceButtonStyles}
|
||||||
|
selectedKey={enableDataPlaneRBACOption}
|
||||||
|
onChange={handleOnDataPlaneRBACOptionChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</>
|
)}
|
||||||
)}
|
{userContext.apiType === "SQL" && userContext.authType === AuthType.AAD && !isFabric() && (
|
||||||
|
<AccordionItem value="3">
|
||||||
|
<AccordionHeader>
|
||||||
|
<div className={styles.header}>Region Selection</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
Changes region the Cosmos Client uses to access account.
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className={styles.subHeader}>Select Region</span>
|
||||||
|
<InfoTooltip className={styles.headerIcon}>
|
||||||
|
Changes the account endpoint used to perform client operations.
|
||||||
|
</InfoTooltip>
|
||||||
|
</div>
|
||||||
|
<Dropdown
|
||||||
|
placeholder={
|
||||||
|
selectedRegionalEndpoint
|
||||||
|
? regionOptions.find((option) => option.key === selectedRegionalEndpoint)?.text
|
||||||
|
: regionOptions[0]?.text
|
||||||
|
}
|
||||||
|
onChange={handleOnSelectedRegionOptionChange}
|
||||||
|
options={regionOptions}
|
||||||
|
styles={{ root: { marginBottom: "10px" } }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
)}
|
||||||
|
{userContext.apiType === "SQL" && !isEmulator && (
|
||||||
|
<>
|
||||||
|
<AccordionItem value="4">
|
||||||
|
<AccordionHeader>
|
||||||
|
<div className={styles.header}>Query Timeout</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
When a query reaches a specified time limit, a popup with an option to cancel the query will
|
||||||
|
show unless automatic cancellation has been enabled.
|
||||||
|
</div>
|
||||||
|
<Toggle
|
||||||
|
styles={toggleStyles}
|
||||||
|
label="Enable query timeout"
|
||||||
|
onChange={handleOnQueryTimeoutToggleChange}
|
||||||
|
defaultChecked={queryTimeoutEnabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{queryTimeoutEnabled && (
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<SpinButton
|
||||||
|
label="Query timeout (ms)"
|
||||||
|
labelPosition={Position.top}
|
||||||
|
defaultValue={(queryTimeout || 5000).toString()}
|
||||||
|
min={100}
|
||||||
|
step={1000}
|
||||||
|
onChange={handleOnQueryTimeoutSpinButtonChange}
|
||||||
|
incrementButtonAriaLabel="Increase value by 1000"
|
||||||
|
decrementButtonAriaLabel="Decrease value by 1000"
|
||||||
|
styles={spinButtonStyles}
|
||||||
|
/>
|
||||||
|
<Toggle
|
||||||
|
label="Automatically cancel query after timeout"
|
||||||
|
styles={toggleStyles}
|
||||||
|
onChange={handleOnAutomaticallyCancelQueryToggleChange}
|
||||||
|
defaultChecked={automaticallyCancelQueryAfterTimeout}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
|
||||||
{showRetrySettings && (
|
<AccordionItem value="5">
|
||||||
<AccordionItem value="7">
|
<AccordionHeader>
|
||||||
<AccordionHeader>
|
<div className={styles.header}>RU Limit</div>
|
||||||
<div className={styles.header}>Retry Settings</div>
|
</AccordionHeader>
|
||||||
</AccordionHeader>
|
<AccordionPanel>
|
||||||
<AccordionPanel>
|
<div className={styles.settingsSectionContainer}>
|
||||||
<div className={styles.settingsSectionContainer}>
|
<div className={styles.settingsSectionDescription}>
|
||||||
<div className={styles.settingsSectionDescription}>
|
If a query exceeds a configured RU limit, the query will be aborted.
|
||||||
Retry policy associated with throttled requests during CosmosDB queries.
|
</div>
|
||||||
|
<Toggle
|
||||||
|
styles={toggleStyles}
|
||||||
|
label="Enable RU limit"
|
||||||
|
onChange={handleOnRUThresholdToggleChange}
|
||||||
|
defaultChecked={ruThresholdEnabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{ruThresholdEnabled && (
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<SpinButton
|
||||||
|
label="RU Limit (RU)"
|
||||||
|
labelPosition={Position.top}
|
||||||
|
defaultValue={(ruThreshold || DefaultRUThreshold).toString()}
|
||||||
|
min={1}
|
||||||
|
step={1000}
|
||||||
|
onChange={handleOnRUThresholdSpinButtonChange}
|
||||||
|
incrementButtonAriaLabel="Increase value by 1000"
|
||||||
|
decrementButtonAriaLabel="Decrease value by 1000"
|
||||||
|
styles={spinButtonStyles}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
|
||||||
|
<AccordionItem value="6">
|
||||||
|
<AccordionHeader>
|
||||||
|
<div className={styles.header}>Default Query Results View</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
Select the default view to use when displaying query results.
|
||||||
|
</div>
|
||||||
|
<ChoiceGroup
|
||||||
|
ariaLabelledBy="defaultQueryResultsView"
|
||||||
|
selectedKey={defaultQueryResultsView}
|
||||||
|
options={defaultQueryResultsViewOptionList}
|
||||||
|
styles={choiceButtonStyles}
|
||||||
|
onChange={handleOnDefaultQueryResultsViewChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</AccordionPanel>
|
||||||
|
</AccordionItem>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showRetrySettings && (
|
||||||
|
<AccordionItem value="7">
|
||||||
|
<AccordionHeader>
|
||||||
|
<div className={styles.header}>Retry Settings</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
Retry policy associated with throttled requests during CosmosDB queries.
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span className={styles.subHeader}>Max retry attempts</span>
|
||||||
|
<InfoTooltip className={styles.headerIcon}>
|
||||||
|
Max number of retries to be performed for a request. Default value 9.
|
||||||
|
</InfoTooltip>
|
||||||
|
</div>
|
||||||
|
<SpinButton
|
||||||
|
labelPosition={Position.top}
|
||||||
|
min={1}
|
||||||
|
step={1}
|
||||||
|
value={"" + retryAttempts}
|
||||||
|
onChange={handleOnQueryRetryAttemptsSpinButtonChange}
|
||||||
|
incrementButtonAriaLabel="Increase value by 1"
|
||||||
|
decrementButtonAriaLabel="Decrease value by 1"
|
||||||
|
onIncrement={(newValue) => setRetryAttempts(parseInt(newValue) + 1 || retryAttempts)}
|
||||||
|
onDecrement={(newValue) => setRetryAttempts(parseInt(newValue) - 1 || retryAttempts)}
|
||||||
|
onValidate={(newValue) => setRetryAttempts(parseInt(newValue) || retryAttempts)}
|
||||||
|
styles={spinButtonStyles}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<span className={styles.subHeader}>Fixed retry interval (ms)</span>
|
||||||
|
<InfoTooltip className={styles.headerIcon}>
|
||||||
|
Fixed retry interval in milliseconds to wait between each retry ignoring the retryAfter returned
|
||||||
|
as part of the response. Default value is 0 milliseconds.
|
||||||
|
</InfoTooltip>
|
||||||
|
</div>
|
||||||
|
<SpinButton
|
||||||
|
labelPosition={Position.top}
|
||||||
|
min={1000}
|
||||||
|
step={1000}
|
||||||
|
value={"" + retryInterval}
|
||||||
|
onChange={handleOnRetryIntervalSpinButtonChange}
|
||||||
|
incrementButtonAriaLabel="Increase value by 1000"
|
||||||
|
decrementButtonAriaLabel="Decrease value by 1000"
|
||||||
|
onIncrement={(newValue) => setRetryInterval(parseInt(newValue) + 1000 || retryInterval)}
|
||||||
|
onDecrement={(newValue) => setRetryInterval(parseInt(newValue) - 1000 || retryInterval)}
|
||||||
|
onValidate={(newValue) => setRetryInterval(parseInt(newValue) || retryInterval)}
|
||||||
|
styles={spinButtonStyles}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<span className={styles.subHeader}>Max wait time (s)</span>
|
||||||
|
<InfoTooltip className={styles.headerIcon}>
|
||||||
|
Max wait time in seconds to wait for a request while the retries are happening. Default value 30
|
||||||
|
seconds.
|
||||||
|
</InfoTooltip>
|
||||||
|
</div>
|
||||||
|
<SpinButton
|
||||||
|
labelPosition={Position.top}
|
||||||
|
min={1}
|
||||||
|
step={1}
|
||||||
|
value={"" + MaxWaitTimeInSeconds}
|
||||||
|
onChange={handleOnMaxWaitTimeSpinButtonChange}
|
||||||
|
incrementButtonAriaLabel="Increase value by 1"
|
||||||
|
decrementButtonAriaLabel="Decrease value by 1"
|
||||||
|
onIncrement={(newValue) =>
|
||||||
|
setMaxWaitTimeInSeconds(parseInt(newValue) + 1 || MaxWaitTimeInSeconds)
|
||||||
|
}
|
||||||
|
onDecrement={(newValue) =>
|
||||||
|
setMaxWaitTimeInSeconds(parseInt(newValue) - 1 || MaxWaitTimeInSeconds)
|
||||||
|
}
|
||||||
|
onValidate={(newValue) => setMaxWaitTimeInSeconds(parseInt(newValue) || MaxWaitTimeInSeconds)}
|
||||||
|
styles={spinButtonStyles}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</AccordionPanel>
|
||||||
<span className={styles.subHeader}>Max retry attempts</span>
|
</AccordionItem>
|
||||||
<InfoTooltip className={styles.headerIcon}>
|
)}
|
||||||
Max number of retries to be performed for a request. Default value 9.
|
{!isEmulator && (
|
||||||
</InfoTooltip>
|
<AccordionItem value="8">
|
||||||
|
<AccordionHeader>
|
||||||
|
<div className={styles.header}>Enable container pagination</div>
|
||||||
|
</AccordionHeader>
|
||||||
|
<AccordionPanel>
|
||||||
|
<div className={styles.settingsSectionContainer}>
|
||||||
|
<div className={styles.settingsSectionDescription}>
|
||||||
|
Load 50 containers at a time. Currently, containers are not pulled in alphanumeric order.
|
||||||
|
</div>
|
||||||
|
<Checkbox
|
||||||
|
styles={{
|
||||||
|
label: { padding: 0 },
|
||||||
|
}}
|
||||||
|
className="padding"
|
||||||
|
ariaLabel="Enable container pagination"
|
||||||
|
checked={containerPaginationEnabled}
|
||||||
|
onChange={() => setContainerPaginationEnabled(!containerPaginationEnabled)}
|
||||||
|
label="Enable container pagination"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<SpinButton
|
</AccordionPanel>
|
||||||
labelPosition={Position.top}
|
</AccordionItem>
|
||||||
min={1}
|
)}
|
||||||
step={1}
|
{shouldShowCrossPartitionOption && (
|
||||||
value={"" + retryAttempts}
|
<AccordionItem value="9">
|
||||||
onChange={handleOnQueryRetryAttemptsSpinButtonChange}
|
<AccordionHeader>
|
||||||
incrementButtonAriaLabel="Increase value by 1"
|
<div className={styles.header}>Enable cross-partition query</div>
|
||||||
decrementButtonAriaLabel="Decrease value by 1"
|
</AccordionHeader>
|
||||||
onIncrement={(newValue) => setRetryAttempts(parseInt(newValue) + 1 || retryAttempts)}
|
<AccordionPanel>
|
||||||
onDecrement={(newValue) => setRetryAttempts(parseInt(newValue) - 1 || retryAttempts)}
|
<div className={styles.settingsSectionContainer}>
|
||||||
onValidate={(newValue) => setRetryAttempts(parseInt(newValue) || retryAttempts)}
|
<div className={styles.settingsSectionDescription}>
|
||||||
styles={spinButtonStyles}
|
Send more than one request while executing a query. More than one request is necessary if the
|
||||||
/>
|
query is not scoped to single partition key value.
|
||||||
<div>
|
</div>
|
||||||
<span className={styles.subHeader}>Fixed retry interval (ms)</span>
|
<Checkbox
|
||||||
<InfoTooltip className={styles.headerIcon}>
|
styles={{
|
||||||
Fixed retry interval in milliseconds to wait between each retry ignoring the retryAfter returned
|
label: { padding: 0 },
|
||||||
as part of the response. Default value is 0 milliseconds.
|
}}
|
||||||
</InfoTooltip>
|
className="padding"
|
||||||
|
ariaLabel="Enable cross partition query"
|
||||||
|
checked={crossPartitionQueryEnabled}
|
||||||
|
onChange={() => setCrossPartitionQueryEnabled(!crossPartitionQueryEnabled)}
|
||||||
|
label="Enable cross-partition query"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<SpinButton
|
</AccordionPanel>
|
||||||
labelPosition={Position.top}
|
</AccordionItem>
|
||||||
min={1000}
|
)}
|
||||||
step={1000}
|
{shouldShowParallelismOption && (
|
||||||
value={"" + retryInterval}
|
<AccordionItem value="10">
|
||||||
onChange={handleOnRetryIntervalSpinButtonChange}
|
<AccordionHeader>
|
||||||
incrementButtonAriaLabel="Increase value by 1000"
|
<div className={styles.header}>Max degree of parallelism</div>
|
||||||
decrementButtonAriaLabel="Decrease value by 1000"
|
</AccordionHeader>
|
||||||
onIncrement={(newValue) => setRetryInterval(parseInt(newValue) + 1000 || retryInterval)}
|
<AccordionPanel>
|
||||||
onDecrement={(newValue) => setRetryInterval(parseInt(newValue) - 1000 || retryInterval)}
|
<div className={styles.settingsSectionContainer}>
|
||||||
onValidate={(newValue) => setRetryInterval(parseInt(newValue) || retryInterval)}
|
<div className={styles.settingsSectionDescription}>
|
||||||
styles={spinButtonStyles}
|
Gets or sets the number of concurrent operations run client side during parallel query execution.
|
||||||
/>
|
A positive property value limits the number of concurrent operations to the set value. If it is
|
||||||
<div>
|
set to less than 0, the system automatically decides the number of concurrent operations to run.
|
||||||
<span className={styles.subHeader}>Max wait time (s)</span>
|
</div>
|
||||||
<InfoTooltip className={styles.headerIcon}>
|
<SpinButton
|
||||||
Max wait time in seconds to wait for a request while the retries are happening. Default value 30
|
min={-1}
|
||||||
seconds.
|
step={1}
|
||||||
</InfoTooltip>
|
className="textfontclr"
|
||||||
|
role="textbox"
|
||||||
|
id="max-degree"
|
||||||
|
value={"" + maxDegreeOfParallelism}
|
||||||
|
onIncrement={(newValue) =>
|
||||||
|
setMaxDegreeOfParallelism(parseInt(newValue) + 1 || maxDegreeOfParallelism)
|
||||||
|
}
|
||||||
|
onDecrement={(newValue) =>
|
||||||
|
setMaxDegreeOfParallelism(parseInt(newValue) - 1 || maxDegreeOfParallelism)
|
||||||
|
}
|
||||||
|
onValidate={(newValue) => setMaxDegreeOfParallelism(parseInt(newValue) || maxDegreeOfParallelism)}
|
||||||
|
ariaLabel="Max degree of parallelism"
|
||||||
|
label="Max degree of parallelism"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<SpinButton
|
</AccordionPanel>
|
||||||
labelPosition={Position.top}
|
</AccordionItem>
|
||||||
min={1}
|
)}
|
||||||
step={1}
|
{shouldShowPriorityLevelOption && (
|
||||||
value={"" + MaxWaitTimeInSeconds}
|
<AccordionItem value="11">
|
||||||
onChange={handleOnMaxWaitTimeSpinButtonChange}
|
<AccordionHeader>
|
||||||
incrementButtonAriaLabel="Increase value by 1"
|
<div className={styles.header}>Priority Level</div>
|
||||||
decrementButtonAriaLabel="Decrease value by 1"
|
</AccordionHeader>
|
||||||
onIncrement={(newValue) => setMaxWaitTimeInSeconds(parseInt(newValue) + 1 || MaxWaitTimeInSeconds)}
|
<AccordionPanel>
|
||||||
onDecrement={(newValue) => setMaxWaitTimeInSeconds(parseInt(newValue) - 1 || MaxWaitTimeInSeconds)}
|
<div className={styles.settingsSectionContainer}>
|
||||||
onValidate={(newValue) => setMaxWaitTimeInSeconds(parseInt(newValue) || MaxWaitTimeInSeconds)}
|
<div className={styles.settingsSectionDescription}>
|
||||||
styles={spinButtonStyles}
|
Sets the priority level for data-plane requests from Data Explorer when using Priority-Based
|
||||||
/>
|
Execution. If "None" is selected, Data Explorer will not specify priority level, and the
|
||||||
</div>
|
server-side default priority level will be used.
|
||||||
</AccordionPanel>
|
</div>
|
||||||
</AccordionItem>
|
<ChoiceGroup
|
||||||
)}
|
ariaLabelledBy="priorityLevel"
|
||||||
{!isEmulator && (
|
selectedKey={priorityLevel}
|
||||||
<AccordionItem value="8">
|
options={priorityLevelOptionList}
|
||||||
<AccordionHeader>
|
styles={choiceButtonStyles}
|
||||||
<div className={styles.header}>Enable container pagination</div>
|
onChange={handleOnPriorityLevelOptionChange}
|
||||||
</AccordionHeader>
|
/>
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Load 50 containers at a time. Currently, containers are not pulled in alphanumeric order.
|
|
||||||
</div>
|
</div>
|
||||||
<Checkbox
|
</AccordionPanel>
|
||||||
styles={{
|
</AccordionItem>
|
||||||
label: { padding: 0 },
|
)}
|
||||||
}}
|
{shouldShowGraphAutoVizOption && (
|
||||||
className="padding"
|
<AccordionItem value="12">
|
||||||
ariaLabel="Enable container pagination"
|
<AccordionHeader>
|
||||||
checked={containerPaginationEnabled}
|
<div className={styles.header}>Display Gremlin query results as: </div>
|
||||||
onChange={() => setContainerPaginationEnabled(!containerPaginationEnabled)}
|
</AccordionHeader>
|
||||||
label="Enable container pagination"
|
<AccordionPanel>
|
||||||
/>
|
<div className={styles.settingsSectionContainer}>
|
||||||
</div>
|
<div className={styles.settingsSectionDescription}>
|
||||||
</AccordionPanel>
|
Select Graph to automatically visualize the query results as a Graph or JSON to display the
|
||||||
</AccordionItem>
|
results as JSON.
|
||||||
)}
|
</div>
|
||||||
{shouldShowCrossPartitionOption && (
|
<ChoiceGroup
|
||||||
<AccordionItem value="9">
|
selectedKey={graphAutoVizDisabled}
|
||||||
<AccordionHeader>
|
options={graphAutoOptionList}
|
||||||
<div className={styles.header}>Enable cross-partition query</div>
|
onChange={handleOnGremlinChange}
|
||||||
</AccordionHeader>
|
aria-label="Graph Auto-visualization"
|
||||||
<AccordionPanel>
|
/>
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Send more than one request while executing a query. More than one request is necessary if the query
|
|
||||||
is not scoped to single partition key value.
|
|
||||||
</div>
|
</div>
|
||||||
<Checkbox
|
</AccordionPanel>
|
||||||
styles={{
|
</AccordionItem>
|
||||||
label: { padding: 0 },
|
)}
|
||||||
}}
|
{shouldShowCopilotSampleDBOption && (
|
||||||
className="padding"
|
<AccordionItem value="13">
|
||||||
ariaLabel="Enable cross partition query"
|
<AccordionHeader>
|
||||||
checked={crossPartitionQueryEnabled}
|
<div className={styles.header}>Enable sample database</div>
|
||||||
onChange={() => setCrossPartitionQueryEnabled(!crossPartitionQueryEnabled)}
|
</AccordionHeader>
|
||||||
label="Enable cross-partition query"
|
<AccordionPanel>
|
||||||
/>
|
<div className={styles.settingsSectionContainer}>
|
||||||
</div>
|
<div className={styles.settingsSectionDescription}>
|
||||||
</AccordionPanel>
|
This is a sample database and collection with synthetic product data you can use to explore using
|
||||||
</AccordionItem>
|
NoSQL queries and Query Advisor. This will appear as another database in the Data Explorer UI, and
|
||||||
)}
|
is created by, and maintained by Microsoft at no cost to you.
|
||||||
{shouldShowParallelismOption && (
|
</div>
|
||||||
<AccordionItem value="10">
|
<Checkbox
|
||||||
<AccordionHeader>
|
styles={{
|
||||||
<div className={styles.header}>Max degree of parallelism</div>
|
label: { padding: 0 },
|
||||||
</AccordionHeader>
|
}}
|
||||||
<AccordionPanel>
|
className="padding"
|
||||||
<div className={styles.settingsSectionContainer}>
|
ariaLabel="Enable sample db for Query Advisor"
|
||||||
<div className={styles.settingsSectionDescription}>
|
checked={copilotSampleDBEnabled}
|
||||||
Gets or sets the number of concurrent operations run client side during parallel query execution. A
|
onChange={handleSampleDatabaseChange}
|
||||||
positive property value limits the number of concurrent operations to the set value. If it is set to
|
label="Enable sample database"
|
||||||
less than 0, the system automatically decides the number of concurrent operations to run.
|
/>
|
||||||
</div>
|
</div>
|
||||||
<SpinButton
|
</AccordionPanel>
|
||||||
min={-1}
|
</AccordionItem>
|
||||||
step={1}
|
)}
|
||||||
className="textfontclr"
|
</Accordion>
|
||||||
role="textbox"
|
)}
|
||||||
id="max-degree"
|
|
||||||
value={"" + maxDegreeOfParallelism}
|
|
||||||
onIncrement={(newValue) =>
|
|
||||||
setMaxDegreeOfParallelism(parseInt(newValue) + 1 || maxDegreeOfParallelism)
|
|
||||||
}
|
|
||||||
onDecrement={(newValue) =>
|
|
||||||
setMaxDegreeOfParallelism(parseInt(newValue) - 1 || maxDegreeOfParallelism)
|
|
||||||
}
|
|
||||||
onValidate={(newValue) => setMaxDegreeOfParallelism(parseInt(newValue) || maxDegreeOfParallelism)}
|
|
||||||
ariaLabel="Max degree of parallelism"
|
|
||||||
label="Max degree of parallelism"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
{shouldShowPriorityLevelOption && (
|
|
||||||
<AccordionItem value="11">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>Priority Level</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Sets the priority level for data-plane requests from Data Explorer when using Priority-Based
|
|
||||||
Execution. If "None" is selected, Data Explorer will not specify priority level, and the
|
|
||||||
server-side default priority level will be used.
|
|
||||||
</div>
|
|
||||||
<ChoiceGroup
|
|
||||||
ariaLabelledBy="priorityLevel"
|
|
||||||
selectedKey={priorityLevel}
|
|
||||||
options={priorityLevelOptionList}
|
|
||||||
styles={choiceButtonStyles}
|
|
||||||
onChange={handleOnPriorityLevelOptionChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
{shouldShowGraphAutoVizOption && (
|
|
||||||
<AccordionItem value="12">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>Display Gremlin query results as: </div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
Select Graph to automatically visualize the query results as a Graph or JSON to display the results
|
|
||||||
as JSON.
|
|
||||||
</div>
|
|
||||||
<ChoiceGroup
|
|
||||||
selectedKey={graphAutoVizDisabled}
|
|
||||||
options={graphAutoOptionList}
|
|
||||||
onChange={handleOnGremlinChange}
|
|
||||||
aria-label="Graph Auto-visualization"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
{shouldShowCopilotSampleDBOption && (
|
|
||||||
<AccordionItem value="13">
|
|
||||||
<AccordionHeader>
|
|
||||||
<div className={styles.header}>Enable sample database</div>
|
|
||||||
</AccordionHeader>
|
|
||||||
<AccordionPanel>
|
|
||||||
<div className={styles.settingsSectionContainer}>
|
|
||||||
<div className={styles.settingsSectionDescription}>
|
|
||||||
This is a sample database and collection with synthetic product data you can use to explore using
|
|
||||||
NoSQL queries and Query Advisor. This will appear as another database in the Data Explorer UI, and
|
|
||||||
is created by, and maintained by Microsoft at no cost to you.
|
|
||||||
</div>
|
|
||||||
<Checkbox
|
|
||||||
styles={{
|
|
||||||
label: { padding: 0 },
|
|
||||||
}}
|
|
||||||
className="padding"
|
|
||||||
ariaLabel="Enable sample db for Query Advisor"
|
|
||||||
checked={copilotSampleDBEnabled}
|
|
||||||
onChange={handleSampleDatabaseChange}
|
|
||||||
label="Enable sample database"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</AccordionPanel>
|
|
||||||
</AccordionItem>
|
|
||||||
)}
|
|
||||||
</Accordion>
|
|
||||||
|
|
||||||
<div className="settingsSection">
|
<div className="settingsSection">
|
||||||
<div className="settingsSectionPart">
|
<div className="settingsSectionPart">
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { BackendDefaults } from "Common/Constants";
|
||||||
import { createCollection } from "Common/dataAccess/createCollection";
|
import { createCollection } from "Common/dataAccess/createCollection";
|
||||||
import Explorer from "Explorer/Explorer";
|
import Explorer from "Explorer/Explorer";
|
||||||
import { useDatabases } from "Explorer/useDatabases";
|
import { useDatabases } from "Explorer/useDatabases";
|
||||||
@ -35,6 +36,11 @@ export const createContainer = async (
|
|||||||
collectionId: containerName,
|
collectionId: containerName,
|
||||||
databaseId: databaseName,
|
databaseId: databaseName,
|
||||||
databaseLevelThroughput: false,
|
databaseLevelThroughput: false,
|
||||||
|
partitionKey: {
|
||||||
|
paths: [`/${SAMPLE_DATA_PARTITION_KEY}`],
|
||||||
|
kind: "Hash",
|
||||||
|
version: BackendDefaults.partitionKeyVersion,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
await createCollection(createRequest);
|
await createCollection(createRequest);
|
||||||
await explorer.refreshAllDatabases();
|
await explorer.refreshAllDatabases();
|
||||||
@ -47,6 +53,8 @@ export const createContainer = async (
|
|||||||
return newCollection;
|
return newCollection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SAMPLE_DATA_PARTITION_KEY = "category"; // This pkey is specifically set for queryCopilotSampleData.json below
|
||||||
|
|
||||||
export const importData = async (collection: ViewModels.Collection): Promise<void> => {
|
export const importData = async (collection: ViewModels.Collection): Promise<void> => {
|
||||||
// TODO: keep same chunk as ContainerSampleGenerator
|
// TODO: keep same chunk as ContainerSampleGenerator
|
||||||
const dataFileContent = await import(
|
const dataFileContent = await import(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user