Added localizations 3rd batch (#2413)

* Added localizations 3rd batch

* Fix unit tests
This commit is contained in:
sunghyunkang1111
2026-03-06 11:19:00 -06:00
committed by GitHub
parent 915f549df9
commit b256ac1e1f
30 changed files with 801 additions and 415 deletions
@@ -42,6 +42,8 @@ import {
} from "Explorer/Panes/AddCollectionPanel/AddCollectionPanelUtility";
import { useSidePanel } from "hooks/useSidePanel";
import { useTeachingBubble } from "hooks/useTeachingBubble";
import { Keys } from "Localization/Keys.generated";
import { t } from "Localization/t";
import { DEFAULT_FABRIC_NATIVE_CONTAINER_THROUGHPUT, isFabricNative } from "Platform/Fabric/FabricUtil";
import React from "react";
import { CollectionCreation } from "Shared/Constants";
@@ -177,7 +179,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
messageType="info"
showErrorDetails={false}
link={Constants.Urls.freeTierInformation}
linkText="Learn more"
linkText={t(Keys.common.learnMore)}
/>
)}
@@ -274,17 +276,17 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
</Text>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content={`A database is analogous to a namespace. It is the unit of management for a set of ${getCollectionName(
true,
).toLocaleLowerCase()}.`}
content={t(Keys.panes.addCollection.databaseTooltip, {
collectionName: getCollectionName(true).toLocaleLowerCase(),
})}
>
<Icon
iconName="Info"
className="panelInfoIcon"
tabIndex={0}
ariaLabel={`A database is analogous to a namespace. It is the unit of management for a set of ${getCollectionName(
true,
).toLocaleLowerCase()}.`}
ariaLabel={t(Keys.panes.addCollection.databaseTooltip, {
collectionName: getCollectionName(true).toLocaleLowerCase(),
})}
/>
</TooltipHost>
</Stack>
@@ -304,7 +306,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
tabIndex={0}
onChange={this.onCreateNewDatabaseRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">Create new</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.createNew)}</span>
<input
className="panelRadioBtn"
@@ -317,7 +319,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
tabIndex={0}
onChange={this.onUseExistingDatabaseRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">Use existing</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.useExisting)}</span>
</div>
</Stack>
)}
@@ -347,7 +349,9 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
{!isServerlessAccount() && (
<Stack horizontal>
<Checkbox
label={`Share throughput across ${getCollectionName(true).toLocaleLowerCase()}`}
label={t(Keys.panes.addCollection.shareThroughput, {
collectionName: getCollectionName(true).toLocaleLowerCase(),
})}
checked={this.state.isSharedThroughputChecked}
styles={{
text: { fontSize: 12, color: "var(--colorNeutralForeground1)" },
@@ -365,17 +369,17 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
/>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content={`Throughput configured at the database level will be shared across all ${getCollectionName(
true,
).toLocaleLowerCase()} within the database.`}
content={t(Keys.panes.addCollection.shareThroughputTooltip, {
collectionName: getCollectionName(true).toLocaleLowerCase(),
})}
>
<Icon
iconName="Info"
className="panelInfoIcon"
tabIndex={0}
ariaLabel={`Throughput configured at the database level will be shared across all ${getCollectionName(
true,
).toLocaleLowerCase()} within the database.`}
ariaLabel={t(Keys.panes.addCollection.shareThroughputTooltip, {
collectionName: getCollectionName(true).toLocaleLowerCase(),
})}
/>
</TooltipHost>
</Stack>
@@ -424,14 +428,18 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
</Text>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content={`Unique identifier for the ${getCollectionName().toLocaleLowerCase()} and used for id-based routing through REST and all SDKs.`}
content={t(Keys.panes.addCollection.collectionIdTooltip, {
collectionName: getCollectionName().toLocaleLowerCase(),
})}
>
<Icon
role="button"
iconName="Info"
className="panelInfoIcon"
tabIndex={0}
ariaLabel={`Unique identifier for the ${getCollectionName().toLocaleLowerCase()} and used for id-based routing through REST and all SDKs.`}
ariaLabel={t(Keys.panes.addCollection.collectionIdTooltip, {
collectionName: getCollectionName().toLocaleLowerCase(),
})}
/>
</TooltipHost>
</Stack>
@@ -445,10 +453,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
autoComplete="off"
pattern={ValidCosmosDbIdInputPattern.source}
title={ValidCosmosDbIdDescription}
placeholder={`e.g., ${getCollectionName()}1`}
placeholder={t(Keys.panes.addCollection.collectionIdPlaceholder, { collectionName: getCollectionName() })}
size={40}
className="panelTextField"
aria-label={`${getCollectionName()} id, Example ${getCollectionName()}1`}
aria-label={t(Keys.panes.addCollection.collectionIdAriaLabel, { collectionName: getCollectionName() })}
value={this.state.collectionId}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
this.setState({ collectionId: event.target.value })
@@ -462,7 +470,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
<Stack horizontal style={{ marginTop: -4, marginBottom: -5 }}>
<span className="mandatoryStar">*&nbsp;</span>
<Text className="panelTextBold" variant="small">
Indexing
{t(Keys.panes.addCollection.indexing)}
</Text>
</Stack>
@@ -470,32 +478,32 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
<input
className="panelRadioBtn"
checked={this.state.enableIndexing}
aria-label="Turn on indexing"
aria-label={t(Keys.panes.addCollection.turnOnIndexing)}
aria-checked={this.state.enableIndexing}
type="radio"
role="radio"
tabIndex={0}
onChange={this.onTurnOnIndexing.bind(this)}
/>
<span className="panelRadioBtnLabel">Automatic</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.automatic)}</span>
<input
className="panelRadioBtn"
checked={!this.state.enableIndexing}
aria-label="Turn off indexing"
aria-label={t(Keys.panes.addCollection.turnOffIndexing)}
aria-checked={!this.state.enableIndexing}
type="radio"
role="radio"
tabIndex={0}
onChange={this.onTurnOffIndexing.bind(this)}
/>
<span className="panelRadioBtnLabel">Off</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.off)}</span>
</Stack>
<Text variant="small">
{this.getFreeTierIndexingText()}{" "}
<Link target="_blank" href="https://aka.ms/cosmos-indexing-policy">
Learn more
{t(Keys.common.learnMore)}
</Link>
</Text>
</Stack>
@@ -508,21 +516,17 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
<Stack horizontal style={{ marginTop: -5, marginBottom: -4 }}>
<span className="mandatoryStar">*&nbsp;</span>
<Text className="panelTextBold" variant="small">
Sharding
{t(Keys.panes.addCollection.sharding)}
</Text>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content={
"Sharded collections split your data across many replica sets (shards) to achieve unlimited scalability. Sharded collections require choosing a shard key (field) to evenly distribute your data."
}
content={t(Keys.panes.addCollection.shardingTooltip)}
>
<Icon
iconName="Info"
className="panelInfoIcon"
tabIndex={0}
ariaLabel={
"Sharded collections split your data across many replica sets (shards) to achieve unlimited scalability. Sharded collections require choosing a shard key (field) to evenly distribute your data."
}
ariaLabel={t(Keys.panes.addCollection.shardingTooltip)}
/>
</TooltipHost>
</Stack>
@@ -531,7 +535,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
<input
className="panelRadioBtn"
checked={!this.state.isSharded}
aria-label="Unsharded"
aria-label={t(Keys.panes.addCollection.unsharded)}
aria-checked={!this.state.isSharded}
name="unsharded"
type="radio"
@@ -540,12 +544,12 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
tabIndex={0}
onChange={this.onUnshardedRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">Unsharded (20GB limit)</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.unshardedLabel)}</span>
<input
className="panelRadioBtn"
checked={this.state.isSharded}
aria-label="Sharded"
aria-label={t(Keys.panes.addCollection.sharded)}
aria-checked={this.state.isSharded}
name="sharded"
type="radio"
@@ -554,7 +558,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
tabIndex={0}
onChange={this.onShardedRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">Sharded</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.sharded)}</span>
</Stack>
</Stack>
)}
@@ -679,15 +683,14 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
disabled={this.state.subPartitionKeys.length >= Constants.BackendDefaults.maxNumMultiHashPartition}
onClick={() => this.setState({ subPartitionKeys: [...this.state.subPartitionKeys, ""] })}
>
Add hierarchical partition key
{t(Keys.panes.addCollection.addPartitionKey)}
</DefaultButton>
{this.state.subPartitionKeys.length > 0 && (
<Text variant="small" style={{ color: "var(--colorNeutralForeground1)" }}>
<Icon iconName="InfoSolid" className="removeIcon" tabIndex={0} /> This feature allows you to
partition your data with up to three levels of keys for better data distribution. Requires .NET
V3, Java V4 SDK, or preview JavaScript V3 SDK.{" "}
<Icon iconName="InfoSolid" className="removeIcon" tabIndex={0} />{" "}
{t(Keys.panes.addCollection.hierarchicalPartitionKeyInfo)}{" "}
<Link href="https://aka.ms/cosmos-hierarchical-partitioning" target="_blank">
Learn more
{t(Keys.common.learnMore)}
</Link>
</Text>
)}
@@ -700,7 +703,9 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
{!isServerlessAccount() && !this.state.createNewDatabase && this.isSelectedDatabaseSharedThroughput() && (
<Stack horizontal verticalAlign="center">
<Checkbox
label={`Provision dedicated throughput for this ${getCollectionName().toLocaleLowerCase()}`}
label={t(Keys.panes.addCollection.provisionDedicatedThroughput, {
collectionName: getCollectionName().toLocaleLowerCase(),
})}
checked={this.state.enableDedicatedThroughput}
styles={{
text: { fontSize: 12, color: "var(--colorNeutralForeground1)" },
@@ -718,23 +723,19 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
/>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content={`You can optionally provision dedicated throughput for a ${getCollectionName().toLocaleLowerCase()} within a database that has throughput
provisioned. This dedicated throughput amount will not be shared with other ${getCollectionName(
true,
).toLocaleLowerCase()} in the database and
does not count towards the throughput you provisioned for the database. This throughput amount will be
billed in addition to the throughput amount you provisioned at the database level.`}
content={t(Keys.panes.addCollection.provisionDedicatedThroughputTooltip, {
collectionName: getCollectionName().toLocaleLowerCase(),
collectionNamePlural: getCollectionName(true).toLocaleLowerCase(),
})}
>
<Icon
iconName="Info"
className="panelInfoIcon"
tabIndex={0}
ariaLabel={`You can optionally provision dedicated throughput for a ${getCollectionName().toLocaleLowerCase()} within a database that has throughput
provisioned. This dedicated throughput amount will not be shared with other ${getCollectionName(
true,
).toLocaleLowerCase()} in the database and
does not count towards the throughput you provisioned for the database. This throughput amount will be
billed in addition to the throughput amount you provisioned at the database level.`}
ariaLabel={t(Keys.panes.addCollection.provisionDedicatedThroughputTooltip, {
collectionName: getCollectionName().toLocaleLowerCase(),
collectionNamePlural: getCollectionName(true).toLocaleLowerCase(),
})}
/>
</TooltipHost>
</Stack>
@@ -769,8 +770,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
autoComplete="off"
placeholder={
userContext.apiType === "Mongo"
? "Comma separated paths e.g. firstName,address.zipCode"
: "Comma separated paths e.g. /firstName,/address/zipCode"
? t(Keys.panes.addCollection.uniqueKeysPlaceholderMongo)
: t(Keys.panes.addCollection.uniqueKeysPlaceholderSql)
}
className="panelTextField"
value={uniqueKey}
@@ -802,7 +803,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
styles={{ root: { padding: 0 }, label: { fontSize: 12, color: "var(--colorNeutralForeground1)" } }}
onClick={() => this.setState({ uniqueKeys: [...this.state.uniqueKeys, ""] })}
>
Add unique key
{t(Keys.panes.addCollection.addUniqueKey)}
</ActionButton>
</Stack>
)}
@@ -823,7 +824,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
className="panelRadioBtn"
checked={this.state.enableAnalyticalStore}
disabled={!isSynapseLinkEnabled()}
aria-label="Enable analytical store"
aria-label={t(Keys.panes.addCollection.enableAnalyticalStore)}
aria-checked={this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
@@ -832,13 +833,13 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
tabIndex={0}
onChange={this.onEnableAnalyticalStoreRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">On</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.on)}</span>
<input
className="panelRadioBtn"
checked={!this.state.enableAnalyticalStore}
disabled={!isSynapseLinkEnabled()}
aria-label="Disable analytical store"
aria-label={t(Keys.panes.addCollection.disableAnalyticalStore)}
aria-checked={!this.state.enableAnalyticalStore}
name="analyticalStore"
type="radio"
@@ -847,26 +848,28 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
tabIndex={0}
onChange={this.onDisableAnalyticalStoreRadioBtnChange.bind(this)}
/>
<span className="panelRadioBtnLabel">Off</span>
<span className="panelRadioBtnLabel">{t(Keys.panes.addCollection.off)}</span>
</div>
</Stack>
{!isSynapseLinkEnabled() && (
<Stack className="panelGroupSpacing">
<Text variant="small" style={{ color: "var(--colorNeutralForeground1)" }}>
Azure Synapse Link is required for creating an analytical store{" "}
{getCollectionName().toLocaleLowerCase()}. Enable Synapse Link for this Cosmos DB account. <br />
{t(Keys.panes.addCollection.analyticalStoreSynapseLinkRequired, {
collectionName: getCollectionName().toLocaleLowerCase(),
})}{" "}
<br />
<Link
href="https://aka.ms/cosmosdb-synapselink"
target="_blank"
aria-label={Constants.ariaLabelForLearnMoreLink.AzureSynapseLink}
className="capacitycalculator-link"
>
Learn more
{t(Keys.common.learnMore)}
</Link>
</Text>
<DefaultButton
text="Enable"
text={t(Keys.panes.addCollection.enable)}
onClick={() => this.props.explorer.openEnableSynapseLinkDialog()}
style={{ height: 27, width: 80 }}
styles={{ label: { fontSize: 12 } }}
@@ -878,7 +881,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
{this.shouldShowVectorSearchParameters() && (
<Stack>
<CollapsibleSectionComponent
title="Container Vector Policy"
title={t(Keys.panes.addCollection.containerVectorPolicy)}
isExpandedByDefault={false}
onExpand={() => {
scrollToSection("collapsibleVectorPolicySectionContent");
@@ -906,7 +909,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
{this.shouldShowFullTextSearchParameters() && (
<Stack>
<CollapsibleSectionComponent
title="Container Full Text Search Policy"
title={t(Keys.panes.addCollection.containerFullTextSearchPolicy)}
isExpandedByDefault={false}
onExpand={() => {
scrollToSection("collapsibleFullTextPolicySectionContent");
@@ -935,7 +938,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
)}
{!isFabricNative() && userContext.apiType !== "Tables" && (
<CollapsibleSectionComponent
title="Advanced"
title={t(Keys.panes.addCollection.advanced)}
isExpandedByDefault={false}
onExpand={() => {
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
@@ -948,23 +951,23 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
<Stack horizontal>
<span className="mandatoryStar">*&nbsp;</span>
<Text className="panelTextBold" variant="small">
Indexing
{t(Keys.panes.addCollection.indexing)}
</Text>
<TooltipHost
directionalHint={DirectionalHint.bottomLeftEdge}
content="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
content={t(Keys.panes.addCollection.mongoIndexingTooltip)}
>
<Icon
iconName="Info"
className="panelInfoIcon"
tabIndex={0}
ariaLabel="The _id field is indexed by default. Creating a wildcard index for all fields will optimize queries and is recommended for development."
ariaLabel={t(Keys.panes.addCollection.mongoIndexingTooltip)}
/>
</TooltipHost>
</Stack>
<Checkbox
label="Create a Wildcard Index on all fields"
label={t(Keys.panes.addCollection.createWildcardIndex)}
checked={this.state.createMongoWildCardIndex}
styles={{
text: { fontSize: 12, color: "var(--colorNeutralForeground1)" },
@@ -986,7 +989,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
{userContext.apiType === "SQL" && (
<Stack className="panelGroupSpacing">
<Checkbox
label="My application uses an older Cosmos .NET or Java SDK version (.NET V1 or Java V2)"
label={t(Keys.panes.addCollection.legacySdkCheckbox)}
checked={this.state.useHashV1}
styles={{
text: { fontSize: 12, color: "var(--colorNeutralForeground1)" },
@@ -1003,11 +1006,9 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
}
/>
<Text variant="small" style={{ color: "var(--colorNeutralForeground1)" }}>
<Icon iconName="InfoSolid" className="removeIcon" /> To ensure compatibility with older SDKs, the
created container will use a legacy partitioning scheme that supports partition key values of size
only up to 101 bytes. If this is enabled, you will not be able to use hierarchical partition keys.{" "}
<Icon iconName="InfoSolid" className="removeIcon" /> {t(Keys.panes.addCollection.legacySdkInfo)}{" "}
<Link href="https://aka.ms/cosmos-large-pk" target="_blank">
Learn more
{t(Keys.common.learnMore)}
</Link>
</Text>
</Stack>
@@ -1018,7 +1019,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
</div>
{!this.props.isCopyJobFlow && (
<PanelFooterComponent buttonLabel="OK" isButtonDisabled={this.state.isThroughputCapExceeded} />
<PanelFooterComponent buttonLabel={t(Keys.common.ok)} isButtonDisabled={this.state.isThroughputCapExceeded} />
)}
{this.state.isExecuting && (
@@ -1044,7 +1045,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
progressTrack: { backgroundColor: "#A6A6A6" },
progressBar: { background: "white" },
}}
label="Adding sample data set"
label={t(Keys.panes.addCollection.addingSampleDataSet)}
/>
</TeachingBubble>
)}
@@ -1150,8 +1151,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
private getFreeTierIndexingText(): string {
return this.state.enableIndexing
? "All properties in your documents will be indexed by default for flexible and efficient queries."
: "Indexing will be turned off. Recommended if you don't need to run queries or only have key value operations.";
? t(Keys.panes.addCollection.indexingOnInfo)
: t(Keys.panes.addCollection.indexingOffInfo);
}
private getPartitionKeySubtext(): string {
@@ -1249,14 +1250,14 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
const throughput = this.state.createNewDatabase ? this.newDatabaseThroughput : this.collectionThroughput;
if (throughput > CollectionCreation.DefaultCollectionRUs100K && !this.isCostAcknowledged) {
const errorMessage = this.isNewDatabaseAutoscale
? "Please acknowledge the estimated monthly spend."
: "Please acknowledge the estimated daily spend.";
? t(Keys.panes.addCollection.acknowledgeSpendErrorMonthly)
: t(Keys.panes.addCollection.acknowledgeSpendErrorDaily);
this.setState({ errorMessage });
return false;
}
if (throughput > CollectionCreation.MaxRUPerPartition && !this.state.isSharded) {
this.setState({ errorMessage: "Unsharded collections support up to 10,000 RUs" });
this.setState({ errorMessage: t(Keys.panes.addCollection.unshardedMaxRuError) });
return false;
}
@@ -1270,12 +1271,12 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
if (this.shouldShowVectorSearchParameters()) {
if (!this.state.vectorPolicyValidated) {
this.setState({ errorMessage: "Please fix errors in container vector policy" });
this.setState({ errorMessage: t(Keys.panes.addCollection.vectorPolicyError) });
return false;
}
if (!this.state.fullTextPolicyValidated) {
this.setState({ errorMessage: "Please fix errors in container full text search polilcy" });
this.setState({ errorMessage: t(Keys.panes.addCollection.fullTextSearchPolicyError) });
return false;
}
}
@@ -3,28 +3,33 @@ import * as Constants from "Common/Constants";
import { configContext, Platform } from "ConfigContext";
import * as DataModels from "Contracts/DataModels";
import { getFullTextLanguageOptions } from "Explorer/Controls/FullTextSeach/FullTextPoliciesComponent";
import { Keys } from "Localization/Keys.generated";
import { t } from "Localization/t";
import { isFabricNative } from "Platform/Fabric/FabricUtil";
import React from "react";
import { userContext } from "UserContext";
export function getPartitionKeyTooltipText(): string {
if (userContext.apiType === "Mongo") {
return "The shard key (field) is used to split your data across many replica sets (shards) to achieve unlimited scalability. Its critical to choose a field that will evenly distribute your data.";
return t(Keys.panes.addCollectionUtility.shardKeyTooltip);
}
let tooltipText = `The ${getPartitionKeyName(
true,
)} is used to automatically distribute data across partitions for scalability. Choose a property in your JSON document that has a wide range of values and evenly distributes request volume.`;
let tooltipText = t(Keys.panes.addCollectionUtility.partitionKeyTooltip, {
partitionKeyName: getPartitionKeyName(true),
});
if (userContext.apiType === "SQL") {
tooltipText += " For small read-heavy workloads or write-heavy workloads of any size, id is often a good choice.";
tooltipText += t(Keys.panes.addCollectionUtility.partitionKeyTooltipSqlSuffix);
}
return tooltipText;
}
export function getPartitionKeyName(isLowerCase?: boolean): string {
const partitionKeyName = userContext.apiType === "Mongo" ? "Shard key" : "Partition key";
const partitionKeyName =
userContext.apiType === "Mongo"
? t(Keys.panes.addCollectionUtility.shardKeyLabel)
: t(Keys.panes.addCollectionUtility.partitionKeyLabel);
return isLowerCase ? partitionKeyName.toLocaleLowerCase() : partitionKeyName;
}
@@ -32,19 +37,19 @@ export function getPartitionKeyName(isLowerCase?: boolean): string {
export function getPartitionKeyPlaceHolder(index?: number): string {
switch (userContext.apiType) {
case "Mongo":
return "e.g., categoryId";
return t(Keys.panes.addCollectionUtility.shardKeyPlaceholder);
case "Gremlin":
return "e.g., /address";
return t(Keys.panes.addCollectionUtility.partitionKeyPlaceholderDefault);
case "SQL":
return `${
index === undefined
? "Required - first partition key e.g., /TenantId"
? t(Keys.panes.addCollectionUtility.partitionKeyPlaceholderFirst)
: index === 0
? "second partition key e.g., /UserId"
: "third partition key e.g., /SessionId"
? t(Keys.panes.addCollectionUtility.partitionKeyPlaceholderSecond)
: t(Keys.panes.addCollectionUtility.partitionKeyPlaceholderThird)
}`;
default:
return "e.g., /address/zipCode";
return t(Keys.panes.addCollectionUtility.partitionKeyPlaceholderGraph);
}
}
@@ -69,13 +74,12 @@ export function isFreeTierAccount(): boolean {
}
export function UniqueKeysHeader(): JSX.Element {
const tooltipContent =
"Unique keys provide developers with the ability to add a layer of data integrity to their database. By creating a unique key policy when a container is created, you ensure the uniqueness of one or more values per partition key.";
const tooltipContent = t(Keys.panes.addCollectionUtility.uniqueKeysTooltip);
return (
<Stack horizontal style={{ marginBottom: -2 }}>
<Text className="panelTextBold" variant="small">
Unique keys
{t(Keys.panes.addCollectionUtility.uniqueKeysLabel)}
</Text>
<TooltipHost directionalHint={DirectionalHint.bottomLeftEdge} content={tooltipContent}>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} ariaLabel={tooltipContent} />
@@ -99,12 +103,11 @@ export function shouldShowAnalyticalStoreOptions(): boolean {
}
export function AnalyticalStoreHeader(): JSX.Element {
const tooltipContent =
"Enable analytical store capability to perform near real-time analytics on your operational data, without impacting the performance of transactional workloads.";
const tooltipContent = t(Keys.panes.addCollectionUtility.analyticalStoreTooltip);
return (
<Stack horizontal style={{ marginBottom: -2 }}>
<Text className="panelTextBold" variant="small">
Analytical Store
{t(Keys.panes.addCollectionUtility.analyticalStoreLabel)}
</Text>
<TooltipHost directionalHint={DirectionalHint.bottomLeftEdge} content={tooltipContent}>
<Icon iconName="Info" className="panelInfoIcon" tabIndex={0} ariaLabel={tooltipContent} />
@@ -116,14 +119,13 @@ export function AnalyticalStoreHeader(): JSX.Element {
export function AnalyticalStorageContent(): JSX.Element {
return (
<Text variant="small">
Enable analytical store capability to perform near real-time analytics on your operational data, without impacting
the performance of transactional workloads.{" "}
{t(Keys.panes.addCollectionUtility.analyticalStoreDescription)}{" "}
<Link
aria-label={Constants.ariaLabelForLearnMoreLink.AnalyticalStore}
target="_blank"
href="https://aka.ms/analytical-store-overview"
>
Learn more
{t(Keys.common.learnMore)}
</Link>
</Text>
);
@@ -155,10 +157,9 @@ export function scrollToSection(id: string): void {
export function ContainerVectorPolicyTooltipContent(): JSX.Element {
return (
<Text variant="small">
Describe any properties in your data that contain vectors, so that they can be made available for similarity
queries.{" "}
{t(Keys.panes.addCollectionUtility.vectorPolicyTooltip)}{" "}
<Link target="_blank" href="https://aka.ms/CosmosDBVectorSetup">
Learn more
{t(Keys.common.learnMore)}
</Link>
</Text>
);
@@ -482,10 +482,8 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
}
variant="small"
>
Azure Synapse Link is required for creating an analytical store
Azure Synapse Link is required for creating an analytical store container. Enable Synapse Link for this Cosmos DB account.
container
. Enable Synapse Link for this Cosmos DB account.
<br />
<StyledLinkBase
aria-label="Learn more about Azure Synapse Link."
@@ -608,7 +606,8 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
className="removeIcon"
iconName="InfoSolid"
/>
To ensure compatibility with older SDKs, the created container will use a legacy partitioning scheme that supports partition key values of size only up to 101 bytes. If this is enabled, you will not be able to use hierarchical partition keys.
To ensure compatibility with older SDKs, the created container will use a legacy partitioning scheme that supports partition key values of size only up to 101 bytes. If this is enabled, you will not be able to use hierarchical partition keys.
<StyledLinkBase
href="https://aka.ms/cosmos-large-pk"