Merge branch 'master' of https://github.com/Azure/cosmos-explorer into users/aisayas/vector-index-shardkey

This commit is contained in:
Asier Isayas 2025-04-28 10:00:24 -04:00
commit bde4428199
14 changed files with 74 additions and 225 deletions

View File

@ -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,

View File

@ -9,6 +9,7 @@ describe("ScaleComponent", () => {
collection: collection, collection: collection,
database: undefined, database: undefined,
isFixedContainer: false, isFixedContainer: false,
isGlobalSecondaryIndex: false,
onThroughputChange: () => { onThroughputChange: () => {
return; return;
}, },

View File

@ -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}
/> />
); );

View File

@ -44,6 +44,7 @@ describe("ThroughputInputAutoPilotV3Component", () => {
}, },
instantMaximumThroughput: 5000, instantMaximumThroughput: 5000,
softAllowedMaximumThroughput: 1000000, softAllowedMaximumThroughput: 1000000,
isGlobalSecondaryIndex: false,
}; };
it("throughput input visible", () => { it("throughput input visible", () => {

View File

@ -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>
); );
}; };

View File

@ -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]}

View File

@ -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">

View File

@ -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 }} />
)} )}

View File

@ -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);
}} }}

View File

@ -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>
);
};

View File

@ -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 {

View File

@ -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",

View File

@ -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],

View File

@ -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) {