mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 17:01:13 +00:00
complete functionality documentMongoTab migration
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -12,9 +12,8 @@ import {
|
|||||||
SelectionMode,
|
SelectionMode,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
TextField,
|
TextField
|
||||||
} from "@fluentui/react";
|
} from "@fluentui/react";
|
||||||
import {} from "@fluentui/react/lib/Image";
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import SplitterLayout from "react-splitter-layout";
|
import SplitterLayout from "react-splitter-layout";
|
||||||
import CloseIcon from "../../../images/close-black.svg";
|
import CloseIcon from "../../../images/close-black.svg";
|
||||||
@@ -28,6 +27,7 @@ import { Areas } from "../../Common/Constants";
|
|||||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||||
import { logError } from "../../Common/Logger";
|
import { logError } from "../../Common/Logger";
|
||||||
import { createDocument, deleteDocument, queryDocuments, updateDocument } from "../../Common/MongoProxyClient";
|
import { createDocument, deleteDocument, queryDocuments, updateDocument } from "../../Common/MongoProxyClient";
|
||||||
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
@@ -36,7 +36,7 @@ import { EditorReact } from "../Controls/Editor/EditorReact";
|
|||||||
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
import { useCommandBar } from "../Menus/CommandBar/CommandBarComponentAdapter";
|
||||||
import DocumentId from "../Tree/DocumentId";
|
import DocumentId from "../Tree/DocumentId";
|
||||||
import ObjectId from "../Tree/ObjectId";
|
import ObjectId from "../Tree/ObjectId";
|
||||||
import DocumentsTab from "./DocumentsTab";
|
import DocumentsTab from "./DocumentsTab1";
|
||||||
import { formatDocumentContent, getPartitionKeyDefinition, hasShardKeySpecified } from "./DocumentTabUtils";
|
import { formatDocumentContent, getPartitionKeyDefinition, hasShardKeySpecified } from "./DocumentTabUtils";
|
||||||
|
|
||||||
const filterIcon: IIconProps = { iconName: "Filter" };
|
const filterIcon: IIconProps = { iconName: "Filter" };
|
||||||
@@ -54,6 +54,7 @@ export interface IDocumentsTabContentState {
|
|||||||
documentIds: Array<DocumentId>;
|
documentIds: Array<DocumentId>;
|
||||||
editorKey: string;
|
editorKey: string;
|
||||||
selectedDocumentId?: DocumentId;
|
selectedDocumentId?: DocumentId;
|
||||||
|
isEditorContentEdited: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDocument {
|
export interface IDocument {
|
||||||
@@ -76,6 +77,8 @@ const imageProps: Partial<IImageProps> = {
|
|||||||
|
|
||||||
const filterSuggestions = [{ value: `{"id": "foo"}` }, { value: "{ qty: { $gte: 20 } }" }];
|
const filterSuggestions = [{ value: `{"id": "foo"}` }, { value: "{ qty: { $gte: 20 } }" }];
|
||||||
const intitalDocumentContent = `{ \n "id": "replace_with_new_document_id" \n }`;
|
const intitalDocumentContent = `{ \n "id": "replace_with_new_document_id" \n }`;
|
||||||
|
const idHeader = userContext.apiType === "Mongo" ? "_id" : "id";
|
||||||
|
|
||||||
export default class DocumentsTabContent extends React.Component<DocumentsTab, IDocumentsTabContentState> {
|
export default class DocumentsTabContent extends React.Component<DocumentsTab, IDocumentsTabContentState> {
|
||||||
public newDocumentButton: IButton;
|
public newDocumentButton: IButton;
|
||||||
public saveNewDocumentButton: IButton;
|
public saveNewDocumentButton: IButton;
|
||||||
@@ -115,7 +118,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
const columns: IColumn[] = [
|
const columns: IColumn[] = [
|
||||||
{
|
{
|
||||||
key: "_id",
|
key: "_id",
|
||||||
name: props.idHeader,
|
name: idHeader,
|
||||||
minWidth: 90,
|
minWidth: 90,
|
||||||
maxWidth: 140,
|
maxWidth: 140,
|
||||||
isResizable: true,
|
isResizable: true,
|
||||||
@@ -153,10 +156,12 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
documentContent: intitalDocumentContent,
|
documentContent: intitalDocumentContent,
|
||||||
documentIds: [],
|
documentIds: [],
|
||||||
editorKey: "",
|
editorKey: "",
|
||||||
|
isEditorContentEdited: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
|
this.props.isExecuting(true);
|
||||||
this.updateTabButton();
|
this.updateTabButton();
|
||||||
if (userContext.apiType === "Mongo") {
|
if (userContext.apiType === "Mongo") {
|
||||||
this.queryDocumentsData();
|
this.queryDocumentsData();
|
||||||
@@ -171,17 +176,17 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
const query: string = filter || "{}";
|
const query: string = filter || "{}";
|
||||||
const queryDocumentsData = await queryDocuments(
|
const queryDocumentsData = await queryDocuments(
|
||||||
this.props.collection.databaseId,
|
this.props.collection.databaseId,
|
||||||
this.props.collection,
|
this.props.collection as ViewModels.Collection,
|
||||||
true,
|
true,
|
||||||
query,
|
query,
|
||||||
undefined
|
undefined
|
||||||
);
|
);
|
||||||
if (queryDocumentsData) {
|
if (queryDocumentsData) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const nextDocumentIds = queryDocumentsData.documents.map((rawDocument: any) => {
|
const nextDocumentIds = queryDocumentsData.documents.map((rawDocument: any) => {
|
||||||
const partitionKeyValue = rawDocument._partitionKeyValue;
|
const partitionKeyValue = rawDocument.partitionKeyValue;
|
||||||
return new DocumentId(this.props, rawDocument, partitionKeyValue);
|
return new DocumentId(this.props as DocumentsTab, rawDocument, partitionKeyValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({ documentIds: nextDocumentIds });
|
this.setState({ documentIds: nextDocumentIds });
|
||||||
}
|
}
|
||||||
if (this.props.onLoadStartKey !== undefined) {
|
if (this.props.onLoadStartKey !== undefined) {
|
||||||
@@ -219,6 +224,19 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleRow = (row: DocumentId): void => {
|
handleRow = (row: DocumentId): void => {
|
||||||
|
if (this.state.isEditorContentEdited) {
|
||||||
|
const isChangesConfirmed = window.confirm("Your unsaved changes will be lost.")
|
||||||
|
if (isChangesConfirmed) {
|
||||||
|
this.handleRowContent(row);
|
||||||
|
this.setState({ isEditorContentEdited: false });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.handleRowContent(row);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleRowContent = (row: DocumentId): void => {
|
||||||
const formattedDocumentContent = formatDocumentContent(row);
|
const formattedDocumentContent = formatDocumentContent(row);
|
||||||
this.newDocumentButton = {
|
this.newDocumentButton = {
|
||||||
visible: false,
|
visible: false,
|
||||||
@@ -255,7 +273,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
this.updateTabButton();
|
this.updateTabButton();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
formatDocumentContent = (row: DocumentId): string => {
|
formatDocumentContent = (row: DocumentId): string => {
|
||||||
const { partitionKeyProperty, partitionKeyValue, rid, self, stringPartitionKeyValue, ts } = row;
|
const { partitionKeyProperty, partitionKeyValue, rid, self, stringPartitionKeyValue, ts } = row;
|
||||||
@@ -291,7 +309,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
try {
|
try {
|
||||||
const updatedDocument = await updateDocument(
|
const updatedDocument = await updateDocument(
|
||||||
collection.databaseId,
|
collection.databaseId,
|
||||||
collection,
|
collection as ViewModels.Collection,
|
||||||
selectedDocumentId,
|
selectedDocumentId,
|
||||||
documentContent
|
documentContent
|
||||||
);
|
);
|
||||||
@@ -304,7 +322,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
|
|
||||||
const partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
const partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
||||||
|
|
||||||
const id = new ObjectId(this.props, updatedDocument, partitionKeyValue);
|
const id = new ObjectId(this.props as DocumentsTab, updatedDocument, partitionKeyValue);
|
||||||
documentId.id(id.id());
|
documentId.id(id.id());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -316,6 +334,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
},
|
},
|
||||||
startKey
|
startKey
|
||||||
);
|
);
|
||||||
|
this.setState({ isEditorContentEdited: false });
|
||||||
isExecuting(false);
|
isExecuting(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
isExecutionError(true);
|
isExecutionError(true);
|
||||||
@@ -427,9 +446,28 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
this.updateMongoDocument();
|
this.updateMongoDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDeleteExisitingDocumentClick(): Promise<void> {
|
private async onDeleteExisitingDocumentClick(): Promise<void> {
|
||||||
const { collection } = this.props;
|
const msg = userContext.apiType !== "Mongo"
|
||||||
return deleteDocument(collection.databaseId, collection, this.state.selectedDocumentId);
|
? "Are you sure you want to delete the selected item ?"
|
||||||
|
: "Are you sure you want to delete the selected document ?";
|
||||||
|
|
||||||
|
const {
|
||||||
|
isExecutionError,
|
||||||
|
isExecuting,
|
||||||
|
collection,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
if (window.confirm(msg)) {
|
||||||
|
try {
|
||||||
|
isExecuting(true)
|
||||||
|
await deleteDocument(collection.databaseId, collection as ViewModels.Collection, this.state.selectedDocumentId);
|
||||||
|
isExecuting(false)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
isExecutionError(true);
|
||||||
|
isExecuting(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRevertExisitingDocumentClick(): void {
|
private onRevertExisitingDocumentClick(): void {
|
||||||
@@ -510,7 +548,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
try {
|
try {
|
||||||
const savedDocument = await createDocument(
|
const savedDocument = await createDocument(
|
||||||
collection.databaseId,
|
collection.databaseId,
|
||||||
collection,
|
collection as ViewModels.Collection,
|
||||||
partitionKeyProperty,
|
partitionKeyProperty,
|
||||||
parsedDocumentContent
|
parsedDocumentContent
|
||||||
);
|
);
|
||||||
@@ -525,6 +563,7 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
startKey
|
startKey
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.setState({ isEditorContentEdited: false });
|
||||||
this.queryDocumentsData();
|
this.queryDocumentsData();
|
||||||
isExecuting(false);
|
isExecuting(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -561,7 +600,11 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.updateTabButton();
|
this.updateTabButton();
|
||||||
this.setState({ isEditorVisible: false });
|
this.setState({
|
||||||
|
isEditorVisible: false,
|
||||||
|
isEditorContentEdited: false,
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onRenderCell = (item: { value: string }): JSX.Element => {
|
onRenderCell = (item: { value: string }): JSX.Element => {
|
||||||
@@ -603,7 +646,10 @@ export default class DocumentsTabContent extends React.Component<DocumentsTab, I
|
|||||||
this.updateTabButton();
|
this.updateTabButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ documentContent: newContent });
|
this.setState({
|
||||||
|
documentContent: newContent,
|
||||||
|
isEditorContentEdited: true,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
|
|||||||
@@ -1,33 +1,12 @@
|
|||||||
import { extractPartitionKey, PartitionKeyDefinition } from "@azure/cosmos";
|
|
||||||
import * as ko from "knockout";
|
|
||||||
import Q from "q";
|
|
||||||
import * as Constants from "../../Common/Constants";
|
|
||||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
|
||||||
import * as Logger from "../../Common/Logger";
|
|
||||||
import {
|
|
||||||
createDocument,
|
|
||||||
deleteDocument,
|
|
||||||
queryDocuments,
|
|
||||||
readDocument,
|
|
||||||
updateDocument,
|
|
||||||
} from "../../Common/MongoProxyClient";
|
|
||||||
import MongoUtility from "../../Common/MongoUtility";
|
|
||||||
import * as DataModels from "../../Contracts/DataModels";
|
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
import * as ViewModels from "../../Contracts/ViewModels";
|
||||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
|
||||||
import DocumentId from "../Tree/DocumentId";
|
|
||||||
import ObjectId from "../Tree/ObjectId";
|
|
||||||
import DocumentsTab from "./DocumentsTab1";
|
import DocumentsTab from "./DocumentsTab1";
|
||||||
|
|
||||||
export default class MongoDocumentsTab extends DocumentsTab {
|
export default class MongoDocumentsTab extends DocumentsTab {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
private continuationToken: string;
|
// private continuationToken: string;
|
||||||
|
|
||||||
constructor(options: ViewModels.DocumentsTabOptions) {
|
constructor(options: ViewModels.DocumentsTabOptions) {
|
||||||
super(options);
|
super(options);
|
||||||
this.lastFilterContents = ko.observableArray<string>(['{"id":"foo"}', "{ qty: { $gte: 20 } }"]);
|
|
||||||
|
|
||||||
if (this.partitionKeyProperty && ~this.partitionKeyProperty.indexOf(`"`)) {
|
if (this.partitionKeyProperty && ~this.partitionKeyProperty.indexOf(`"`)) {
|
||||||
this.partitionKeyProperty = this.partitionKeyProperty.replace(/["]+/g, "");
|
this.partitionKeyProperty = this.partitionKeyProperty.replace(/["]+/g, "");
|
||||||
}
|
}
|
||||||
@@ -38,279 +17,279 @@ export default class MongoDocumentsTab extends DocumentsTab {
|
|||||||
this.partitionKeyPropertyHeader = "/" + this.partitionKeyProperty;
|
this.partitionKeyPropertyHeader = "/" + this.partitionKeyProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isFilterExpanded = ko.observable<boolean>(true);
|
// this.isFilterExpanded = ko.observable<boolean>(true);
|
||||||
super.buildCommandBarOptions.bind(this);
|
super.buildCommandBarOptions.bind(this);
|
||||||
super.buildCommandBarOptions();
|
super.buildCommandBarOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onSaveNewDocumentClick = (): Promise<any> => {
|
// public onSaveNewDocumentClick = (): Promise<any> => {
|
||||||
const documentContent = JSON.parse(this.selectedDocumentContent());
|
// const documentContent = JSON.parse(this.selectedDocumentContent());
|
||||||
this.displayedError("");
|
// this.displayedError("");
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.CreateDocument, {
|
// const startKey: number = TelemetryProcessor.traceStart(Action.CreateDocument, {
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (
|
// if (
|
||||||
this.partitionKeyProperty &&
|
// this.partitionKeyProperty &&
|
||||||
this.partitionKeyProperty !== "_id" &&
|
// this.partitionKeyProperty !== "_id" &&
|
||||||
!this._hasShardKeySpecified(documentContent)
|
// !this._hasShardKeySpecified(documentContent)
|
||||||
) {
|
// ) {
|
||||||
const message = `The document is lacking the shard property: ${this.partitionKeyProperty}`;
|
// const message = `The document is lacking the shard property: ${this.partitionKeyProperty}`;
|
||||||
this.displayedError(message);
|
// this.displayedError(message);
|
||||||
let that = this;
|
// let that = this;
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
that.displayedError("");
|
// that.displayedError("");
|
||||||
}, Constants.ClientDefaults.errorNotificationTimeoutMs);
|
// }, Constants.ClientDefaults.errorNotificationTimeoutMs);
|
||||||
this.isExecutionError(true);
|
// this.isExecutionError(true);
|
||||||
TelemetryProcessor.traceFailure(
|
// TelemetryProcessor.traceFailure(
|
||||||
Action.CreateDocument,
|
// Action.CreateDocument,
|
||||||
{
|
// {
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
error: message,
|
// error: message,
|
||||||
},
|
// },
|
||||||
startKey
|
// startKey
|
||||||
);
|
// );
|
||||||
Logger.logError("Failed to save new document: Document shard key not defined", "MongoDocumentsTab");
|
// Logger.logError("Failed to save new document: Document shard key not defined", "MongoDocumentsTab");
|
||||||
throw new Error("Document without shard key");
|
// throw new Error("Document without shard key");
|
||||||
}
|
// }
|
||||||
|
|
||||||
this.isExecutionError(false);
|
// this.isExecutionError(false);
|
||||||
this.isExecuting(true);
|
// this.isExecuting(true);
|
||||||
return createDocument(this.collection.databaseId, this.collection, this.partitionKeyProperty, documentContent)
|
// return createDocument(this.collection.databaseId, this.collection, this.partitionKeyProperty, documentContent)
|
||||||
.then(
|
// .then(
|
||||||
(savedDocument: any) => {
|
// (savedDocument: any) => {
|
||||||
let partitionKeyArray = extractPartitionKey(
|
// let partitionKeyArray = extractPartitionKey(
|
||||||
savedDocument,
|
// savedDocument,
|
||||||
this._getPartitionKeyDefinition() as PartitionKeyDefinition
|
// this._getPartitionKeyDefinition() as PartitionKeyDefinition
|
||||||
);
|
// );
|
||||||
|
|
||||||
let partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
// let partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
||||||
|
|
||||||
let id = new ObjectId(this, savedDocument, partitionKeyValue);
|
// let id = new ObjectId(this, savedDocument, partitionKeyValue);
|
||||||
let ids = this.documentIds();
|
// let ids = this.documentIds();
|
||||||
ids.push(id);
|
// ids.push(id);
|
||||||
delete savedDocument._self;
|
// delete savedDocument._self;
|
||||||
|
|
||||||
let value: string = this.renderObjectForEditor(savedDocument || {}, null, 4);
|
// let value: string = this.renderObjectForEditor(savedDocument || {}, null, 4);
|
||||||
this.selectedDocumentContent.setBaseline(value);
|
// this.selectedDocumentContent.setBaseline(value);
|
||||||
|
|
||||||
this.selectedDocumentId(id);
|
// this.selectedDocumentId(id);
|
||||||
this.documentIds(ids);
|
// this.documentIds(ids);
|
||||||
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
|
// this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
|
||||||
TelemetryProcessor.traceSuccess(
|
// TelemetryProcessor.traceSuccess(
|
||||||
Action.CreateDocument,
|
// Action.CreateDocument,
|
||||||
{
|
// {
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
},
|
// },
|
||||||
startKey
|
// startKey
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
(error) => {
|
// (error) => {
|
||||||
this.isExecutionError(true);
|
// this.isExecutionError(true);
|
||||||
const errorMessage = getErrorMessage(error);
|
// const errorMessage = getErrorMessage(error);
|
||||||
window.alert(errorMessage);
|
// window.alert(errorMessage);
|
||||||
TelemetryProcessor.traceFailure(
|
// TelemetryProcessor.traceFailure(
|
||||||
Action.CreateDocument,
|
// Action.CreateDocument,
|
||||||
{
|
// {
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
error: errorMessage,
|
// error: errorMessage,
|
||||||
errorStack: getErrorStack(error),
|
// errorStack: getErrorStack(error),
|
||||||
},
|
// },
|
||||||
startKey
|
// startKey
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
.finally(() => this.isExecuting(false));
|
// .finally(() => this.isExecuting(false));
|
||||||
};
|
// };
|
||||||
|
|
||||||
public onSaveExisitingDocumentClick = (): Promise<any> => {
|
// public onSaveExisitingDocumentClick = (): Promise<any> => {
|
||||||
const selectedDocumentId = this.selectedDocumentId();
|
// const selectedDocumentId = this.selectedDocumentId();
|
||||||
const documentContent = this.selectedDocumentContent();
|
// const documentContent = this.selectedDocumentContent();
|
||||||
this.isExecutionError(false);
|
// this.isExecutionError(false);
|
||||||
this.isExecuting(true);
|
// this.isExecuting(true);
|
||||||
const startKey: number = TelemetryProcessor.traceStart(Action.UpdateDocument, {
|
// const startKey: number = TelemetryProcessor.traceStart(Action.UpdateDocument, {
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
});
|
// });
|
||||||
|
|
||||||
return updateDocument(this.collection.databaseId, this.collection, selectedDocumentId, documentContent)
|
// return updateDocument(this.collection.databaseId, this.collection, selectedDocumentId, documentContent)
|
||||||
.then(
|
// .then(
|
||||||
(updatedDocument: any) => {
|
// (updatedDocument: any) => {
|
||||||
let value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
|
// let value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
|
||||||
this.selectedDocumentContent.setBaseline(value);
|
// this.selectedDocumentContent.setBaseline(value);
|
||||||
|
|
||||||
this.documentIds().forEach((documentId: DocumentId) => {
|
// this.documentIds().forEach((documentId: DocumentId) => {
|
||||||
if (documentId.rid === updatedDocument._rid) {
|
// if (documentId.rid === updatedDocument._rid) {
|
||||||
const partitionKeyArray = extractPartitionKey(
|
// const partitionKeyArray = extractPartitionKey(
|
||||||
updatedDocument,
|
// updatedDocument,
|
||||||
this._getPartitionKeyDefinition() as PartitionKeyDefinition
|
// this._getPartitionKeyDefinition() as PartitionKeyDefinition
|
||||||
);
|
// );
|
||||||
|
|
||||||
let partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
// let partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
|
||||||
|
|
||||||
const id = new ObjectId(this, updatedDocument, partitionKeyValue);
|
// const id = new ObjectId(this, updatedDocument, partitionKeyValue);
|
||||||
documentId.id(id.id());
|
// documentId.id(id.id());
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
|
// this.editorState(ViewModels.DocumentExplorerState.exisitingDocumentNoEdits);
|
||||||
TelemetryProcessor.traceSuccess(
|
// TelemetryProcessor.traceSuccess(
|
||||||
Action.UpdateDocument,
|
// Action.UpdateDocument,
|
||||||
{
|
// {
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
},
|
// },
|
||||||
startKey
|
// startKey
|
||||||
);
|
// );
|
||||||
},
|
// },
|
||||||
(error) => {
|
// (error) => {
|
||||||
this.isExecutionError(true);
|
// this.isExecutionError(true);
|
||||||
const errorMessage = getErrorMessage(error);
|
// const errorMessage = getErrorMessage(error);
|
||||||
window.alert(errorMessage);
|
// window.alert(errorMessage);
|
||||||
TelemetryProcessor.traceFailure(
|
// TelemetryProcessor.traceFailure(
|
||||||
Action.UpdateDocument,
|
// Action.UpdateDocument,
|
||||||
{
|
// {
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
error: errorMessage,
|
// error: errorMessage,
|
||||||
errorStack: getErrorStack(error),
|
// errorStack: getErrorStack(error),
|
||||||
},
|
// },
|
||||||
startKey
|
// startKey
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
.finally(() => this.isExecuting(false));
|
// .finally(() => this.isExecuting(false));
|
||||||
};
|
// };
|
||||||
|
|
||||||
public buildQuery(filter: string): string {
|
public buildQuery(filter: string): string {
|
||||||
return filter || "{}";
|
return filter || "{}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public async selectDocument(documentId: DocumentId): Promise<void> {
|
// public async selectDocument(documentId: DocumentId): Promise<void> {
|
||||||
this.selectedDocumentId(documentId);
|
// this.selectedDocumentId(documentId);
|
||||||
const content = await readDocument(this.collection.databaseId, this.collection, documentId);
|
// const content = await readDocument(this.collection.databaseId, this.collection, documentId);
|
||||||
this.initDocumentEditor(documentId, content);
|
// this.initDocumentEditor(documentId, content);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public loadNextPage(): Q.Promise<any> {
|
// public loadNextPage(): Q.Promise<any> {
|
||||||
this.isExecuting(true);
|
// this.isExecuting(true);
|
||||||
this.isExecutionError(false);
|
// this.isExecutionError(false);
|
||||||
const filter: string = this.filterContent().trim();
|
// const filter: string = this.filterContent().trim();
|
||||||
const query: string = this.buildQuery(filter);
|
// const query: string = this.buildQuery(filter);
|
||||||
|
|
||||||
return Q(queryDocuments(this.collection.databaseId, this.collection, true, query, this.continuationToken))
|
// return Q(queryDocuments(this.collection.databaseId, this.collection, true, query, this.continuationToken))
|
||||||
.then(
|
// .then(
|
||||||
({ continuationToken, documents }) => {
|
// ({ continuationToken, documents }) => {
|
||||||
this.continuationToken = continuationToken;
|
// this.continuationToken = continuationToken;
|
||||||
let currentDocuments = this.documentIds();
|
// let currentDocuments = this.documentIds();
|
||||||
const currentDocumentsRids = currentDocuments.map((currentDocument) => currentDocument.rid);
|
// const currentDocumentsRids = currentDocuments.map((currentDocument) => currentDocument.rid);
|
||||||
const nextDocumentIds = documents
|
// const nextDocumentIds = documents
|
||||||
.filter((d: any) => {
|
// .filter((d: any) => {
|
||||||
return currentDocumentsRids.indexOf(d._rid) < 0;
|
// return currentDocumentsRids.indexOf(d._rid) < 0;
|
||||||
})
|
// })
|
||||||
.map((rawDocument: any) => {
|
// .map((rawDocument: any) => {
|
||||||
const partitionKeyValue = rawDocument._partitionKeyValue;
|
// const partitionKeyValue = rawDocument._partitionKeyValue;
|
||||||
return new DocumentId(this, rawDocument, partitionKeyValue);
|
// return new DocumentId(this, rawDocument, partitionKeyValue);
|
||||||
});
|
// });
|
||||||
|
|
||||||
const merged = currentDocuments.concat(nextDocumentIds);
|
// const merged = currentDocuments.concat(nextDocumentIds);
|
||||||
|
|
||||||
this.documentIds(merged);
|
// this.documentIds(merged);
|
||||||
currentDocuments = this.documentIds();
|
// currentDocuments = this.documentIds();
|
||||||
if (this.filterContent().length > 0 && currentDocuments.length > 0) {
|
// if (this.filterContent().length > 0 && currentDocuments.length > 0) {
|
||||||
currentDocuments[0].click();
|
// currentDocuments[0].click();
|
||||||
} else {
|
// } else {
|
||||||
this.selectedDocumentContent("");
|
// this.selectedDocumentContent("");
|
||||||
this.selectedDocumentId(null);
|
// this.selectedDocumentId(null);
|
||||||
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
// this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
|
||||||
}
|
// }
|
||||||
if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) {
|
// if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) {
|
||||||
TelemetryProcessor.traceSuccess(
|
// TelemetryProcessor.traceSuccess(
|
||||||
Action.Tab,
|
// Action.Tab,
|
||||||
{
|
// {
|
||||||
databaseName: this.collection.databaseId,
|
// databaseName: this.collection.databaseId,
|
||||||
collectionName: this.collection.id(),
|
// collectionName: this.collection.id(),
|
||||||
|
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
},
|
// },
|
||||||
this.onLoadStartKey
|
// this.onLoadStartKey
|
||||||
);
|
// );
|
||||||
this.onLoadStartKey = null;
|
// this.onLoadStartKey = null;
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
(error: any) => {
|
// (error: any) => {
|
||||||
if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) {
|
// if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) {
|
||||||
TelemetryProcessor.traceFailure(
|
// TelemetryProcessor.traceFailure(
|
||||||
Action.Tab,
|
// Action.Tab,
|
||||||
{
|
// {
|
||||||
databaseName: this.collection.databaseId,
|
// databaseName: this.collection.databaseId,
|
||||||
collectionName: this.collection.id(),
|
// collectionName: this.collection.id(),
|
||||||
|
|
||||||
dataExplorerArea: Constants.Areas.Tab,
|
// dataExplorerArea: Constants.Areas.Tab,
|
||||||
tabTitle: this.tabTitle(),
|
// tabTitle: this.tabTitle(),
|
||||||
error: getErrorMessage(error),
|
// error: getErrorMessage(error),
|
||||||
errorStack: getErrorStack(error),
|
// errorStack: getErrorStack(error),
|
||||||
},
|
// },
|
||||||
this.onLoadStartKey
|
// this.onLoadStartKey
|
||||||
);
|
// );
|
||||||
this.onLoadStartKey = null;
|
// this.onLoadStartKey = null;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
.finally(() => this.isExecuting(false));
|
// .finally(() => this.isExecuting(false));
|
||||||
}
|
// }
|
||||||
|
|
||||||
protected _onEditorContentChange(newContent: string) {
|
// protected _onEditorContentChange(newContent: string) {
|
||||||
try {
|
// try {
|
||||||
if (
|
// if (
|
||||||
this.editorState() === ViewModels.DocumentExplorerState.newDocumentValid ||
|
// this.editorState() === ViewModels.DocumentExplorerState.newDocumentValid ||
|
||||||
this.editorState() === ViewModels.DocumentExplorerState.newDocumentInvalid
|
// this.editorState() === ViewModels.DocumentExplorerState.newDocumentInvalid
|
||||||
) {
|
// ) {
|
||||||
let parsed: any = JSON.parse(newContent);
|
// let parsed: any = JSON.parse(newContent);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Mongo uses BSON format for _id, trying to parse it as JSON blocks normal flow in an edit
|
// // Mongo uses BSON format for _id, trying to parse it as JSON blocks normal flow in an edit
|
||||||
this.onValidDocumentEdit();
|
// this.onValidDocumentEdit();
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
this.onInvalidDocumentEdit();
|
// this.onInvalidDocumentEdit();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
/** Renders a Javascript object to be displayed inside Monaco Editor */
|
||||||
protected renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
// protected renderObjectForEditor(value: any, replacer: any, space: string | number): string {
|
||||||
return MongoUtility.tojson(value, null, false);
|
// return MongoUtility.tojson(value, null, false);
|
||||||
}
|
// }
|
||||||
|
|
||||||
private _hasShardKeySpecified(document: any): boolean {
|
// private _hasShardKeySpecified(document: any): boolean {
|
||||||
return Boolean(extractPartitionKey(document, this._getPartitionKeyDefinition() as PartitionKeyDefinition));
|
// return Boolean(extractPartitionKey(document, this._getPartitionKeyDefinition() as PartitionKeyDefinition));
|
||||||
}
|
// }
|
||||||
|
|
||||||
private _getPartitionKeyDefinition(): DataModels.PartitionKey {
|
// private _getPartitionKeyDefinition(): DataModels.PartitionKey {
|
||||||
let partitionKey: DataModels.PartitionKey = this.partitionKey;
|
// let partitionKey: DataModels.PartitionKey = this.partitionKey;
|
||||||
|
|
||||||
if (
|
// if (
|
||||||
this.partitionKey &&
|
// this.partitionKey &&
|
||||||
this.partitionKey.paths &&
|
// this.partitionKey.paths &&
|
||||||
this.partitionKey.paths.length &&
|
// this.partitionKey.paths.length &&
|
||||||
this.partitionKey.paths.length > 0 &&
|
// this.partitionKey.paths.length > 0 &&
|
||||||
this.partitionKey.paths[0].indexOf("$v") > -1
|
// this.partitionKey.paths[0].indexOf("$v") > -1
|
||||||
) {
|
// ) {
|
||||||
// Convert BsonSchema2 to /path format
|
// // Convert BsonSchema2 to /path format
|
||||||
partitionKey = {
|
// partitionKey = {
|
||||||
kind: partitionKey.kind,
|
// kind: partitionKey.kind,
|
||||||
paths: ["/" + this.partitionKeyProperty.replace(/\./g, "/")],
|
// paths: ["/" + this.partitionKeyProperty.replace(/\./g, "/")],
|
||||||
version: partitionKey.version,
|
// version: partitionKey.version,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
return partitionKey;
|
// return partitionKey;
|
||||||
}
|
// }
|
||||||
|
|
||||||
protected __deleteDocument(documentId: DocumentId): Promise<void> {
|
// protected __deleteDocument(documentId: DocumentId): Promise<void> {
|
||||||
return deleteDocument(this.collection.databaseId, this.collection, documentId);
|
// return deleteDocument(this.collection.databaseId, this.collection, documentId);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ export default class DocumentId {
|
|||||||
this.isDirty = ko.observable(false);
|
this.isDirty = ko.observable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public click() {
|
// public click() {
|
||||||
if (!this.container.isEditorDirty() || window.confirm("Your unsaved changes will be lost.")) {
|
// if (!this.container.isEditorDirty() || window.confirm("Your unsaved changes will be lost.")) {
|
||||||
this.loadDocument();
|
// this.loadDocument();
|
||||||
}
|
// }
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public partitionKeyHeader(): Object {
|
public partitionKeyHeader(): Object {
|
||||||
if (!this.partitionKeyProperty) {
|
if (!this.partitionKeyProperty) {
|
||||||
@@ -65,7 +65,7 @@ export default class DocumentId {
|
|||||||
return JSON.stringify(partitionKeyValue);
|
return JSON.stringify(partitionKeyValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadDocument(): Promise<void> {
|
// public async loadDocument(): Promise<void> {
|
||||||
await this.container.selectDocument(this);
|
// await this.container.selectDocument(this);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user