mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +00:00
Update prettier to latest. Remove tslint (#1641)
* Rev up prettier * Reformat * Remove deprecated tslint * Remove call to tslint and update package-lock.json
This commit is contained in:
@@ -57,7 +57,7 @@ export const createDatabaseContextMenu = (container: Explorer, databaseId: strin
|
||||
.getState()
|
||||
.openSidePanel(
|
||||
"Delete " + getDatabaseName(),
|
||||
<DeleteDatabaseConfirmationPanel refreshDatabases={() => container.refreshAllDatabases()} />
|
||||
<DeleteDatabaseConfirmationPanel refreshDatabases={() => container.refreshAllDatabases()} />,
|
||||
),
|
||||
label: `Delete ${getDatabaseName()}`,
|
||||
styleClass: "deleteDatabaseMenuItem",
|
||||
@@ -68,7 +68,7 @@ export const createDatabaseContextMenu = (container: Explorer, databaseId: strin
|
||||
|
||||
export const createCollectionContextMenuButton = (
|
||||
container: Explorer,
|
||||
selectedCollection: ViewModels.Collection
|
||||
selectedCollection: ViewModels.Collection,
|
||||
): TreeNodeMenuItem[] => {
|
||||
const items: TreeNodeMenuItem[] = [];
|
||||
if (userContext.apiType === "SQL" || userContext.apiType === "Gremlin") {
|
||||
@@ -137,7 +137,7 @@ export const createCollectionContextMenuButton = (
|
||||
.getState()
|
||||
.openSidePanel(
|
||||
"Delete " + getCollectionName(),
|
||||
<DeleteCollectionConfirmationPane refreshDatabases={() => container.refreshAllDatabases()} />
|
||||
<DeleteCollectionConfirmationPane refreshDatabases={() => container.refreshAllDatabases()} />,
|
||||
);
|
||||
},
|
||||
label: `Delete ${getCollectionName()}`,
|
||||
@@ -175,7 +175,7 @@ export const createSampleCollectionContextMenuButton = (): TreeNodeMenuItem[] =>
|
||||
|
||||
export const createStoreProcedureContextMenuItems = (
|
||||
container: Explorer,
|
||||
storedProcedure: StoredProcedure
|
||||
storedProcedure: StoredProcedure,
|
||||
): TreeNodeMenuItem[] => {
|
||||
if (userContext.apiType === "Cassandra") {
|
||||
return [];
|
||||
@@ -206,7 +206,7 @@ export const createTriggerContextMenuItems = (container: Explorer, trigger: Trig
|
||||
|
||||
export const createUserDefinedFunctionContextMenuItems = (
|
||||
container: Explorer,
|
||||
userDefinedFunction: UserDefinedFunction
|
||||
userDefinedFunction: UserDefinedFunction,
|
||||
): TreeNodeMenuItem[] => {
|
||||
if (userContext.apiType === "Cassandra") {
|
||||
return [];
|
||||
|
||||
@@ -203,11 +203,9 @@ export class CommandButtonComponent extends React.Component<CommandButtonCompone
|
||||
}}
|
||||
>
|
||||
<div className="commandDropdown">
|
||||
{this.props.children.map(
|
||||
(c: CommandButtonComponentProps, index: number): JSX.Element => {
|
||||
return CommandButtonComponent.renderButton(c, `${index}`);
|
||||
}
|
||||
)}
|
||||
{this.props.children.map((c: CommandButtonComponentProps, index: number): JSX.Element => {
|
||||
return CommandButtonComponent.renderButton(c, `${index}`);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -217,7 +215,7 @@ export class CommandButtonComponent extends React.Component<CommandButtonCompone
|
||||
public static renderLabel(
|
||||
props: CommandButtonComponentProps,
|
||||
key?: string,
|
||||
refct?: (input: HTMLElement) => void
|
||||
refct?: (input: HTMLElement) => void,
|
||||
): JSX.Element {
|
||||
if (!props.commandButtonLabel) {
|
||||
return <React.Fragment />;
|
||||
|
||||
@@ -33,7 +33,7 @@ export interface DialogState {
|
||||
contentHtml?: JSX.Element,
|
||||
choiceGroupProps?: IChoiceGroupProps,
|
||||
textFieldProps?: TextFieldProps,
|
||||
primaryButtonDisabled?: boolean
|
||||
primaryButtonDisabled?: boolean,
|
||||
) => void;
|
||||
showOkModalDialog: (title: string, subText: string) => void;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export const useDialog: UseStore<DialogState> = create((set, get) => ({
|
||||
showOkCancelModalDialog: state.showOkCancelModalDialog,
|
||||
showOkModalDialog: state.showOkModalDialog,
|
||||
}),
|
||||
true // TODO: This probably should not be true but its causing a prod bug so easier to just set the proper state above
|
||||
true, // TODO: This probably should not be true but its causing a prod bug so easier to just set the proper state above
|
||||
),
|
||||
showOkCancelModalDialog: (
|
||||
title: string,
|
||||
@@ -62,7 +62,7 @@ export const useDialog: UseStore<DialogState> = create((set, get) => ({
|
||||
contentHtml?: JSX.Element,
|
||||
choiceGroupProps?: IChoiceGroupProps,
|
||||
textFieldProps?: TextFieldProps,
|
||||
primaryButtonDisabled?: boolean
|
||||
primaryButtonDisabled?: boolean,
|
||||
): void =>
|
||||
get().openDialog({
|
||||
isModal: true,
|
||||
|
||||
@@ -95,7 +95,7 @@ export class DiffEditorViewModel {
|
||||
protected async createDiffEditor(
|
||||
originalContent: string,
|
||||
modifiedContent: string,
|
||||
createCallback: (e: monaco.editor.IStandaloneDiffEditor) => void
|
||||
createCallback: (e: monaco.editor.IStandaloneDiffEditor) => void,
|
||||
) {
|
||||
this.editorContainer = document.getElementById(this.getEditorId());
|
||||
this.editorContainer.innerHTML = "";
|
||||
@@ -116,7 +116,7 @@ export class DiffEditorViewModel {
|
||||
const modifiedModel = monaco.editor.createModel(modifiedContent, language);
|
||||
const diffEditor: monaco.editor.IStandaloneDiffEditor = monaco.editor.createDiffEditor(
|
||||
this.editorContainer,
|
||||
options
|
||||
options,
|
||||
);
|
||||
diffEditor.setModel({
|
||||
original: originalModel,
|
||||
|
||||
@@ -84,7 +84,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
||||
(event: monaco.editor.ICursorSelectionChangedEvent) => {
|
||||
const selectedContent: string = this.editor.getModel().getValueInRange(event.selection);
|
||||
this.props.onContentSelected(selectedContent);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ export const FeaturePanelComponent: React.FunctionComponent = () => {
|
||||
|
||||
// React hooks to keep state
|
||||
const [baseUrl, setBaseUrl] = React.useState<IDropdownOption>(
|
||||
baseUrlOptions.find((o) => o.key === window.location.origin + window.location.pathname) || baseUrlOptions[0]
|
||||
baseUrlOptions.find((o) => o.key === window.location.origin + window.location.pathname) || baseUrlOptions[0],
|
||||
);
|
||||
const [platform, setPlatform] = React.useState<IDropdownOption>(
|
||||
urlParams.has("platform")
|
||||
? platformOptions.find((o) => o.key === urlParams.get("platform")) || platformOptions[0]
|
||||
: platformOptions[0]
|
||||
: platformOptions[0],
|
||||
);
|
||||
|
||||
const booleanFeatures: {
|
||||
@@ -93,10 +93,10 @@ export const FeaturePanelComponent: React.FunctionComponent = () => {
|
||||
];
|
||||
|
||||
booleanFeatures.forEach(
|
||||
(f) => (f.reactState = React.useState<boolean>(urlParams.has(f.key) ? urlParams.get(f.key) === "true" : false))
|
||||
(f) => (f.reactState = React.useState<boolean>(urlParams.has(f.key) ? urlParams.get(f.key) === "true" : false)),
|
||||
);
|
||||
stringFeatures.forEach(
|
||||
(f) => (f.reactState = React.useState<string>(urlParams.has(f.key) ? urlParams.get(f.key) : undefined))
|
||||
(f) => (f.reactState = React.useState<string>(urlParams.has(f.key) ? urlParams.get(f.key) : undefined)),
|
||||
);
|
||||
|
||||
const buildUrl = (): string => {
|
||||
@@ -121,14 +121,14 @@ export const FeaturePanelComponent: React.FunctionComponent = () => {
|
||||
(f) =>
|
||||
(f.onChange = (ev?: React.FormEvent<HTMLElement | HTMLInputElement>, checked?: boolean): void => {
|
||||
f.reactState[1](checked);
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
stringFeatures.forEach(
|
||||
(f) =>
|
||||
(f.onChange = (event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string): void => {
|
||||
f.reactState[1](newValue);
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
const onNotebookShortcut = (): void => {
|
||||
|
||||
@@ -63,7 +63,7 @@ export class AddRepoComponent extends React.Component<AddRepoComponentProps, Add
|
||||
|
||||
private onTextFieldChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => {
|
||||
this.setState({
|
||||
textFieldValue: newValue || "",
|
||||
@@ -100,7 +100,7 @@ export class AddRepoComponent extends React.Component<AddRepoComponentProps, Add
|
||||
{
|
||||
dataExplorerArea: Constants.Areas.Notebook,
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
return this.props.pinRepo(item);
|
||||
}
|
||||
@@ -115,7 +115,7 @@ export class AddRepoComponent extends React.Component<AddRepoComponentProps, Add
|
||||
dataExplorerArea: Constants.Areas.Notebook,
|
||||
error: AddRepoComponent.TextFieldErrorMessage,
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ export class ReposListComponent extends React.Component<ReposListComponentProps>
|
||||
};
|
||||
|
||||
private onRenderBranchesDropdownList = (
|
||||
props: ISelectableDroppableTextProps<IDropdown, HTMLDivElement>
|
||||
props: ISelectableDroppableTextProps<IDropdown, HTMLDivElement>,
|
||||
): JSX.Element => {
|
||||
const renderedList: JSX.Element[] = [];
|
||||
props.options.forEach((option: IDropdownOption) => {
|
||||
|
||||
@@ -42,7 +42,7 @@ export class GalleryHeaderComponent extends React.Component {
|
||||
{this.renderHeaderItem(
|
||||
GalleryHeaderComponent.azureText,
|
||||
GalleryHeaderComponent.openPortal,
|
||||
GalleryHeaderComponent.mainHeaderTextProps
|
||||
GalleryHeaderComponent.mainHeaderTextProps,
|
||||
)}
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
@@ -52,7 +52,7 @@ export class GalleryHeaderComponent extends React.Component {
|
||||
{this.renderHeaderItem(
|
||||
GalleryHeaderComponent.cosmosdbText,
|
||||
GalleryHeaderComponent.openDataExplorer,
|
||||
GalleryHeaderComponent.headerItemTextProps
|
||||
GalleryHeaderComponent.headerItemTextProps,
|
||||
)}
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
@@ -62,7 +62,7 @@ export class GalleryHeaderComponent extends React.Component {
|
||||
{this.renderHeaderItem(
|
||||
GalleryHeaderComponent.galleryText,
|
||||
() => "",
|
||||
GalleryHeaderComponent.headerItemTextProps
|
||||
GalleryHeaderComponent.headerItemTextProps,
|
||||
)}
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
@@ -72,7 +72,7 @@ export class GalleryHeaderComponent extends React.Component {
|
||||
{this.renderHeaderItem(
|
||||
GalleryHeaderComponent.loginText,
|
||||
GalleryHeaderComponent.openDataExplorer,
|
||||
GalleryHeaderComponent.headerItemTextProps
|
||||
GalleryHeaderComponent.headerItemTextProps,
|
||||
)}
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
|
||||
@@ -133,7 +133,7 @@ export class InputTypeaheadComponent extends React.Component<
|
||||
private filterChoiceByValue = (choices: Item[], searchKeyword: string): Item[] => {
|
||||
return choices.filter((choice) =>
|
||||
// @ts-ignore
|
||||
Object.keys(choice).some((key) => choice[key].toLowerCase().includes(searchKeyword.toLowerCase()))
|
||||
Object.keys(choice).some((key) => choice[key].toLowerCase().includes(searchKeyword.toLowerCase())),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ export class JsonEditorViewModel extends WaitsForTemplateViewModel {
|
||||
(event: monaco.editor.ICursorSelectionChangedEvent) => {
|
||||
const selectedContent: string = this.editor.getModel().getValueInRange(event.selection);
|
||||
this.params.selectedContent(selectedContent);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
|
||||
iconName: string,
|
||||
title: string,
|
||||
horizontalAlign: "right" | "left",
|
||||
activate: () => void
|
||||
activate: () => void,
|
||||
): JSX.Element => {
|
||||
return (
|
||||
<TooltipHost
|
||||
@@ -116,7 +116,7 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
|
||||
HTMLAnchorElement | HTMLButtonElement | HTMLDivElement | BaseButton | Button | HTMLSpanElement,
|
||||
MouseEvent
|
||||
>,
|
||||
activate: () => void
|
||||
activate: () => void,
|
||||
): void => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
@@ -183,7 +183,7 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
|
||||
isFavorite ? "HeartFill" : "Heart",
|
||||
isFavorite ? "Unfavorite" : "Favorite",
|
||||
"left",
|
||||
isFavorite ? onUnfavoriteClick : onFavoriteClick
|
||||
isFavorite ? onUnfavoriteClick : onFavoriteClick,
|
||||
)}
|
||||
|
||||
{showDownload && generateIconButtonWithTooltip("Download", "Download", "left", onDownloadClick)}
|
||||
@@ -192,8 +192,8 @@ export const GalleryCardComponent: FunctionComponent<GalleryCardComponentProps>
|
||||
generateIconButtonWithTooltip("Delete", "Remove", "right", () =>
|
||||
onDeleteClick(
|
||||
() => setIsDeletingPublishedNotebook(true),
|
||||
() => setIsDeletingPublishedNotebook(false)
|
||||
)
|
||||
() => setIsDeletingPublishedNotebook(false),
|
||||
),
|
||||
)}
|
||||
</span>
|
||||
</DocumentCardDetails>
|
||||
|
||||
@@ -44,7 +44,7 @@ export const CodeOfConduct: FunctionComponent<CodeOfConductProps> = ({
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
|
||||
handleError(error, "CodeOfConduct/acceptCodeOfConduct", "Failed to accept code of conduct");
|
||||
|
||||
@@ -155,8 +155,8 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
this.createPublicGalleryTab(
|
||||
GalleryTab.PublicGallery,
|
||||
this.state.publicNotebooks,
|
||||
this.state.isCodeOfConductAccepted
|
||||
)
|
||||
this.state.isCodeOfConductAccepted,
|
||||
),
|
||||
);
|
||||
}
|
||||
tabs.push(this.createSamplesTab(GalleryTab.OfficialSamples, this.state.sampleNotebooks));
|
||||
@@ -265,7 +265,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
private createPublicGalleryTab(
|
||||
tab: GalleryTab,
|
||||
data: IGalleryItem[],
|
||||
acceptedCodeOfConduct: boolean
|
||||
acceptedCodeOfConduct: boolean,
|
||||
): GalleryTabInfo {
|
||||
return {
|
||||
tab,
|
||||
@@ -285,7 +285,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
Favorite any notebook from the{" "}
|
||||
<Link onClick={() => this.setState({ selectedTab: GalleryTab.OfficialSamples })}>official samples</Link> or{" "}
|
||||
<Link onClick={() => this.setState({ selectedTab: GalleryTab.PublicGallery })}>public gallery</Link>
|
||||
</>
|
||||
</>,
|
||||
);
|
||||
}
|
||||
return this.createSearchBarHeader(this.createCardsTabContent(data));
|
||||
@@ -309,7 +309,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
You have not published anything to the{" "}
|
||||
<Link onClick={() => this.setState({ selectedTab: GalleryTab.PublicGallery })}>public gallery</Link> yet
|
||||
</>,
|
||||
<>Publish your notebooks to share your work with other users</>
|
||||
<>Publish your notebooks to share your work with other users</>,
|
||||
);
|
||||
}
|
||||
return this.createPublishedNotebooksTabContent(data);
|
||||
@@ -330,19 +330,19 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
this.createPublishedNotebooksSectionContent(
|
||||
undefined,
|
||||
"You have successfully published and shared the following notebook(s) to the public gallery.",
|
||||
this.createCardsTabContent(published)
|
||||
this.createCardsTabContent(published),
|
||||
)}
|
||||
{underReview?.length > 0 &&
|
||||
this.createPublishedNotebooksSectionContent(
|
||||
"Under Review",
|
||||
"Content of a notebook you published is currently being scanned for illegal content. It will not be available to public gallery until the review is completed (may take a few days)",
|
||||
this.createCardsTabContent(underReview)
|
||||
this.createCardsTabContent(underReview),
|
||||
)}
|
||||
{removed?.length > 0 &&
|
||||
this.createPublishedNotebooksSectionContent(
|
||||
"Removed",
|
||||
"These notebooks were found to contain illegal content and has been taken down.",
|
||||
this.createPolicyViolationsListContent(removed)
|
||||
this.createPolicyViolationsListContent(removed),
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
@@ -353,7 +353,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
private createPublishedNotebooksSectionContent = (
|
||||
title: string,
|
||||
description: string,
|
||||
content: JSX.Element
|
||||
content: JSX.Element,
|
||||
): JSX.Element => {
|
||||
return (
|
||||
<Stack tokens={{ childrenGap: 10 }}>
|
||||
@@ -708,7 +708,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
|
||||
private downloadItem = async (data: IGalleryItem): Promise<void> => {
|
||||
GalleryUtils.downloadItem(this.props.container, this.props.junoClient, data, (item) =>
|
||||
this.refreshSelectedTab(item)
|
||||
this.refreshSelectedTab(item),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -722,7 +722,7 @@ export class GalleryViewerComponent extends React.Component<GalleryViewerCompone
|
||||
this.refreshSelectedTab(item);
|
||||
},
|
||||
beforeDelete,
|
||||
afterDelete
|
||||
afterDelete,
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ interface NotebookViewerComponentState {
|
||||
|
||||
export class NotebookViewerComponent
|
||||
extends React.Component<NotebookViewerComponentProps, NotebookViewerComponentState>
|
||||
implements DialogHost {
|
||||
implements DialogHost
|
||||
{
|
||||
private clientManager: NotebookClientV2;
|
||||
private notebookComponentBootstrapper: NotebookComponentBootstrapper;
|
||||
|
||||
@@ -97,7 +98,7 @@ export class NotebookViewerComponent
|
||||
notebookId: this.props.galleryItem?.id,
|
||||
isSample: this.props.galleryItem?.isSample,
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
|
||||
const notebook: Notebook = await response.json();
|
||||
@@ -123,7 +124,7 @@ export class NotebookViewerComponent
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
|
||||
this.setState({ showProgressBar: false });
|
||||
@@ -172,7 +173,7 @@ export class NotebookViewerComponent
|
||||
|
||||
public static getDerivedStateFromProps(
|
||||
props: NotebookViewerComponentProps,
|
||||
state: NotebookViewerComponentState
|
||||
state: NotebookViewerComponentState,
|
||||
): Partial<NotebookViewerComponentState> {
|
||||
let galleryItem = props.galleryItem;
|
||||
let isFavorite = props.isFavorite;
|
||||
@@ -196,7 +197,7 @@ export class NotebookViewerComponent
|
||||
msg: string,
|
||||
okLabel: string,
|
||||
onOk: () => void,
|
||||
progressIndicatorProps?: IProgressIndicatorProps
|
||||
progressIndicatorProps?: IProgressIndicatorProps,
|
||||
): void {
|
||||
useDialog.getState().openDialog({
|
||||
isModal: true,
|
||||
@@ -223,7 +224,7 @@ export class NotebookViewerComponent
|
||||
progressIndicatorProps?: IProgressIndicatorProps,
|
||||
choiceGroupProps?: IChoiceGroupProps,
|
||||
textFieldProps?: TextFieldProps,
|
||||
primaryButtonDisabled?: boolean
|
||||
primaryButtonDisabled?: boolean,
|
||||
): void {
|
||||
useDialog.getState().openDialog({
|
||||
isModal: true,
|
||||
@@ -248,19 +249,19 @@ export class NotebookViewerComponent
|
||||
|
||||
private favoriteItem = async (): Promise<void> => {
|
||||
GalleryUtils.favoriteItem(this.props.container, this.props.junoClient, this.state.galleryItem, (item) =>
|
||||
this.setState({ galleryItem: item, isFavorite: true })
|
||||
this.setState({ galleryItem: item, isFavorite: true }),
|
||||
);
|
||||
};
|
||||
|
||||
private unfavoriteItem = async (): Promise<void> => {
|
||||
GalleryUtils.unfavoriteItem(this.props.container, this.props.junoClient, this.state.galleryItem, (item) =>
|
||||
this.setState({ galleryItem: item, isFavorite: false })
|
||||
this.setState({ galleryItem: item, isFavorite: false }),
|
||||
);
|
||||
};
|
||||
|
||||
private downloadItem = async (): Promise<void> => {
|
||||
GalleryUtils.downloadItem(this.props.container, this.props.junoClient, this.state.galleryItem, (item) =>
|
||||
this.setState({ galleryItem: item })
|
||||
this.setState({ galleryItem: item }),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ export class QueriesGridComponent extends React.Component<QueriesGridComponentPr
|
||||
public componentDidUpdate(prevProps: QueriesGridComponentProps, prevState: QueriesGridComponentState): void {
|
||||
this.selection.setItems(
|
||||
this.state.filteredResults,
|
||||
!_.isEqual(prevState.filteredResults, this.state.filteredResults)
|
||||
!_.isEqual(prevState.filteredResults, this.state.filteredResults),
|
||||
);
|
||||
this.queryFilter && this.queryFilter.focus();
|
||||
const querySetupCompleted: boolean = !prevProps.saveQueryEnabled && this.props.saveQueryEnabled;
|
||||
@@ -159,7 +159,7 @@ export class QueriesGridComponent extends React.Component<QueriesGridComponentPr
|
||||
if (query) {
|
||||
const filteredQueries: Query[] = this.state.queries.filter(
|
||||
(savedQuery: Query) =>
|
||||
savedQuery.queryName.indexOf(query) > -1 || savedQuery.queryName.toLowerCase().indexOf(query) > -1
|
||||
savedQuery.queryName.indexOf(query) > -1 || savedQuery.queryName.toLowerCase().indexOf(query) > -1,
|
||||
);
|
||||
this.setState({
|
||||
filteredResults: filteredQueries,
|
||||
@@ -240,7 +240,7 @@ export class QueriesGridComponent extends React.Component<QueriesGridComponentPr
|
||||
dataExplorerArea: Constants.Areas.ContextualPane,
|
||||
paneTitle: title,
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
} catch (error) {
|
||||
TelemetryProcessor.traceFailure(
|
||||
@@ -251,13 +251,13 @@ export class QueriesGridComponent extends React.Component<QueriesGridComponentPr
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
}
|
||||
await this.fetchSavedQueries(); // get latest state
|
||||
},
|
||||
"Cancel",
|
||||
undefined
|
||||
undefined,
|
||||
);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -251,7 +251,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
if (userContext.apiType === "Mongo" && userContext?.databaseAccount) {
|
||||
this.mongoDBCollectionResource = await readMongoDBCollectionThroughRP(
|
||||
this.collection.databaseId,
|
||||
this.collection.id()
|
||||
this.collection.id(),
|
||||
);
|
||||
|
||||
if (this.mongoDBCollectionResource) {
|
||||
@@ -357,7 +357,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
} finally {
|
||||
this.props.settingsTab.isExecuting(false);
|
||||
@@ -431,7 +431,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.props.settingsTab.tabTitle(),
|
||||
},
|
||||
this.props.settingsTab.onLoadStartKey
|
||||
this.props.settingsTab.onLoadStartKey,
|
||||
);
|
||||
this.props.settingsTab.onLoadStartKey = undefined;
|
||||
}
|
||||
@@ -566,7 +566,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
this.collection.databaseId,
|
||||
this.collection.id(),
|
||||
this.state.conflictResolutionPolicyProcedure,
|
||||
false
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
const conflictResolutionPolicyMode = parseConflictResolutionMode(conflictResolutionPolicy?.mode);
|
||||
const conflictResolutionPolicyPath = conflictResolutionPolicy?.conflictResolutionPath;
|
||||
const conflictResolutionPolicyProcedure = parseConflictResolutionProcedure(
|
||||
conflictResolutionPolicy?.conflictResolutionProcedure
|
||||
conflictResolutionPolicy?.conflictResolutionProcedure,
|
||||
);
|
||||
const geospatialConfigTypeString: string =
|
||||
(this.collection.geospatialConfig && this.collection.geospatialConfig()?.type) || GeospatialConfigType.Geometry;
|
||||
@@ -780,7 +780,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.props.settingsTab.tabTitle(),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -828,7 +828,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
const updatedCollection: DataModels.Collection = await updateCollection(
|
||||
this.collection.databaseId,
|
||||
this.collection.id(),
|
||||
newCollection
|
||||
newCollection,
|
||||
);
|
||||
this.collection.rawDataModel = updatedCollection;
|
||||
this.collection.defaultTtl(updatedCollection.defaultTtl);
|
||||
@@ -862,7 +862,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
this.mongoDBCollectionResource = await updateCollection(
|
||||
this.collection.databaseId,
|
||||
this.collection.id(),
|
||||
newMongoCollection
|
||||
newMongoCollection,
|
||||
);
|
||||
|
||||
await this.refreshIndexTransformationProgress();
|
||||
@@ -881,7 +881,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.props.settingsTab.tabTitle(),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
} catch (error) {
|
||||
traceFailure(
|
||||
@@ -895,7 +895,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
@@ -942,12 +942,12 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: this.props.settingsTab.tabTitle(),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
};
|
||||
|
||||
public getMongoIndexTabContent = (
|
||||
mongoIndexingPolicyComponentProps: MongoIndexingPolicyComponentProps
|
||||
mongoIndexingPolicyComponentProps: MongoIndexingPolicyComponentProps,
|
||||
): JSX.Element => {
|
||||
if (userContext.authType === AuthType.AAD) {
|
||||
if (userContext.apiType === "Mongo") {
|
||||
|
||||
@@ -179,7 +179,7 @@ export const getRuPriceBreakdown = (
|
||||
serverId: string,
|
||||
numberOfRegions: number,
|
||||
isMultimaster: boolean,
|
||||
isAutoscale: boolean
|
||||
isAutoscale: boolean,
|
||||
): PriceBreakdown => {
|
||||
const hourlyPrice: number = computeRUUsagePriceHourly({
|
||||
serverId: serverId,
|
||||
@@ -207,7 +207,7 @@ export const getEstimatedSpendingElement = (
|
||||
throughput: number,
|
||||
numberOfRegions: number,
|
||||
priceBreakdown: PriceBreakdown,
|
||||
isAutoscale: boolean
|
||||
isAutoscale: boolean,
|
||||
): JSX.Element => {
|
||||
const ruRange: string = isAutoscale ? throughput / 10 + " RU/s - " : "";
|
||||
return (
|
||||
@@ -279,7 +279,7 @@ export const getUpdateThroughputBeyondInstantLimitMessage = (instantMaximumThrou
|
||||
|
||||
export const getUpdateThroughputBeyondSupportLimitMessage = (
|
||||
instantMaximumThroughput: number,
|
||||
maximumThroughput: number
|
||||
maximumThroughput: number,
|
||||
): JSX.Element => {
|
||||
return (
|
||||
<>
|
||||
@@ -333,15 +333,15 @@ const getCurrentThroughput = (
|
||||
isAutoscale: boolean,
|
||||
throughput: number,
|
||||
throughputUnit: string,
|
||||
targetThroughput?: number
|
||||
targetThroughput?: number,
|
||||
): string => {
|
||||
if (targetThroughput) {
|
||||
if (throughput) {
|
||||
return isAutoscale
|
||||
? `, Current autoscale throughput: ${Math.round(
|
||||
throughput / 10
|
||||
throughput / 10,
|
||||
)} - ${throughput} ${throughputUnit}, Target autoscale throughput: ${Math.round(
|
||||
targetThroughput / 10
|
||||
targetThroughput / 10,
|
||||
)} - ${targetThroughput} ${throughputUnit}`
|
||||
: `, Current manual throughput: ${throughput} ${throughputUnit}, Target manual throughput: ${targetThroughput}`;
|
||||
} else {
|
||||
@@ -366,7 +366,7 @@ export const getThroughputApplyDelayedMessage = (
|
||||
throughputUnit: string,
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
requestedThroughput: number
|
||||
requestedThroughput: number,
|
||||
): JSX.Element => (
|
||||
<Text styles={infoAndToolTipTextStyle}>
|
||||
The request to increase the throughput has successfully been submitted. This operation will take 1-3 business days
|
||||
@@ -382,7 +382,7 @@ export const getThroughputApplyShortDelayMessage = (
|
||||
throughput: number,
|
||||
throughputUnit: string,
|
||||
databaseName: string,
|
||||
collectionName: string
|
||||
collectionName: string,
|
||||
): JSX.Element => (
|
||||
<Text styles={infoAndToolTipTextStyle} id="throughputApplyShortDelayMessage">
|
||||
A request to increase the throughput is currently in progress. This operation will take some time to complete.
|
||||
@@ -398,7 +398,7 @@ export const getThroughputApplyLongDelayMessage = (
|
||||
throughputUnit: string,
|
||||
databaseName: string,
|
||||
collectionName: string,
|
||||
requestedThroughput: number
|
||||
requestedThroughput: number,
|
||||
): JSX.Element => (
|
||||
<Text styles={infoAndToolTipTextStyle} id="throughputApplyLongDelayMessage">
|
||||
A request to increase the throughput is currently in progress. This operation will take 1-3 business days to
|
||||
@@ -480,7 +480,7 @@ export const mongoIndexTransformationRefreshingMessage: JSX.Element = (
|
||||
|
||||
export const renderMongoIndexTransformationRefreshMessage = (
|
||||
progress: number,
|
||||
performRefresh: () => void
|
||||
performRefresh: () => void,
|
||||
): JSX.Element => {
|
||||
if (progress === 0) {
|
||||
return (
|
||||
@@ -516,7 +516,7 @@ export const getTextFieldStyles = (current: isDirtyTypes, baseline: isDirtyTypes
|
||||
export const getChoiceGroupStyles = (
|
||||
current: isDirtyTypes,
|
||||
baseline: isDirtyTypes,
|
||||
isHorizontal?: boolean
|
||||
isHorizontal?: boolean,
|
||||
): Partial<IChoiceGroupStyles> => ({
|
||||
flexContainer: [
|
||||
{
|
||||
|
||||
@@ -68,20 +68,20 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
|
||||
|
||||
private onConflictResolutionPolicyModeChange = (
|
||||
event?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||
option?: IChoiceGroupOption
|
||||
option?: IChoiceGroupOption,
|
||||
): void =>
|
||||
this.props.onConflictResolutionPolicyModeChange(
|
||||
DataModels.ConflictResolutionMode[option.key as keyof typeof DataModels.ConflictResolutionMode]
|
||||
DataModels.ConflictResolutionMode[option.key as keyof typeof DataModels.ConflictResolutionMode],
|
||||
);
|
||||
|
||||
private onConflictResolutionPolicyPathChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => this.props.onConflictResolutionPolicyPathChange(newValue);
|
||||
|
||||
private onConflictResolutionPolicyProcedureChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => this.props.onConflictResolutionPolicyProcedureChange(newValue);
|
||||
|
||||
private getConflictResolutionModeComponent = (): JSX.Element => (
|
||||
@@ -92,7 +92,7 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
|
||||
onChange={this.onConflictResolutionPolicyModeChange}
|
||||
styles={getChoiceGroupStyles(
|
||||
this.props.conflictResolutionPolicyMode,
|
||||
this.props.conflictResolutionPolicyModeBaseline
|
||||
this.props.conflictResolutionPolicyModeBaseline,
|
||||
)}
|
||||
/>
|
||||
);
|
||||
@@ -108,7 +108,7 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
|
||||
onRenderLabel={this.onRenderLwwComponentTextField}
|
||||
styles={getTextFieldStyles(
|
||||
this.props.conflictResolutionPolicyPath,
|
||||
this.props.conflictResolutionPolicyPathBaseline
|
||||
this.props.conflictResolutionPolicyPathBaseline,
|
||||
)}
|
||||
value={this.props.conflictResolutionPolicyPath}
|
||||
onChange={this.onConflictResolutionPolicyPathChange}
|
||||
@@ -126,7 +126,7 @@ export class ConflictResolutionComponent extends React.Component<ConflictResolut
|
||||
onRenderLabel={this.onRenderCustomComponentTextField}
|
||||
styles={getTextFieldStyles(
|
||||
this.props.conflictResolutionPolicyProcedure,
|
||||
this.props.conflictResolutionPolicyProcedureBaseline
|
||||
this.props.conflictResolutionPolicyProcedureBaseline,
|
||||
)}
|
||||
value={this.props.conflictResolutionPolicyProcedure}
|
||||
onChange={this.onConflictResolutionPolicyProcedureChange}
|
||||
|
||||
@@ -35,7 +35,7 @@ export class IndexingPolicyRefreshComponent extends React.Component<
|
||||
} else if (isIndexTransforming(this.props.indexTransformationProgress)) {
|
||||
return renderMongoIndexTransformationRefreshMessage(
|
||||
this.props.indexTransformationProgress,
|
||||
this.onClickRefreshIndexingTransformationLink
|
||||
this.onClickRefreshIndexingTransformationLink,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
|
||||
@@ -40,12 +40,12 @@ export class AddMongoIndexComponent extends React.Component<AddMongoIndexCompone
|
||||
(value: MongoIndexTypes) => ({
|
||||
text: getMongoIndexTypeText(value),
|
||||
key: value,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
private onDescriptionChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => {
|
||||
this.props.onIndexAddOrChange(newValue, this.props.type);
|
||||
};
|
||||
|
||||
@@ -90,7 +90,7 @@ describe("MongoIndexingPolicyComponent", () => {
|
||||
indexToDropIsPresent: boolean,
|
||||
isMongoIndexingPolicySaveable: boolean,
|
||||
isMongoIndexingPolicyDiscardable: boolean,
|
||||
mongoWarningNotificationMessage: string
|
||||
mongoWarningNotificationMessage: string,
|
||||
) => {
|
||||
const addMongoIndexProps = {
|
||||
mongoIndex: { key: { keys: ["sampleKey"] } },
|
||||
@@ -107,7 +107,7 @@ describe("MongoIndexingPolicyComponent", () => {
|
||||
|
||||
expect(mongoIndexingPolicyComponent.isMongoIndexingPolicySaveable()).toEqual(isMongoIndexingPolicySaveable);
|
||||
expect(mongoIndexingPolicyComponent.isMongoIndexingPolicyDiscardable()).toEqual(
|
||||
isMongoIndexingPolicyDiscardable
|
||||
isMongoIndexingPolicyDiscardable,
|
||||
);
|
||||
if (mongoWarningNotificationMessage) {
|
||||
const elementAsString = renderToString(mongoIndexingPolicyComponent.getMongoWarningNotificationMessage());
|
||||
@@ -115,7 +115,7 @@ describe("MongoIndexingPolicyComponent", () => {
|
||||
} else {
|
||||
expect(mongoIndexingPolicyComponent.getMongoWarningNotificationMessage()).toBeUndefined();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -130,7 +130,7 @@ export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingP
|
||||
|
||||
public getMongoWarningNotificationMessage = (): JSX.Element => {
|
||||
const warningMessage = this.props.indexesToAdd.find(
|
||||
(addMongoIndexProps) => addMongoIndexProps.notification?.type === MongoNotificationType.Warning
|
||||
(addMongoIndexProps) => addMongoIndexProps.notification?.type === MongoNotificationType.Warning,
|
||||
)?.notification.message;
|
||||
|
||||
if (warningMessage) {
|
||||
@@ -163,7 +163,7 @@ export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingP
|
||||
private getMongoIndexDisplayProps = (
|
||||
mongoIndex: MongoIndex,
|
||||
arrayPosition: number,
|
||||
isCurrentIndex: boolean
|
||||
isCurrentIndex: boolean,
|
||||
): MongoIndexDisplayProps => {
|
||||
const keys = mongoIndex?.key?.keys;
|
||||
const type = getMongoIndexType(keys);
|
||||
@@ -261,7 +261,7 @@ export class MongoIndexingPolicyComponent extends React.Component<MongoIndexingP
|
||||
|
||||
private renderIndexesToBeDropped = (): JSX.Element => {
|
||||
const indexesToBeDropped = this.props.indexesToDrop.map((dropIndex, arrayPosition) =>
|
||||
this.getMongoIndexDisplayProps(this.props.mongoIndexes[dropIndex], arrayPosition, false)
|
||||
this.getMongoIndexDisplayProps(this.props.mongoIndexes[dropIndex], arrayPosition, false),
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -113,7 +113,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
||||
throughput,
|
||||
throughputUnit,
|
||||
this.databaseId,
|
||||
this.collectionId
|
||||
this.collectionId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
||||
|
||||
public getLongDelayMessage = (): JSX.Element => {
|
||||
const matches: string[] = this.props.initialNotification?.description.match(
|
||||
`Throughput update for (.*) ${throughputUnit}`
|
||||
`Throughput update for (.*) ${throughputUnit}`,
|
||||
);
|
||||
|
||||
const throughput = this.props.throughputBaseline;
|
||||
@@ -134,7 +134,7 @@ export class ScaleComponent extends React.Component<ScaleComponentProps> {
|
||||
throughputUnit,
|
||||
this.databaseId,
|
||||
this.collectionId,
|
||||
targetThroughput
|
||||
targetThroughput,
|
||||
);
|
||||
}
|
||||
return <></>;
|
||||
|
||||
@@ -145,7 +145,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
||||
|
||||
private onTimeToLiveSecondsChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => {
|
||||
const newTimeToLiveSeconds = getSanitizedInputValue(newValue, Int32.Max);
|
||||
this.props.onDisplayedTtlSecondsChange(newTimeToLiveSeconds.toString());
|
||||
@@ -154,18 +154,18 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
||||
|
||||
private onGeoSpatialConfigTypeChange = (
|
||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||
option?: IChoiceGroupOption
|
||||
option?: IChoiceGroupOption,
|
||||
): void =>
|
||||
this.props.onGeoSpatialConfigTypeChange(GeospatialConfigType[option.key as keyof typeof GeospatialConfigType]);
|
||||
|
||||
private onAnalyticalStorageTtlSelectionChange = (
|
||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||
option?: IChoiceGroupOption
|
||||
option?: IChoiceGroupOption,
|
||||
): void => this.props.onAnalyticalStorageTtlSelectionChange(this.getTtlValue(option.key));
|
||||
|
||||
private onAnalyticalStorageTtlSecondsChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => {
|
||||
const newAnalyticalStorageTtlSeconds = getSanitizedInputValue(newValue, Int32.Max);
|
||||
this.props.onAnalyticalStorageTtlSecondsChange(newAnalyticalStorageTtlSeconds);
|
||||
@@ -173,7 +173,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
||||
|
||||
private onChangeFeedPolicyChange = (
|
||||
ev?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||
option?: IChoiceGroupOption
|
||||
option?: IChoiceGroupOption,
|
||||
): void =>
|
||||
this.props.onChangeFeedPolicyChange(ChangeFeedPolicyState[option.key as keyof typeof ChangeFeedPolicyState]);
|
||||
|
||||
@@ -240,7 +240,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
||||
onChange={this.onAnalyticalStorageTtlSelectionChange}
|
||||
styles={getChoiceGroupStyles(
|
||||
this.props.analyticalStorageTtlSelection,
|
||||
this.props.analyticalStorageTtlSelectionBaseline
|
||||
this.props.analyticalStorageTtlSelectionBaseline,
|
||||
)}
|
||||
/>
|
||||
{this.props.analyticalStorageTtlSelection === TtlType.On && (
|
||||
@@ -248,7 +248,7 @@ export class SubSettingsComponent extends React.Component<SubSettingsComponentPr
|
||||
id="analyticalStorageTimeToLiveSeconds"
|
||||
styles={getTextFieldStyles(
|
||||
this.props.analyticalStorageTtlSeconds,
|
||||
this.props.analyticalStorageTtlSecondsBaseline
|
||||
this.props.analyticalStorageTtlSecondsBaseline,
|
||||
)}
|
||||
type="number"
|
||||
required
|
||||
|
||||
@@ -202,7 +202,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
userContext.portalEnv,
|
||||
regions,
|
||||
multimaster,
|
||||
isDirty ? this.props.maxAutoPilotThroughput : undefined
|
||||
isDirty ? this.props.maxAutoPilotThroughput : undefined,
|
||||
);
|
||||
} else {
|
||||
estimatedSpend = this.getEstimatedManualSpendElement(
|
||||
@@ -211,7 +211,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
userContext.portalEnv,
|
||||
regions,
|
||||
multimaster,
|
||||
isDirty ? this.props.throughput : undefined
|
||||
isDirty ? this.props.throughput : undefined,
|
||||
);
|
||||
}
|
||||
return estimatedSpend;
|
||||
@@ -222,7 +222,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
serverId: string,
|
||||
numberOfRegions: number,
|
||||
isMultimaster: boolean,
|
||||
newThroughput?: number
|
||||
newThroughput?: number,
|
||||
): JSX.Element => {
|
||||
const prices: PriceBreakdown = getRuPriceBreakdown(throughput, serverId, numberOfRegions, isMultimaster, true);
|
||||
|
||||
@@ -232,7 +232,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
serverId,
|
||||
numberOfRegions,
|
||||
isMultimaster,
|
||||
true
|
||||
true,
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
@@ -275,7 +275,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
serverId: string,
|
||||
numberOfRegions: number,
|
||||
isMultimaster: boolean,
|
||||
newThroughput?: number
|
||||
newThroughput?: number,
|
||||
): JSX.Element => {
|
||||
const prices: PriceBreakdown = getRuPriceBreakdown(throughput, serverId, numberOfRegions, isMultimaster, false);
|
||||
|
||||
@@ -285,7 +285,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
serverId,
|
||||
numberOfRegions,
|
||||
isMultimaster,
|
||||
true
|
||||
true,
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
@@ -331,7 +331,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
|
||||
private onAutoPilotThroughputChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => {
|
||||
const newThroughput = getSanitizedInputValue(newValue);
|
||||
this.props.onMaxAutoPilotThroughputChange(newThroughput);
|
||||
@@ -339,7 +339,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
|
||||
private onThroughputChange = (
|
||||
event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
newValue?: string
|
||||
newValue?: string,
|
||||
): void => {
|
||||
const newThroughput = getSanitizedInputValue(newValue);
|
||||
if (this.overrideWithAutoPilotSettings()) {
|
||||
@@ -354,7 +354,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
|
||||
private onChoiceGroupChange = (
|
||||
event?: React.FormEvent<HTMLElement | HTMLInputElement>,
|
||||
option?: IChoiceGroupOption
|
||||
option?: IChoiceGroupOption,
|
||||
): void => {
|
||||
this.props.onAutoPilotSelected(option.key === "true");
|
||||
TelemetryProcessor.trace(Action.ToggleAutoscaleSetting, ActionModifiers.Mark, {
|
||||
@@ -557,7 +557,7 @@ export class ThroughputInputAutoPilotV3Component extends React.Component<
|
||||
case "requireSupport":
|
||||
return getUpdateThroughputBeyondSupportLimitMessage(
|
||||
this.props.instantMaximumThroughput,
|
||||
this.props.softAllowedMaximumThroughput
|
||||
this.props.softAllowedMaximumThroughput,
|
||||
);
|
||||
default:
|
||||
return <></>;
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("SettingsUtils", () => {
|
||||
|
||||
notification = getMongoNotification(singleIndexDescription, MongoIndexTypes.Wildcard);
|
||||
expect(notification.message).toEqual(
|
||||
"Wildcard path is not present in the field name. Use a pattern like " + MongoWildcardPlaceHolder
|
||||
"Wildcard path is not present in the field name. Use a pattern like " + MongoWildcardPlaceHolder,
|
||||
);
|
||||
expect(notification.type).toEqual(MongoNotificationType.Error);
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import Explorer from "../../Explorer";
|
||||
|
||||
export const container = new Explorer();
|
||||
|
||||
export const collection = ({
|
||||
export const collection = {
|
||||
container: container,
|
||||
databaseId: "test",
|
||||
id: ko.observable<string>("test"),
|
||||
@@ -27,7 +27,7 @@ export const collection = ({
|
||||
offerReplacePending: false,
|
||||
}),
|
||||
conflictResolutionPolicy: ko.observable<DataModels.ConflictResolutionPolicy>(
|
||||
{} as DataModels.ConflictResolutionPolicy
|
||||
{} as DataModels.ConflictResolutionPolicy,
|
||||
),
|
||||
changeFeedPolicy: ko.observable<DataModels.ChangeFeedPolicy>({} as DataModels.ChangeFeedPolicy),
|
||||
geospatialConfig: ko.observable<DataModels.GeospatialConfig>({} as DataModels.GeospatialConfig),
|
||||
@@ -43,4 +43,4 @@ export const collection = ({
|
||||
readSettings: () => {
|
||||
return;
|
||||
},
|
||||
} as unknown) as ViewModels.Collection;
|
||||
} as unknown as ViewModels.Collection;
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("SmartUiComponent", () => {
|
||||
getTranslation={(key: string) => {
|
||||
return key;
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -153,7 +153,7 @@ describe("SmartUiComponent", () => {
|
||||
getTranslation={(key: string) => {
|
||||
return key;
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -25,7 +25,7 @@ describe("ThroughputInput Pane", () => {
|
||||
it("should switch mode properly", () => {
|
||||
wrapper.find('[aria-label="Manual database throughput"]').simulate("change");
|
||||
expect(wrapper.find('[aria-label="Throughput header"]').at(0).text()).toBe(
|
||||
"Container throughput (400 - unlimited RU/s)"
|
||||
"Container throughput (400 - unlimited RU/s)",
|
||||
);
|
||||
|
||||
wrapper.find('[aria-label="Autoscale database throughput"]').simulate("change");
|
||||
|
||||
@@ -36,7 +36,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
}: ThroughputInputProps) => {
|
||||
const [isAutoscaleSelected, setIsAutoScaleSelected] = useState<boolean>(true);
|
||||
const [throughput, setThroughput] = useState<number>(
|
||||
isFreeTier || isQuickstart ? AutoPilotUtils.autoPilotThroughput1K : AutoPilotUtils.autoPilotThroughput4K
|
||||
isFreeTier || isQuickstart ? AutoPilotUtils.autoPilotThroughput1K : AutoPilotUtils.autoPilotThroughput4K,
|
||||
);
|
||||
const [isCostAcknowledged, setIsCostAcknowledged] = useState<boolean>(false);
|
||||
const [throughputError, setThroughputError] = useState<string>("");
|
||||
@@ -71,7 +71,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
setThroughputError(
|
||||
`Your account is currently configured with a total throughput limit of ${throughputCap} RU/s. This update isn't possible because it would increase the total throughput to ${
|
||||
totalThroughput + throughput * numberOfRegions
|
||||
} RU/s. Change total throughput limit in cost management.`
|
||||
} RU/s. Change total throughput limit in cost management.`,
|
||||
);
|
||||
|
||||
setIsThroughputCapExceeded(true);
|
||||
@@ -83,7 +83,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
setThroughputError(
|
||||
`Your account is currently configured with a total throughput limit of ${throughputCap} RU/s. This update isn't possible because it would increase the total throughput to ${
|
||||
totalThroughputUsed + newThroughput * numberOfRegions
|
||||
} RU/s. Change total throughput limit in cost management.`
|
||||
} RU/s. Change total throughput limit in cost management.`,
|
||||
);
|
||||
setIsThroughputCapExceeded(true);
|
||||
return false;
|
||||
@@ -151,7 +151,7 @@ export const ThroughputInput: FunctionComponent<ThroughputInputProps> = ({
|
||||
userContext.portalEnv,
|
||||
numberOfRegions,
|
||||
multimasterEnabled,
|
||||
isAutoscaleSelected
|
||||
isAutoscaleSelected,
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ export class TreeNodeComponent extends React.Component<TreeNodeComponentProps, T
|
||||
node.children.reduce(
|
||||
(previous: boolean, child: TreeNode) =>
|
||||
previous || (child.isSelected && child.isSelected()) || TreeNodeComponent.isAnyDescendantSelected(child),
|
||||
false
|
||||
false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export class ContainerSampleGenerator {
|
||||
*/
|
||||
public static async createSampleGeneratorAsync(
|
||||
container: Explorer,
|
||||
isCopilot?: boolean
|
||||
isCopilot?: boolean,
|
||||
): Promise<ContainerSampleGenerator> {
|
||||
const generator = new ContainerSampleGenerator(container);
|
||||
let dataFileContent: any;
|
||||
@@ -113,7 +113,7 @@ export class ContainerSampleGenerator {
|
||||
} catch (error) {
|
||||
NotificationConsoleUtils.logConsoleError(error);
|
||||
}
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ export default class Explorer {
|
||||
this.phoenixClient = new PhoenixClient(userContext?.databaseAccount?.id);
|
||||
useNotebook.subscribe(
|
||||
() => this.refreshCommandBarButtons(),
|
||||
(state) => state.isNotebooksEnabledForAccount
|
||||
(state) => state.isNotebooksEnabledForAccount,
|
||||
);
|
||||
|
||||
this.queriesClient = new QueriesClient(this);
|
||||
@@ -130,7 +130,7 @@ export default class Explorer {
|
||||
useCommandBar.getState().setContextButtons([]);
|
||||
}
|
||||
},
|
||||
(state) => state.openedTabs
|
||||
(state) => state.openedTabs,
|
||||
);
|
||||
|
||||
this.isTabsContentExpanded = ko.observable(false);
|
||||
@@ -140,7 +140,7 @@ export default class Explorer {
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
},
|
||||
false
|
||||
false,
|
||||
);
|
||||
|
||||
$(() => {
|
||||
@@ -162,13 +162,13 @@ export default class Explorer {
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.InitializeDataExplorer,
|
||||
{ dataExplorerArea: Constants.Areas.ResourceTree },
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
|
||||
useNotebook.subscribe(
|
||||
async () => this.initiateAndRefreshNotebookList(),
|
||||
(state) => [state.isNotebookEnabled, state.isRefreshed],
|
||||
shallow
|
||||
shallow,
|
||||
);
|
||||
|
||||
this.resourceTree = new ResourceTreeAdapter(this);
|
||||
@@ -226,7 +226,7 @@ export default class Explorer {
|
||||
onPrimaryButtonClick: async () => {
|
||||
const startTime = TelemetryProcessor.traceStart(Action.EnableAzureSynapseLink);
|
||||
const clearInProgressMessage = logConsoleProgress(
|
||||
"Enabling Azure Synapse Link for this account. This may take a few minutes before you can enable analytical store for this account."
|
||||
"Enabling Azure Synapse Link for this account. This may take a few minutes before you can enable analytical store for this account.",
|
||||
);
|
||||
useNotebook.getState().setIsSynapseLinkUpdating(true);
|
||||
useDialog.getState().closeDialog();
|
||||
@@ -275,7 +275,7 @@ export default class Explorer {
|
||||
const ONE_DAY_IN_MS = 86400000;
|
||||
const isAccountNewerThanNinetyDays = isAccountNewerThanThresholdInMs(
|
||||
userContext.databaseAccount?.systemData?.createdAt || "",
|
||||
NINETY_DAYS_IN_MS
|
||||
NINETY_DAYS_IN_MS,
|
||||
);
|
||||
const lastSubmitted: string = localStorage.getItem("lastSubmitted");
|
||||
|
||||
@@ -343,15 +343,15 @@ export default class Explorer {
|
||||
{
|
||||
dataExplorerArea: Constants.Areas.ResourceTree,
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
const currentDatabases = useDatabases.getState().databases;
|
||||
const deltaDatabases = this.getDeltaDatabases(databases, currentDatabases);
|
||||
let updatedDatabases = currentDatabases.filter(
|
||||
(database) => !deltaDatabases.toDelete.some((deletedDatabase) => deletedDatabase.id() === database.id())
|
||||
(database) => !deltaDatabases.toDelete.some((deletedDatabase) => deletedDatabase.id() === database.id()),
|
||||
);
|
||||
updatedDatabases = [...updatedDatabases, ...deltaDatabases.toAdd].sort((db1, db2) =>
|
||||
db1.id().localeCompare(db2.id())
|
||||
db1.id().localeCompare(db2.id()),
|
||||
);
|
||||
useDatabases.setState({ databases: updatedDatabases });
|
||||
await this.refreshAndExpandNewDatabases(deltaDatabases.toAdd, updatedDatabases);
|
||||
@@ -364,7 +364,7 @@ export default class Explorer {
|
||||
error: errorMessage,
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
logConsoleError(`Error while refreshing databases: ${errorMessage}`);
|
||||
}
|
||||
@@ -462,7 +462,7 @@ export default class Explorer {
|
||||
.getState()
|
||||
.showOkModalDialog(
|
||||
"Connection Failed",
|
||||
"We are unable to connect to the temporary workspace. Please try again in a few minutes. If the error persists, file a support ticket."
|
||||
"We are unable to connect to the temporary workspace. Please try again in a few minutes. If the error persists, file a support ticket.",
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
@@ -480,7 +480,7 @@ export default class Explorer {
|
||||
private async setNotebookInfo(
|
||||
shouldUseNotebookStates: boolean,
|
||||
connectionInfo: IResponse<IPhoenixServiceInfo>,
|
||||
connectionStatus: DataModels.ContainerConnectionInfo
|
||||
connectionStatus: DataModels.ContainerConnectionInfo,
|
||||
) {
|
||||
const containerData = {
|
||||
forwardingId: connectionInfo.data.forwardingId,
|
||||
@@ -512,7 +512,7 @@ export default class Explorer {
|
||||
if (!useNotebook.getState().isNotebookEnabled || !this.notebookManager?.notebookClient) {
|
||||
handleError(
|
||||
"Attempt to reset notebook workspace, but notebook is not enabled",
|
||||
"Explorer/resetNotebookWorkspace"
|
||||
"Explorer/resetNotebookWorkspace",
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -540,7 +540,7 @@ export default class Explorer {
|
||||
const { value: workspaces } = await listByDatabaseAccount(
|
||||
userContext.subscriptionId,
|
||||
userContext.resourceGroup,
|
||||
userContext.databaseAccount.name
|
||||
userContext.databaseAccount.name,
|
||||
);
|
||||
return workspaces && workspaces.length > 0 && workspaces.some((workspace) => workspace.name === "default");
|
||||
} catch (error) {
|
||||
@@ -608,7 +608,7 @@ export default class Explorer {
|
||||
|
||||
private getDeltaDatabases(
|
||||
updatedDatabaseList: DataModels.Database[],
|
||||
databases: ViewModels.Database[]
|
||||
databases: ViewModels.Database[],
|
||||
): {
|
||||
toAdd: ViewModels.Database[];
|
||||
toDelete: ViewModels.Database[];
|
||||
@@ -616,19 +616,19 @@ export default class Explorer {
|
||||
const newDatabases: DataModels.Database[] = _.filter(updatedDatabaseList, (database: DataModels.Database) => {
|
||||
const databaseExists = _.some(
|
||||
databases,
|
||||
(existingDatabase: ViewModels.Database) => existingDatabase.id() === database.id
|
||||
(existingDatabase: ViewModels.Database) => existingDatabase.id() === database.id,
|
||||
);
|
||||
return !databaseExists;
|
||||
});
|
||||
const databasesToAdd: ViewModels.Database[] = newDatabases.map(
|
||||
(newDatabase: DataModels.Database) => new Database(this, newDatabase)
|
||||
(newDatabase: DataModels.Database) => new Database(this, newDatabase),
|
||||
);
|
||||
|
||||
const databasesToDelete: ViewModels.Database[] = [];
|
||||
databases.forEach((database: ViewModels.Database) => {
|
||||
const databasePresentInUpdatedList = _.some(
|
||||
updatedDatabaseList,
|
||||
(db: DataModels.Database) => db.id === database.id()
|
||||
(db: DataModels.Database) => db.id === database.id(),
|
||||
);
|
||||
if (!databasePresentInUpdatedList) {
|
||||
databasesToDelete.push(database);
|
||||
@@ -640,7 +640,7 @@ export default class Explorer {
|
||||
|
||||
private async refreshAndExpandNewDatabases(
|
||||
newDatabases: ViewModels.Database[],
|
||||
databases: ViewModels.Database[]
|
||||
databases: ViewModels.Database[],
|
||||
): Promise<void> {
|
||||
// we reload collections for all databases so the resource tree reflects any collection-level changes
|
||||
// i.e addition of stored procedures, etc.
|
||||
@@ -669,9 +669,9 @@ export default class Explorer {
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.LoadCollections,
|
||||
{ dataExplorerArea: Constants.Areas.ResourceTree },
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
TelemetryProcessor.traceFailure(
|
||||
@@ -681,7 +681,7 @@ export default class Explorer {
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -698,7 +698,7 @@ export default class Explorer {
|
||||
name: string,
|
||||
content: string,
|
||||
parent: NotebookContentItem,
|
||||
isGithubTree?: boolean
|
||||
isGithubTree?: boolean,
|
||||
): Promise<NotebookContentItem> {
|
||||
if (!useNotebook.getState().isNotebookEnabled || !this.notebookManager?.notebookContentClient) {
|
||||
const error = "Attempt to upload notebook, but notebook is not enabled";
|
||||
@@ -758,7 +758,7 @@ export default class Explorer {
|
||||
content: NotebookPaneContent,
|
||||
notebookContentRef?: string,
|
||||
onTakeSnapshot?: (request: SnapshotRequest) => void,
|
||||
onClosePanel?: () => void
|
||||
onClosePanel?: () => void,
|
||||
): Promise<void> {
|
||||
if (this.notebookManager) {
|
||||
await this.notebookManager.openPublishNotebookPane(
|
||||
@@ -766,7 +766,7 @@ export default class Explorer {
|
||||
content,
|
||||
notebookContentRef,
|
||||
onTakeSnapshot,
|
||||
onClosePanel
|
||||
onClosePanel,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -803,7 +803,7 @@ export default class Explorer {
|
||||
ViewModels.CollectionTabKind.NotebookV2,
|
||||
(tab) =>
|
||||
(tab as NotebookV2Tab).notebookPath &&
|
||||
FileSystemUtil.isPathEqual((tab as NotebookV2Tab).notebookPath(), notebookContentItem.path)
|
||||
FileSystemUtil.isPathEqual((tab as NotebookV2Tab).notebookPath(), notebookContentItem.path),
|
||||
) as NotebookV2Tab[];
|
||||
let notebookTab = notebookTabs && notebookTabs[0];
|
||||
|
||||
@@ -873,7 +873,7 @@ export default class Explorer {
|
||||
this.notebookManager?.notebookContentClient.renameNotebook(notebookFile, input, isGithubTree)
|
||||
}
|
||||
notebookFile={notebookFile}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -903,7 +903,7 @@ export default class Explorer {
|
||||
this.notebookManager?.notebookContentClient.createDirectory(notebookFile, input, isGithubTree)
|
||||
}
|
||||
notebookFile={parent}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -951,7 +951,7 @@ export default class Explorer {
|
||||
(error) => {
|
||||
logConsoleError(`Could not download notebook ${getErrorMessage(error)}`);
|
||||
clearMessage();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1004,7 +1004,7 @@ export default class Explorer {
|
||||
|
||||
return this.notebookManager?.notebookContentClient.deleteContentItem(item, isGithubTree).then(
|
||||
() => logConsoleInfo(`Successfully deleted: ${item.path}`),
|
||||
(reason) => logConsoleError(`Failed to delete "${item.path}": ${JSON.stringify(reason)}`)
|
||||
(reason) => logConsoleError(`Failed to delete "${item.path}": ${JSON.stringify(reason)}`),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1034,7 +1034,7 @@ export default class Explorer {
|
||||
},
|
||||
"Cancel",
|
||||
undefined,
|
||||
this.getNewNoteWarningText()
|
||||
this.getNewNoteWarningText(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -1073,7 +1073,7 @@ export default class Explorer {
|
||||
{
|
||||
dataExplorerArea: Constants.Areas.Notebook,
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
return this.openNotebook(newFile);
|
||||
})
|
||||
@@ -1088,7 +1088,7 @@ export default class Explorer {
|
||||
error: errorMessage,
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
})
|
||||
.finally(clearInProgressMessage);
|
||||
@@ -1116,7 +1116,7 @@ export default class Explorer {
|
||||
.getState()
|
||||
.showOkModalDialog(
|
||||
"Failed to connect",
|
||||
"Failed to connect to temporary workspace. This could happen because of network issues. Please refresh the page and try again."
|
||||
"Failed to connect to temporary workspace. This could happen because of network issues. Please refresh the page and try again.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -1182,7 +1182,7 @@ export default class Explorer {
|
||||
selectedTab?: GalleryTabKind,
|
||||
notebookUrl?: string,
|
||||
galleryItem?: IGalleryItem,
|
||||
isFavorite?: boolean
|
||||
isFavorite?: boolean,
|
||||
): Promise<void> {
|
||||
const title = "Gallery";
|
||||
const GalleryTab = await (await import(/* webpackChunkName: "GalleryTab" */ "./Tabs/GalleryTab")).default;
|
||||
@@ -1211,8 +1211,8 @@ export default class Explorer {
|
||||
notebookUrl,
|
||||
galleryItem,
|
||||
isFavorite,
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1221,14 +1221,14 @@ export default class Explorer {
|
||||
options: {
|
||||
databaseId?: string;
|
||||
isQuickstart?: boolean;
|
||||
} = {}
|
||||
} = {},
|
||||
): Promise<void> {
|
||||
if (userContext.apiType === "Cassandra") {
|
||||
useSidePanel
|
||||
.getState()
|
||||
.openSidePanel(
|
||||
"Add Table",
|
||||
<CassandraAddCollectionPane explorer={this} cassandraApiClient={new CassandraAPIDataClient()} />
|
||||
<CassandraAddCollectionPane explorer={this} cassandraApiClient={new CassandraAPIDataClient()} />,
|
||||
);
|
||||
} else {
|
||||
const throughputCap = userContext.databaseAccount?.properties.capacity?.totalThroughputLimit;
|
||||
@@ -1298,7 +1298,7 @@ export default class Explorer {
|
||||
},
|
||||
"Cancel",
|
||||
undefined,
|
||||
this.getNewNoteWarningText()
|
||||
this.getNewNoteWarningText(),
|
||||
);
|
||||
} else {
|
||||
parent = parent || this.resourceTree.myNotebooksContentRoot;
|
||||
@@ -1311,7 +1311,7 @@ export default class Explorer {
|
||||
.getState()
|
||||
.openSidePanel(
|
||||
"Upload file to notebook server",
|
||||
<UploadFilePane uploadFile={(name: string, content: string) => this.uploadFile(name, content, parent)} />
|
||||
<UploadFilePane uploadFile={(name: string, content: string) => this.uploadFile(name, content, parent)} />,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ export class D3ForceGraph implements GraphRenderer {
|
||||
|
||||
if (this.uniqueValues.length === D3ForceGraph.MAX_COLOR_NB) {
|
||||
this.errorMsgs.push(
|
||||
`Number of unique values for property ${key} exceeds maximum (${D3ForceGraph.MAX_COLOR_NB})`
|
||||
`Number of unique values for property ${key} exceeds maximum (${D3ForceGraph.MAX_COLOR_NB})`,
|
||||
);
|
||||
// ignore rest of values
|
||||
break;
|
||||
@@ -347,14 +347,14 @@ export class D3ForceGraph implements GraphRenderer {
|
||||
return d.id;
|
||||
})
|
||||
.distance(D3ForceGraph.FORCE_LINK_DISTANCE)
|
||||
.strength(D3ForceGraph.FORCE_LINK_STRENGTH)
|
||||
.strength(D3ForceGraph.FORCE_LINK_STRENGTH),
|
||||
)
|
||||
.force("charge", forceManyBody())
|
||||
.force(
|
||||
"collide",
|
||||
forceCollide(D3ForceGraph.FORCE_COLLIDE_RADIUS)
|
||||
.strength(D3ForceGraph.FORCE_COLLIDE_STRENGTH)
|
||||
.iterations(D3ForceGraph.FORCE_COLLIDE_ITERATIONS)
|
||||
.iterations(D3ForceGraph.FORCE_COLLIDE_ITERATIONS),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -695,7 +695,7 @@ export class D3ForceGraph implements GraphRenderer {
|
||||
}) as any)
|
||||
.on("end", ((e: D3DragEvent<SVGGElement, D3Node, unknown>, d: D3Node) => {
|
||||
return this.dragended(d, e);
|
||||
}) as any)
|
||||
}) as any),
|
||||
)
|
||||
.on("mouseover", (_: MouseEvent, d: D3Node) => {
|
||||
if (this.isHighlightDisabled || this.selectedNode || this.isDragging) {
|
||||
@@ -867,7 +867,7 @@ export class D3ForceGraph implements GraphRenderer {
|
||||
select(e.target as any).classed("active", false);
|
||||
}) as any)
|
||||
.attr("visibility", (d: D3Node) =>
|
||||
!d._pagination || d._pagination.currentPage.start !== 0 ? "visible" : "hidden"
|
||||
!d._pagination || d._pagination.currentPage.start !== 0 ? "visible" : "hidden",
|
||||
);
|
||||
parent
|
||||
.append("rect")
|
||||
@@ -921,7 +921,7 @@ export class D3ForceGraph implements GraphRenderer {
|
||||
gaugeYOffset +
|
||||
gaugeHeight / 2 +
|
||||
D3ForceGraph.PAGINATION_LINE1_Y_OFFSET_PX +
|
||||
D3ForceGraph.PAGINATION_LINE2_Y_OFFSET_PX
|
||||
D3ForceGraph.PAGINATION_LINE2_Y_OFFSET_PX,
|
||||
)
|
||||
.text((d: D3Node) => {
|
||||
const pageInfo = d._pagination;
|
||||
@@ -1100,7 +1100,7 @@ export class D3ForceGraph implements GraphRenderer {
|
||||
default:
|
||||
case NeighborType.BOTH:
|
||||
return (this.graphDataWrapper.getSourcesForId(nodeId) || []).concat(
|
||||
this.graphDataWrapper.getTargetsForId(nodeId)
|
||||
this.graphDataWrapper.getTargetsForId(nodeId),
|
||||
);
|
||||
}
|
||||
})(this.igraphConfig.showNeighborType);
|
||||
|
||||
@@ -79,8 +79,8 @@ export class EditorNodePropertiesComponent extends React.Component<EditorNodePro
|
||||
{this.props.editedProperties.readOnlyProperties.map((nodeProp: ViewModels.InputProperty) =>
|
||||
ReadOnlyNodePropertiesComponent.renderReadOnlyPropertyKeyPair(
|
||||
nodeProp.key,
|
||||
nodeProp.values.map((val) => val.value)
|
||||
)
|
||||
nodeProp.values.map((val) => val.value),
|
||||
),
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -72,7 +72,7 @@ describe("Graph Data", () => {
|
||||
testString: [{ id: "123", value: stringValue }],
|
||||
},
|
||||
},
|
||||
"testString"
|
||||
"testString",
|
||||
);
|
||||
|
||||
expect(value).toEqual(stringValue);
|
||||
@@ -88,7 +88,7 @@ describe("Graph Data", () => {
|
||||
testString: [{ id: "123", value: numberValue }],
|
||||
},
|
||||
},
|
||||
"testString"
|
||||
"testString",
|
||||
);
|
||||
|
||||
expect(value).toEqual(numberValue);
|
||||
@@ -104,7 +104,7 @@ describe("Graph Data", () => {
|
||||
testString: [{ id: "123", value: booleanValue }],
|
||||
},
|
||||
},
|
||||
"testString"
|
||||
"testString",
|
||||
);
|
||||
|
||||
expect(value).toEqual(booleanValue);
|
||||
|
||||
@@ -235,7 +235,7 @@ export class GraphData<V extends GremlinVertex, E extends GremlinEdge> {
|
||||
*/
|
||||
public static addToEdgeArray(
|
||||
edge: GremlinShortInEdge | GremlinShortOutEdge,
|
||||
edgeArray: (GremlinShortInEdge | GremlinShortOutEdge)[]
|
||||
edgeArray: (GremlinShortInEdge | GremlinShortOutEdge)[],
|
||||
) {
|
||||
for (let i = 0; i < edgeArray.length; i++) {
|
||||
if (edgeArray[i].id === edge.id) {
|
||||
|
||||
@@ -54,7 +54,7 @@ describe("Check whether query result is edge-vertex array", () => {
|
||||
e: { id: "ide", type: "edge" },
|
||||
v: { id: "idv", type: "vertex" },
|
||||
},
|
||||
])
|
||||
]),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -207,11 +207,9 @@ describe("GraphExplorer", () => {
|
||||
const gVRU = 123.456;
|
||||
|
||||
const disableMonacoEditor = (graphExplorer: GraphExplorer) => {
|
||||
renderResultAsJsonStub = sinon.stub(graphExplorer, "renderResultAsJson").callsFake(
|
||||
(): JSX.Element => {
|
||||
return <div>[Monaco Editor Stub]</div>;
|
||||
}
|
||||
);
|
||||
renderResultAsJsonStub = sinon.stub(graphExplorer, "renderResultAsJson").callsFake((): JSX.Element => {
|
||||
return <div>[Monaco Editor Stub]</div>;
|
||||
});
|
||||
};
|
||||
|
||||
interface AjaxResponse {
|
||||
@@ -227,7 +225,7 @@ describe("GraphExplorer", () => {
|
||||
graphExplorer: GraphExplorer,
|
||||
backendResponses: BackendResponses,
|
||||
done: any,
|
||||
ignoreD3Update: boolean
|
||||
ignoreD3Update: boolean,
|
||||
) => {
|
||||
const complete = (): void => {
|
||||
wrapper.update();
|
||||
@@ -299,7 +297,7 @@ describe("GraphExplorer", () => {
|
||||
docDBResponse: AjaxResponse,
|
||||
backendResponses: BackendResponses,
|
||||
done: any,
|
||||
ignoreD3Update: boolean
|
||||
ignoreD3Update: boolean,
|
||||
): GraphExplorer => {
|
||||
(queryDocuments as jest.Mock).mockImplementation((container: any, query: string, options: any) => {
|
||||
return {
|
||||
@@ -321,7 +319,7 @@ describe("GraphExplorer", () => {
|
||||
headers: [] as any[],
|
||||
requestCharge: gVRU,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
const props: GraphExplorerProps = createMockProps();
|
||||
wrapper = mount(<GraphExplorer {...props} />);
|
||||
|
||||
@@ -346,7 +346,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
// DO NOT UPDATE Multi-value properties (as this is not supported)
|
||||
if (p.values.length === 1) {
|
||||
updateQueryFragment += `.Property("${GraphUtil.escapeDoubleQuotes(p.key)}", ${GraphUtil.getQuotedPropValue(
|
||||
p.values[0]
|
||||
p.values[0],
|
||||
)})`;
|
||||
}
|
||||
});
|
||||
@@ -374,12 +374,12 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
// TODO Wait for dropping to end. Can we drop all of them in a single query?
|
||||
// Must execute these drops sequentially to avoid a 500 "{"Message":"An error has occurred."}"
|
||||
promise = this.submitToBackend(
|
||||
`g.V(${pkId}).properties("${GraphUtil.escapeDoubleQuotes(droppedKeys[0])}").drop()`
|
||||
`g.V(${pkId}).properties("${GraphUtil.escapeDoubleQuotes(droppedKeys[0])}").drop()`,
|
||||
);
|
||||
for (let i = 1; i < droppedKeys.length; i++) {
|
||||
promise = promise.then(() => {
|
||||
return this.submitToBackend(
|
||||
`g.V(${pkId}).properties("${GraphUtil.escapeDoubleQuotes(droppedKeys[i])}").drop()`
|
||||
`g.V(${pkId}).properties("${GraphUtil.escapeDoubleQuotes(droppedKeys[i])}").drop()`,
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -413,7 +413,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
},
|
||||
(error: string) => {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, "Failed to update vertex properties: " + error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return promise;
|
||||
@@ -458,9 +458,9 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
(error: string) => {
|
||||
GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.Error,
|
||||
`Failed to remove node (Gremlin failed to execute). id=${id} : ${error}`
|
||||
`Failed to remove node (Gremlin failed to execute). id=${id} : ${error}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
outE: boolean,
|
||||
vertex: GraphData.GremlinVertex,
|
||||
startIndex: number,
|
||||
pageSize: number
|
||||
pageSize: number,
|
||||
): Q.Promise<EdgeVertexPair[]> {
|
||||
if (startIndex < 0) {
|
||||
const error = `Attempt to fetch edge-vertex pairs with negative index: outE:${outE}, vertex id:${vertex.id}, startIndex:${startIndex}, pageSize:${pageSize}`;
|
||||
@@ -528,7 +528,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
excludedEdgeIds,
|
||||
startIndex,
|
||||
pageSize,
|
||||
GraphExplorer.WITHOUT_STEP_ARGS_MAX_CHARS
|
||||
GraphExplorer.WITHOUT_STEP_ARGS_MAX_CHARS,
|
||||
);
|
||||
|
||||
return this.submitToBackend(gremlinQuery).then((result: GremlinClient.GremlinRequestResult) => {
|
||||
@@ -572,7 +572,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
public loadNeighborsPage(
|
||||
vertex: GraphData.GremlinVertex,
|
||||
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>,
|
||||
offsetIndex: number
|
||||
offsetIndex: number,
|
||||
): Q.Promise<GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>> {
|
||||
const updateGraphData = () => {
|
||||
// Cache results
|
||||
@@ -627,46 +627,44 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
});
|
||||
addedEdgesNb += pairsToAdd.length;
|
||||
return pairs.length;
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
promise = Q.resolve(0);
|
||||
}
|
||||
|
||||
promise = promise.then(
|
||||
(outEPairsNb: number): Q.Promise<number> => {
|
||||
const inEdgesToFetch = totalEdgesToFetch - outEPairsNb;
|
||||
if (!vertex._inEAllLoaded && inEdgesToFetch > 0) {
|
||||
let start: number;
|
||||
if (offsetIndex <= vertex._outEdgeIds.length) {
|
||||
start = 0;
|
||||
} else {
|
||||
start = offsetIndex - vertex._outEdgeIds.length;
|
||||
}
|
||||
|
||||
return this.fetchEdgeVertexPairs(false, vertex, start, inEdgesToFetch).then(
|
||||
(pairs: EdgeVertexPair[]): number => {
|
||||
vertex._inEAllLoaded = pairs.length < inEdgesToFetch;
|
||||
|
||||
const pairsToAdd = pairs.slice(0, GraphExplorer.LOAD_PAGE_SIZE - outEPairsNb);
|
||||
pairsToAdd.forEach((p: EdgeVertexPair) => {
|
||||
GraphData.GraphData.addInE(vertex, p.e.label, p.e);
|
||||
GraphUtil.addRootChildToGraph(vertex, p.v, graphData);
|
||||
graphData.addEdge(p.e);
|
||||
vertex._inEdgeIds.push(p.e.id);
|
||||
|
||||
// Cache results (graphdata now contains a vertex with outE's filled in)
|
||||
this.edgeInfoCache.addVertex(graphData.getVertexById(p.v.id));
|
||||
});
|
||||
addedEdgesNb += pairsToAdd.length;
|
||||
return outEPairsNb + pairs.length;
|
||||
}
|
||||
);
|
||||
promise = promise.then((outEPairsNb: number): Q.Promise<number> => {
|
||||
const inEdgesToFetch = totalEdgesToFetch - outEPairsNb;
|
||||
if (!vertex._inEAllLoaded && inEdgesToFetch > 0) {
|
||||
let start: number;
|
||||
if (offsetIndex <= vertex._outEdgeIds.length) {
|
||||
start = 0;
|
||||
} else {
|
||||
return Q.resolve(outEPairsNb);
|
||||
start = offsetIndex - vertex._outEdgeIds.length;
|
||||
}
|
||||
|
||||
return this.fetchEdgeVertexPairs(false, vertex, start, inEdgesToFetch).then(
|
||||
(pairs: EdgeVertexPair[]): number => {
|
||||
vertex._inEAllLoaded = pairs.length < inEdgesToFetch;
|
||||
|
||||
const pairsToAdd = pairs.slice(0, GraphExplorer.LOAD_PAGE_SIZE - outEPairsNb);
|
||||
pairsToAdd.forEach((p: EdgeVertexPair) => {
|
||||
GraphData.GraphData.addInE(vertex, p.e.label, p.e);
|
||||
GraphUtil.addRootChildToGraph(vertex, p.v, graphData);
|
||||
graphData.addEdge(p.e);
|
||||
vertex._inEdgeIds.push(p.e.id);
|
||||
|
||||
// Cache results (graphdata now contains a vertex with outE's filled in)
|
||||
this.edgeInfoCache.addVertex(graphData.getVertexById(p.v.id));
|
||||
});
|
||||
addedEdgesNb += pairsToAdd.length;
|
||||
return outEPairsNb + pairs.length;
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return Q.resolve(outEPairsNb);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return promise.then(() => {
|
||||
if (offsetIndex >= GraphExplorer.LOAD_PAGE_SIZE || !vertex._outEAllLoaded || !vertex._inEAllLoaded) {
|
||||
@@ -706,7 +704,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
}
|
||||
GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.Info,
|
||||
`Executed: ${cmd} ${GremlinClient.GremlinClient.getRequestChargeString(result.totalRequestCharge)}`
|
||||
`Executed: ${cmd} ${GremlinClient.GremlinClient.getRequestChargeString(result.totalRequestCharge)}`,
|
||||
);
|
||||
return result;
|
||||
},
|
||||
@@ -715,7 +713,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, `Gremlin query failed: ${cmd}`, err);
|
||||
clearConsoleProgress();
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -733,9 +731,9 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
maxItemCount: GraphExplorer.PAGE_ALL,
|
||||
enableCrossPartitionQuery:
|
||||
StorageUtility.LocalStorageUtility.getEntryString(
|
||||
StorageUtility.StorageKey.IsCrossPartitionQueryEnabled
|
||||
StorageUtility.StorageKey.IsCrossPartitionQueryEnabled,
|
||||
) === "true",
|
||||
} as FeedOptions
|
||||
} as FeedOptions,
|
||||
);
|
||||
const response = await iterator.fetchNext();
|
||||
|
||||
@@ -744,7 +742,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.Error,
|
||||
`Failed to execute non-paged query ${query}. Reason:${error}`,
|
||||
error
|
||||
error,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
@@ -756,7 +754,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
*/
|
||||
public createNewEdge(e: GraphNewEdgeData): Q.Promise<unknown> {
|
||||
const q = `g.V('${GraphUtil.escapeSingleQuotes(e.inputOutV)}').addE('${GraphUtil.escapeSingleQuotes(
|
||||
e.label
|
||||
e.label,
|
||||
)}').To(g.V('${GraphUtil.escapeSingleQuotes(e.inputInV)}'))`;
|
||||
return this.submitToBackend(q).then(
|
||||
(result: GremlinClient.GremlinRequestResult) => {
|
||||
@@ -789,9 +787,9 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
(error: string) => {
|
||||
GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.Error,
|
||||
"Failed to create edge (Gremlin query failed to execute): " + error
|
||||
"Failed to create edge (Gremlin query failed to execute): " + error,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -810,9 +808,9 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
(error: string) => {
|
||||
GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.Error,
|
||||
"Failed to remove edge (Gremlin query failed to execute): " + error
|
||||
"Failed to remove edge (Gremlin query failed to execute): " + error,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -960,7 +958,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
const title = "Failed to create vertex (Gremlin query failed to execute)";
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, title + " :" + error);
|
||||
throw { title: title, detail: error };
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1035,7 +1033,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
dataExplorerArea: Constants.Areas.Tab,
|
||||
tabTitle: "Graph",
|
||||
},
|
||||
this.props.onLoadStartKey
|
||||
this.props.onLoadStartKey,
|
||||
);
|
||||
this.props.onLoadStartKeyChange(null);
|
||||
}
|
||||
@@ -1119,7 +1117,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
this.collectNodeProperties(
|
||||
Object.keys(rootMap).map((id: string) => {
|
||||
return rootMap[id];
|
||||
})
|
||||
}),
|
||||
);
|
||||
if (this.state.igraphConfigUiData.nodeProperties.indexOf(GraphExplorer.DISPLAY_DEFAULT_PROPERTY_KEY) !== -1) {
|
||||
this.setState({
|
||||
@@ -1161,8 +1159,8 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
const newIconsMap = {} as D3ForceGraph.D3GraphIconMap;
|
||||
this.executeNonPagedDocDbQuery(
|
||||
`SELECT c._graph_icon_property_value, c.format, c.icon FROM c WHERE c._graph_icon_set = "${GraphUtil.escapeDoubleQuotes(
|
||||
iconSet
|
||||
)}"`
|
||||
iconSet,
|
||||
)}"`,
|
||||
).then(
|
||||
(documents: DataModels.DocumentId[]) => {
|
||||
$.each(
|
||||
@@ -1172,7 +1170,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
data: doc["icon"],
|
||||
format: doc["format"],
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Update graph configuration
|
||||
@@ -1186,7 +1184,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
},
|
||||
() => {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, `Failed to retrieve icons. iconSet:${iconSet}`);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1228,16 +1226,13 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
|
||||
private getPossibleRootNodes(): LeftPane.CaptionId[] {
|
||||
const key = this.state.igraphConfig.nodeCaption;
|
||||
return $.map(
|
||||
this.state.rootMap,
|
||||
(value: any): LeftPane.CaptionId => {
|
||||
const result = GraphData.GraphData.getNodePropValue(value, key);
|
||||
return {
|
||||
caption: result !== undefined ? result : value.id,
|
||||
id: value.id,
|
||||
};
|
||||
}
|
||||
);
|
||||
return $.map(this.state.rootMap, (value: any): LeftPane.CaptionId => {
|
||||
const result = GraphData.GraphData.getNodePropValue(value, key);
|
||||
return {
|
||||
caption: result !== undefined ? result : value.id,
|
||||
id: value.id,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1291,7 +1286,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
},
|
||||
(reason: string) => {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, `Failed to select root node. Reason:${reason}`);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1459,7 +1454,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
() => {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, "Failed to retrieve list of possible vertices");
|
||||
return [];
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1485,7 +1480,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
// Reload neighbors in case we linked to a vertex that isn't loaded in the graph
|
||||
const highlightedVertex = this.originalGraphData.getVertexById(this.state.highlightedNode.id);
|
||||
return this.loadNeighborsPage(highlightedVertex, this.originalGraphData, 0);
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1617,7 +1612,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
id: string,
|
||||
nodeCaption: string,
|
||||
sources: NeighborVertexBasicInfo[],
|
||||
targets: NeighborVertexBasicInfo[]
|
||||
targets: NeighborVertexBasicInfo[],
|
||||
): void {
|
||||
// update neighbors
|
||||
const gd = this.originalGraphData;
|
||||
@@ -1668,11 +1663,9 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
}
|
||||
|
||||
this.setState({
|
||||
possibleEdgeLabels: Object.keys(possibleEdgeLabels).map(
|
||||
(value: string): InputTypeaheadComponent.Item => {
|
||||
return { caption: value, value: value };
|
||||
}
|
||||
),
|
||||
possibleEdgeLabels: Object.keys(possibleEdgeLabels).map((value: string): InputTypeaheadComponent.Item => {
|
||||
return { caption: value, value: value };
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1714,7 +1707,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
*/
|
||||
private updateGraphData(
|
||||
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>,
|
||||
igraphConfig?: IGraphConfig
|
||||
igraphConfig?: IGraphConfig,
|
||||
) {
|
||||
this.originalGraphData = graphData;
|
||||
const gd = JSON.parse(JSON.stringify(this.originalGraphData));
|
||||
@@ -1792,7 +1785,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
maxItemCount: GraphExplorer.ROOT_LIST_PAGE_SIZE,
|
||||
enableCrossPartitionQuery:
|
||||
LocalStorageUtility.getEntryString(StorageKey.IsCrossPartitionQueryEnabled) === "true",
|
||||
} as FeedOptions
|
||||
} as FeedOptions,
|
||||
);
|
||||
this.currentDocDBQueryInfo = {
|
||||
iterator: iterator,
|
||||
@@ -1803,7 +1796,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
} catch (error) {
|
||||
GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.Error,
|
||||
`Failed to execute CosmosDB query: ${query} reason:${error}`
|
||||
`Failed to execute CosmosDB query: ${query} reason:${error}`,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
@@ -1820,14 +1813,14 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
})`;
|
||||
const clearConsoleProgress = GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.InProgress,
|
||||
`Executing: ${queryInfoStr}`
|
||||
`Executing: ${queryInfoStr}`,
|
||||
);
|
||||
|
||||
try {
|
||||
const results: ViewModels.QueryResults = await queryDocumentsPage(
|
||||
this.props.collectionId,
|
||||
this.currentDocDBQueryInfo.iterator,
|
||||
this.currentDocDBQueryInfo.index
|
||||
this.currentDocDBQueryInfo.index,
|
||||
);
|
||||
|
||||
clearConsoleProgress();
|
||||
@@ -1836,10 +1829,10 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
RU = results.requestCharge.toString();
|
||||
GraphExplorer.reportToConsole(
|
||||
ConsoleDataType.Info,
|
||||
`Executed: ${queryInfoStr} ${GremlinClient.GremlinClient.getRequestChargeString(RU)}`
|
||||
`Executed: ${queryInfoStr} ${GremlinClient.GremlinClient.getRequestChargeString(RU)}`,
|
||||
);
|
||||
const pkIds: string[] = (results.documents || []).map((item: DataModels.DocumentId) =>
|
||||
GraphExplorer.getPkIdFromDocumentId(item, this.props.collectionPartitionKeyProperty)
|
||||
GraphExplorer.getPkIdFromDocumentId(item, this.props.collectionPartitionKeyProperty),
|
||||
);
|
||||
|
||||
const arg = pkIds.join(",");
|
||||
@@ -1877,7 +1870,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
});
|
||||
this.setFilterQueryStatus(FilterQueryStatus.ErrorResult);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
promise
|
||||
|
||||
@@ -103,19 +103,19 @@ describe("fetchEdgeVertexPairs()", () => {
|
||||
|
||||
it("should perform outE() query", () => {
|
||||
expect(GraphUtil.createFetchEdgePairQuery(true, pkid, [], startIndex, pageSize, max)).toMatch(
|
||||
new RegExp(OUT_E_MATCHER, "g")
|
||||
new RegExp(OUT_E_MATCHER, "g"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should perform inE() query", () => {
|
||||
expect(GraphUtil.createFetchEdgePairQuery(false, pkid, [], startIndex, pageSize, max)).toMatch(
|
||||
new RegExp(IN_E_MATCHER, "g")
|
||||
new RegExp(IN_E_MATCHER, "g"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should contain .has(id, without()) step which contains excludedIds", () => {
|
||||
expect(GraphUtil.createFetchEdgePairQuery(true, pkid, ["id1", "id2"], startIndex, pageSize, max)).toMatch(
|
||||
/\.has\(id, *without\('id1', *'id2'\)\)/g
|
||||
/\.has\(id, *without\('id1', *'id2'\)\)/g,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -127,7 +127,7 @@ describe("fetchEdgeVertexPairs()", () => {
|
||||
const regex = new RegExp(`\\.limit\\(${pageSize}\\)`, "g");
|
||||
expect(GraphUtil.createFetchEdgePairQuery(true, pkid, ["id1", "id2"], startIndex, pageSize, max)).toMatch(regex);
|
||||
expect(GraphUtil.createFetchEdgePairQuery(true, pkid, ["id1", "id2"], startIndex, pageSize, max)).toMatch(
|
||||
/^((?!range).)*$/g
|
||||
/^((?!range).)*$/g,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -140,7 +140,7 @@ describe("fetchEdgeVertexPairs()", () => {
|
||||
const regex = new RegExp(`\\.range\\(${expectedStart}, *${expectedStart + size}\\)`, "g");
|
||||
expect(GraphUtil.createFetchEdgePairQuery(true, pkid, excludedIds, start, size, smallLimit)).toMatch(regex);
|
||||
expect(GraphUtil.createFetchEdgePairQuery(true, pkid, excludedIds, start, size, smallLimit)).toMatch(
|
||||
/^((?!limit).)*$/g
|
||||
/^((?!limit).)*$/g,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export const getNeighborTitle = (neighbor: NeighborVertexBasicInfo): string => {
|
||||
export const createEdgesfromNode = (
|
||||
vertex: GraphData.GremlinVertex,
|
||||
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>,
|
||||
newNodes?: { [id: string]: boolean }
|
||||
newNodes?: { [id: string]: boolean },
|
||||
): void => {
|
||||
if (Object.prototype.hasOwnProperty.call(vertex, "outE")) {
|
||||
const outE = vertex.outE;
|
||||
@@ -104,7 +104,7 @@ export const createFetchEdgePairQuery = (
|
||||
excludedEdgeIds: string[],
|
||||
startIndex: number,
|
||||
pageSize: number,
|
||||
withoutStepArgMaxLenght: number
|
||||
withoutStepArgMaxLenght: number,
|
||||
): string => {
|
||||
let gremlinQuery: string;
|
||||
if (excludedEdgeIds.length > 0) {
|
||||
@@ -135,7 +135,7 @@ export const createFetchEdgePairQuery = (
|
||||
*/
|
||||
export const trimGraph = (
|
||||
currentRoot: GraphData.GremlinVertex,
|
||||
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>
|
||||
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>,
|
||||
): void => {
|
||||
const importantNodes = [currentRoot.id].concat(currentRoot._ancestorsId);
|
||||
graphData.unloadAllVertices(importantNodes);
|
||||
@@ -149,7 +149,7 @@ export const trimGraph = (
|
||||
export const addRootChildToGraph = (
|
||||
root: GraphData.GremlinVertex,
|
||||
child: GraphData.GremlinVertex,
|
||||
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>
|
||||
graphData: GraphData.GraphData<GraphData.GremlinVertex, GraphData.GremlinEdge>,
|
||||
): void => {
|
||||
child._ancestorsId = (root._ancestorsId || []).concat([root.id]);
|
||||
graphData.addVertex(child);
|
||||
|
||||
@@ -145,7 +145,7 @@ describe("Gremlin Client", () => {
|
||||
done(e);
|
||||
}
|
||||
},
|
||||
(error) => done.fail(error)
|
||||
(error) => done.fail(error),
|
||||
)
|
||||
.finally(() => {
|
||||
logConsoleSpy.restore();
|
||||
@@ -188,7 +188,7 @@ describe("Gremlin Client", () => {
|
||||
done(e);
|
||||
}
|
||||
},
|
||||
(error) => done.fail(error)
|
||||
(error) => done.fail(error),
|
||||
)
|
||||
.finally(() => {
|
||||
logConsoleSpy.restore();
|
||||
@@ -225,7 +225,7 @@ describe("Gremlin Client", () => {
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
gremlinClient.client.params.failureCallback(
|
||||
@@ -234,7 +234,7 @@ describe("Gremlin Client", () => {
|
||||
requestCharge: RU,
|
||||
requestId: requestId,
|
||||
},
|
||||
error
|
||||
error,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -260,7 +260,7 @@ describe("Gremlin Client", () => {
|
||||
requestCharge: undefined,
|
||||
requestId: undefined,
|
||||
},
|
||||
error
|
||||
error,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ export class GremlinClient {
|
||||
|
||||
if (!requestId || !this.pendingResults.has(requestId)) {
|
||||
const errorMsg = `Error: ${errorMessage}, unknown requestId:${requestId} ${GremlinClient.getRequestChargeString(
|
||||
result.requestCharge
|
||||
result.requestCharge,
|
||||
)}`;
|
||||
handleError(errorMsg, GremlinClient.LOG_AREA);
|
||||
|
||||
@@ -90,7 +90,7 @@ export class GremlinClient {
|
||||
deferred: deferred,
|
||||
timeoutId: window.setTimeout(
|
||||
() => this.abortPendingRequest(requestId, GremlinClient.TIMEOUT_ERROR_MSG, null),
|
||||
GremlinClient.PENDING_REQUEST_TIMEOUT_MS
|
||||
GremlinClient.PENDING_REQUEST_TIMEOUT_MS,
|
||||
),
|
||||
});
|
||||
return deferred.promise;
|
||||
@@ -126,7 +126,7 @@ export class GremlinClient {
|
||||
this.pendingResults.delete(requestId);
|
||||
|
||||
const errorMsg = `Aborting pending request ${requestId}. Error:${error} ${GremlinClient.getRequestChargeString(
|
||||
requestCharge
|
||||
requestCharge,
|
||||
)}`;
|
||||
handleError(errorMsg, GremlinClient.LOG_AREA);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ describe("Gremlin Simple Client", () => {
|
||||
|
||||
const fakeStatus = (
|
||||
code: number,
|
||||
requestCharge: number
|
||||
requestCharge: number,
|
||||
): {
|
||||
attributes: {
|
||||
"x-ms-request-charge": number;
|
||||
@@ -94,236 +94,16 @@ describe("Gremlin Simple Client", () => {
|
||||
result: { data: ["é"], meta: {} },
|
||||
};
|
||||
const expectedDecodedUint8ArrayValues = [
|
||||
123,
|
||||
34,
|
||||
114,
|
||||
101,
|
||||
113,
|
||||
117,
|
||||
101,
|
||||
115,
|
||||
116,
|
||||
73,
|
||||
100,
|
||||
34,
|
||||
58,
|
||||
34,
|
||||
100,
|
||||
55,
|
||||
55,
|
||||
50,
|
||||
102,
|
||||
56,
|
||||
57,
|
||||
55,
|
||||
45,
|
||||
48,
|
||||
100,
|
||||
52,
|
||||
100,
|
||||
45,
|
||||
52,
|
||||
99,
|
||||
100,
|
||||
49,
|
||||
45,
|
||||
98,
|
||||
51,
|
||||
54,
|
||||
48,
|
||||
45,
|
||||
100,
|
||||
100,
|
||||
102,
|
||||
54,
|
||||
99,
|
||||
56,
|
||||
54,
|
||||
98,
|
||||
57,
|
||||
51,
|
||||
97,
|
||||
51,
|
||||
34,
|
||||
44,
|
||||
34,
|
||||
115,
|
||||
116,
|
||||
97,
|
||||
116,
|
||||
117,
|
||||
115,
|
||||
34,
|
||||
58,
|
||||
123,
|
||||
34,
|
||||
99,
|
||||
111,
|
||||
100,
|
||||
101,
|
||||
34,
|
||||
58,
|
||||
50,
|
||||
48,
|
||||
48,
|
||||
44,
|
||||
34,
|
||||
97,
|
||||
116,
|
||||
116,
|
||||
114,
|
||||
105,
|
||||
98,
|
||||
117,
|
||||
116,
|
||||
101,
|
||||
115,
|
||||
34,
|
||||
58,
|
||||
123,
|
||||
34,
|
||||
103,
|
||||
114,
|
||||
97,
|
||||
112,
|
||||
104,
|
||||
69,
|
||||
120,
|
||||
101,
|
||||
99,
|
||||
117,
|
||||
116,
|
||||
105,
|
||||
111,
|
||||
110,
|
||||
83,
|
||||
116,
|
||||
97,
|
||||
116,
|
||||
117,
|
||||
115,
|
||||
34,
|
||||
58,
|
||||
50,
|
||||
48,
|
||||
48,
|
||||
44,
|
||||
34,
|
||||
83,
|
||||
116,
|
||||
111,
|
||||
114,
|
||||
97,
|
||||
103,
|
||||
101,
|
||||
82,
|
||||
85,
|
||||
34,
|
||||
58,
|
||||
50,
|
||||
46,
|
||||
50,
|
||||
57,
|
||||
44,
|
||||
34,
|
||||
67,
|
||||
111,
|
||||
109,
|
||||
112,
|
||||
117,
|
||||
116,
|
||||
101,
|
||||
82,
|
||||
85,
|
||||
34,
|
||||
58,
|
||||
49,
|
||||
46,
|
||||
48,
|
||||
55,
|
||||
44,
|
||||
34,
|
||||
80,
|
||||
101,
|
||||
114,
|
||||
80,
|
||||
97,
|
||||
114,
|
||||
116,
|
||||
105,
|
||||
116,
|
||||
105,
|
||||
111,
|
||||
110,
|
||||
67,
|
||||
111,
|
||||
109,
|
||||
112,
|
||||
117,
|
||||
116,
|
||||
101,
|
||||
67,
|
||||
104,
|
||||
97,
|
||||
114,
|
||||
103,
|
||||
101,
|
||||
115,
|
||||
34,
|
||||
58,
|
||||
123,
|
||||
125,
|
||||
125,
|
||||
44,
|
||||
34,
|
||||
109,
|
||||
101,
|
||||
115,
|
||||
115,
|
||||
97,
|
||||
103,
|
||||
101,
|
||||
34,
|
||||
58,
|
||||
34,
|
||||
34,
|
||||
125,
|
||||
44,
|
||||
34,
|
||||
114,
|
||||
101,
|
||||
115,
|
||||
117,
|
||||
108,
|
||||
116,
|
||||
34,
|
||||
58,
|
||||
123,
|
||||
34,
|
||||
100,
|
||||
97,
|
||||
116,
|
||||
97,
|
||||
34,
|
||||
58,
|
||||
91,
|
||||
34,
|
||||
195,
|
||||
169,
|
||||
34,
|
||||
93,
|
||||
44,
|
||||
34,
|
||||
109,
|
||||
101,
|
||||
116,
|
||||
97,
|
||||
34,
|
||||
58,
|
||||
123,
|
||||
125,
|
||||
125,
|
||||
125,
|
||||
123, 34, 114, 101, 113, 117, 101, 115, 116, 73, 100, 34, 58, 34, 100, 55, 55, 50, 102, 56, 57, 55, 45, 48, 100,
|
||||
52, 100, 45, 52, 99, 100, 49, 45, 98, 51, 54, 48, 45, 100, 100, 102, 54, 99, 56, 54, 98, 57, 51, 97, 51, 34, 44,
|
||||
34, 115, 116, 97, 116, 117, 115, 34, 58, 123, 34, 99, 111, 100, 101, 34, 58, 50, 48, 48, 44, 34, 97, 116, 116,
|
||||
114, 105, 98, 117, 116, 101, 115, 34, 58, 123, 34, 103, 114, 97, 112, 104, 69, 120, 101, 99, 117, 116, 105, 111,
|
||||
110, 83, 116, 97, 116, 117, 115, 34, 58, 50, 48, 48, 44, 34, 83, 116, 111, 114, 97, 103, 101, 82, 85, 34, 58, 50,
|
||||
46, 50, 57, 44, 34, 67, 111, 109, 112, 117, 116, 101, 82, 85, 34, 58, 49, 46, 48, 55, 44, 34, 80, 101, 114, 80,
|
||||
97, 114, 116, 105, 116, 105, 111, 110, 67, 111, 109, 112, 117, 116, 101, 67, 104, 97, 114, 103, 101, 115, 34, 58,
|
||||
123, 125, 125, 44, 34, 109, 101, 115, 115, 97, 103, 101, 34, 58, 34, 34, 125, 44, 34, 114, 101, 115, 117, 108,
|
||||
116, 34, 58, 123, 34, 100, 97, 116, 97, 34, 58, 91, 34, 195, 169, 34, 93, 44, 34, 109, 101, 116, 97, 34, 58, 123,
|
||||
125, 125, 125,
|
||||
];
|
||||
// We do our best here to emulate what the server should return
|
||||
const gremlinResponseData = new Uint8Array(<any>expectedDecodedUint8ArrayValues).buffer;
|
||||
@@ -395,7 +175,7 @@ describe("Gremlin Simple Client", () => {
|
||||
requestId: fakeResponse.requestId,
|
||||
data: fakeResponse.result.data,
|
||||
requestCharge: RU,
|
||||
})
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
@@ -419,7 +199,7 @@ describe("Gremlin Simple Client", () => {
|
||||
requestId: fakeResponse.requestId,
|
||||
data: null,
|
||||
requestCharge: RU,
|
||||
})
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
@@ -444,7 +224,7 @@ describe("Gremlin Simple Client", () => {
|
||||
requestId: fakeResponse.requestId,
|
||||
data: fakeResponse.result.data,
|
||||
requestCharge: RU,
|
||||
})
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(onSuccessSpy.notCalled).toBe(true);
|
||||
});
|
||||
|
||||
@@ -136,7 +136,7 @@ export class GremlinSimpleClient {
|
||||
if (this.params.failureCallback) {
|
||||
this.params.failureCallback(
|
||||
null,
|
||||
`Unexpected error while decoding backend response: ${e} msg:${JSON.stringify(msg)}`
|
||||
`Unexpected error while decoding backend response: ${e} msg:${JSON.stringify(msg)}`,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
@@ -169,7 +169,7 @@ export class GremlinSimpleClient {
|
||||
if (this.params.failureCallback) {
|
||||
this.params.failureCallback(
|
||||
result,
|
||||
`Received response for missing or closed request: ${requestId} code:${statusCode} message:${statusMessage}`
|
||||
`Received response for missing or closed request: ${requestId} code:${statusCode} message:${statusMessage}`,
|
||||
);
|
||||
}
|
||||
return;
|
||||
@@ -282,7 +282,7 @@ export class GremlinSimpleClient {
|
||||
return btoa(
|
||||
encodeURIComponent(utf8Str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode(parseInt(p1, 16));
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ export class NodePropertiesComponent extends React.Component<
|
||||
},
|
||||
() => {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, "Failed to update Vertex sources.");
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ export class NodePropertiesComponent extends React.Component<
|
||||
isSectionExpanded: boolean,
|
||||
expandClickHandler: () => void,
|
||||
currentView: Mode,
|
||||
saveClickHandler: () => void
|
||||
saveClickHandler: () => void,
|
||||
): JSX.Element {
|
||||
if (isSectionExpanded) {
|
||||
return (
|
||||
@@ -444,7 +444,7 @@ export class NodePropertiesComponent extends React.Component<
|
||||
this.state.isPropertiesExpanded,
|
||||
this.showPropertyEditor.bind(this),
|
||||
Mode.PROPERTY_EDITOR,
|
||||
this.saveProperties.bind(this)
|
||||
this.saveProperties.bind(this),
|
||||
)}
|
||||
<AccessibleElement
|
||||
className="sectionHeader"
|
||||
@@ -508,7 +508,7 @@ export class NodePropertiesComponent extends React.Component<
|
||||
isNeighborExpanded,
|
||||
showNeighborEditor,
|
||||
currentNeighborView,
|
||||
this.updateVertexNeighbors.bind(this, isSource)
|
||||
this.updateVertexNeighbors.bind(this, isSource),
|
||||
)}
|
||||
|
||||
<AccessibleElement
|
||||
|
||||
@@ -39,10 +39,10 @@ export class ReadOnlyNodePropertiesComponent extends React.Component<ReadOnlyNod
|
||||
|
||||
public static renderReadOnlyPropertyKeyPair(
|
||||
key: string,
|
||||
propertyValues: ViewModels.GremlinPropertyValueType[]
|
||||
propertyValues: ViewModels.GremlinPropertyValueType[],
|
||||
): JSX.Element {
|
||||
const renderedValues = propertyValues.map((value) =>
|
||||
ReadOnlyNodePropertiesComponent.renderSinglePropertyValue(value)
|
||||
ReadOnlyNodePropertiesComponent.renderSinglePropertyValue(value),
|
||||
);
|
||||
const stringifiedValues = propertyValues
|
||||
.map((value) => ReadOnlyNodePropertiesComponent.singlePropertyValueToString(value))
|
||||
|
||||
@@ -27,7 +27,7 @@ export const NewVertexComponent: FunctionComponent<INewVertexComponentProps> = (
|
||||
values: [{ value: "", type: DEFAULT_PROPERTY_TYPE }],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const propertyTypes: string[] = EditorNodePropertiesComponent.VERTEX_PROPERTY_TYPES;
|
||||
|
||||
@@ -57,7 +57,7 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
|
||||
|
||||
const staticButtons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(container, selectedNodeState);
|
||||
const contextButtons = (buttons || []).concat(
|
||||
CommandBarComponentButtonFactory.createContextCommandBarButtons(container, selectedNodeState)
|
||||
CommandBarComponentButtonFactory.createContextCommandBarButtons(container, selectedNodeState),
|
||||
);
|
||||
const controlButtons = CommandBarComponentButtonFactory.createControlCommandBarButtons(container);
|
||||
|
||||
@@ -82,7 +82,7 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
|
||||
connectionInfo?.status !== ConnectionStatusType.Connect
|
||||
) {
|
||||
uiFabricControlButtons.unshift(
|
||||
CommandBarUtil.createConnectionStatus(container, PoolIdType.DefaultPoolId, "connectionStatus")
|
||||
CommandBarUtil.createConnectionStatus(container, PoolIdType.DefaultPoolId, "connectionStatus"),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
||||
it("Button should be visible", () => {
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const enableAzureSynapseLinkBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel,
|
||||
);
|
||||
expect(enableAzureSynapseLinkBtn).toBeDefined();
|
||||
});
|
||||
@@ -50,7 +50,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
||||
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const enableAzureSynapseLinkBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel,
|
||||
);
|
||||
expect(enableAzureSynapseLinkBtn).toBeUndefined();
|
||||
});
|
||||
@@ -66,7 +66,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
||||
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const enableAzureSynapseLinkBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel
|
||||
(button) => button.commandButtonLabel === enableAzureSynapseLinkBtnLabel,
|
||||
);
|
||||
expect(enableAzureSynapseLinkBtn).toBeUndefined();
|
||||
});
|
||||
@@ -354,7 +354,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
||||
it("creates Postgres shell button", () => {
|
||||
const buttons = CommandBarComponentButtonFactory.createPostgreButtons(mockExplorer);
|
||||
const openPostgresShellButton = buttons.find(
|
||||
(button) => button.commandButtonLabel === openPostgresShellButtonLabel
|
||||
(button) => button.commandButtonLabel === openPostgresShellButtonLabel,
|
||||
);
|
||||
expect(openPostgresShellButton).toBeDefined();
|
||||
});
|
||||
@@ -362,7 +362,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
||||
it("creates vCore Mongo shell button", () => {
|
||||
const buttons = CommandBarComponentButtonFactory.createVCoreMongoButtons(mockExplorer);
|
||||
const openVCoreMongoShellButton = buttons.find(
|
||||
(button) => button.commandButtonLabel === openVCoreMongoShellButtonLabel
|
||||
(button) => button.commandButtonLabel === openVCoreMongoShellButtonLabel,
|
||||
);
|
||||
expect(openVCoreMongoShellButton).toBeDefined();
|
||||
});
|
||||
@@ -406,7 +406,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
||||
|
||||
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
|
||||
const manageGitHubSettingsBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === manageGitHubSettingsBtnLabel
|
||||
(button) => button.commandButtonLabel === manageGitHubSettingsBtnLabel,
|
||||
);
|
||||
expect(manageGitHubSettingsBtn).toBeDefined();
|
||||
});
|
||||
@@ -418,7 +418,7 @@ describe("CommandBarComponentButtonFactory tests", () => {
|
||||
expect(connectToGitHubBtn).toBeUndefined();
|
||||
|
||||
const manageGitHubSettingsBtn = buttons.find(
|
||||
(button) => button.commandButtonLabel === manageGitHubSettingsBtnLabel
|
||||
(button) => button.commandButtonLabel === manageGitHubSettingsBtnLabel,
|
||||
);
|
||||
expect(manageGitHubSettingsBtn).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ let counter = 0;
|
||||
|
||||
export function createStaticCommandBarButtons(
|
||||
container: Explorer,
|
||||
selectedNodeState: SelectedNodeState
|
||||
selectedNodeState: SelectedNodeState,
|
||||
): CommandButtonComponentProps[] {
|
||||
if (userContext.authType === AuthType.ResourceToken) {
|
||||
return createStaticCommandBarButtonsForResourceToken(container, selectedNodeState);
|
||||
@@ -166,7 +166,7 @@ export function createStaticCommandBarButtons(
|
||||
|
||||
export function createContextCommandBarButtons(
|
||||
container: Explorer,
|
||||
selectedNodeState: SelectedNodeState
|
||||
selectedNodeState: SelectedNodeState,
|
||||
): CommandButtonComponentProps[] {
|
||||
const buttons: CommandButtonComponentProps[] = [];
|
||||
|
||||
@@ -507,7 +507,7 @@ function createOpenTerminalButton(container: Explorer): CommandButtonComponentPr
|
||||
|
||||
function createOpenTerminalButtonByKind(
|
||||
container: Explorer,
|
||||
terminalKind: ViewModels.TerminalKind
|
||||
terminalKind: ViewModels.TerminalKind,
|
||||
): CommandButtonComponentProps {
|
||||
const terminalFriendlyName = (): string => {
|
||||
switch (terminalKind) {
|
||||
@@ -573,7 +573,7 @@ function createManageGitHubAccountButton(container: Explorer): CommandButtonComp
|
||||
explorer={container}
|
||||
gitHubClientProp={container.notebookManager.gitHubClient}
|
||||
junoClientProp={junoClient}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
},
|
||||
commandButtonLabel: label,
|
||||
@@ -585,7 +585,7 @@ function createManageGitHubAccountButton(container: Explorer): CommandButtonComp
|
||||
|
||||
function createStaticCommandBarButtonsForResourceToken(
|
||||
container: Explorer,
|
||||
selectedNodeState: SelectedNodeState
|
||||
selectedNodeState: SelectedNodeState,
|
||||
): CommandButtonComponentProps[] {
|
||||
const newSqlQueryBtn = createNewSQLQueryButton(selectedNodeState);
|
||||
const openQueryBtn = createOpenQueryButton(container);
|
||||
|
||||
@@ -38,156 +38,154 @@ export const convertButton = (btns: CommandButtonComponentProps[], backgroundCol
|
||||
|
||||
return btns
|
||||
.filter((btn) => btn)
|
||||
.map(
|
||||
(btn: CommandButtonComponentProps, index: number): ICommandBarItemProps => {
|
||||
if (btn.isDivider) {
|
||||
return createDivider(btn.commandButtonLabel);
|
||||
}
|
||||
.map((btn: CommandButtonComponentProps, index: number): ICommandBarItemProps => {
|
||||
if (btn.isDivider) {
|
||||
return createDivider(btn.commandButtonLabel);
|
||||
}
|
||||
|
||||
const isSplit = !!btn.children && btn.children.length > 0;
|
||||
const label = btn.commandButtonLabel || btn.tooltipText;
|
||||
const result: ICommandBarItemProps = {
|
||||
iconProps: {
|
||||
style: {
|
||||
width: StyleConstants.CommandBarIconWidth, // 16
|
||||
alignSelf: btn.iconName ? "baseline" : undefined,
|
||||
filter: getFilter(btn.disabled),
|
||||
},
|
||||
imageProps: btn.iconSrc ? { src: btn.iconSrc, alt: btn.iconAlt } : undefined,
|
||||
iconName: btn.iconName,
|
||||
const isSplit = !!btn.children && btn.children.length > 0;
|
||||
const label = btn.commandButtonLabel || btn.tooltipText;
|
||||
const result: ICommandBarItemProps = {
|
||||
iconProps: {
|
||||
style: {
|
||||
width: StyleConstants.CommandBarIconWidth, // 16
|
||||
alignSelf: btn.iconName ? "baseline" : undefined,
|
||||
filter: getFilter(btn.disabled),
|
||||
},
|
||||
onClick: (ev?: React.MouseEvent<HTMLElement, MouseEvent> | React.KeyboardEvent<HTMLElement>) => {
|
||||
btn.onCommandClick(ev);
|
||||
TelemetryProcessor.trace(Action.ClickCommandBarButton, ActionModifiers.Mark, { label });
|
||||
imageProps: btn.iconSrc ? { src: btn.iconSrc, alt: btn.iconAlt } : undefined,
|
||||
iconName: btn.iconName,
|
||||
},
|
||||
onClick: (ev?: React.MouseEvent<HTMLElement, MouseEvent> | React.KeyboardEvent<HTMLElement>) => {
|
||||
btn.onCommandClick(ev);
|
||||
TelemetryProcessor.trace(Action.ClickCommandBarButton, ActionModifiers.Mark, { label });
|
||||
},
|
||||
key: `${btn.commandButtonLabel}${index}`,
|
||||
text: label,
|
||||
"data-test": label,
|
||||
title: btn.tooltipText,
|
||||
name: label,
|
||||
disabled: btn.disabled,
|
||||
ariaLabel: btn.ariaLabel,
|
||||
buttonStyles: {
|
||||
root: {
|
||||
backgroundColor: backgroundColor,
|
||||
height: buttonHeightPx,
|
||||
paddingRight: 0,
|
||||
paddingLeft: 0,
|
||||
borderRadius: configContext.platform == Platform.Fabric ? StyleConstants.FabricButtonBorderRadius : "0px",
|
||||
minWidth: 24,
|
||||
marginLeft: isSplit ? 0 : 5,
|
||||
marginRight: isSplit ? 0 : 5,
|
||||
},
|
||||
key: `${btn.commandButtonLabel}${index}`,
|
||||
text: label,
|
||||
"data-test": label,
|
||||
title: btn.tooltipText,
|
||||
name: label,
|
||||
disabled: btn.disabled,
|
||||
ariaLabel: btn.ariaLabel,
|
||||
buttonStyles: {
|
||||
root: {
|
||||
backgroundColor: backgroundColor,
|
||||
height: buttonHeightPx,
|
||||
paddingRight: 0,
|
||||
paddingLeft: 0,
|
||||
borderRadius: configContext.platform == Platform.Fabric ? StyleConstants.FabricButtonBorderRadius : "0px",
|
||||
minWidth: 24,
|
||||
marginLeft: isSplit ? 0 : 5,
|
||||
marginRight: isSplit ? 0 : 5,
|
||||
rootDisabled: {
|
||||
backgroundColor: backgroundColor,
|
||||
pointerEvents: "auto",
|
||||
},
|
||||
splitButtonMenuButton: {
|
||||
backgroundColor: backgroundColor,
|
||||
selectors: {
|
||||
":hover": { backgroundColor: hoverColor },
|
||||
},
|
||||
rootDisabled: {
|
||||
backgroundColor: backgroundColor,
|
||||
pointerEvents: "auto",
|
||||
width: 16,
|
||||
},
|
||||
label: { fontSize: StyleConstants.mediumFontSize },
|
||||
rootHovered: { backgroundColor: hoverColor },
|
||||
rootPressed: { backgroundColor: hoverColor },
|
||||
splitButtonMenuButtonExpanded: {
|
||||
backgroundColor: StyleConstants.AccentExtra,
|
||||
selectors: {
|
||||
":hover": { backgroundColor: hoverColor },
|
||||
},
|
||||
splitButtonMenuButton: {
|
||||
backgroundColor: backgroundColor,
|
||||
},
|
||||
splitButtonDivider: {
|
||||
display: "none",
|
||||
},
|
||||
icon: {
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
},
|
||||
splitButtonContainer: {
|
||||
marginLeft: 5,
|
||||
marginRight: 5,
|
||||
},
|
||||
},
|
||||
className: btn.className,
|
||||
id: btn.id,
|
||||
};
|
||||
|
||||
if (isSplit) {
|
||||
// It's a split button
|
||||
result.split = true;
|
||||
|
||||
result.subMenuProps = {
|
||||
items: convertButton(btn.children, backgroundColor),
|
||||
styles: {
|
||||
list: {
|
||||
// TODO Figure out how to do it the proper way with subComponentStyles.
|
||||
// TODO Remove all this crazy styling once we adopt Ui-Fabric Azure themes
|
||||
selectors: {
|
||||
":hover": { backgroundColor: hoverColor },
|
||||
},
|
||||
width: 16,
|
||||
},
|
||||
label: { fontSize: StyleConstants.mediumFontSize },
|
||||
rootHovered: { backgroundColor: hoverColor },
|
||||
rootPressed: { backgroundColor: hoverColor },
|
||||
splitButtonMenuButtonExpanded: {
|
||||
backgroundColor: StyleConstants.AccentExtra,
|
||||
selectors: {
|
||||
":hover": { backgroundColor: hoverColor },
|
||||
".ms-ContextualMenu-itemText": { fontSize: StyleConstants.mediumFontSize },
|
||||
".ms-ContextualMenu-link:hover": { backgroundColor: hoverColor },
|
||||
".ms-ContextualMenu-icon": { width: 16, height: 16 },
|
||||
},
|
||||
},
|
||||
splitButtonDivider: {
|
||||
display: "none",
|
||||
},
|
||||
icon: {
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
},
|
||||
splitButtonContainer: {
|
||||
marginLeft: 5,
|
||||
marginRight: 5,
|
||||
},
|
||||
},
|
||||
className: btn.className,
|
||||
id: btn.id,
|
||||
};
|
||||
|
||||
if (isSplit) {
|
||||
// It's a split button
|
||||
result.split = true;
|
||||
|
||||
result.subMenuProps = {
|
||||
items: convertButton(btn.children, backgroundColor),
|
||||
styles: {
|
||||
list: {
|
||||
// TODO Figure out how to do it the proper way with subComponentStyles.
|
||||
// TODO Remove all this crazy styling once we adopt Ui-Fabric Azure themes
|
||||
selectors: {
|
||||
".ms-ContextualMenu-itemText": { fontSize: StyleConstants.mediumFontSize },
|
||||
".ms-ContextualMenu-link:hover": { backgroundColor: hoverColor },
|
||||
".ms-ContextualMenu-icon": { width: 16, height: 16 },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
result.menuIconProps = {
|
||||
iconType: IconType.image,
|
||||
style: {
|
||||
width: 12,
|
||||
paddingLeft: 1,
|
||||
paddingTop: 6,
|
||||
filter: getFilter(btn.disabled),
|
||||
},
|
||||
imageProps: {
|
||||
src: ChevronDownIcon,
|
||||
alt: btn.iconAlt,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (btn.isDropdown) {
|
||||
const selectedChild = _.find(btn.children, (child) => child.dropdownItemKey === btn.dropdownSelectedKey);
|
||||
result.name = selectedChild?.commandButtonLabel || btn.dropdownPlaceholder;
|
||||
|
||||
const dropdownStyles: Partial<IDropdownStyles> = {
|
||||
root: { margin: 5 },
|
||||
dropdown: { width: btn.dropdownWidth },
|
||||
title: { fontSize: 12, height: 30, lineHeight: 28 },
|
||||
dropdownItem: { fontSize: 12, lineHeight: 28, minHeight: 30 },
|
||||
dropdownItemSelected: { fontSize: 12, lineHeight: 28, minHeight: 30 },
|
||||
};
|
||||
|
||||
const onDropdownChange = (
|
||||
event: React.FormEvent<HTMLDivElement>,
|
||||
option?: IDropdownOption,
|
||||
index?: number
|
||||
): void => {
|
||||
btn.children[index].onCommandClick(event);
|
||||
TelemetryProcessor.trace(Action.ClickCommandBarButton, ActionModifiers.Mark, { label: option.text });
|
||||
};
|
||||
|
||||
result.commandBarButtonAs = (props: IComponentAsProps<ICommandBarItemProps>) => {
|
||||
return (
|
||||
<Dropdown
|
||||
placeholder={btn.dropdownPlaceholder}
|
||||
defaultSelectedKey={btn.dropdownSelectedKey}
|
||||
onChange={onDropdownChange}
|
||||
options={btn.children.map((child: CommandButtonComponentProps) => ({
|
||||
key: child.dropdownItemKey,
|
||||
text: child.commandButtonLabel,
|
||||
}))}
|
||||
styles={dropdownStyles}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
result.menuIconProps = {
|
||||
iconType: IconType.image,
|
||||
style: {
|
||||
width: 12,
|
||||
paddingLeft: 1,
|
||||
paddingTop: 6,
|
||||
filter: getFilter(btn.disabled),
|
||||
},
|
||||
imageProps: {
|
||||
src: ChevronDownIcon,
|
||||
alt: btn.iconAlt,
|
||||
},
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
if (btn.isDropdown) {
|
||||
const selectedChild = _.find(btn.children, (child) => child.dropdownItemKey === btn.dropdownSelectedKey);
|
||||
result.name = selectedChild?.commandButtonLabel || btn.dropdownPlaceholder;
|
||||
|
||||
const dropdownStyles: Partial<IDropdownStyles> = {
|
||||
root: { margin: 5 },
|
||||
dropdown: { width: btn.dropdownWidth },
|
||||
title: { fontSize: 12, height: 30, lineHeight: 28 },
|
||||
dropdownItem: { fontSize: 12, lineHeight: 28, minHeight: 30 },
|
||||
dropdownItemSelected: { fontSize: 12, lineHeight: 28, minHeight: 30 },
|
||||
};
|
||||
|
||||
const onDropdownChange = (
|
||||
event: React.FormEvent<HTMLDivElement>,
|
||||
option?: IDropdownOption,
|
||||
index?: number,
|
||||
): void => {
|
||||
btn.children[index].onCommandClick(event);
|
||||
TelemetryProcessor.trace(Action.ClickCommandBarButton, ActionModifiers.Mark, { label: option.text });
|
||||
};
|
||||
|
||||
result.commandBarButtonAs = (props: IComponentAsProps<ICommandBarItemProps>) => {
|
||||
return (
|
||||
<Dropdown
|
||||
placeholder={btn.dropdownPlaceholder}
|
||||
defaultSelectedKey={btn.dropdownSelectedKey}
|
||||
onChange={onDropdownChange}
|
||||
options={btn.children.map((child: CommandButtonComponentProps) => ({
|
||||
key: child.dropdownItemKey,
|
||||
text: child.commandButtonLabel,
|
||||
}))}
|
||||
styles={dropdownStyles}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
export const createDivider = (key: string): ICommandBarItemProps => {
|
||||
|
||||
@@ -125,7 +125,7 @@ export const ConnectionStatus: React.FC<Props> = ({ container, poolId }: Props):
|
||||
content={
|
||||
containerInfo?.status === ContainerStatusType.Active
|
||||
? `Connected to temporary workspace. This temporary workspace will get disconnected in ${Math.round(
|
||||
containerInfo.durationLeftInMinutes
|
||||
containerInfo.durationLeftInMinutes,
|
||||
)} minutes.`
|
||||
: toolTipContent
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ export class NotificationConsoleComponent extends React.Component<
|
||||
|
||||
public componentDidUpdate(
|
||||
prevProps: NotificationConsoleComponentProps,
|
||||
prevState: NotificationConsoleComponentState
|
||||
prevState: NotificationConsoleComponentState,
|
||||
): void {
|
||||
const currentHeaderStatus = NotificationConsoleComponent.extractHeaderStatus(this.props.consoleData);
|
||||
|
||||
@@ -87,12 +87,14 @@ export class NotificationConsoleComponent extends React.Component<
|
||||
|
||||
public render(): JSX.Element {
|
||||
const numInProgress = this.state.allConsoleData.filter(
|
||||
(data: ConsoleData) => data.type === ConsoleDataType.InProgress
|
||||
(data: ConsoleData) => data.type === ConsoleDataType.InProgress,
|
||||
).length;
|
||||
const numErroredItems = this.state.allConsoleData.filter(
|
||||
(data: ConsoleData) => data.type === ConsoleDataType.Error,
|
||||
).length;
|
||||
const numInfoItems = this.state.allConsoleData.filter(
|
||||
(data: ConsoleData) => data.type === ConsoleDataType.Info,
|
||||
).length;
|
||||
const numErroredItems = this.state.allConsoleData.filter((data: ConsoleData) => data.type === ConsoleDataType.Error)
|
||||
.length;
|
||||
const numInfoItems = this.state.allConsoleData.filter((data: ConsoleData) => data.type === ConsoleDataType.Info)
|
||||
.length;
|
||||
|
||||
return (
|
||||
<div className="notificationConsoleContainer">
|
||||
@@ -246,7 +248,7 @@ export class NotificationConsoleComponent extends React.Component<
|
||||
this.setState({ headerStatus: statusMessage });
|
||||
this.headerTimeoutId = window.setTimeout(
|
||||
() => this.setState({ headerStatus: "" }),
|
||||
ClientDefaults.errorNotificationTimeoutMs
|
||||
ClientDefaults.errorNotificationTimeoutMs,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -272,7 +274,7 @@ export class NotificationConsoleComponent extends React.Component<
|
||||
) {
|
||||
const allConsoleData = this.state.allConsoleData.filter(
|
||||
(data: ConsoleData) =>
|
||||
!(data.type === ConsoleDataType.InProgress && data.id === this.props.inProgressConsoleDataIdToBeDeleted)
|
||||
!(data.type === ConsoleDataType.InProgress && data.id === this.props.inProgressConsoleDataIdToBeDeleted),
|
||||
);
|
||||
this.setState({ allConsoleData });
|
||||
}
|
||||
@@ -312,7 +314,7 @@ export const NotificationConsole: React.FC = () => {
|
||||
const isExpanded = useNotificationConsole((state) => state.isExpanded);
|
||||
const consoleData = useNotificationConsole((state) => state.consoleData);
|
||||
const inProgressConsoleDataIdToBeDeleted = useNotificationConsole(
|
||||
(state) => state.inProgressConsoleDataIdToBeDeleted
|
||||
(state) => state.inProgressConsoleDataIdToBeDeleted,
|
||||
);
|
||||
// TODO Refactor NotificationConsoleComponent into a functional component and remove this wrapper
|
||||
// This component only exists so we can use hooks and pass them down to a non-functional component
|
||||
|
||||
@@ -72,7 +72,7 @@ export class NotebookClientV2 {
|
||||
actions.fetchKernelspecs({
|
||||
hostRef: this.contentHostRef,
|
||||
kernelspecsRef: this.kernelSpecsRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -192,36 +192,36 @@ export class NotebookClientV2 {
|
||||
* is triggered for *any* state change).
|
||||
* TODO: Use react-redux connect() to subscribe to state changes?
|
||||
*/
|
||||
const cacheKernelSpecsMiddleware: Middleware = <D extends Dispatch<AnyAction>, S extends AppState>({
|
||||
dispatch,
|
||||
getState,
|
||||
}: MiddlewareAPI<D, S>) => (next: Dispatch<AnyAction>) => <A extends AnyAction>(action: A): A => {
|
||||
switch (action.type) {
|
||||
case actions.FETCH_KERNELSPECS_FULFILLED: {
|
||||
const payload = ((action as unknown) as actions.FetchKernelspecsFulfilled).payload;
|
||||
const defaultKernelName = payload.defaultKernelName;
|
||||
this.kernelSpecsForDisplay = Object.values(payload.kernelspecs)
|
||||
.filter((spec) => !spec.metadata?.hasOwnProperty("hidden"))
|
||||
.map((spec) => ({
|
||||
name: spec.name,
|
||||
displayName: spec.displayName,
|
||||
}))
|
||||
.sort((a: KernelSpecsDisplay, b: KernelSpecsDisplay) => {
|
||||
// Put default at the top, otherwise lexicographically compare
|
||||
if (a.displayName === defaultKernelName) {
|
||||
return -1;
|
||||
} else if (b.name === defaultKernelName) {
|
||||
return 1;
|
||||
} else {
|
||||
return a.displayName.localeCompare(b.displayName);
|
||||
}
|
||||
});
|
||||
break;
|
||||
const cacheKernelSpecsMiddleware: Middleware =
|
||||
<D extends Dispatch<AnyAction>, S extends AppState>({ dispatch, getState }: MiddlewareAPI<D, S>) =>
|
||||
(next: Dispatch<AnyAction>) =>
|
||||
<A extends AnyAction>(action: A): A => {
|
||||
switch (action.type) {
|
||||
case actions.FETCH_KERNELSPECS_FULFILLED: {
|
||||
const payload = (action as unknown as actions.FetchKernelspecsFulfilled).payload;
|
||||
const defaultKernelName = payload.defaultKernelName;
|
||||
this.kernelSpecsForDisplay = Object.values(payload.kernelspecs)
|
||||
.filter((spec) => !spec.metadata?.hasOwnProperty("hidden"))
|
||||
.map((spec) => ({
|
||||
name: spec.name,
|
||||
displayName: spec.displayName,
|
||||
}))
|
||||
.sort((a: KernelSpecsDisplay, b: KernelSpecsDisplay) => {
|
||||
// Put default at the top, otherwise lexicographically compare
|
||||
if (a.displayName === defaultKernelName) {
|
||||
return -1;
|
||||
} else if (b.name === defaultKernelName) {
|
||||
return 1;
|
||||
} else {
|
||||
return a.displayName.localeCompare(b.displayName);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return next(action);
|
||||
};
|
||||
return next(action);
|
||||
};
|
||||
|
||||
const traceErrorFct = (title: string, message: string) => {
|
||||
TelemetryProcessor.traceFailure(Action.NotebookErrorNotification, {
|
||||
@@ -238,13 +238,13 @@ export class NotebookClientV2 {
|
||||
params.contentProvider,
|
||||
traceErrorFct,
|
||||
[cacheKernelSpecsMiddleware],
|
||||
!params.isReadOnly
|
||||
!params.isReadOnly,
|
||||
);
|
||||
|
||||
// Additional configuration
|
||||
this.store.dispatch(configOption("editorType").action(params.cellEditorType ?? "codemirror"));
|
||||
this.store.dispatch(
|
||||
configOption("autoSaveInterval").action(params.autoSaveInterval ?? Constants.Notebook.autoSaveIntervalMs)
|
||||
configOption("autoSaveInterval").action(params.autoSaveInterval ?? Constants.Notebook.autoSaveIntervalMs),
|
||||
);
|
||||
this.store.dispatch(configOption("codeMirror.lineNumbers").action(true));
|
||||
|
||||
|
||||
@@ -12,7 +12,10 @@ export interface InMemoryContentProviderParams {
|
||||
// Nteract relies on `errno` property to figure out the kind of failure
|
||||
// That's why we need a custom wrapper around Error to include `errno` property
|
||||
class InMemoryContentProviderError extends Error {
|
||||
constructor(error: string, public errno: number = InMemoryContentProvider.SelfErrorCode) {
|
||||
constructor(
|
||||
error: string,
|
||||
public errno: number = InMemoryContentProvider.SelfErrorCode,
|
||||
) {
|
||||
super(error);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +50,7 @@ export class InMemoryContentProvider implements IContentProvider {
|
||||
public save<FT extends FileType>(
|
||||
_config: ServerConfig, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
uri: string,
|
||||
model: Partial<IContent<FT>>
|
||||
model: Partial<IContent<FT>>,
|
||||
): Observable<AjaxResponse> {
|
||||
const item = this.params[uri];
|
||||
if (item) {
|
||||
|
||||
@@ -39,7 +39,7 @@ export class NotebookComponentAdapter extends NotebookComponentBootstrapper impl
|
||||
params: {},
|
||||
kernelRef,
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ export class NotebookComponentBootstrapper {
|
||||
model: NotebookComponentBootstrapper.wrapModelIntoContent(name, undefined, content),
|
||||
kernelRef: undefined,
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ export class NotebookComponentBootstrapper {
|
||||
*/
|
||||
public renderComponent(
|
||||
renderer?: any, // TODO FIX THIS React.ComponentClass<{ contentRef: ContentRef; isReadOnly?: boolean }>,
|
||||
props?: any
|
||||
props?: any,
|
||||
): JSX.Element {
|
||||
return (
|
||||
<Provider store={this.getStore()}>
|
||||
@@ -149,18 +149,18 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.save({
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
"Cancel",
|
||||
undefined,
|
||||
this.getSaveNotebookSubText()
|
||||
this.getSaveNotebookSubText(),
|
||||
);
|
||||
} else {
|
||||
this.getStore().dispatch(
|
||||
actions.save({
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -171,7 +171,7 @@ export class NotebookComponentBootstrapper {
|
||||
contentRef: this.contentRef,
|
||||
kernelSpecName,
|
||||
oldKernelRef: this.getCurrentKernelRef(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
CdbActions.executeFocusedCellAndFocusNext({
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.executeAllCells({
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.interruptKernel({
|
||||
kernelRef: this.getCurrentKernelRef(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ export class NotebookComponentBootstrapper {
|
||||
actions.killKernel({
|
||||
restarting: false,
|
||||
kernelRef: this.getCurrentKernelRef(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ export class NotebookComponentBootstrapper {
|
||||
kernelRef: this.getCurrentKernelRef(),
|
||||
contentRef: this.contentRef,
|
||||
outputHandling: "None",
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.clearAllOutputs({
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ export class NotebookComponentBootstrapper {
|
||||
actions.createCellBelow({
|
||||
cellType: "code",
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ export class NotebookComponentBootstrapper {
|
||||
id: focusedCellId,
|
||||
contentRef: this.contentRef,
|
||||
to: type,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ export class NotebookComponentBootstrapper {
|
||||
actions.copyCell({
|
||||
id: focusedCellId,
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ export class NotebookComponentBootstrapper {
|
||||
actions.cutCell({
|
||||
id: focusedCellId,
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.getStore().dispatch(
|
||||
actions.pasteCell({
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -298,14 +298,14 @@ export class NotebookComponentBootstrapper {
|
||||
actions.killKernel({
|
||||
restarting: false,
|
||||
kernelRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
store.dispatch(
|
||||
CdbActions.closeNotebook({
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export class NotebookContentProvider implements IContentProvider {
|
||||
constructor(
|
||||
private inMemoryContentProvider: InMemoryContentProvider,
|
||||
private gitHubContentProvider: GitHubContentProvider,
|
||||
private jupyterContentProvider: IContentProvider
|
||||
private jupyterContentProvider: IContentProvider,
|
||||
) {}
|
||||
|
||||
public remove(serverConfig: ServerConfig, path: string): Observable<AjaxResponse> {
|
||||
@@ -24,7 +24,7 @@ export class NotebookContentProvider implements IContentProvider {
|
||||
public update<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>>
|
||||
model: Partial<IContent<FT>>,
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).update(serverConfig, path, model);
|
||||
}
|
||||
@@ -32,7 +32,7 @@ export class NotebookContentProvider implements IContentProvider {
|
||||
public create<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>> & { type: FT }
|
||||
model: Partial<IContent<FT>> & { type: FT },
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).create(serverConfig, path, model);
|
||||
}
|
||||
@@ -40,7 +40,7 @@ export class NotebookContentProvider implements IContentProvider {
|
||||
public save<FT extends FileType>(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
model: Partial<IContent<FT>>
|
||||
model: Partial<IContent<FT>>,
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).save(serverConfig, path, model);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ export class NotebookContentProvider implements IContentProvider {
|
||||
public restoreFromCheckpoint(
|
||||
serverConfig: ServerConfig,
|
||||
path: string,
|
||||
checkpointID: string
|
||||
checkpointID: string,
|
||||
): Observable<AjaxResponse> {
|
||||
return this.getContentProvider(path).restoreFromCheckpoint(serverConfig, path, checkpointID);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ interface InitialProps {
|
||||
// Redux
|
||||
const makeMapStateToProps = (
|
||||
initialState: AppState,
|
||||
initialProps: InitialProps
|
||||
initialProps: InitialProps,
|
||||
): ((state: AppState) => VirtualCommandBarComponentProps) => {
|
||||
const { contentRef } = initialProps;
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
|
||||
@@ -84,7 +84,7 @@ interface InitialProps {
|
||||
|
||||
function makeMapStateToTextFileProps(
|
||||
initialState: AppState,
|
||||
initialProps: InitialProps
|
||||
initialProps: InitialProps,
|
||||
): (state: AppState) => MappedStateProps {
|
||||
const { contentRef } = initialProps;
|
||||
|
||||
@@ -107,7 +107,7 @@ function makeMapStateToTextFileProps(
|
||||
|
||||
const makeMapDispatchToTextFileProps = (
|
||||
initialDispatch: Dispatch,
|
||||
initialProps: InitialProps
|
||||
initialProps: InitialProps,
|
||||
): ((dispatch: Dispatch) => MappedDispatchProps) => {
|
||||
const { contentRef } = initialProps;
|
||||
|
||||
@@ -118,7 +118,7 @@ const makeMapDispatchToTextFileProps = (
|
||||
actions.updateFileText({
|
||||
contentRef,
|
||||
text: source,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -128,7 +128,7 @@ const makeMapDispatchToTextFileProps = (
|
||||
|
||||
const ConnectedTextFile = connect<MappedStateProps, MappedDispatchProps, InitialProps, AppState>(
|
||||
makeMapStateToTextFileProps,
|
||||
makeMapDispatchToTextFileProps
|
||||
makeMapDispatchToTextFileProps,
|
||||
)(TextFile);
|
||||
|
||||
export function handles(mimetype: string) {
|
||||
|
||||
@@ -141,7 +141,7 @@ const mapDispatchToProps = (dispatch: Dispatch, ownProps: ContentsProps): object
|
||||
actions.overwriteMetadataFields({
|
||||
...props,
|
||||
contentRef: ownProps.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
// `HotKeys` handlers object
|
||||
|
||||
@@ -131,7 +131,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
@@ -197,7 +197,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName,
|
||||
cwd,
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
@@ -250,7 +250,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName: undefined,
|
||||
cwd,
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
@@ -299,7 +299,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName: undefined,
|
||||
cwd,
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
(sessions as any).__setResponse({
|
||||
@@ -397,7 +397,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName: "kernel2",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
@@ -418,7 +418,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName: undefined,
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
@@ -440,7 +440,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName: "This is an unknown kernelspec",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
@@ -462,7 +462,7 @@ describe("launchWebSocketKernelEpic", () => {
|
||||
kernelSpecName: "ernel1",
|
||||
cwd: "cwd",
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
await launchWebSocketKernelEpic(action$, state$).pipe(toArray()).toPromise();
|
||||
|
||||
@@ -66,7 +66,7 @@ const logFailureToTelemetry = (state: CdbAppState, title: string, error?: string
|
||||
*/
|
||||
const addInitialCodeCellEpic = (
|
||||
action$: Observable<actions.FetchContentFulfilled>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<{} | actions.CreateCellBelow> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FULFILLED),
|
||||
@@ -86,12 +86,12 @@ const addInitialCodeCellEpic = (
|
||||
actions.createCellAppend({
|
||||
cellType: "code",
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -126,7 +126,7 @@ export const acquireKernelInfoEpic = (action$: Observable<actions.NewKernelActio
|
||||
},
|
||||
} = action;
|
||||
return acquireKernelInfo(channels, kernelRef, contentRef);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -183,7 +183,7 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
kernelRef,
|
||||
contentRef,
|
||||
error: new Error(
|
||||
"The kernel that you are attempting to launch does not support the latest version (v5) of the messaging protocol."
|
||||
"The kernel that you are attempting to launch does not support the latest version (v5) of the messaging protocol.",
|
||||
),
|
||||
}),
|
||||
];
|
||||
@@ -203,7 +203,7 @@ function acquireKernelInfo(channels: Channels, kernelRef: KernelRef, contentRef:
|
||||
}
|
||||
|
||||
return of(...result);
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return Observable.create((observer: Observer<any>) => {
|
||||
@@ -246,13 +246,13 @@ const connect = (serverConfig: NotebookServiceConfig, kernelID: string, sessionI
|
||||
}
|
||||
},
|
||||
(e: Error) => wsSubject.error(e),
|
||||
() => wsSubject.complete()
|
||||
() => wsSubject.complete(),
|
||||
), // Subscriber
|
||||
// Subject.create takes a subscriber and an observable. We're only
|
||||
// overriding the subscriber here so we pass the subject on as an
|
||||
// observable as the second argument to Subject.create (since it's
|
||||
// _also_ an observable)
|
||||
wsSubject
|
||||
wsSubject,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -268,7 +268,7 @@ const connect = (serverConfig: NotebookServiceConfig, kernelID: string, sessionI
|
||||
*/
|
||||
export const launchWebSocketKernelEpic = (
|
||||
action$: Observable<actions.LaunchKernelByNameAction>,
|
||||
state$: StateObservable<CdbAppState>
|
||||
state$: StateObservable<CdbAppState>,
|
||||
) => {
|
||||
return action$.pipe(
|
||||
ofType(actions.LAUNCH_KERNEL_BY_NAME),
|
||||
@@ -305,10 +305,10 @@ export const launchWebSocketKernelEpic = (
|
||||
return of(
|
||||
actions.launchKernelFailed({
|
||||
error: new Error(
|
||||
"Unable to launch kernel: no kernelspec name specified to launch and no default kernelspecs"
|
||||
"Unable to launch kernel: no kernelspec name specified to launch and no default kernelspecs",
|
||||
),
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
} else if (currentKernelspecs && !currentKernelspecs.byName.get(kernelSpecToLaunch)) {
|
||||
@@ -316,7 +316,7 @@ export const launchWebSocketKernelEpic = (
|
||||
|
||||
// Find a kernel that best matches the kernel name
|
||||
const match = currentKernelspecs.byName.find(
|
||||
(value) => value.name.toLowerCase().indexOf(kernelSpecName.toLowerCase()) !== -1
|
||||
(value) => value.name.toLowerCase().indexOf(kernelSpecName.toLowerCase()) !== -1,
|
||||
);
|
||||
if (match) {
|
||||
kernelSpecToLaunch = match.name;
|
||||
@@ -362,14 +362,14 @@ export const launchWebSocketKernelEpic = (
|
||||
kernelRef,
|
||||
contentRef: action.payload.contentRef,
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}),
|
||||
catchError((error) => {
|
||||
return of(actions.launchKernelFailed({ error }));
|
||||
})
|
||||
}),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
/**
|
||||
@@ -379,7 +379,7 @@ export const launchWebSocketKernelEpic = (
|
||||
*/
|
||||
export const restartWebSocketKernelEpic = (
|
||||
action$: Observable<actions.RestartKernel | actions.NewKernelAction>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
) =>
|
||||
action$.pipe(
|
||||
ofType(actions.RESTART_KERNEL),
|
||||
@@ -398,7 +398,7 @@ export const restartWebSocketKernelEpic = (
|
||||
error: new Error("Can't execute restart without kernel ref."),
|
||||
kernelRef: "none provided",
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -409,7 +409,7 @@ export const restartWebSocketKernelEpic = (
|
||||
error: new Error("Can't restart a kernel with no Jupyter host."),
|
||||
kernelRef,
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ export const restartWebSocketKernelEpic = (
|
||||
error: new Error("Can't restart a kernel that does not exist."),
|
||||
kernelRef,
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -430,7 +430,7 @@ export const restartWebSocketKernelEpic = (
|
||||
error: new Error("Can only restart Websocket kernels via API."),
|
||||
kernelRef,
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -471,13 +471,13 @@ export const restartWebSocketKernelEpic = (
|
||||
error,
|
||||
kernelRef: newKernelRef,
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return merge(of(kill, relaunch), awaitKernelReady);
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -489,7 +489,7 @@ export const restartWebSocketKernelEpic = (
|
||||
*/
|
||||
const changeWebSocketKernelEpic = (
|
||||
action$: Observable<actions.ChangeKernelByName>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
) => {
|
||||
return action$.pipe(
|
||||
ofType(actions.CHANGE_KERNEL_BY_NAME),
|
||||
@@ -552,15 +552,15 @@ const changeWebSocketKernelEpic = (
|
||||
kernelRef,
|
||||
contentRef: action.payload.contentRef,
|
||||
selectNextKernel: true,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}),
|
||||
catchError((error) => of(actions.launchKernelFailed({ error, kernelRef, contentRef })))
|
||||
catchError((error) => of(actions.launchKernelFailed({ error, kernelRef, contentRef }))),
|
||||
);
|
||||
}),
|
||||
catchError((error) => of(actions.launchKernelFailed({ error, kernelRef, contentRef })))
|
||||
catchError((error) => of(actions.launchKernelFailed({ error, kernelRef, contentRef }))),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -571,7 +571,7 @@ const changeWebSocketKernelEpic = (
|
||||
*/
|
||||
const focusInitialCodeCellEpic = (
|
||||
action$: Observable<actions.CreateCellAppend>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<{} | actions.FocusCell> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.CREATE_CELL_APPEND),
|
||||
@@ -593,12 +593,12 @@ const focusInitialCodeCellEpic = (
|
||||
actions.focusCell({
|
||||
id,
|
||||
contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return EMPTY;
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -615,7 +615,7 @@ const notificationsToUserEpic = (action$: Observable<any>, state$: StateObservab
|
||||
actions.RESTART_KERNEL_FAILED,
|
||||
actions.SAVE_FULFILLED,
|
||||
actions.SAVE_FAILED,
|
||||
actions.FETCH_CONTENT_FAILED
|
||||
actions.FETCH_CONTENT_FAILED,
|
||||
),
|
||||
mergeMap((action) => {
|
||||
switch (action.type) {
|
||||
@@ -648,7 +648,7 @@ const notificationsToUserEpic = (action$: Observable<any>, state$: StateObservab
|
||||
}
|
||||
}
|
||||
return EMPTY;
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -659,7 +659,7 @@ const notificationsToUserEpic = (action$: Observable<any>, state$: StateObservab
|
||||
*/
|
||||
const handleKernelConnectionLostEpic = (
|
||||
action$: Observable<actions.UpdateDisplayFailed>,
|
||||
state$: StateObservable<CdbAppState>
|
||||
state$: StateObservable<CdbAppState>,
|
||||
): Observable<CdbActions.UpdateKernelRestartDelayAction | actions.RestartKernel | {}> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.UPDATE_DISPLAY_FAILED),
|
||||
@@ -702,12 +702,12 @@ const handleKernelConnectionLostEpic = (
|
||||
retryWhen((errors) => {
|
||||
return errors.pipe(
|
||||
delayWhen(() => timer(Constants.Notebook.heartbeatDelayMs)),
|
||||
tap(() => console.log("retrying...")) // TODO: Send new action?
|
||||
tap(() => console.log("retrying...")), // TODO: Send new action?
|
||||
);
|
||||
})
|
||||
)
|
||||
}),
|
||||
),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -718,7 +718,7 @@ const handleKernelConnectionLostEpic = (
|
||||
*/
|
||||
export const cleanKernelOnConnectionLostEpic = (
|
||||
action$: Observable<actions.UpdateDisplayFailed>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<actions.KillKernelSuccessful> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.UPDATE_DISPLAY_FAILED),
|
||||
@@ -728,9 +728,9 @@ export const cleanKernelOnConnectionLostEpic = (
|
||||
return of(
|
||||
actions.killKernelSuccessful({
|
||||
kernelRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -741,7 +741,7 @@ export const cleanKernelOnConnectionLostEpic = (
|
||||
*/
|
||||
const executeFocusedCellAndFocusNextEpic = (
|
||||
action$: Observable<CdbActions.ExecuteFocusedCellAndFocusNextAction>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<{} | actions.FocusNextCellEditor> => {
|
||||
return action$.pipe(
|
||||
ofType(CdbActions.EXECUTE_FOCUSED_CELL_AND_FOCUS_NEXT),
|
||||
@@ -749,9 +749,9 @@ const executeFocusedCellAndFocusNextEpic = (
|
||||
const contentRef = action.payload.contentRef;
|
||||
return concat(
|
||||
of(actions.executeFocusedCell({ contentRef })),
|
||||
of(actions.focusNextCell({ contentRef, createCellIfUndefined: false }))
|
||||
of(actions.focusNextCell({ contentRef, createCellIfUndefined: false })),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -762,7 +762,7 @@ const executeFocusedCellAndFocusNextEpic = (
|
||||
*/
|
||||
const closeUnsupportedMimetypesEpic = (
|
||||
action$: Observable<actions.FetchContentFulfilled>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<{}> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FULFILLED),
|
||||
@@ -774,14 +774,15 @@ const closeUnsupportedMimetypesEpic = (
|
||||
useTabs
|
||||
.getState()
|
||||
.closeTabsByComparator(
|
||||
(tab: any) => (tab as any).notebookPath && FileSystemUtil.isPathEqual((tab as any).notebookPath(), filepath)
|
||||
(tab: any) =>
|
||||
(tab as any).notebookPath && FileSystemUtil.isPathEqual((tab as any).notebookPath(), filepath),
|
||||
);
|
||||
const msg = `${filepath} cannot be rendered. Please download the file, in order to view it outside of Data Explorer.`;
|
||||
useDialog.getState().showOkModalDialog("File cannot be rendered", msg);
|
||||
logConsoleError(msg);
|
||||
}
|
||||
return EMPTY;
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -792,7 +793,7 @@ const closeUnsupportedMimetypesEpic = (
|
||||
*/
|
||||
const closeContentFailedToFetchEpic = (
|
||||
action$: Observable<actions.FetchContentFailed>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<{}> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FAILED),
|
||||
@@ -802,19 +803,19 @@ const closeContentFailedToFetchEpic = (
|
||||
useTabs
|
||||
.getState()
|
||||
.closeTabsByComparator(
|
||||
(tab: any) => (tab as any).notebookPath && FileSystemUtil.isPathEqual((tab as any).notebookPath(), filepath)
|
||||
(tab: any) => (tab as any).notebookPath && FileSystemUtil.isPathEqual((tab as any).notebookPath(), filepath),
|
||||
);
|
||||
const msg = `Failed to load file: ${filepath}.`;
|
||||
useDialog.getState().showOkModalDialog("Failure to load", msg);
|
||||
logConsoleError(msg);
|
||||
return EMPTY;
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const traceNotebookTelemetryEpic = (
|
||||
action$: Observable<cdbActions.TraceNotebookTelemetryAction>,
|
||||
state$: StateObservable<CdbAppState>
|
||||
state$: StateObservable<CdbAppState>,
|
||||
): Observable<{}> => {
|
||||
return action$.pipe(
|
||||
ofType(cdbActions.TRACE_NOTEBOOK_TELEMETRY),
|
||||
@@ -828,7 +829,7 @@ const traceNotebookTelemetryEpic = (
|
||||
dataExplorerArea: Areas.Notebook,
|
||||
});
|
||||
return EMPTY;
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -840,7 +841,7 @@ const traceNotebookTelemetryEpic = (
|
||||
*/
|
||||
const traceNotebookInfoEpic = (
|
||||
action$: Observable<actions.FetchContentFulfilled>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<{} | cdbActions.TraceNotebookTelemetryAction> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.FETCH_CONTENT_FULFILLED),
|
||||
@@ -880,9 +881,9 @@ const traceNotebookInfoEpic = (
|
||||
action: TelemetryAction.NotebooksFetched,
|
||||
actionModifier: ActionModifiers.Mark,
|
||||
data: dataToLog,
|
||||
})
|
||||
}),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -893,7 +894,7 @@ const traceNotebookInfoEpic = (
|
||||
*/
|
||||
const traceNotebookKernelEpic = (
|
||||
action$: Observable<AnyAction>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<cdbActions.TraceNotebookTelemetryAction> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.LAUNCH_KERNEL_SUCCESSFUL),
|
||||
@@ -905,15 +906,15 @@ const traceNotebookKernelEpic = (
|
||||
data: {
|
||||
kernelSpecName: action.payload.kernel.name,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const resetCellStatusOnExecuteCanceledEpic = (
|
||||
action$: Observable<actions.ExecuteCanceled>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<actions.UpdateCellStatus> => {
|
||||
return action$.pipe(
|
||||
ofType(actions.EXECUTE_CANCELED),
|
||||
@@ -938,9 +939,9 @@ const resetCellStatusOnExecuteCanceledEpic = (
|
||||
return from(busyCellIds).pipe(
|
||||
map((busyCellId) => {
|
||||
return actions.updateCellStatus({ id: busyCellId, contentRef, status: undefined });
|
||||
})
|
||||
}),
|
||||
);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -956,7 +957,7 @@ const { selector: autoSaveInterval } = defineConfigOption({
|
||||
*/
|
||||
export function autoSaveCurrentContentEpic(
|
||||
action$: Observable<Action>,
|
||||
state$: StateObservable<AppState>
|
||||
state$: StateObservable<AppState>,
|
||||
): Observable<actions.Save> {
|
||||
return state$.pipe(
|
||||
map((state) => autoSaveInterval(state)),
|
||||
@@ -971,9 +972,9 @@ export function autoSaveCurrentContentEpic(
|
||||
* Only save contents that are files or notebooks with
|
||||
* a filepath already set.
|
||||
*/
|
||||
(content) => (content.type === "file" || content.type === "notebook") && content.filepath !== ""
|
||||
(content) => (content.type === "file" || content.type === "notebook") && content.filepath !== "",
|
||||
)
|
||||
.keys()
|
||||
.keys(),
|
||||
);
|
||||
}),
|
||||
filter((contentRef: ContentRef) => {
|
||||
@@ -988,7 +989,7 @@ export function autoSaveCurrentContentEpic(
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
map((contentRef: ContentRef) => actions.save({ contentRef }))
|
||||
map((contentRef: ContentRef) => actions.save({ contentRef })),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export const coreReducer = (state: CoreRecord, action: Action) => {
|
||||
typedAction = action as cdbActions.CloseNotebookAction;
|
||||
return state.setIn(
|
||||
["entities", "contents", "byRef"],
|
||||
state.entities.contents.byRef.delete(typedAction.payload.contentRef)
|
||||
state.entities.contents.byRef.delete(typedAction.payload.contentRef),
|
||||
);
|
||||
}
|
||||
case actions.CHANGE_KERNEL_BY_NAME: {
|
||||
|
||||
@@ -16,21 +16,21 @@ export default function configureStore(
|
||||
contentProvider: IContentProvider,
|
||||
onTraceFailure: (title: string, message: string) => void,
|
||||
customMiddlewares?: Middleware<{}, any, Dispatch<AnyAction>>[],
|
||||
autoStartKernelOnNotebookOpen?: boolean
|
||||
autoStartKernelOnNotebookOpen?: boolean,
|
||||
): Store<CdbAppState, AnyAction> {
|
||||
/**
|
||||
* Catches errors in reducers
|
||||
*/
|
||||
const catchErrorMiddleware: Middleware = <D extends Dispatch<AnyAction>, S extends AppState>({
|
||||
dispatch,
|
||||
getState,
|
||||
}: MiddlewareAPI<D, S>) => (next: Dispatch<AnyAction>) => <A extends AnyAction>(action: A): any => {
|
||||
try {
|
||||
next(action);
|
||||
} catch (error) {
|
||||
traceFailure("Reducer failure", error);
|
||||
}
|
||||
};
|
||||
const catchErrorMiddleware: Middleware =
|
||||
<D extends Dispatch<AnyAction>, S extends AppState>({ dispatch, getState }: MiddlewareAPI<D, S>) =>
|
||||
(next: Dispatch<AnyAction>) =>
|
||||
<A extends AnyAction>(action: A): any => {
|
||||
try {
|
||||
next(action);
|
||||
} catch (error) {
|
||||
traceFailure("Reducer failure", error);
|
||||
}
|
||||
};
|
||||
|
||||
const protect = (epic: Epic) => {
|
||||
return (action$: Observable<any>, state$: any, dependencies: any) =>
|
||||
@@ -38,7 +38,7 @@ export default function configureStore(
|
||||
catchError((error, caught) => {
|
||||
traceFailure("Epic failure", error);
|
||||
return caught;
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ export class NotebookContainerClient {
|
||||
|
||||
useNotebook.subscribe(
|
||||
() => this.scheduleHeartbeat(delayMs),
|
||||
(state) => state.notebookServerInfo
|
||||
(state) => state.notebookServerInfo,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ export class NotebookContainerClient {
|
||||
Logger.logError(getErrorMessage(error), "NotebookContainerClient/getMemoryUsage");
|
||||
if (!this.clearReconnectionAttemptMessage) {
|
||||
this.clearReconnectionAttemptMessage = logConsoleProgress(
|
||||
"Connection lost with Notebook server. Attempting to reconnect..."
|
||||
"Connection lost with Notebook server. Attempting to reconnect...",
|
||||
);
|
||||
}
|
||||
this.onConnectionLost();
|
||||
@@ -91,7 +91,7 @@ export class NotebookContainerClient {
|
||||
|
||||
private async _getMemoryAsync(
|
||||
notebookServerEndpoint: string,
|
||||
authToken: string
|
||||
authToken: string,
|
||||
): Promise<DataModels.MemoryUsageInfo> {
|
||||
if (this.shouldExecuteMemoryCall()) {
|
||||
const response = await fetch(`${notebookServerEndpoint}api/metrics/memory`, {
|
||||
@@ -168,7 +168,7 @@ export class NotebookContainerClient {
|
||||
.getState()
|
||||
.showOkModalDialog(
|
||||
"Connection Failed",
|
||||
"We are unable to connect to the temporary workspace. Please try again in a few minutes. If the error persists, file a support ticket."
|
||||
"We are unable to connect to the temporary workspace. Please try again in a few minutes. If the error persists, file a support ticket.",
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
|
||||
@@ -38,7 +38,7 @@ export class NotebookContentClient {
|
||||
*/
|
||||
public async createNewNotebookFile(
|
||||
parent: NotebookContentItem,
|
||||
isGithubTree?: boolean
|
||||
isGithubTree?: boolean,
|
||||
): Promise<NotebookContentItem> {
|
||||
if (!parent || parent.type !== NotebookContentItemType.Directory) {
|
||||
throw new Error(`Parent must be a directory: ${parent}`);
|
||||
@@ -97,7 +97,7 @@ export class NotebookContentClient {
|
||||
name: string,
|
||||
content: string,
|
||||
parent: NotebookContentItem,
|
||||
isGithubTree?: boolean
|
||||
isGithubTree?: boolean,
|
||||
): Promise<NotebookContentItem> {
|
||||
if (!parent || parent.type !== NotebookContentItemType.Directory) {
|
||||
throw new Error(`Parent must be a directory: ${parent}`);
|
||||
@@ -147,7 +147,7 @@ export class NotebookContentClient {
|
||||
public renameNotebook(
|
||||
item: NotebookContentItem,
|
||||
targetName: string,
|
||||
isGithubTree?: boolean
|
||||
isGithubTree?: boolean,
|
||||
): Promise<NotebookContentItem> {
|
||||
const sourcePath = item.path;
|
||||
// Match extension
|
||||
@@ -189,7 +189,7 @@ export class NotebookContentClient {
|
||||
public async createDirectory(
|
||||
parent: NotebookContentItem,
|
||||
newDirectoryName: string,
|
||||
isGithubTree?: boolean
|
||||
isGithubTree?: boolean,
|
||||
): Promise<NotebookContentItem> {
|
||||
if (parent.type !== NotebookContentItemType.Directory) {
|
||||
throw new Error(`Parent is not a directory: ${parent.path}`);
|
||||
@@ -295,7 +295,7 @@ export class NotebookContentClient {
|
||||
name: item.name,
|
||||
path: item.path,
|
||||
type: NotebookUtil.getType(item.type),
|
||||
})
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ export default class NotebookManager {
|
||||
this.notebookContentProvider = new NotebookContentProvider(
|
||||
this.inMemoryContentProvider,
|
||||
this.gitHubContentProvider,
|
||||
contents.JupyterContentProvider
|
||||
contents.JupyterContentProvider,
|
||||
);
|
||||
|
||||
this.notebookClient = new NotebookContainerClient(() =>
|
||||
this.params.container.initNotebooks(userContext?.databaseAccount)
|
||||
this.params.container.initNotebooks(userContext?.databaseAccount),
|
||||
);
|
||||
|
||||
this.notebookContentClient = new NotebookContentClient(this.notebookContentProvider);
|
||||
@@ -100,7 +100,7 @@ export default class NotebookManager {
|
||||
explorer={this.params.container}
|
||||
gitHubClientProp={this.params.container.notebookManager.gitHubClient}
|
||||
junoClientProp={this.junoClient}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}, 200);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ export default class NotebookManager {
|
||||
content: NotebookPaneContent,
|
||||
notebookContentRef: string,
|
||||
onTakeSnapshot: (request: SnapshotRequest) => void,
|
||||
onClosePanel: () => void
|
||||
onClosePanel: () => void,
|
||||
): Promise<void> {
|
||||
useSidePanel
|
||||
.getState()
|
||||
@@ -145,7 +145,7 @@ export default class NotebookManager {
|
||||
onTakeSnapshot={onTakeSnapshot}
|
||||
/>,
|
||||
"440px",
|
||||
onClosePanel
|
||||
onClosePanel,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ export default class NotebookManager {
|
||||
gitHubOAuthService={this.gitHubOAuthService}
|
||||
name={name}
|
||||
content={content}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -188,10 +188,10 @@ export default class NotebookManager {
|
||||
explorer={this.params.container}
|
||||
gitHubClientProp={this.params.container.notebookManager.gitHubClient}
|
||||
junoClientProp={this.junoClient}
|
||||
/>
|
||||
/>,
|
||||
),
|
||||
"Cancel",
|
||||
undefined
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -223,7 +223,7 @@ export default class NotebookManager {
|
||||
commitMsg = newValue;
|
||||
},
|
||||
},
|
||||
!commitMsg
|
||||
!commitMsg,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -108,7 +108,7 @@ const makeMapDispatchToProps = (initialDispatch: Dispatch, initialProps: Noteboo
|
||||
actions.addTransform({
|
||||
mediaType: transform.MIMETYPE,
|
||||
component: transform,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -93,7 +93,7 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
this.notebookRendererRef.current,
|
||||
this.props.pendingSnapshotRequest.aspectRatio,
|
||||
[...this.props.cellOutputSnapshots.values()],
|
||||
this.props.pendingSnapshotRequest.downloadFilename
|
||||
this.props.pendingSnapshotRequest.downloadFilename,
|
||||
);
|
||||
this.props.storeNotebookSnapshot(result.imageSrc, this.props.pendingSnapshotRequest.requestId);
|
||||
} catch (error) {
|
||||
@@ -136,7 +136,7 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
? () => <SandboxOutputs id={id} contentRef={contentRef} />
|
||||
: undefined,
|
||||
}}
|
||||
</CodeCell>
|
||||
</CodeCell>,
|
||||
),
|
||||
markdown: ({ id, contentRef }: { id: any; contentRef: ContentRef }) =>
|
||||
decorate(
|
||||
@@ -152,7 +152,7 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
},
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />,
|
||||
}}
|
||||
</MarkdownCell>
|
||||
</MarkdownCell>,
|
||||
),
|
||||
|
||||
raw: ({ id, contentRef }: { id: any; contentRef: ContentRef }) =>
|
||||
@@ -169,7 +169,7 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
},
|
||||
toolbar: () => <CellToolbar id={id} contentRef={contentRef} />,
|
||||
}}
|
||||
</RawCell>
|
||||
</RawCell>,
|
||||
),
|
||||
}}
|
||||
</Cells>
|
||||
@@ -186,7 +186,7 @@ class BaseNotebookRenderer extends React.Component<NotebookRendererProps> {
|
||||
|
||||
export const makeMapStateToProps = (
|
||||
initialState: CdbAppState,
|
||||
ownProps: NotebookRendererProps
|
||||
ownProps: NotebookRendererProps,
|
||||
): ((state: CdbAppState) => StateProps) => {
|
||||
const mapStateToProps = (state: CdbAppState): StateProps => {
|
||||
const { contentRef } = ownProps;
|
||||
@@ -210,7 +210,7 @@ const makeMapDispatchToProps = (initialDispatch: Dispatch, initialProps: Noteboo
|
||||
actions.addTransform({
|
||||
mediaType: transform.MIMETYPE,
|
||||
component: transform,
|
||||
})
|
||||
}),
|
||||
),
|
||||
storeNotebookSnapshot: (imageSrc: string, requestId: string) =>
|
||||
dispatch(cdbActions.storeNotebookSnapshot({ imageSrc, requestId })),
|
||||
|
||||
@@ -87,7 +87,7 @@ const makeMapStateToProps = (_state: CdbAppState, ownProps: ComponentProps): ((s
|
||||
|
||||
const mapDispatchToProps = (
|
||||
dispatch: Dispatch,
|
||||
{ id, contentRef }: { id: string; contentRef: ContentRef }
|
||||
{ id, contentRef }: { id: string; contentRef: ContentRef },
|
||||
): DispatchProps => ({
|
||||
executeCell: () => {
|
||||
dispatch(actions.executeCell({ id, contentRef }));
|
||||
@@ -95,7 +95,7 @@ const mapDispatchToProps = (
|
||||
cdbActions.traceNotebookTelemetry({
|
||||
action: Action.ExecuteCellPromptBtn,
|
||||
actionModifier: ActionModifiers.Mark,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
stopExecution: () => dispatch(actions.interruptKernel({})),
|
||||
|
||||
@@ -8,7 +8,7 @@ describe("StatusBar", () => {
|
||||
const kernelSpecDisplayName = "python3";
|
||||
|
||||
const component = shallow(
|
||||
<StatusBar kernelStatus="kernel status" lastSaved={lastSaved} kernelSpecDisplayName={kernelSpecDisplayName} />
|
||||
<StatusBar kernelStatus="kernel status" lastSaved={lastSaved} kernelSpecDisplayName={kernelSpecDisplayName} />,
|
||||
);
|
||||
|
||||
expect(component).not.toBeNull();
|
||||
@@ -18,7 +18,7 @@ describe("StatusBar", () => {
|
||||
const kernelSpecDisplayName = "python3";
|
||||
|
||||
const component = shallow(
|
||||
<StatusBar kernelStatus="kernel status" lastSaved={lastSaved} kernelSpecDisplayName={kernelSpecDisplayName} />
|
||||
<StatusBar kernelStatus="kernel status" lastSaved={lastSaved} kernelSpecDisplayName={kernelSpecDisplayName} />,
|
||||
);
|
||||
|
||||
const shouldUpdate = component.instance().shouldComponentUpdate(
|
||||
@@ -28,7 +28,7 @@ describe("StatusBar", () => {
|
||||
kernelStatus: "kernelStatus",
|
||||
},
|
||||
undefined,
|
||||
undefined
|
||||
undefined,
|
||||
);
|
||||
expect(shouldUpdate).toBe(true);
|
||||
});
|
||||
@@ -37,7 +37,7 @@ describe("StatusBar", () => {
|
||||
const kernelSpecDisplayName = "python3";
|
||||
|
||||
const component = shallow(
|
||||
<StatusBar kernelStatus="kernel status" lastSaved={lastSaved} kernelSpecDisplayName={kernelSpecDisplayName} />
|
||||
<StatusBar kernelStatus="kernel status" lastSaved={lastSaved} kernelSpecDisplayName={kernelSpecDisplayName} />,
|
||||
);
|
||||
|
||||
const shouldUpdate = component.instance().shouldComponentUpdate(
|
||||
@@ -47,7 +47,7 @@ describe("StatusBar", () => {
|
||||
kernelStatus: "kernelStatus",
|
||||
},
|
||||
undefined,
|
||||
undefined
|
||||
undefined,
|
||||
);
|
||||
expect(shouldUpdate).toBe(true);
|
||||
});
|
||||
|
||||
@@ -197,7 +197,7 @@ class BaseToolbar extends React.PureComponent<ComponentProps & DispatchProps & S
|
||||
|
||||
const mapDispatchToProps = (
|
||||
dispatch: Dispatch,
|
||||
{ id, contentRef }: { id: CellId; contentRef: ContentRef }
|
||||
{ id, contentRef }: { id: CellId; contentRef: ContentRef },
|
||||
): DispatchProps => ({
|
||||
executeCell: () => dispatch(actions.executeCell({ id, contentRef })),
|
||||
insertCodeCellAbove: () => dispatch(actions.createCellAbove({ id, contentRef, cellType: "code" })),
|
||||
|
||||
@@ -144,7 +144,7 @@ export const cellTarget = {
|
||||
|
||||
function collectSource(
|
||||
connect: DragSourceConnector,
|
||||
monitor: DragSourceMonitor
|
||||
monitor: DragSourceMonitor,
|
||||
): {
|
||||
connectDragSource: ConnectDragSource;
|
||||
isDragging: boolean;
|
||||
@@ -159,7 +159,7 @@ function collectSource(
|
||||
|
||||
function collectTarget(
|
||||
connect: DropTargetConnector,
|
||||
monitor: DropTargetMonitor
|
||||
monitor: DropTargetMonitor,
|
||||
): {
|
||||
connectDropTarget: ConnectDropTarget;
|
||||
isOver: boolean;
|
||||
@@ -210,12 +210,12 @@ export class DraggableCellView extends React.Component<Props & DnDSourceProps &
|
||||
// Same thing with connectDragSource... It also needs a React Element that matches a DOM element
|
||||
<div>
|
||||
<DragHandle onClick={this.selectCell} />
|
||||
</div>
|
||||
</div>,
|
||||
)}
|
||||
{this.props.children}
|
||||
</DragHandleAnchor>
|
||||
</DragArea>
|
||||
</div>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ export class PureMarkdownCell extends React.Component<ComponentProps & DispatchP
|
||||
|
||||
export const makeMapStateToProps = (
|
||||
initialState: AppState,
|
||||
ownProps: ComponentProps
|
||||
ownProps: ComponentProps,
|
||||
): ((state: AppState) => StateProps) => {
|
||||
const { id, contentRef } = ownProps;
|
||||
const mapStateToProps = (state: AppState): StateProps => {
|
||||
@@ -135,7 +135,7 @@ export const makeMapStateToProps = (
|
||||
|
||||
const makeMapDispatchToProps = (
|
||||
initialDispatch: Dispatch,
|
||||
ownProps: ComponentProps
|
||||
ownProps: ComponentProps,
|
||||
): ((dispatch: Dispatch) => DispatchProps) => {
|
||||
const { id, contentRef } = ownProps;
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ export class SandboxOutputs extends React.Component<SandboxOutputsProps> {
|
||||
const { data } = (await postRobot.send(
|
||||
this.childWindow,
|
||||
"snapshotRequest",
|
||||
this.props.pendingSnapshotRequest
|
||||
this.props.pendingSnapshotRequest,
|
||||
)) as { data: SnapshotResponse };
|
||||
if (this.props.pendingSnapshotRequest.type === "notebook") {
|
||||
if (data.imageSrc === undefined) {
|
||||
@@ -145,7 +145,7 @@ export class SandboxOutputs extends React.Component<SandboxOutputsProps> {
|
||||
|
||||
export const makeMapStateToProps = (
|
||||
initialState: AppState,
|
||||
ownProps: ComponentProps
|
||||
ownProps: ComponentProps,
|
||||
): ((state: AppState) => StateProps) => {
|
||||
const mapStateToProps = (state: CdbAppState): StateProps => {
|
||||
let outputs = Immutable.List();
|
||||
@@ -181,7 +181,7 @@ export const makeMapStateToProps = (
|
||||
|
||||
export const makeMapDispatchToProps = (
|
||||
initialDispath: Dispatch,
|
||||
ownProps: ComponentProps
|
||||
ownProps: ComponentProps,
|
||||
): ((dispatch: Dispatch) => DispatchProps) => {
|
||||
const { id, contentRef } = ownProps;
|
||||
const mapDispatchToProps = (dispatch: Dispatch) => {
|
||||
@@ -194,7 +194,7 @@ export const makeMapDispatchToProps = (
|
||||
metadata,
|
||||
index: index || 0,
|
||||
mediaType,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
storeSnapshotFragment: (cellId: string, snapshot: SnapshotFragment) =>
|
||||
@@ -209,5 +209,5 @@ export const makeMapDispatchToProps = (
|
||||
|
||||
export default connect<StateProps, DispatchProps, ComponentProps, AppState>(
|
||||
makeMapStateToProps,
|
||||
makeMapDispatchToProps
|
||||
makeMapDispatchToProps,
|
||||
)(SandboxOutputs);
|
||||
|
||||
@@ -123,7 +123,7 @@ describe("NotebookUtil", () => {
|
||||
it("works for github file uris", () => {
|
||||
expect(NotebookUtil.replaceName(gitHubFileUri, "newName")).toEqual(gitHubFileUri.replace(fileName, "newName"));
|
||||
expect(NotebookUtil.replaceName(gitHubNotebookUri, "newName")).toEqual(
|
||||
gitHubNotebookUri.replace(notebookName, "newName")
|
||||
gitHubNotebookUri.replace(notebookName, "newName"),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ export class NotebookUtil {
|
||||
contentInfo.owner,
|
||||
contentInfo.repo,
|
||||
contentInfo.branch,
|
||||
parentPath.replace(/\/$/, "") // no trailling slash
|
||||
parentPath.replace(/\/$/, ""), // no trailling slash
|
||||
);
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ export class NotebookUtil {
|
||||
(output) =>
|
||||
output.output_type === "display_data" ||
|
||||
output.output_type === "execute_result" ||
|
||||
output.output_type === "stream"
|
||||
output.output_type === "stream",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ export class NotebookUtil {
|
||||
target: HTMLElement,
|
||||
aspectRatio: number,
|
||||
subSnapshots: SnapshotFragment[],
|
||||
downloadFilename?: string
|
||||
downloadFilename?: string,
|
||||
): Promise<{ imageSrc: string | undefined }> => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
@@ -248,7 +248,7 @@ export class NotebookUtil {
|
||||
context.drawImage(
|
||||
snapshot.image,
|
||||
snapshot.boundingClientRect.x - parentRect.x,
|
||||
snapshot.boundingClientRect.y - parentRect.y
|
||||
snapshot.boundingClientRect.y - parentRect.y,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -259,7 +259,7 @@ export class NotebookUtil {
|
||||
if (downloadFilename) {
|
||||
NotebookUtil.downloadFile(
|
||||
downloadFilename,
|
||||
canvas.toDataURL("image/png").replace("image/png", "image/octet-stream")
|
||||
canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"),
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -273,7 +273,7 @@ export class NotebookUtil {
|
||||
target: HTMLElement,
|
||||
aspectRatio: number,
|
||||
subSnapshots: SnapshotFragment[],
|
||||
downloadFilename?: string
|
||||
downloadFilename?: string,
|
||||
): Promise<{ imageSrc?: string }> => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
// target.scrollIntoView();
|
||||
@@ -317,7 +317,7 @@ export class NotebookUtil {
|
||||
context.drawImage(
|
||||
snapshot.image,
|
||||
snapshot.boundingClientRect.x - parentRect.x,
|
||||
snapshot.boundingClientRect.y - parentRect.y
|
||||
snapshot.boundingClientRect.y - parentRect.y,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -328,7 +328,7 @@ export class NotebookUtil {
|
||||
if (downloadFilename) {
|
||||
NotebookUtil.downloadFile(
|
||||
downloadFilename,
|
||||
canvas.toDataURL("image/png").replace("image/png", "image/octet-stream")
|
||||
canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -211,7 +211,7 @@ const makeMapDispatchToProps = () => {
|
||||
actions.addTransform({
|
||||
mediaType: transform.MIMETYPE,
|
||||
component: transform,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
runCell: (contentRef: ContentRef, cellId: string) => {
|
||||
@@ -219,7 +219,7 @@ const makeMapDispatchToProps = () => {
|
||||
actions.executeCell({
|
||||
contentRef,
|
||||
id: cellId,
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
updateCell: (text: string, id: string, contentRef: ContentRef) => {
|
||||
|
||||
@@ -13,7 +13,11 @@ export class SchemaAnalyzerAdapter extends NotebookComponentBootstrapper impleme
|
||||
public parameters: unknown;
|
||||
private kernelRef: KernelRef;
|
||||
|
||||
constructor(options: NotebookComponentBootstrapperOptions, private databaseId: string, private collectionId: string) {
|
||||
constructor(
|
||||
options: NotebookComponentBootstrapperOptions,
|
||||
private databaseId: string,
|
||||
private collectionId: string,
|
||||
) {
|
||||
super(options);
|
||||
|
||||
if (!this.contentRef) {
|
||||
@@ -26,7 +30,7 @@ export class SchemaAnalyzerAdapter extends NotebookComponentBootstrapper impleme
|
||||
params: {},
|
||||
kernelRef: this.kernelRef,
|
||||
contentRef: this.contentRef,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ export const SchemaAnalyzerHeader = ({
|
||||
|
||||
const onSampleSizeWrapDefaultLabelRenderer = (
|
||||
props: ITextFieldProps,
|
||||
defaultRender: IRenderFunction<ITextFieldProps>
|
||||
defaultRender: IRenderFunction<ITextFieldProps>,
|
||||
): JSX.Element => {
|
||||
return (
|
||||
<Stack horizontal verticalAlign="center" tokens={{ childrenGap: 4 }}>
|
||||
|
||||
@@ -10,7 +10,7 @@ describe("SecurityWarningBar", () => {
|
||||
isNotebookUntrusted={true}
|
||||
markNotebookAsTrusted={undefined}
|
||||
saveNotebook={undefined}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -23,7 +23,7 @@ describe("SecurityWarningBar", () => {
|
||||
isNotebookUntrusted={false}
|
||||
markNotebookAsTrusted={undefined}
|
||||
saveNotebook={undefined}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -81,7 +81,7 @@ const makeMapDispatchToProps = () => {
|
||||
actions.deleteMetadataField({
|
||||
contentRef,
|
||||
field: "untrusted",
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
saveNotebook: (contentRef: string) => dispatch(actions.save({ contentRef })),
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("auto start kernel", () => {
|
||||
undefined, // content provider
|
||||
expect.anything(), // onTraceFailure
|
||||
expect.anything(), // customMiddlewares
|
||||
!isReadOnly
|
||||
!isReadOnly,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ function generateQueryText(action: ActionContracts.OpenQueryTab, partitionKeyPro
|
||||
function openCollectionTab(
|
||||
action: ActionContracts.OpenCollectionTab,
|
||||
databases: ViewModels.Database[],
|
||||
initialDatabaseIndex = 0
|
||||
initialDatabaseIndex = 0,
|
||||
) {
|
||||
for (let i = initialDatabaseIndex; i < databases.length; i++) {
|
||||
const database: ViewModels.Database = databases[i];
|
||||
@@ -109,7 +109,7 @@ function openCollectionTab(
|
||||
collection.onNewQueryClick(
|
||||
collection,
|
||||
undefined,
|
||||
generateQueryText(action as ActionContracts.OpenQueryTab, collection.partitionKeyProperties)
|
||||
generateQueryText(action as ActionContracts.OpenQueryTab, collection.partitionKeyProperties),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ function openPane(action: ActionContracts.OpenPane, explorer: Explorer) {
|
||||
.getState()
|
||||
.openSidePanel(
|
||||
"Add Table",
|
||||
<CassandraAddCollectionPane explorer={explorer} cassandraApiClient={new CassandraAPIDataClient()} />
|
||||
<CassandraAddCollectionPane explorer={explorer} cassandraApiClient={new CassandraAPIDataClient()} />,
|
||||
);
|
||||
} else if (
|
||||
action.paneKind === ActionContracts.PaneKind.GlobalSettings ||
|
||||
@@ -161,7 +161,7 @@ function openPane(action: ActionContracts.OpenPane, explorer: Explorer) {
|
||||
export function handleOpenAction(
|
||||
action: ActionContracts.DataExplorerAction,
|
||||
databases: ViewModels.Database[],
|
||||
explorer: Explorer
|
||||
explorer: Explorer,
|
||||
): boolean {
|
||||
if (
|
||||
action.actionType === ActionContracts.ActionType.OpenCollectionTab ||
|
||||
|
||||
@@ -260,7 +260,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
<TooltipHost
|
||||
directionalHint={DirectionalHint.bottomLeftEdge}
|
||||
content={`A database is analogous to a namespace. It is the unit of management for a set of ${getCollectionName(
|
||||
true
|
||||
true,
|
||||
).toLocaleLowerCase()}.`}
|
||||
>
|
||||
<Icon
|
||||
@@ -268,7 +268,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
className="panelInfoIcon"
|
||||
tabIndex={0}
|
||||
ariaLabel={`A database is analogous to a namespace. It is the unit of management for a set of ${getCollectionName(
|
||||
true
|
||||
true,
|
||||
).toLocaleLowerCase()}.`}
|
||||
/>
|
||||
</TooltipHost>
|
||||
@@ -345,7 +345,7 @@ 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
|
||||
true,
|
||||
).toLocaleLowerCase()} within the database.`}
|
||||
>
|
||||
<Icon
|
||||
@@ -353,7 +353,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
className="panelInfoIcon"
|
||||
tabIndex={0}
|
||||
ariaLabel={`Throughput configured at the database level will be shared across all ${getCollectionName(
|
||||
true
|
||||
true,
|
||||
).toLocaleLowerCase()} within the database.`}
|
||||
/>
|
||||
</TooltipHost>
|
||||
@@ -675,7 +675,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
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
|
||||
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.`}
|
||||
@@ -686,7 +686,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
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
|
||||
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.`}
|
||||
@@ -736,44 +736,42 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
</TooltipHost>
|
||||
</Stack>
|
||||
|
||||
{this.state.uniqueKeys.map(
|
||||
(uniqueKey: string, i: number): JSX.Element => {
|
||||
return (
|
||||
<Stack style={{ marginBottom: 8 }} key={`uniqueKey${i}`} 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>) => {
|
||||
const uniqueKeys = this.state.uniqueKeys.map((uniqueKey: string, j: number) => {
|
||||
if (i === j) {
|
||||
return event.target.value;
|
||||
}
|
||||
return uniqueKey;
|
||||
});
|
||||
this.setState({ uniqueKeys });
|
||||
}}
|
||||
/>
|
||||
{this.state.uniqueKeys.map((uniqueKey: string, i: number): JSX.Element => {
|
||||
return (
|
||||
<Stack style={{ marginBottom: 8 }} key={`uniqueKey${i}`} 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>) => {
|
||||
const uniqueKeys = this.state.uniqueKeys.map((uniqueKey: string, j: number) => {
|
||||
if (i === j) {
|
||||
return event.target.value;
|
||||
}
|
||||
return uniqueKey;
|
||||
});
|
||||
this.setState({ uniqueKeys });
|
||||
}}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
iconProps={{ iconName: "Delete" }}
|
||||
style={{ height: 27 }}
|
||||
onClick={() => {
|
||||
const uniqueKeys = this.state.uniqueKeys.filter((uniqueKey, j) => i !== j);
|
||||
this.setState({ uniqueKeys });
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
)}
|
||||
<IconButton
|
||||
iconProps={{ iconName: "Delete" }}
|
||||
style={{ height: 27 }}
|
||||
onClick={() => {
|
||||
const uniqueKeys = this.state.uniqueKeys.filter((uniqueKey, j) => i !== j);
|
||||
this.setState({ uniqueKeys });
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
})}
|
||||
|
||||
<ActionButton
|
||||
iconProps={{ iconName: "Add" }}
|
||||
@@ -1100,7 +1098,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
}
|
||||
|
||||
let tooltipText = `The ${this.getPartitionKeyName(
|
||||
true
|
||||
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.`;
|
||||
|
||||
if (userContext.apiType === "SQL") {
|
||||
@@ -1204,7 +1202,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
}
|
||||
|
||||
return properties.capabilities?.some(
|
||||
(capability) => capability.name === Constants.CapabilityNames.EnableStorageAnalytics
|
||||
(capability) => capability.name === Constants.CapabilityNames.EnableStorageAnalytics,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
|
||||
const databaseLevelThroughputTooltipText = `Provisioned throughput at the ${databaseLabel} level will be shared across all ${collectionsLabel} within the ${databaseLabel}.`;
|
||||
const [databaseCreateNewShared, setDatabaseCreateNewShared] = useState<boolean>(
|
||||
subscriptionType !== SubscriptionType.EA && !isServerlessAccount()
|
||||
subscriptionType !== SubscriptionType.EA && !isServerlessAccount(),
|
||||
);
|
||||
const [formErrors, setFormErrors] = useState<string>("");
|
||||
const [isExecuting, setIsExecuting] = useState<boolean>(false);
|
||||
@@ -114,7 +114,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
},
|
||||
(error: string) => {
|
||||
_onCreateDatabaseFailure(error, throughput, startKey);
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
@@ -147,7 +147,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
if (isAutoscaleSelected) {
|
||||
if (!AutoPilotUtils.isValidAutoPilotThroughput(throughput)) {
|
||||
setFormErrors(
|
||||
`Please enter a value greater than ${AutoPilotUtils.autoPilotThroughput1K} for autopilot throughput`
|
||||
`Please enter a value greater than ${AutoPilotUtils.autoPilotThroughput1K} for autopilot throughput`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -165,7 +165,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue?: string) => {
|
||||
setDatabaseId(newValue || "");
|
||||
},
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const props: RightPaneFormProps = {
|
||||
@@ -184,7 +184,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
|
||||
userContext.portalEnv,
|
||||
true,
|
||||
useDatabases.getState().isFirstResourceCreated(),
|
||||
true
|
||||
true,
|
||||
)}
|
||||
messageType="info"
|
||||
showErrorDetails={false}
|
||||
|
||||
@@ -36,7 +36,7 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
const [existingKeyspaceId, setExistingKeyspaceId] = useState<string>("");
|
||||
const [tableId, setTableId] = useState<string>("");
|
||||
const [userTableQuery, setUserTableQuery] = useState<string>(
|
||||
"(userid int, name text, email text, PRIMARY KEY (userid))"
|
||||
"(userid int, name text, email text, PRIMARY KEY (userid))",
|
||||
);
|
||||
const [isKeyspaceShared, setIsKeyspaceShared] = useState<boolean>(false);
|
||||
const [keyspaceCreateNew, setKeyspaceCreateNew] = useState<boolean>(true);
|
||||
@@ -118,14 +118,14 @@ export const CassandraAddCollectionPane: FunctionComponent<CassandraAddCollectio
|
||||
userContext?.databaseAccount?.id,
|
||||
container,
|
||||
tableQuery,
|
||||
createKeyspaceQuery
|
||||
createKeyspaceQuery,
|
||||
);
|
||||
} else {
|
||||
await cassandraApiClient.createTableAndKeyspace(
|
||||
userContext?.databaseAccount?.properties?.cassandraEndpoint,
|
||||
userContext?.databaseAccount?.id,
|
||||
container,
|
||||
tableQuery
|
||||
tableQuery,
|
||||
);
|
||||
}
|
||||
container.refreshAllDatabases();
|
||||
|
||||
@@ -72,7 +72,7 @@ export const CopyNotebookPane: FunctionComponent<CopyNotebookPanelProps> = ({
|
||||
if (selectedLocation.type === "GitHub") {
|
||||
destination = `${destination} - ${GitHubUtils.toRepoFullName(
|
||||
selectedLocation.owner,
|
||||
selectedLocation.repo
|
||||
selectedLocation.repo,
|
||||
)} - ${selectedLocation.branch}`;
|
||||
} else if (selectedLocation.type === "MyNotebooks" && useNotebook.getState().isPhoenixNotebooks) {
|
||||
destination = useNotebook.getState().notebookFolderName;
|
||||
|
||||
@@ -88,7 +88,7 @@ export const CopyNotebookPaneComponent: FunctionComponent<CopyNotebookPaneProps>
|
||||
repo: pinnedRepo.name,
|
||||
branch: branch.name,
|
||||
} as Location,
|
||||
})
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ describe("Delete Collection Confirmation Pane", () => {
|
||||
"testDatabaseAccountId",
|
||||
"testDatabaseAccountName",
|
||||
ApiKind.SQL,
|
||||
feedbackText
|
||||
feedbackText,
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(TelemetryProcessor.trace).toHaveBeenCalledWith(Action.DeleteCollection, ActionModifiers.Mark, {
|
||||
|
||||
@@ -41,7 +41,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
||||
const errorMessage = "Input " + collectionName + " id does not match the selected " + collectionName;
|
||||
setFormError(errorMessage);
|
||||
NotificationConsoleUtils.logConsoleError(
|
||||
`Error while deleting ${collectionName} ${collection.id()}: ${errorMessage}`
|
||||
`Error while deleting ${collectionName} ${collection.id()}: ${errorMessage}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
||||
useTabs
|
||||
.getState()
|
||||
.closeTabsByComparator(
|
||||
(tab) => tab.node?.id() === collection.id() && (tab.node as Collection).databaseId === collection.databaseId
|
||||
(tab) => tab.node?.id() === collection.id() && (tab.node as Collection).databaseId === collection.databaseId,
|
||||
);
|
||||
refreshDatabases();
|
||||
|
||||
@@ -76,7 +76,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
||||
userContext.databaseAccount?.id,
|
||||
userContext.databaseAccount?.name,
|
||||
DefaultExperienceUtility.getApiKindFromDefaultExperience(userContext.apiType),
|
||||
deleteCollectionFeedback
|
||||
deleteCollectionFeedback,
|
||||
);
|
||||
|
||||
TelemetryProcessor.trace(Action.DeleteCollection, ActionModifiers.Mark, {
|
||||
@@ -98,7 +98,7 @@ export const DeleteCollectionConfirmationPane: FunctionComponent<DeleteCollectio
|
||||
error: errorMessage,
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -96,7 +96,7 @@ describe("Delete Database Confirmation Pane", () => {
|
||||
"testDatabaseAccountId",
|
||||
"testDatabaseAccountName",
|
||||
ApiKind.SQL,
|
||||
feedbackText
|
||||
feedbackText,
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(TelemetryProcessor.trace).toHaveBeenCalledWith(Action.DeleteDatabase, ActionModifiers.Mark, {
|
||||
|
||||
@@ -37,11 +37,11 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
|
||||
const submit = async (): Promise<void> => {
|
||||
if (selectedDatabase?.id() && databaseInput !== selectedDatabase.id()) {
|
||||
setFormError(
|
||||
`Input database name "${databaseInput}" does not match the selected database "${selectedDatabase.id()}"`
|
||||
`Input database name "${databaseInput}" does not match the selected database "${selectedDatabase.id()}"`,
|
||||
);
|
||||
logConsoleError(`Error while deleting collection ${selectedDatabase && selectedDatabase.id()}`);
|
||||
logConsoleError(
|
||||
`Input database name "${databaseInput}" does not match the selected database "${selectedDatabase.id()}"`
|
||||
`Input database name "${databaseInput}" does not match the selected database "${selectedDatabase.id()}"`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -67,8 +67,8 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
|
||||
.getState()
|
||||
.closeTabsByComparator(
|
||||
(tab) =>
|
||||
tab.node?.id() === collection.id() && (tab.node as Collection).databaseId === collection.databaseId
|
||||
)
|
||||
tab.node?.id() === collection.id() && (tab.node as Collection).databaseId === collection.databaseId,
|
||||
),
|
||||
);
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.DeleteDatabase,
|
||||
@@ -77,7 +77,7 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
|
||||
dataExplorerArea: Areas.ContextualPane,
|
||||
paneTitle: "Delete Database",
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
|
||||
if (isLastNonEmptyDatabase()) {
|
||||
@@ -85,7 +85,7 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
|
||||
userContext?.databaseAccount.id,
|
||||
userContext?.databaseAccount.name,
|
||||
DefaultExperienceUtility.getApiKindFromDefaultExperience(userContext.apiType),
|
||||
databaseFeedbackInput
|
||||
databaseFeedbackInput,
|
||||
);
|
||||
|
||||
TelemetryProcessor.trace(Action.DeleteDatabase, ActionModifiers.Mark, {
|
||||
@@ -105,7 +105,7 @@ export const DeleteDatabaseConfirmationPanel: FunctionComponent<DeleteDatabaseCo
|
||||
error: errorMessage,
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -119,7 +119,7 @@ export const ExecuteSprocParamsPane: FunctionComponent<ExecuteSprocParamsPanePro
|
||||
}
|
||||
paramValue={paramKeyValue.text}
|
||||
selectedKey={paramKeyValue.key}
|
||||
/>
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -182,8 +182,8 @@ export class GitHubReposPanel extends React.Component<IGitHubReposPanelProps, IG
|
||||
const unpinnedGitHubRepos = this.allGitHubRepos.filter(
|
||||
(gitHubRepo) =>
|
||||
this.pinnedReposProps.repos.findIndex(
|
||||
(pinnedRepo) => pinnedRepo.key === GitHubUtils.toRepoFullName(gitHubRepo.owner, gitHubRepo.name)
|
||||
) === -1
|
||||
(pinnedRepo) => pinnedRepo.key === GitHubUtils.toRepoFullName(gitHubRepo.owner, gitHubRepo.name),
|
||||
) === -1,
|
||||
);
|
||||
return unpinnedGitHubRepos.map((gitHubRepo) => ({
|
||||
key: GitHubUtils.toRepoFullName(gitHubRepo.owner, gitHubRepo.name),
|
||||
@@ -202,7 +202,7 @@ export class GitHubReposPanel extends React.Component<IGitHubReposPanelProps, IG
|
||||
repo.owner,
|
||||
repo.name,
|
||||
GitHubReposPanel.PageSize,
|
||||
branchesProps.lastPageInfo?.endCursor
|
||||
branchesProps.lastPageInfo?.endCursor,
|
||||
);
|
||||
|
||||
if (response.status !== HttpStatusCodes.OK) {
|
||||
@@ -215,7 +215,7 @@ export class GitHubReposPanel extends React.Component<IGitHubReposPanelProps, IG
|
||||
branchesProps.defaultBranchName = branchesProps.branches[0].name;
|
||||
const defaultbranchName = branchesProps.branches.find(
|
||||
(branch) =>
|
||||
branch.name === GitHubReposPanel.MasterBranchName || branch.name === GitHubReposPanel.MainBranchName
|
||||
branch.name === GitHubReposPanel.MasterBranchName || branch.name === GitHubReposPanel.MainBranchName,
|
||||
)?.name;
|
||||
if (defaultbranchName) {
|
||||
branchesProps.defaultBranchName = defaultbranchName;
|
||||
@@ -255,7 +255,7 @@ export class GitHubReposPanel extends React.Component<IGitHubReposPanelProps, IG
|
||||
try {
|
||||
const response = await this.gitHubClient.getReposAsync(
|
||||
GitHubReposPanel.PageSize,
|
||||
this.allGitHubReposLastPageInfo?.endCursor
|
||||
this.allGitHubReposLastPageInfo?.endCursor,
|
||||
);
|
||||
|
||||
if (response.status !== HttpStatusCodes.OK) {
|
||||
@@ -366,7 +366,7 @@ export class GitHubReposPanel extends React.Component<IGitHubReposPanelProps, IG
|
||||
|
||||
try {
|
||||
const response = await this.junoClient.getPinnedRepos(
|
||||
this.props.explorer.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope
|
||||
this.props.explorer.notebookManager?.gitHubOAuthService.getTokenObservable()()?.scope,
|
||||
);
|
||||
|
||||
if (response.status !== HttpStatusCodes.OK && response.status !== HttpStatusCodes.NoContent) {
|
||||
@@ -380,7 +380,7 @@ export class GitHubReposPanel extends React.Component<IGitHubReposPanelProps, IG
|
||||
key: GitHubUtils.toRepoFullName(pinnedRepo.owner, pinnedRepo.name),
|
||||
branches: pinnedRepo.branches,
|
||||
repo: JunoUtils.toGitHubRepo(pinnedRepo),
|
||||
} as RepoListItem)
|
||||
}) as RepoListItem,
|
||||
);
|
||||
|
||||
this.pinnedReposProps.repos = pinnedRepos;
|
||||
|
||||
@@ -59,7 +59,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
||||
handleError(
|
||||
error,
|
||||
"PublishNotebookPaneAdapter/isCodeOfConductAccepted",
|
||||
"Failed to check if code of conduct was accepted"
|
||||
"Failed to check if code of conduct was accepted",
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -106,7 +106,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
||||
notebookDescription,
|
||||
notebookTags?.split(","),
|
||||
imageSrc,
|
||||
content
|
||||
content,
|
||||
);
|
||||
|
||||
const data = response.data;
|
||||
@@ -116,7 +116,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
||||
if (data.pendingScanJobIds?.length > 0) {
|
||||
isPublishPending = true;
|
||||
NotificationConsoleUtils.logConsoleInfo(
|
||||
`Content of ${name} is currently being scanned for illegal content. It will not be available in the public gallery until the review is complete (may take a few days).`
|
||||
`Content of ${name} is currently being scanned for illegal content. It will not be available in the public gallery until the review is complete (may take a few days).`,
|
||||
);
|
||||
} else {
|
||||
NotificationConsoleUtils.logConsoleInfo(`Published ${notebookName} to gallery`);
|
||||
@@ -129,7 +129,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
||||
notebookId: data.id,
|
||||
isPublishPending,
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -139,7 +139,7 @@ export const PublishNotebookPane: FunctionComponent<PublishNotebookPaneAProps> =
|
||||
error: getErrorMessage(error),
|
||||
errorStack: getErrorStack(error),
|
||||
},
|
||||
startKey
|
||||
startKey,
|
||||
);
|
||||
|
||||
const errorMessage = getErrorMessage(error);
|
||||
|
||||
@@ -62,7 +62,7 @@ export const PublishNotebookPaneComponent: FunctionComponent<PublishNotebookPane
|
||||
|
||||
const descriptionPara2 = `Would you like to publish and share "${FileSystemUtil.stripExtension(
|
||||
notebookName,
|
||||
"ipynb"
|
||||
"ipynb",
|
||||
)}" to the gallery?`;
|
||||
|
||||
const options: ImageTypes[] = [ImageTypes.CustomImage, ImageTypes.Url];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user