mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-26 13:14:04 +00:00
Compare commits
3 Commits
users/aisa
...
hotfix/nov
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d35ae7e0f1 | ||
|
|
d0d615a85a | ||
|
|
2996120235 |
@@ -89,7 +89,7 @@ export class CapabilityNames {
|
|||||||
public static readonly EnableMongo: string = "EnableMongo";
|
public static readonly EnableMongo: string = "EnableMongo";
|
||||||
public static readonly EnableServerless: string = "EnableServerless";
|
public static readonly EnableServerless: string = "EnableServerless";
|
||||||
public static readonly EnableNoSQLVectorSearch: string = "EnableNoSQLVectorSearch";
|
public static readonly EnableNoSQLVectorSearch: string = "EnableNoSQLVectorSearch";
|
||||||
public static readonly EnableNoSQLFullTextSearch: string = "EnableNoSQLFullTextSearch";
|
public static readonly EnableNoSQLFullTextSearchPreviewFeatures: string = "EnableNoSQLFullTextSearchPreviewFeatures";
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CapacityMode {
|
export enum CapacityMode {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
import { FullTextIndex, FullTextPath, FullTextPolicy } from "Contracts/DataModels";
|
import { FullTextIndex, FullTextPath, FullTextPolicy } from "Contracts/DataModels";
|
||||||
import { CollapsibleSectionComponent } from "Explorer/Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
import { CollapsibleSectionComponent } from "Explorer/Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import { isFullTextSearchPreviewFeaturesEnabled } from "Utils/CapabilityUtils";
|
||||||
|
|
||||||
export interface FullTextPoliciesComponentProps {
|
export interface FullTextPoliciesComponentProps {
|
||||||
fullTextPolicy: FullTextPolicy;
|
fullTextPolicy: FullTextPolicy;
|
||||||
@@ -22,6 +23,7 @@ export interface FullTextPoliciesComponentProps {
|
|||||||
) => void;
|
) => void;
|
||||||
discardChanges?: boolean;
|
discardChanges?: boolean;
|
||||||
onChangesDiscarded?: () => void;
|
onChangesDiscarded?: () => void;
|
||||||
|
englishOnly?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FullTextPolicyData {
|
export interface FullTextPolicyData {
|
||||||
@@ -66,6 +68,7 @@ export const FullTextPoliciesComponent: React.FunctionComponent<FullTextPolicies
|
|||||||
onFullTextPathChange,
|
onFullTextPathChange,
|
||||||
discardChanges,
|
discardChanges,
|
||||||
onChangesDiscarded,
|
onChangesDiscarded,
|
||||||
|
englishOnly,
|
||||||
}): JSX.Element => {
|
}): JSX.Element => {
|
||||||
const getFullTextPathError = (path: string, index?: number): string => {
|
const getFullTextPathError = (path: string, index?: number): string => {
|
||||||
let error = "";
|
let error = "";
|
||||||
@@ -87,6 +90,7 @@ export const FullTextPoliciesComponent: React.FunctionComponent<FullTextPolicies
|
|||||||
if (!fullTextPolicy) {
|
if (!fullTextPolicy) {
|
||||||
fullTextPolicy = { defaultLanguage: getFullTextLanguageOptions()[0].key as never, fullTextPaths: [] };
|
fullTextPolicy = { defaultLanguage: getFullTextLanguageOptions()[0].key as never, fullTextPaths: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullTextPolicy.fullTextPaths.map((fullTextPath: FullTextPath) => ({
|
return fullTextPolicy.fullTextPaths.map((fullTextPath: FullTextPath) => ({
|
||||||
...fullTextPath,
|
...fullTextPath,
|
||||||
pathError: getFullTextPathError(fullTextPath.path),
|
pathError: getFullTextPathError(fullTextPath.path),
|
||||||
@@ -166,7 +170,7 @@ export const FullTextPoliciesComponent: React.FunctionComponent<FullTextPolicies
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
required={true}
|
required={true}
|
||||||
styles={dropdownStyles}
|
styles={dropdownStyles}
|
||||||
options={getFullTextLanguageOptions()}
|
options={getFullTextLanguageOptions(englishOnly)}
|
||||||
selectedKey={defaultLanguage}
|
selectedKey={defaultLanguage}
|
||||||
onChange={(_event: React.FormEvent<HTMLDivElement>, option: IDropdownOption) =>
|
onChange={(_event: React.FormEvent<HTMLDivElement>, option: IDropdownOption) =>
|
||||||
setDefaultLanguage(option.key as never)
|
setDefaultLanguage(option.key as never)
|
||||||
@@ -211,7 +215,7 @@ export const FullTextPoliciesComponent: React.FunctionComponent<FullTextPolicies
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
required={true}
|
required={true}
|
||||||
styles={dropdownStyles}
|
styles={dropdownStyles}
|
||||||
options={getFullTextLanguageOptions()}
|
options={getFullTextLanguageOptions(englishOnly)}
|
||||||
selectedKey={fullTextPolicy.language}
|
selectedKey={fullTextPolicy.language}
|
||||||
onChange={(_event: React.FormEvent<HTMLDivElement>, option: IDropdownOption) =>
|
onChange={(_event: React.FormEvent<HTMLDivElement>, option: IDropdownOption) =>
|
||||||
onFullTextPathPolicyChange(index, option)
|
onFullTextPathPolicyChange(index, option)
|
||||||
@@ -229,11 +233,30 @@ export const FullTextPoliciesComponent: React.FunctionComponent<FullTextPolicies
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getFullTextLanguageOptions = (): IDropdownOption[] => {
|
export const getFullTextLanguageOptions = (englishOnly?: boolean): IDropdownOption[] => {
|
||||||
return [
|
const multiLanguageSupportEnabled: boolean = isFullTextSearchPreviewFeaturesEnabled() && !englishOnly;
|
||||||
|
const fullTextLanguageOptions: IDropdownOption[] = [
|
||||||
{
|
{
|
||||||
key: "en-US",
|
key: "en-US",
|
||||||
text: "English (US)",
|
text: "English (US)",
|
||||||
},
|
},
|
||||||
|
...(multiLanguageSupportEnabled
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
key: "fr-FR",
|
||||||
|
text: "French",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "de-DE",
|
||||||
|
text: "German",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "es-ES",
|
||||||
|
text: "Spanish",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
return fullTextLanguageOptions;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -893,6 +893,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
|||||||
) => {
|
) => {
|
||||||
this.setState({ fullTextPolicy, fullTextIndexes, fullTextPolicyValidated });
|
this.setState({ fullTextPolicy, fullTextIndexes, fullTextPolicyValidated });
|
||||||
}}
|
}}
|
||||||
|
// Remove when multi language support on container create issue is fixed
|
||||||
|
englishOnly={true}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -516,6 +516,7 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<FullTextPoliciesComponent
|
<FullTextPoliciesComponent
|
||||||
|
englishOnly={true}
|
||||||
fullTextPolicy={
|
fullTextPolicy={
|
||||||
{
|
{
|
||||||
"defaultLanguage": "en-US",
|
"defaultLanguage": "en-US",
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
IToggleStyles,
|
IToggleStyles,
|
||||||
Position,
|
Position,
|
||||||
SpinButton,
|
SpinButton,
|
||||||
|
Stack,
|
||||||
Toggle,
|
Toggle,
|
||||||
} from "@fluentui/react";
|
} from "@fluentui/react";
|
||||||
import { Accordion, AccordionHeader, AccordionItem, AccordionPanel, makeStyles } from "@fluentui/react-components";
|
import { Accordion, AccordionHeader, AccordionItem, AccordionPanel, makeStyles } from "@fluentui/react-components";
|
||||||
@@ -1163,14 +1164,20 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
|||||||
</AccordionHeader>
|
</AccordionHeader>
|
||||||
<AccordionPanel>
|
<AccordionPanel>
|
||||||
<div className={styles.settingsSectionContainer}>
|
<div className={styles.settingsSectionContainer}>
|
||||||
<Checkbox
|
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
|
||||||
styles={{ label: { padding: 0 } }}
|
<Checkbox
|
||||||
className="padding"
|
styles={{ label: { padding: 0 } }}
|
||||||
ariaLabel="Ignore partition key on document update"
|
className="padding"
|
||||||
checked={ignorePartitionKeyOnDocumentUpdate}
|
ariaLabel="Ignore partition key on document update"
|
||||||
onChange={handleOnIgnorePartitionKeyOnDocumentUpdateChange}
|
checked={ignorePartitionKeyOnDocumentUpdate}
|
||||||
label="Ignore partition key on document update"
|
onChange={handleOnIgnorePartitionKeyOnDocumentUpdateChange}
|
||||||
/>
|
label="Ignore partition key on document update"
|
||||||
|
/>
|
||||||
|
<InfoTooltip className={styles.headerIcon}>
|
||||||
|
If checked, the partition key value will not be used to locate the document during update
|
||||||
|
operations. Only use this if document updates are failing due to an abnormal partition key.
|
||||||
|
</InfoTooltip>
|
||||||
|
</Stack>
|
||||||
</div>
|
</div>
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
|||||||
@@ -589,20 +589,35 @@ exports[`Settings Pane should render Default properly 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="___1dfa554_0000000 fo7qwa0"
|
className="___1dfa554_0000000 fo7qwa0"
|
||||||
>
|
>
|
||||||
<StyledCheckboxBase
|
<Stack
|
||||||
ariaLabel="Ignore partition key on document update"
|
horizontal={true}
|
||||||
checked={false}
|
tokens={
|
||||||
className="padding"
|
|
||||||
label="Ignore partition key on document update"
|
|
||||||
onChange={[Function]}
|
|
||||||
styles={
|
|
||||||
{
|
{
|
||||||
"label": {
|
"childrenGap": 4,
|
||||||
"padding": 0,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/>
|
verticalAlign="center"
|
||||||
|
>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
ariaLabel="Ignore partition key on document update"
|
||||||
|
checked={false}
|
||||||
|
className="padding"
|
||||||
|
label="Ignore partition key on document update"
|
||||||
|
onChange={[Function]}
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"label": {
|
||||||
|
"padding": 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<InfoTooltip
|
||||||
|
className="___vtc5hy0_0000000 f10ra9hq f1k6fduh"
|
||||||
|
>
|
||||||
|
If checked, the partition key value will not be used to locate the document during update operations. Only use this if document updates are failing due to an abnormal partition key.
|
||||||
|
</InfoTooltip>
|
||||||
|
</Stack>
|
||||||
</div>
|
</div>
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
@@ -883,20 +898,35 @@ exports[`Settings Pane should render Gremlin properly 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="___1dfa554_0000000 fo7qwa0"
|
className="___1dfa554_0000000 fo7qwa0"
|
||||||
>
|
>
|
||||||
<StyledCheckboxBase
|
<Stack
|
||||||
ariaLabel="Ignore partition key on document update"
|
horizontal={true}
|
||||||
checked={false}
|
tokens={
|
||||||
className="padding"
|
|
||||||
label="Ignore partition key on document update"
|
|
||||||
onChange={[Function]}
|
|
||||||
styles={
|
|
||||||
{
|
{
|
||||||
"label": {
|
"childrenGap": 4,
|
||||||
"padding": 0,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/>
|
verticalAlign="center"
|
||||||
|
>
|
||||||
|
<StyledCheckboxBase
|
||||||
|
ariaLabel="Ignore partition key on document update"
|
||||||
|
checked={false}
|
||||||
|
className="padding"
|
||||||
|
label="Ignore partition key on document update"
|
||||||
|
onChange={[Function]}
|
||||||
|
styles={
|
||||||
|
{
|
||||||
|
"label": {
|
||||||
|
"padding": 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<InfoTooltip
|
||||||
|
className="___vtc5hy0_0000000 f10ra9hq f1k6fduh"
|
||||||
|
>
|
||||||
|
If checked, the partition key value will not be used to locate the document during update operations. Only use this if document updates are failing due to an abnormal partition key.
|
||||||
|
</InfoTooltip>
|
||||||
|
</Stack>
|
||||||
</div>
|
</div>
|
||||||
</AccordionPanel>
|
</AccordionPanel>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
import { Upload } from "Common/Upload/Upload";
|
import { Upload } from "Common/Upload/Upload";
|
||||||
import { UploadDetailsRecord } from "Contracts/ViewModels";
|
import { UploadDetailsRecord } from "Contracts/ViewModels";
|
||||||
import { logConsoleError } from "Utils/NotificationConsoleUtils";
|
import { logConsoleError } from "Utils/NotificationConsoleUtils";
|
||||||
import React, { ChangeEvent, FunctionComponent, useState } from "react";
|
import React, { ChangeEvent, FunctionComponent, useReducer, useState } from "react";
|
||||||
import { getErrorMessage } from "../../Tables/Utilities";
|
import { getErrorMessage } from "../../Tables/Utilities";
|
||||||
import { useSelectedNode } from "../../useSelectedNode";
|
import { useSelectedNode } from "../../useSelectedNode";
|
||||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
@@ -57,6 +57,7 @@ export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({ onUpl
|
|||||||
const [uploadFileData, setUploadFileData] = useState<UploadDetailsRecord[]>([]);
|
const [uploadFileData, setUploadFileData] = useState<UploadDetailsRecord[]>([]);
|
||||||
const [formError, setFormError] = useState<string>("");
|
const [formError, setFormError] = useState<string>("");
|
||||||
const [isExecuting, setIsExecuting] = useState<boolean>();
|
const [isExecuting, setIsExecuting] = useState<boolean>();
|
||||||
|
const [reducer, setReducer] = useReducer((x) => x + 1, 1);
|
||||||
|
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
setFormError("");
|
setFormError("");
|
||||||
@@ -75,6 +76,7 @@ export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({ onUpl
|
|||||||
(uploadDetails) => {
|
(uploadDetails) => {
|
||||||
setUploadFileData(uploadDetails.data);
|
setUploadFileData(uploadDetails.data);
|
||||||
setFiles(undefined);
|
setFiles(undefined);
|
||||||
|
setReducer(); // Trigger a re-render to update the UI with new upload details
|
||||||
// Emit the upload details to the parent component
|
// Emit the upload details to the parent component
|
||||||
onUpload && onUpload(uploadDetails.data);
|
onUpload && onUpload(uploadDetails.data);
|
||||||
},
|
},
|
||||||
@@ -95,6 +97,7 @@ export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({ onUpl
|
|||||||
const props: RightPaneFormProps = {
|
const props: RightPaneFormProps = {
|
||||||
formError,
|
formError,
|
||||||
isExecuting: isExecuting,
|
isExecuting: isExecuting,
|
||||||
|
isSubmitButtonDisabled: !files || files.length === 0,
|
||||||
submitButtonText: "Upload",
|
submitButtonText: "Upload",
|
||||||
onSubmit,
|
onSubmit,
|
||||||
};
|
};
|
||||||
@@ -192,6 +195,7 @@ export const UploadItemsPane: FunctionComponent<UploadItemsPaneProps> = ({ onUpl
|
|||||||
<RightPaneForm {...props}>
|
<RightPaneForm {...props}>
|
||||||
<div className="paneMainContent">
|
<div className="paneMainContent">
|
||||||
<Upload
|
<Upload
|
||||||
|
key={reducer} // Force re-render on state change
|
||||||
label="Select JSON Files"
|
label="Select JSON Files"
|
||||||
onUpload={updateSelectedFiles}
|
onUpload={updateSelectedFiles}
|
||||||
accept="application/json"
|
accept="application/json"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
exports[`Upload Items Pane should render Default properly 1`] = `
|
exports[`Upload Items Pane should render Default properly 1`] = `
|
||||||
<RightPaneForm
|
<RightPaneForm
|
||||||
formError=""
|
formError=""
|
||||||
|
isSubmitButtonDisabled={true}
|
||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
submitButtonText="Upload"
|
submitButtonText="Upload"
|
||||||
>
|
>
|
||||||
@@ -11,6 +12,7 @@ exports[`Upload Items Pane should render Default properly 1`] = `
|
|||||||
>
|
>
|
||||||
<Upload
|
<Upload
|
||||||
accept="application/json"
|
accept="application/json"
|
||||||
|
key="1"
|
||||||
label="Select JSON Files"
|
label="Select JSON Files"
|
||||||
multiple={true}
|
multiple={true}
|
||||||
onUpload={[Function]}
|
onUpload={[Function]}
|
||||||
|
|||||||
@@ -24,3 +24,10 @@ export const isVectorSearchEnabled = (): boolean => {
|
|||||||
(isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLVectorSearch) || isFabricNative())
|
(isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLVectorSearch) || isFabricNative())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isFullTextSearchPreviewFeaturesEnabled = (): boolean => {
|
||||||
|
return (
|
||||||
|
userContext.apiType === "SQL" &&
|
||||||
|
isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLFullTextSearchPreviewFeatures)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user