mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-05-29 19:55:08 +01:00
Merge branch 'master' of https://github.com/Azure/cosmos-explorer into users/aisayas/vector-index-shardkey
This commit is contained in:
commit
bde4428199
@ -1149,6 +1149,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
database: this.database,
|
database: this.database,
|
||||||
isFixedContainer: this.isFixedContainer,
|
isFixedContainer: this.isFixedContainer,
|
||||||
|
isGlobalSecondaryIndex: this.isGlobalSecondaryIndex,
|
||||||
onThroughputChange: this.onThroughputChange,
|
onThroughputChange: this.onThroughputChange,
|
||||||
throughput: this.state.throughput,
|
throughput: this.state.throughput,
|
||||||
throughputBaseline: this.state.throughputBaseline,
|
throughputBaseline: this.state.throughputBaseline,
|
||||||
|
@ -9,6 +9,7 @@ describe("ScaleComponent", () => {
|
|||||||
collection: collection,
|
collection: collection,
|
||||||
database: undefined,
|
database: undefined,
|
||||||
isFixedContainer: false,
|
isFixedContainer: false,
|
||||||
|
isGlobalSecondaryIndex: false,
|
||||||
onThroughputChange: () => {
|
onThroughputChange: () => {
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
@ -22,6 +22,7 @@ export interface ScaleComponentProps {
|
|||||||
collection: ViewModels.Collection;
|
collection: ViewModels.Collection;
|
||||||
database: ViewModels.Database;
|
database: ViewModels.Database;
|
||||||
isFixedContainer: boolean;
|
isFixedContainer: boolean;
|
||||||
|
isGlobalSecondaryIndex: boolean;
|
||||||
onThroughputChange: (newThroughput: number) => void;
|
onThroughputChange: (newThroughput: number) => void;
|
||||||
throughput: number;
|
throughput: number;
|
||||||
throughputBaseline: number;
|
throughputBaseline: number;
|
||||||
@ -143,6 +144,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
|||||||
throughputError={this.props.throughputError}
|
throughputError={this.props.throughputError}
|
||||||
instantMaximumThroughput={this.offer?.instantMaximumThroughput}
|
instantMaximumThroughput={this.offer?.instantMaximumThroughput}
|
||||||
softAllowedMaximumThroughput={this.offer?.softAllowedMaximumThroughput}
|
softAllowedMaximumThroughput={this.offer?.softAllowedMaximumThroughput}
|
||||||
|
isGlobalSecondaryIndex={this.props.isGlobalSecondaryIndex}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ describe("ThroughputInputAutoPilotV3Component", () => {
|
|||||||
},
|
},
|
||||||
instantMaximumThroughput: 5000,
|
instantMaximumThroughput: 5000,
|
||||||
softAllowedMaximumThroughput: 1000000,
|
softAllowedMaximumThroughput: 1000000,
|
||||||
|
isGlobalSecondaryIndex: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
it("throughput input visible", () => {
|
it("throughput input visible", () => {
|
||||||
|
@ -80,6 +80,7 @@ export interface ThroughputInputAutoPilotV3Props {
|
|||||||
throughputError?: string;
|
throughputError?: string;
|
||||||
instantMaximumThroughput: number;
|
instantMaximumThroughput: number;
|
||||||
softAllowedMaximumThroughput: number;
|
softAllowedMaximumThroughput: number;
|
||||||
|
isGlobalSecondaryIndex: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ThroughputInputAutoPilotV3State {
|
interface ThroughputInputAutoPilotV3State {
|
||||||
@ -375,22 +376,26 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
|||||||
toolTipElement={getToolTipContainer(this.props.infoBubbleText)}
|
toolTipElement={getToolTipContainer(this.props.infoBubbleText)}
|
||||||
/>
|
/>
|
||||||
</Label>
|
</Label>
|
||||||
{this.overrideWithProvisionedThroughputSettings() && (
|
{!this.props.isGlobalSecondaryIndex && (
|
||||||
<MessageBar
|
<>
|
||||||
messageBarIconProps={{ iconName: "InfoSolid", className: "messageBarInfoIcon" }}
|
{this.overrideWithProvisionedThroughputSettings() && (
|
||||||
styles={messageBarStyles}
|
<MessageBar
|
||||||
>
|
messageBarIconProps={{ iconName: "InfoSolid", className: "messageBarInfoIcon" }}
|
||||||
{manualToAutoscaleDisclaimerElement}
|
styles={messageBarStyles}
|
||||||
</MessageBar>
|
>
|
||||||
|
{manualToAutoscaleDisclaimerElement}
|
||||||
|
</MessageBar>
|
||||||
|
)}
|
||||||
|
<ChoiceGroup
|
||||||
|
selectedKey={this.props.isAutoPilotSelected.toString()}
|
||||||
|
options={this.options}
|
||||||
|
onChange={this.onChoiceGroupChange}
|
||||||
|
required={this.props.showAsMandatory}
|
||||||
|
ariaLabelledBy={labelId}
|
||||||
|
styles={getChoiceGroupStyles(this.props.wasAutopilotOriginallySet, this.props.isAutoPilotSelected, true)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<ChoiceGroup
|
|
||||||
selectedKey={this.props.isAutoPilotSelected.toString()}
|
|
||||||
options={this.options}
|
|
||||||
onChange={this.onChoiceGroupChange}
|
|
||||||
required={this.props.showAsMandatory}
|
|
||||||
ariaLabelledBy={labelId}
|
|
||||||
styles={getChoiceGroupStyles(this.props.wasAutopilotOriginallySet, this.props.isAutoPilotSelected, true)}
|
|
||||||
/>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -79,6 +79,7 @@ exports[`SettingsComponent renders 1`] = `
|
|||||||
}
|
}
|
||||||
isAutoPilotSelected={false}
|
isAutoPilotSelected={false}
|
||||||
isFixedContainer={false}
|
isFixedContainer={false}
|
||||||
|
isGlobalSecondaryIndex={true}
|
||||||
onAutoPilotSelected={[Function]}
|
onAutoPilotSelected={[Function]}
|
||||||
onMaxAutoPilotThroughputChange={[Function]}
|
onMaxAutoPilotThroughputChange={[Function]}
|
||||||
onScaleDiscardableChange={[Function]}
|
onScaleDiscardableChange={[Function]}
|
||||||
|
@ -18,6 +18,7 @@ export interface ThroughputInputProps {
|
|||||||
isFreeTier: boolean;
|
isFreeTier: boolean;
|
||||||
showFreeTierExceedThroughputTooltip: boolean;
|
showFreeTierExceedThroughputTooltip: boolean;
|
||||||
isQuickstart?: boolean;
|
isQuickstart?: boolean;
|
||||||
|
isGlobalSecondaryIndex?: boolean;
|
||||||
setThroughputValue: (throughput: number) => void;
|
setThroughputValue: (throughput: number) => void;
|
||||||
setIsAutoscale: (isAutoscale: boolean) => void;
|
setIsAutoscale: (isAutoscale: boolean) => void;
|
||||||
setIsThroughputCapExceeded: (isThroughputCapExceeded: boolean) => void;
|
setIsThroughputCapExceeded: (isThroughputCapExceeded: boolean) => void;
|
||||||
@ -30,6 +31,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
isFreeTier,
|
isFreeTier,
|
||||||
showFreeTierExceedThroughputTooltip,
|
showFreeTierExceedThroughputTooltip,
|
||||||
isQuickstart,
|
isQuickstart,
|
||||||
|
isGlobalSecondaryIndex,
|
||||||
setThroughputValue,
|
setThroughputValue,
|
||||||
setIsAutoscale,
|
setIsAutoscale,
|
||||||
setIsThroughputCapExceeded,
|
setIsThroughputCapExceeded,
|
||||||
@ -193,41 +195,41 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
|||||||
</Text>
|
</Text>
|
||||||
<InfoTooltip>{PricingUtils.getRuToolTipText()}</InfoTooltip>
|
<InfoTooltip>{PricingUtils.getRuToolTipText()}</InfoTooltip>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
{!isGlobalSecondaryIndex && (
|
||||||
|
<Stack horizontal verticalAlign="center">
|
||||||
|
<div role="radiogroup">
|
||||||
|
<input
|
||||||
|
id="Autoscale-input"
|
||||||
|
className="throughputInputRadioBtn"
|
||||||
|
aria-label={`${getThroughputLabelText()} Autoscale`}
|
||||||
|
aria-required={true}
|
||||||
|
checked={isAutoscaleSelected}
|
||||||
|
type="radio"
|
||||||
|
role="radio"
|
||||||
|
tabIndex={0}
|
||||||
|
onChange={(e) => handleOnChangeMode(e, "Autoscale")}
|
||||||
|
/>
|
||||||
|
<label htmlFor="Autoscale-input" className="throughputInputRadioBtnLabel">
|
||||||
|
Autoscale
|
||||||
|
</label>
|
||||||
|
|
||||||
<Stack horizontal verticalAlign="center">
|
<input
|
||||||
<div role="radiogroup">
|
id="Manual-input"
|
||||||
<input
|
className="throughputInputRadioBtn"
|
||||||
id="Autoscale-input"
|
aria-label={`${getThroughputLabelText()} Manual`}
|
||||||
className="throughputInputRadioBtn"
|
checked={!isAutoscaleSelected}
|
||||||
aria-label={`${getThroughputLabelText()} Autoscale`}
|
type="radio"
|
||||||
aria-required={true}
|
aria-required={true}
|
||||||
checked={isAutoscaleSelected}
|
role="radio"
|
||||||
type="radio"
|
tabIndex={0}
|
||||||
role="radio"
|
onChange={(e) => handleOnChangeMode(e, "Manual")}
|
||||||
tabIndex={0}
|
/>
|
||||||
onChange={(e) => handleOnChangeMode(e, "Autoscale")}
|
<label className="throughputInputRadioBtnLabel" htmlFor="Manual-input">
|
||||||
/>
|
Manual
|
||||||
<label htmlFor="Autoscale-input" className="throughputInputRadioBtnLabel">
|
</label>
|
||||||
Autoscale
|
</div>
|
||||||
</label>
|
</Stack>
|
||||||
|
)}
|
||||||
<input
|
|
||||||
id="Manual-input"
|
|
||||||
className="throughputInputRadioBtn"
|
|
||||||
aria-label={`${getThroughputLabelText()} Manual`}
|
|
||||||
checked={!isAutoscaleSelected}
|
|
||||||
type="radio"
|
|
||||||
aria-required={true}
|
|
||||||
role="radio"
|
|
||||||
tabIndex={0}
|
|
||||||
onChange={(e) => handleOnChangeMode(e, "Manual")}
|
|
||||||
/>
|
|
||||||
<label className="throughputInputRadioBtnLabel" htmlFor="Manual-input">
|
|
||||||
Manual
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</Stack>
|
|
||||||
|
|
||||||
{isAutoscaleSelected && (
|
{isAutoscaleSelected && (
|
||||||
<Stack className="throughputInputSpacing">
|
<Stack className="throughputInputSpacing">
|
||||||
<Text variant="small" aria-label="capacity calculator of azure cosmos db">
|
<Text variant="small" aria-label="capacity calculator of azure cosmos db">
|
||||||
|
@ -22,7 +22,6 @@ import {
|
|||||||
FullTextPolicyDefault,
|
FullTextPolicyDefault,
|
||||||
getPartitionKey,
|
getPartitionKey,
|
||||||
isSynapseLinkEnabled,
|
isSynapseLinkEnabled,
|
||||||
parseUniqueKeys,
|
|
||||||
scrollToSection,
|
scrollToSection,
|
||||||
shouldShowAnalyticalStoreOptions,
|
shouldShowAnalyticalStoreOptions,
|
||||||
} from "Explorer/Panes/AddCollectionPanel/AddCollectionPanelUtility";
|
} from "Explorer/Panes/AddCollectionPanel/AddCollectionPanelUtility";
|
||||||
@ -35,7 +34,6 @@ import { AnalyticalStoreComponent } from "Explorer/Panes/AddGlobalSecondaryIndex
|
|||||||
import { FullTextSearchComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/FullTextSearchComponent";
|
import { FullTextSearchComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/FullTextSearchComponent";
|
||||||
import { PartitionKeyComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/PartitionKeyComponent";
|
import { PartitionKeyComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/PartitionKeyComponent";
|
||||||
import { ThroughputComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/ThroughputComponent";
|
import { ThroughputComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/ThroughputComponent";
|
||||||
import { UniqueKeysComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/UniqueKeysComponent";
|
|
||||||
import { VectorSearchComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/VectorSearchComponent";
|
import { VectorSearchComponent } from "Explorer/Panes/AddGlobalSecondaryIndexPanel/Components/VectorSearchComponent";
|
||||||
import { PanelFooterComponent } from "Explorer/Panes/PanelFooterComponent";
|
import { PanelFooterComponent } from "Explorer/Panes/PanelFooterComponent";
|
||||||
import { PanelInfoErrorComponent } from "Explorer/Panes/PanelInfoErrorComponent";
|
import { PanelInfoErrorComponent } from "Explorer/Panes/PanelInfoErrorComponent";
|
||||||
@ -66,14 +64,13 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
const [useHashV1, setUseHashV1] = useState<boolean>();
|
const [useHashV1, setUseHashV1] = useState<boolean>();
|
||||||
const [enableDedicatedThroughput, setEnabledDedicatedThroughput] = useState<boolean>();
|
const [enableDedicatedThroughput, setEnabledDedicatedThroughput] = useState<boolean>();
|
||||||
const [isThroughputCapExceeded, setIsThroughputCapExceeded] = useState<boolean>();
|
const [isThroughputCapExceeded, setIsThroughputCapExceeded] = useState<boolean>();
|
||||||
const [uniqueKeys, setUniqueKeys] = useState<string[]>([]);
|
|
||||||
const [enableAnalyticalStore, setEnableAnalyticalStore] = useState<boolean>();
|
const [enableAnalyticalStore, setEnableAnalyticalStore] = useState<boolean>();
|
||||||
const [vectorEmbeddingPolicy, setVectorEmbeddingPolicy] = useState<VectorEmbedding[]>();
|
const [vectorEmbeddingPolicy, setVectorEmbeddingPolicy] = useState<VectorEmbedding[]>([]);
|
||||||
const [vectorIndexingPolicy, setVectorIndexingPolicy] = useState<VectorIndex[]>();
|
const [vectorIndexingPolicy, setVectorIndexingPolicy] = useState<VectorIndex[]>([]);
|
||||||
const [vectorPolicyValidated, setVectorPolicyValidated] = useState<boolean>();
|
const [vectorPolicyValidated, setVectorPolicyValidated] = useState<boolean>(true);
|
||||||
const [fullTextPolicy, setFullTextPolicy] = useState<FullTextPolicy>(FullTextPolicyDefault);
|
const [fullTextPolicy, setFullTextPolicy] = useState<FullTextPolicy>(FullTextPolicyDefault);
|
||||||
const [fullTextIndexes, setFullTextIndexes] = useState<FullTextIndex[]>();
|
const [fullTextIndexes, setFullTextIndexes] = useState<FullTextIndex[]>([]);
|
||||||
const [fullTextPolicyValidated, setFullTextPolicyValidated] = useState<boolean>();
|
const [fullTextPolicyValidated, setFullTextPolicyValidated] = useState<boolean>(true);
|
||||||
const [errorMessage, setErrorMessage] = useState<string>();
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
const [showErrorDetails, setShowErrorDetails] = useState<boolean>();
|
const [showErrorDetails, setShowErrorDetails] = useState<boolean>();
|
||||||
const [isExecuting, setIsExecuting] = useState<boolean>();
|
const [isExecuting, setIsExecuting] = useState<boolean>();
|
||||||
@ -109,17 +106,12 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
}, [errorMessage]);
|
}, [errorMessage]);
|
||||||
|
|
||||||
let globalSecondaryIndexThroughput: number;
|
let globalSecondaryIndexThroughput: number;
|
||||||
let isGlobalSecondaryIndexAutoscale: boolean;
|
|
||||||
let isCostAcknowledged: boolean;
|
let isCostAcknowledged: boolean;
|
||||||
|
|
||||||
const globalSecondaryIndexThroughputOnChange = (globalSecondaryIndexThroughputValue: number): void => {
|
const globalSecondaryIndexThroughputOnChange = (globalSecondaryIndexThroughputValue: number): void => {
|
||||||
globalSecondaryIndexThroughput = globalSecondaryIndexThroughputValue;
|
globalSecondaryIndexThroughput = globalSecondaryIndexThroughputValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
const isGlobalSecondaryIndexAutoscaleOnChange = (isGlobalSecondaryIndexAutoscaleValue: boolean): void => {
|
|
||||||
isGlobalSecondaryIndexAutoscale = isGlobalSecondaryIndexAutoscaleValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isCostAknowledgedOnChange = (isCostAcknowledgedValue: boolean): void => {
|
const isCostAknowledgedOnChange = (isCostAcknowledgedValue: boolean): void => {
|
||||||
isCostAcknowledged = isCostAcknowledgedValue;
|
isCostAcknowledged = isCostAcknowledgedValue;
|
||||||
};
|
};
|
||||||
@ -178,9 +170,7 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (globalSecondaryIndexThroughput > CollectionCreation.DefaultCollectionRUs100K && !isCostAcknowledged) {
|
if (globalSecondaryIndexThroughput > CollectionCreation.DefaultCollectionRUs100K && !isCostAcknowledged) {
|
||||||
const errorMessage = isGlobalSecondaryIndexAutoscale
|
const errorMessage: string = "Please acknowledge the estimated monthly spend.";
|
||||||
? "Please acknowledge the estimated monthly spend."
|
|
||||||
: "Please acknowledge the estimated daily spend.";
|
|
||||||
setErrorMessage(errorMessage);
|
setErrorMessage(errorMessage);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -221,7 +211,6 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
|
|
||||||
const partitionKeyTrimmed: string = partitionKey.trim();
|
const partitionKeyTrimmed: string = partitionKey.trim();
|
||||||
|
|
||||||
const uniqueKeyPolicy: DataModels.UniqueKeyPolicy = parseUniqueKeys(uniqueKeys);
|
|
||||||
const partitionKeyVersion = useHashV1 ? undefined : 2;
|
const partitionKeyVersion = useHashV1 ? undefined : 2;
|
||||||
const partitionKeyPaths: DataModels.PartitionKey = partitionKeyTrimmed
|
const partitionKeyPaths: DataModels.PartitionKey = partitionKeyTrimmed
|
||||||
? {
|
? {
|
||||||
@ -256,9 +245,8 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
collection: {
|
collection: {
|
||||||
id: globalSecondaryIdTrimmed,
|
id: globalSecondaryIdTrimmed,
|
||||||
throughput: globalSecondaryIndexThroughput,
|
throughput: globalSecondaryIndexThroughput,
|
||||||
isAutoscale: isGlobalSecondaryIndexAutoscale,
|
isAutoscale: true,
|
||||||
partitionKeyPaths,
|
partitionKeyPaths,
|
||||||
uniqueKeyPolicy,
|
|
||||||
collectionWithDedicatedThroughput: enableDedicatedThroughput,
|
collectionWithDedicatedThroughput: enableDedicatedThroughput,
|
||||||
},
|
},
|
||||||
subscriptionQuotaId: userContext.quotaId,
|
subscriptionQuotaId: userContext.quotaId,
|
||||||
@ -268,28 +256,17 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
const startKey: number = TelemetryProcessor.traceStart(Action.CreateCollection, telemetryData);
|
const startKey: number = TelemetryProcessor.traceStart(Action.CreateCollection, telemetryData);
|
||||||
const databaseLevelThroughput: boolean = isSelectedSourceContainerSharedThroughput() && !enableDedicatedThroughput;
|
const databaseLevelThroughput: boolean = isSelectedSourceContainerSharedThroughput() && !enableDedicatedThroughput;
|
||||||
|
|
||||||
let offerThroughput: number;
|
|
||||||
let autoPilotMaxThroughput: number;
|
|
||||||
|
|
||||||
if (!databaseLevelThroughput) {
|
|
||||||
if (isGlobalSecondaryIndexAutoscale) {
|
|
||||||
autoPilotMaxThroughput = globalSecondaryIndexThroughput;
|
|
||||||
} else {
|
|
||||||
offerThroughput = globalSecondaryIndexThroughput;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const createGlobalSecondaryIndexParams: DataModels.CreateMaterializedViewsParams = {
|
const createGlobalSecondaryIndexParams: DataModels.CreateMaterializedViewsParams = {
|
||||||
materializedViewId: globalSecondaryIdTrimmed,
|
materializedViewId: globalSecondaryIdTrimmed,
|
||||||
materializedViewDefinition: globalSecondaryIndexDefinition,
|
materializedViewDefinition: globalSecondaryIndexDefinition,
|
||||||
databaseId: selectedSourceContainer.databaseId,
|
databaseId: selectedSourceContainer.databaseId,
|
||||||
databaseLevelThroughput: databaseLevelThroughput,
|
databaseLevelThroughput: databaseLevelThroughput,
|
||||||
offerThroughput: offerThroughput,
|
...(!databaseLevelThroughput && {
|
||||||
autoPilotMaxThroughput: autoPilotMaxThroughput,
|
autoPilotMaxThroughput: globalSecondaryIndexThroughput,
|
||||||
|
}),
|
||||||
analyticalStorageTtl: getAnalyticalStorageTtl(),
|
analyticalStorageTtl: getAnalyticalStorageTtl(),
|
||||||
indexingPolicy: indexingPolicy,
|
indexingPolicy: indexingPolicy,
|
||||||
partitionKey: partitionKeyPaths,
|
partitionKey: partitionKeyPaths,
|
||||||
uniqueKeyPolicy: uniqueKeyPolicy,
|
|
||||||
vectorEmbeddingPolicy: vectorEmbeddingPolicyFinal,
|
vectorEmbeddingPolicy: vectorEmbeddingPolicyFinal,
|
||||||
fullTextPolicy: fullTextPolicy,
|
fullTextPolicy: fullTextPolicy,
|
||||||
};
|
};
|
||||||
@ -395,12 +372,10 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
isSelectedSourceContainerSharedThroughput,
|
isSelectedSourceContainerSharedThroughput,
|
||||||
showCollectionThroughputInput,
|
showCollectionThroughputInput,
|
||||||
globalSecondaryIndexThroughputOnChange,
|
globalSecondaryIndexThroughputOnChange,
|
||||||
isGlobalSecondaryIndexAutoscaleOnChange,
|
|
||||||
setIsThroughputCapExceeded,
|
setIsThroughputCapExceeded,
|
||||||
isCostAknowledgedOnChange,
|
isCostAknowledgedOnChange,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<UniqueKeysComponent {...{ uniqueKeys, setUniqueKeys }} />
|
|
||||||
{shouldShowAnalyticalStoreOptions() && (
|
{shouldShowAnalyticalStoreOptions() && (
|
||||||
<AnalyticalStoreComponent {...{ explorer, enableAnalyticalStore, setEnableAnalyticalStore }} />
|
<AnalyticalStoreComponent {...{ explorer, enableAnalyticalStore, setEnableAnalyticalStore }} />
|
||||||
)}
|
)}
|
||||||
|
@ -12,7 +12,6 @@ export interface ThroughputComponentProps {
|
|||||||
isSelectedSourceContainerSharedThroughput: () => boolean;
|
isSelectedSourceContainerSharedThroughput: () => boolean;
|
||||||
showCollectionThroughputInput: () => boolean;
|
showCollectionThroughputInput: () => boolean;
|
||||||
globalSecondaryIndexThroughputOnChange: (globalSecondaryIndexThroughputValue: number) => void;
|
globalSecondaryIndexThroughputOnChange: (globalSecondaryIndexThroughputValue: number) => void;
|
||||||
isGlobalSecondaryIndexAutoscaleOnChange: (isGlobalSecondaryIndexAutoscaleValue: boolean) => void;
|
|
||||||
setIsThroughputCapExceeded: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsThroughputCapExceeded: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
isCostAknowledgedOnChange: (isCostAknowledgedValue: boolean) => void;
|
isCostAknowledgedOnChange: (isCostAknowledgedValue: boolean) => void;
|
||||||
}
|
}
|
||||||
@ -24,7 +23,6 @@ export const ThroughputComponent = (props: ThroughputComponentProps): JSX.Elemen
|
|||||||
isSelectedSourceContainerSharedThroughput,
|
isSelectedSourceContainerSharedThroughput,
|
||||||
showCollectionThroughputInput,
|
showCollectionThroughputInput,
|
||||||
globalSecondaryIndexThroughputOnChange,
|
globalSecondaryIndexThroughputOnChange,
|
||||||
isGlobalSecondaryIndexAutoscaleOnChange,
|
|
||||||
setIsThroughputCapExceeded,
|
setIsThroughputCapExceeded,
|
||||||
isCostAknowledgedOnChange,
|
isCostAknowledgedOnChange,
|
||||||
} = props;
|
} = props;
|
||||||
@ -52,12 +50,11 @@ export const ThroughputComponent = (props: ThroughputComponentProps): JSX.Elemen
|
|||||||
isSharded={false}
|
isSharded={false}
|
||||||
isFreeTier={isFreeTierAccount()}
|
isFreeTier={isFreeTierAccount()}
|
||||||
isQuickstart={false}
|
isQuickstart={false}
|
||||||
|
isGlobalSecondaryIndex={true}
|
||||||
setThroughputValue={(throughput: number) => {
|
setThroughputValue={(throughput: number) => {
|
||||||
globalSecondaryIndexThroughputOnChange(throughput);
|
globalSecondaryIndexThroughputOnChange(throughput);
|
||||||
}}
|
}}
|
||||||
setIsAutoscale={(isAutoscale: boolean) => {
|
setIsAutoscale={() => {}}
|
||||||
isGlobalSecondaryIndexAutoscaleOnChange(isAutoscale);
|
|
||||||
}}
|
|
||||||
setIsThroughputCapExceeded={(isThroughputCapExceeded: boolean) => {
|
setIsThroughputCapExceeded={(isThroughputCapExceeded: boolean) => {
|
||||||
setIsThroughputCapExceeded(isThroughputCapExceeded);
|
setIsThroughputCapExceeded(isThroughputCapExceeded);
|
||||||
}}
|
}}
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
import { ActionButton, IconButton, Stack } from "@fluentui/react";
|
|
||||||
import { UniqueKeysHeader } from "Explorer/Panes/AddCollectionPanel/AddCollectionPanelUtility";
|
|
||||||
import React from "react";
|
|
||||||
import { userContext } from "UserContext";
|
|
||||||
|
|
||||||
export interface UniqueKeysComponentProps {
|
|
||||||
uniqueKeys: string[];
|
|
||||||
setUniqueKeys: React.Dispatch<React.SetStateAction<string[]>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const UniqueKeysComponent = (props: UniqueKeysComponentProps): JSX.Element => {
|
|
||||||
const { uniqueKeys, setUniqueKeys } = props;
|
|
||||||
|
|
||||||
const updateUniqueKeysOnChange = (value: string, uniqueKeyToReplaceIndex: number): void => {
|
|
||||||
const updatedUniqueKeys = uniqueKeys.map((uniqueKey: string, uniqueKeyIndex: number) => {
|
|
||||||
if (uniqueKeyToReplaceIndex === uniqueKeyIndex) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return uniqueKey;
|
|
||||||
});
|
|
||||||
setUniqueKeys(updatedUniqueKeys);
|
|
||||||
};
|
|
||||||
|
|
||||||
const deleteUniqueKeyOnClick = (uniqueKeyToDeleteIndex: number): void => {
|
|
||||||
const updatedUniqueKeys = uniqueKeys.filter((_, uniqueKeyIndex) => uniqueKeyToDeleteIndex !== uniqueKeyIndex);
|
|
||||||
setUniqueKeys(updatedUniqueKeys);
|
|
||||||
};
|
|
||||||
|
|
||||||
const addUniqueKeyOnClick = (): void => {
|
|
||||||
setUniqueKeys([...uniqueKeys, ""]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Stack>
|
|
||||||
{UniqueKeysHeader()}
|
|
||||||
|
|
||||||
{uniqueKeys.map((uniqueKey: string, uniqueKeyIndex: number): JSX.Element => {
|
|
||||||
return (
|
|
||||||
<Stack style={{ marginBottom: 8 }} key={`uniqueKey-${uniqueKeyIndex}`} horizontal>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
placeholder={
|
|
||||||
userContext.apiType === "Mongo"
|
|
||||||
? "Comma separated paths e.g. firstName,address.zipCode"
|
|
||||||
: "Comma separated paths e.g. /firstName,/address/zipCode"
|
|
||||||
}
|
|
||||||
className="panelTextField"
|
|
||||||
autoFocus
|
|
||||||
value={uniqueKey}
|
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
updateUniqueKeysOnChange(event.target.value, uniqueKeyIndex);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
iconProps={{ iconName: "Delete" }}
|
|
||||||
style={{ height: 27 }}
|
|
||||||
onClick={() => {
|
|
||||||
deleteUniqueKeyOnClick(uniqueKeyIndex);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
<ActionButton
|
|
||||||
iconProps={{ iconName: "Add" }}
|
|
||||||
styles={{ root: { padding: 0 }, label: { fontSize: 12 } }}
|
|
||||||
onClick={() => {
|
|
||||||
addUniqueKeyOnClick();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Add unique key
|
|
||||||
</ActionButton>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
};
|
|
@ -137,16 +137,11 @@ exports[`AddGlobalSecondaryIndexPanel render default panel 1`] = `
|
|||||||
<ThroughputComponent
|
<ThroughputComponent
|
||||||
globalSecondaryIndexThroughputOnChange={[Function]}
|
globalSecondaryIndexThroughputOnChange={[Function]}
|
||||||
isCostAknowledgedOnChange={[Function]}
|
isCostAknowledgedOnChange={[Function]}
|
||||||
isGlobalSecondaryIndexAutoscaleOnChange={[Function]}
|
|
||||||
isSelectedSourceContainerSharedThroughput={[Function]}
|
isSelectedSourceContainerSharedThroughput={[Function]}
|
||||||
setEnabledDedicatedThroughput={[Function]}
|
setEnabledDedicatedThroughput={[Function]}
|
||||||
setIsThroughputCapExceeded={[Function]}
|
setIsThroughputCapExceeded={[Function]}
|
||||||
showCollectionThroughputInput={[Function]}
|
showCollectionThroughputInput={[Function]}
|
||||||
/>
|
/>
|
||||||
<UniqueKeysComponent
|
|
||||||
setUniqueKeys={[Function]}
|
|
||||||
uniqueKeys={[]}
|
|
||||||
/>
|
|
||||||
<AnalyticalStoreComponent
|
<AnalyticalStoreComponent
|
||||||
explorer={
|
explorer={
|
||||||
Explorer {
|
Explorer {
|
||||||
|
@ -241,21 +241,6 @@ export class ResourceTreeAdapter implements ReactAdapter {
|
|||||||
contextMenu: ResourceTreeContextMenuButtonFactory.createCollectionContextMenuButton(this.container, collection),
|
contextMenu: ResourceTreeContextMenuButtonFactory.createCollectionContextMenuButton(this.container, collection),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
|
||||||
useNotebook.getState().isNotebookEnabled &&
|
|
||||||
userContext.apiType === "Mongo" &&
|
|
||||||
isPublicInternetAccessAllowed()
|
|
||||||
) {
|
|
||||||
children.push({
|
|
||||||
label: "Schema (Preview)",
|
|
||||||
onClick: collection.onSchemaAnalyzerClick.bind(collection),
|
|
||||||
isSelected: () =>
|
|
||||||
useSelectedNode
|
|
||||||
.getState()
|
|
||||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.SchemaAnalyzer]),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
||||||
children.push({
|
children.push({
|
||||||
label: database.isDatabaseShared() || isServerlessAccount() ? "Settings" : "Scale & Settings",
|
label: database.isDatabaseShared() || isServerlessAccount() ? "Settings" : "Scale & Settings",
|
||||||
|
@ -338,11 +338,6 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||||||
"label": "Documents",
|
"label": "Documents",
|
||||||
"onClick": [Function],
|
"onClick": [Function],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"isSelected": [Function],
|
|
||||||
"label": "Schema (Preview)",
|
|
||||||
"onClick": [Function],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "",
|
"id": "",
|
||||||
"isSelected": [Function],
|
"isSelected": [Function],
|
||||||
@ -406,11 +401,6 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||||||
"label": "Documents",
|
"label": "Documents",
|
||||||
"onClick": [Function],
|
"onClick": [Function],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"isSelected": [Function],
|
|
||||||
"label": "Schema (Preview)",
|
|
||||||
"onClick": [Function],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "",
|
"id": "",
|
||||||
"isSelected": [Function],
|
"isSelected": [Function],
|
||||||
@ -515,11 +505,6 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||||||
"label": "Documents",
|
"label": "Documents",
|
||||||
"onClick": [Function],
|
"onClick": [Function],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"isSelected": [Function],
|
|
||||||
"label": "Schema (Preview)",
|
|
||||||
"onClick": [Function],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "sampleSettings",
|
"id": "sampleSettings",
|
||||||
"isSelected": [Function],
|
"isSelected": [Function],
|
||||||
@ -610,11 +595,6 @@ exports[`createDatabaseTreeNodes generates the correct tree structure for the Mo
|
|||||||
"label": "Documents",
|
"label": "Documents",
|
||||||
"onClick": [Function],
|
"onClick": [Function],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"isSelected": [Function],
|
|
||||||
"label": "Schema (Preview)",
|
|
||||||
"onClick": [Function],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "",
|
"id": "",
|
||||||
"isSelected": [Function],
|
"isSelected": [Function],
|
||||||
|
@ -11,7 +11,6 @@ import { getItemName } from "Utils/APITypeUtils";
|
|||||||
import { isServerlessAccount } from "Utils/CapabilityUtils";
|
import { isServerlessAccount } from "Utils/CapabilityUtils";
|
||||||
import { useTabs } from "hooks/useTabs";
|
import { useTabs } from "hooks/useTabs";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { isPublicInternetAccessAllowed } from "../../Common/DatabaseAccountUtility";
|
|
||||||
import { Platform, configContext } from "../../ConfigContext";
|
import { Platform, configContext } from "../../ConfigContext";
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
import * as DataModels from "../../Contracts/DataModels";
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
@ -19,7 +18,6 @@ import { userContext } from "../../UserContext";
|
|||||||
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
import * as ResourceTreeContextMenuButtonFactory from "../ContextMenuButtonFactory";
|
||||||
import Explorer from "../Explorer";
|
import Explorer from "../Explorer";
|
||||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import { useNotebook } from "../Notebook/useNotebook";
|
|
||||||
import { useSelectedNode } from "../useSelectedNode";
|
import { useSelectedNode } from "../useSelectedNode";
|
||||||
|
|
||||||
export const shouldShowScriptNodes = (): boolean => {
|
export const shouldShowScriptNodes = (): boolean => {
|
||||||
@ -294,22 +292,6 @@ const buildCollectionNodeChildren = (
|
|||||||
contextMenu: ResourceTreeContextMenuButtonFactory.createCollectionContextMenuButton(container, collection),
|
contextMenu: ResourceTreeContextMenuButtonFactory.createCollectionContextMenuButton(container, collection),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (
|
|
||||||
isNotebookEnabled &&
|
|
||||||
userContext.apiType === "Mongo" &&
|
|
||||||
isPublicInternetAccessAllowed() &&
|
|
||||||
useNotebook.getState().isPhoenixFeatures
|
|
||||||
) {
|
|
||||||
children.push({
|
|
||||||
label: "Schema (Preview)",
|
|
||||||
onClick: collection.onSchemaAnalyzerClick.bind(collection),
|
|
||||||
isSelected: () =>
|
|
||||||
useSelectedNode
|
|
||||||
.getState()
|
|
||||||
.isDataNodeSelected(collection.databaseId, collection.id(), [ViewModels.CollectionTabKind.SchemaAnalyzer]),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
if (userContext.apiType !== "Cassandra" || !isServerlessAccount()) {
|
||||||
let id = "";
|
let id = "";
|
||||||
if (collection.isSampleCollection) {
|
if (collection.isSampleCollection) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user