Compare commits

..

3 Commits

Author SHA1 Message Date
vaidankarswapnil
5b6a1b345f Fix eslint issues for D3ForceGraph and test file 2021-10-19 13:54:57 +05:30
victor-meng
55837db65b Revert "Fix keyboard focus does not retain on 'New Database' button a… (#1139)
* Revert "Fix keyboard focus does not retain on 'New Database' button after closing the 'New Database' blade via ESC key (#1109)"

This reverts commit f7e7240010.

* Revert "Fix ally database panel open issue (#1120)"

This reverts commit ed1ffb692f.
2021-10-15 17:36:48 -07:00
victor-meng
9f27cb95b9 Only use the SET keyword once in the update query (#1138) 2021-10-15 12:33:59 -07:00
10 changed files with 115 additions and 126 deletions

View File

@@ -46,8 +46,8 @@ src/Explorer/DataSamples/DataSamplesUtil.test.ts
src/Explorer/DataSamples/DataSamplesUtil.ts
src/Explorer/Graph/GraphExplorerComponent/ArraysByKeyCache.test.ts
src/Explorer/Graph/GraphExplorerComponent/ArraysByKeyCache.ts
src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.test.ts
src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts
# src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.test.ts
# src/Explorer/Graph/GraphExplorerComponent/D3ForceGraph.ts
src/Explorer/Graph/GraphExplorerComponent/EdgeInfoCache.ts
src/Explorer/Graph/GraphExplorerComponent/GraphData.test.ts
src/Explorer/Graph/GraphExplorerComponent/GraphData.ts
@@ -85,10 +85,14 @@ src/Explorer/Tables/DataTable/DataTableViewModel.ts
src/Explorer/Tables/DataTable/TableEntityListViewModel.ts
src/Explorer/Tables/QueryBuilder/CustomTimestampHelper.ts
src/Explorer/Tables/TableDataClient.ts
src/Explorer/Tables/TableEntityProcessor.ts
src/Explorer/Tables/Utilities.ts
src/Explorer/Tabs/ConflictsTab.ts
src/Explorer/Tabs/DatabaseSettingsTab.ts
src/Explorer/Tabs/DocumentsTab.test.ts
src/Explorer/Tabs/DocumentsTab.ts
src/Explorer/Tabs/GraphTab.ts
src/Explorer/Tabs/MongoDocumentsTab.ts
src/Explorer/Tabs/NotebookV2Tab.ts
src/Explorer/Tabs/ScriptTabBase.ts
src/Explorer/Tabs/TabComponents.ts

View File

@@ -1,4 +1,5 @@
import * as sinon from "sinon";
/*eslint-disable jest/no-test-callback */
import * as sinon from "sinon";
import GraphTab from "../../Tabs/GraphTab";
import { D3Link, D3Node, GraphData } from "../GraphExplorerComponent/GraphData";
import { D3ForceGraph, D3GraphNodeData, LoadMoreDataAction } from "./D3ForceGraph";
@@ -70,6 +71,7 @@ describe("D3ForceGraph", () => {
forceGraph = new D3ForceGraph({
igraphConfig: GraphTab.createIGraphConfig(),
onHighlightedNode: sinon.spy(),
//eslint-disable-next-line
onLoadMoreData: (action: LoadMoreDataAction): void => {},
// parent to graph

View File

@@ -1,4 +1,6 @@
import { BaseType } from "d3";
/*eslint-disable @typescript-eslint/no-explicit-any*/
/*eslint-disable @typescript-eslint/no-this-alias*/
import { BaseType } from "d3";
import { map as d3Map } from "d3-collection";
import { D3DragEvent, drag } from "d3-drag";
import { forceCollide, forceLink, forceManyBody, forceSimulation } from "d3-force";
@@ -261,10 +263,10 @@ export class D3ForceGraph implements GraphRenderer {
return;
}
var self = this;
const self = this;
// Select this node id
selectAll(".node")
.filter(function (d: D3Node, i) {
.filter((d: D3Node) => {
return d.id === newVal;
})
.each(function (d: D3Node) {
@@ -277,15 +279,15 @@ export class D3ForceGraph implements GraphRenderer {
} // initialize
private updateUniqueValues(key: string) {
for (var i = 0; i < this.graphDataWrapper.vertices.length; i++) {
let vertex = this.graphDataWrapper.vertices[i];
for (let i = 0; i < this.graphDataWrapper.vertices.length; i++) {
const vertex = this.graphDataWrapper.vertices[i];
let props = D3ForceGraph.getNodeProperties(vertex);
const props = D3ForceGraph.getNodeProperties(vertex);
if (props.indexOf(key) === -1) {
// Vertex doesn't have the property
continue;
}
let val = GraphData.getNodePropValue(vertex, key);
const val = GraphData.getNodePropValue(vertex, key);
if (typeof val !== "string" && typeof val !== "number") {
// Not a type we can map
continue;
@@ -313,7 +315,7 @@ export class D3ForceGraph implements GraphRenderer {
*/
private static getNodeProperties(node: D3Node): string[] {
let props = ["id", "label"];
//eslint-disable-next-line
if (node.hasOwnProperty("properties")) {
props = props.concat(Object.keys(node.properties));
}
@@ -405,7 +407,7 @@ export class D3ForceGraph implements GraphRenderer {
// Remember nodes current position
const posMap = new Map<string, Point2D>();
this.simulation.nodes().forEach((d: D3Node) => {
if (d.x == undefined || d.y == undefined) {
if (d.x === undefined || d.y === undefined) {
return;
}
posMap.set(d.id, { x: d.x, y: d.y });
@@ -549,7 +551,7 @@ export class D3ForceGraph implements GraphRenderer {
.transition()
.delay(D3ForceGraph.TRANSITION_STEP3_MS - 100)
.duration(D3ForceGraph.TRANSITION_STEP3_MS)
.attrTween("fill", (t: any) => {
.attrTween("fill", () => {
const ic = interpolate("#ffffff", "#000000");
return (t: number) => {
return ic(t);
@@ -567,7 +569,7 @@ export class D3ForceGraph implements GraphRenderer {
// Distribute nodes initial position before simulation
const nodes = graph.vertices;
for (let i = 0; i < nodes.length; i++) {
let v = nodes[i];
const v = nodes[i];
if (v._isRoot) {
this.rootVertex = v;
@@ -611,6 +613,20 @@ export class D3ForceGraph implements GraphRenderer {
const self = this;
const ticked = () => {
self.linkSelection.select(".link").attr("d", (l: D3Link) => {
return self.positionLink(l);
});
if (!D3ForceGraph.useSvgMarkerEnd()) {
self.linkSelection.select(".markerEnd").attr("transform", (l: D3Link) => {
return self.positionLinkEnd(l);
});
}
self.nodeSelection.attr("transform", (d: D3Node) => {
return self.positionNode(d);
});
};
this.simulation.nodes(nodes).on("tick", ticked);
this.simulation.force<d3.ForceLink<D3Node, D3Link>>("link").links(graph.edges);
@@ -634,20 +650,6 @@ export class D3ForceGraph implements GraphRenderer {
this.simulation.alpha(1).restart();
this.params.onGraphUpdated(new Date().getTime());
});
function ticked() {
self.linkSelection.select(".link").attr("d", (l: D3Link) => {
return self.positionLink(l);
});
if (!D3ForceGraph.useSvgMarkerEnd()) {
self.linkSelection.select(".markerEnd").attr("transform", (l: D3Link) => {
return self.positionLinkEnd(l);
});
}
self.nodeSelection.attr("transform", (d: D3Node) => {
return self.positionNode(d);
});
}
}
private addNewLinks(): d3.Selection<Element, any, any, any> {
@@ -677,7 +679,7 @@ export class D3ForceGraph implements GraphRenderer {
}
private addNewNodes(): d3.Selection<Element, any, any, any> {
var self = this;
const self = this;
const newNodes = this.nodeSelection
.enter()
@@ -705,7 +707,7 @@ export class D3ForceGraph implements GraphRenderer {
this.highlightNode(this, d);
this.simulation.stop();
})
.on("mouseout", (_: MouseEvent, d: D3Node) => {
.on("mouseout", () => {
if (this.isHighlightDisabled || this.selectedNode || this.isDragging) {
return;
}
@@ -726,7 +728,7 @@ export class D3ForceGraph implements GraphRenderer {
.attr("class", "main")
.attr("r", this.igraphConfig.nodeSize);
var iconGroup = newNodes
const iconGroup = newNodes
.append("g")
.attr("class", "iconContainer")
.attr("tabindex", 0)
@@ -749,8 +751,8 @@ export class D3ForceGraph implements GraphRenderer {
self.onNodeClicked(this.parentNode, d);
}
});
var nodeSize = this.igraphConfig.nodeSize;
var bgsize = nodeSize + 1;
const nodeSize = this.igraphConfig.nodeSize;
const bgsize = nodeSize + 1;
iconGroup
.append("rect")
@@ -758,7 +760,7 @@ export class D3ForceGraph implements GraphRenderer {
.attr("y", -bgsize)
.attr("width", bgsize * 2)
.attr("height", bgsize * 2)
.attr("fill-opacity", (d: D3Node) => {
.attr("fill-opacity", () => {
return this.igraphConfig.nodeIconKey ? 1 : 0;
})
.attr("class", "icon-background");
@@ -830,10 +832,10 @@ export class D3ForceGraph implements GraphRenderer {
self.loadNeighbors(d, PAGE_ACTION.NEXT_PAGE);
}
}) as any)
.on("mouseover", ((e: MouseEvent, d: D3Node) => {
.on("mouseover", ((e: MouseEvent) => {
select(e.target as any).classed("active", true);
}) as any)
.on("mouseout", ((e: MouseEvent, d: D3Node) => {
.on("mouseout", ((e: MouseEvent) => {
select(e.target as any).classed("active", false);
}) as any)
.attr("visibility", (d: D3Node) => (!d._outEAllLoaded || !d._inEAllLoaded ? "visible" : "hidden"));
@@ -859,10 +861,10 @@ export class D3ForceGraph implements GraphRenderer {
self.loadNeighbors(d, PAGE_ACTION.PREVIOUS_PAGE);
}
}) as any)
.on("mouseover", ((e: MouseEvent, d: D3Node) => {
.on("mouseover", ((e: MouseEvent) => {
select(e.target as any).classed("active", true);
}) as any)
.on("mouseout", ((e: MouseEvent, d: D3Node) => {
.on("mouseout", ((e: MouseEvent) => {
select(e.target as any).classed("active", false);
}) as any)
.attr("visibility", (d: D3Node) =>
@@ -955,10 +957,10 @@ export class D3ForceGraph implements GraphRenderer {
self.loadNeighbors(d, PAGE_ACTION.FIRST_PAGE);
}
}) as any)
.on("mouseover", ((e: MouseEvent, d: D3Node) => {
.on("mouseover", ((e: MouseEvent) => {
select(e.target as any).classed("active", true);
}) as any)
.on("mouseout", ((e: MouseEvent, d: D3Node) => {
.on("mouseout", ((e: MouseEvent) => {
select(e.target as any).classed("active", false);
}) as any);
}
@@ -967,10 +969,9 @@ export class D3ForceGraph implements GraphRenderer {
* Remove LoadMore subassembly for existing nodes that show all their children in the graph
*/
private updateLoadMore(nodeSelection: d3.Selection<Element, any, any, any>) {
const self = this;
nodeSelection.selectAll(".loadmore").remove();
var nodeSize = this.igraphConfig.nodeSize;
const nodeSize = this.igraphConfig.nodeSize;
const rootSelectionG = nodeSelection
.filter((d: D3Node) => {
return !!d._isRoot && !!d._pagination;
@@ -1090,7 +1091,7 @@ export class D3ForceGraph implements GraphRenderer {
private fadeNonNeighbors(nodeId: string) {
this.g.selectAll(".node").classed("inactive", (d: D3Node) => {
var neighbors = ((showNeighborType) => {
const neighbors = ((showNeighborType) => {
switch (showNeighborType) {
case NeighborType.SOURCES_ONLY:
return this.graphDataWrapper.getSourcesForId(nodeId);
@@ -1151,7 +1152,7 @@ export class D3ForceGraph implements GraphRenderer {
}
private retrieveNodeCaption(d: D3Node) {
let key = this.igraphConfig.nodeCaption;
const key = this.igraphConfig.nodeCaption;
let value: string = d.id || d.label;
if (key) {
value = <string>GraphData.getNodePropValue(d, key) || "";
@@ -1202,14 +1203,14 @@ export class D3ForceGraph implements GraphRenderer {
y: (<D3Node>l.target).y,
};
const d1 = D3ForceGraph.calculateControlPoint(source, target);
var radius = this.igraphConfig.nodeSize + 3;
const radius = this.igraphConfig.nodeSize + 3;
// End
const dx = target.x - d1.x;
const dy = target.y - d1.y;
const angle = Math.atan2(dy, dx);
var ux = target.x - Math.cos(angle) * radius;
var uy = target.y - Math.sin(angle) * radius;
const ux = target.x - Math.cos(angle) * radius;
const uy = target.y - Math.sin(angle) * radius;
return `translate(${ux},${uy}) rotate(${(angle * 180) / Math.PI})`;
}
@@ -1224,21 +1225,21 @@ export class D3ForceGraph implements GraphRenderer {
y: (<D3Node>l.target).y,
};
const d1 = D3ForceGraph.calculateControlPoint(source, target);
var radius = this.igraphConfig.nodeSize + 3;
const radius = this.igraphConfig.nodeSize + 3;
// Start
var dx = d1.x - source.x;
var dy = d1.y - source.y;
var angle = Math.atan2(dy, dx);
var tx = source.x + Math.cos(angle) * radius;
var ty = source.y + Math.sin(angle) * radius;
let dx = d1.x - source.x;
let dy = d1.y - source.y;
let angle = Math.atan2(dy, dx);
const tx = source.x + Math.cos(angle) * radius;
const ty = source.y + Math.sin(angle) * radius;
// End
dx = target.x - d1.x;
dy = target.y - d1.y;
angle = Math.atan2(dy, dx);
var ux = target.x - Math.cos(angle) * radius;
var uy = target.y - Math.sin(angle) * radius;
const ux = target.x - Math.cos(angle) * radius;
const uy = target.y - Math.sin(angle) * radius;
return "M" + tx + "," + ty + "S" + d1.x + "," + d1.y + " " + ux + "," + uy;
}
@@ -1260,9 +1261,9 @@ export class D3ForceGraph implements GraphRenderer {
}
private static computeImageData(d: D3Node, config: IGraphConfig): string {
let propValue = <string>GraphData.getNodePropValue(d, config.nodeIconKey) || "";
const propValue = <string>GraphData.getNodePropValue(d, config.nodeIconKey) || "";
// Trim leading and trailing spaces to make comparison more forgiving.
let value = config.iconsMap[propValue.trim()];
const value = config.iconsMap[propValue.trim()];
if (!value) {
return undefined;
}
@@ -1288,7 +1289,7 @@ export class D3ForceGraph implements GraphRenderer {
// clear icons
this.g.selectAll(".node .icon").attr("xlink:href", undefined);
}
this.g.selectAll(".node .icon-background").attr("fill-opacity", (d: D3Node) => {
this.g.selectAll(".node .icon-background").attr("fill-opacity", () => {
return config.nodeIconKey ? 1 : 0;
});
this.g.selectAll(".node text.caption").text((d: D3Node) => {

View File

@@ -307,18 +307,11 @@ function createOpenSynapseLinkDialogButton(container: Explorer): CommandButtonCo
function createNewDatabase(container: Explorer): CommandButtonComponentProps {
const label = "New " + getDatabaseName();
const newDatabaseButton = document.activeElement as HTMLElement;
return {
iconSrc: AddDatabaseIcon,
iconAlt: label,
onCommandClick: () =>
useSidePanel
.getState()
.openSidePanel(
"New " + getDatabaseName(),
<AddDatabasePanel explorer={container} buttonElement={newDatabaseButton} />
),
useSidePanel.getState().openSidePanel("New " + getDatabaseName(), <AddDatabasePanel explorer={container} />),
commandButtonLabel: label,
ariaLabel: label,
hasPopup: true,

View File

@@ -23,12 +23,10 @@ import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneFor
export interface AddDatabasePaneProps {
explorer: Explorer;
buttonElement?: HTMLElement;
}
export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
explorer: container,
buttonElement,
}: AddDatabasePaneProps) => {
const closeSidePanel = useSidePanel((state) => state.closeSidePanel);
let throughput: number;
@@ -79,7 +77,6 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
dataExplorerArea: Constants.Areas.ContextualPane,
};
TelemetryProcessor.trace(Action.CreateDatabase, ActionModifiers.Open, addDatabasePaneOpenMessage);
buttonElement.focus();
}, []);
const onSubmit = () => {

View File

@@ -307,23 +307,16 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
iconSrc: AddDatabaseIcon,
title: "New " + getDatabaseName(),
description: undefined,
onClick: () => this.openAddDatabasePanel(),
onClick: () =>
useSidePanel
.getState()
.openSidePanel("New " + getDatabaseName(), <AddDatabasePanel explorer={this.container} />),
});
}
return items;
}
private openAddDatabasePanel() {
const newDatabaseButton = document.activeElement as HTMLElement;
useSidePanel
.getState()
.openSidePanel(
"New " + getDatabaseName(),
<AddDatabasePanel explorer={this.container} buttonElement={newDatabaseButton} />
);
}
private decorateOpenCollectionActivity({ databaseId, collectionId }: MostRecentActivity.OpenCollectionItem) {
return {
iconSrc: NotebookIcon,

View File

@@ -202,14 +202,21 @@ export class CassandraAPIDataClient extends TableDataClient {
let updateQuery = `UPDATE ${collection.databaseId}.${collection.id()}`;
let isPropertyUpdated = false;
let isFirstPropertyToUpdate = true;
for (let property in newEntity) {
if (
!originalDocument[property] ||
newEntity[property]._.toString() !== originalDocument[property]._.toString()
) {
updateQuery += this.isStringType(newEntity[property].$)
? ` SET ${property} = '${newEntity[property]._}',`
: ` SET ${property} = ${newEntity[property]._},`;
let propertyQuerySegment = this.isStringType(newEntity[property].$)
? `${property} = '${newEntity[property]._}',`
: `${property} = ${newEntity[property]._},`;
// Only add the "SET" keyword once
if (isFirstPropertyToUpdate) {
propertyQuerySegment = " SET " + propertyQuerySegment;
isFirstPropertyToUpdate = false;
}
updateQuery += propertyQuerySegment;
isPropertyUpdated = true;
}
}

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as ViewModels from "../../Contracts/ViewModels";
import * as Constants from "./Constants";
import * as Entities from "./Entities";
@@ -17,12 +16,12 @@ enum DataTypes {
Int64 = 18,
}
const tablesIndexers = {
var tablesIndexers = {
Value: "$v",
Type: "$t",
};
export const keyProperties = {
export var keyProperties = {
PartitionKey: "$pk",
Id: "id",
Id2: "$id", // This should always be the same value as Id
@@ -34,17 +33,14 @@ export const keyProperties = {
};
export function convertDocumentsToEntities(documents: any[]): Entities.ITableEntityForTablesAPI[] {
const results: Entities.ITableEntityForTablesAPI[] = [];
let results: Entities.ITableEntityForTablesAPI[] = [];
documents &&
documents.forEach((document) => {
if (
!Object.prototype.hasOwnProperty.call(document, keyProperties.PartitionKey) ||
Object.prototype.hasOwnProperty.call(document, keyProperties.Id)
) {
if (!document.hasOwnProperty(keyProperties.PartitionKey) || !document.hasOwnProperty(keyProperties.Id)) {
//Document does not match the current required format for Tables, so we ignore it
return; // The rest of the key properties should be guaranteed as DocumentDB properties
}
const entity: Entities.ITableEntityForTablesAPI = <Entities.ITableEntityForTablesAPI>{
let entity: Entities.ITableEntityForTablesAPI = <Entities.ITableEntityForTablesAPI>{
PartitionKey: {
_: document[keyProperties.PartitionKey],
$: Constants.TableType.String,
@@ -75,8 +71,8 @@ export function convertDocumentsToEntities(documents: any[]): Entities.ITableEnt
$: Constants.TableType.String,
},
};
for (const property in document) {
if (Object.prototype.hasOwnProperty.call(document, property)) {
for (var property in document) {
if (document.hasOwnProperty(property)) {
if (
property !== keyProperties.PartitionKey &&
property !== keyProperties.Id &&
@@ -87,10 +83,7 @@ export function convertDocumentsToEntities(documents: any[]): Entities.ITableEnt
property !== keyProperties.attachments &&
property !== keyProperties.Id2
) {
if (
!Object.prototype.hasOwnProperty.call(document[property], "$v") ||
!Object.prototype.hasOwnProperty.call(document[property], "$t")
) {
if (!document[property].hasOwnProperty("$v") || !document[property].hasOwnProperty("$t")) {
return; //Document property does not match the current required format for Tables, so we ignore it
}
if (DataTypes[document[property][tablesIndexers.Type]] === DataTypes[DataTypes.DateTime]) {
@@ -118,10 +111,10 @@ export function convertEntitiesToDocuments(
entities: Entities.ITableEntityForTablesAPI[],
collection: ViewModels.Collection
): any[] {
const results: any[] = [];
let results: any[] = [];
entities &&
entities.forEach((entity) => {
const document: any = {
let document: any = {
$id: entity.RowKey._,
id: entity.RowKey._,
ts: DateTimeUtilities.convertJSDateToUnix(entity.Timestamp._), // Convert back to unix time
@@ -136,7 +129,7 @@ export function convertEntitiesToDocuments(
document[collection.partitionKeyProperty] = entity.PartitionKey._;
document["partitionKeyValue"] = entity.PartitionKey._;
}
for (const property in entity) {
for (var property in entity) {
if (
property !== Constants.EntityKeyNames.PartitionKey &&
property !== Constants.EntityKeyNames.RowKey &&
@@ -167,7 +160,7 @@ export function convertEntitiesToDocuments(
}
export function convertEntityToNewDocument(entity: Entities.ITableEntityForTablesAPI): any {
const document: any = {
let document: any = {
$pk: entity.PartitionKey._,
$id: entity.RowKey._,
id: entity.RowKey._,

View File

@@ -92,7 +92,7 @@ export default class DocumentsTab extends TabsBase {
this.partitionKeyPropertyHeader =
(this.collection && this.collection.partitionKeyPropertyHeader) || this._getPartitionKeyPropertyHeader();
this.partitionKeyProperty = this.partitionKeyPropertyHeader
this.partitionKeyProperty = !!this.partitionKeyPropertyHeader
? this.partitionKeyPropertyHeader.replace(/[/]+/g, ".").substr(1).replace(/[']+/g, "")
: null;
@@ -446,8 +446,8 @@ export default class DocumentsTab extends TabsBase {
this.partitionKey as PartitionKeyDefinition
);
const partitionKeyValue = partitionKeyValueArray && partitionKeyValueArray[0];
const id = new DocumentId(this, savedDocument, partitionKeyValue);
const ids = this.documentIds();
let id = new DocumentId(this, savedDocument, partitionKeyValue);
let ids = this.documentIds();
ids.push(id);
this.selectedDocumentId(id);
@@ -682,10 +682,10 @@ export default class DocumentsTab extends TabsBase {
}
public createIterator(): QueryIterator<ItemDefinition & Resource> {
const filters = this.lastFilterContents();
let filters = this.lastFilterContents();
const filter: string = this.filterContent().trim();
const query: string = this.buildQuery(filter);
const options: any = {};
let options: any = {};
options.enableCrossPartitionQuery = HeadersUtility.shouldEnableCrossPartitionKey();
if (this._resourceTokenPartitionKey) {
@@ -778,7 +778,7 @@ export default class DocumentsTab extends TabsBase {
protected _onEditorContentChange(newContent: string) {
try {
const parsed: any = JSON.parse(newContent);
let parsed: any = JSON.parse(newContent);
this.onValidDocumentEdit();
} catch (e) {
this.onInvalidDocumentEdit();

View File

@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { extractPartitionKey, PartitionKeyDefinition } from "@azure/cosmos";
import * as ko from "knockout";
import Q from "q";
@@ -46,7 +44,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
super.buildCommandBarOptions();
}
public onSaveNewDocumentClick = (): Promise<void> => {
public onSaveNewDocumentClick = (): Promise<any> => {
const documentContent = JSON.parse(this.selectedDocumentContent());
this.displayedError("");
const startKey: number = TelemetryProcessor.traceStart(Action.CreateDocument, {
@@ -61,8 +59,9 @@ export default class MongoDocumentsTab extends DocumentsTab {
) {
const message = `The document is lacking the shard property: ${this.partitionKeyProperty}`;
this.displayedError(message);
let that = this;
setTimeout(() => {
this.displayedError("");
that.displayedError("");
}, Constants.ClientDefaults.errorNotificationTimeoutMs);
this.isExecutionError(true);
TelemetryProcessor.traceFailure(
@@ -83,19 +82,19 @@ export default class MongoDocumentsTab extends DocumentsTab {
return createDocument(this.collection.databaseId, this.collection, this.partitionKeyProperty, documentContent)
.then(
(savedDocument: any) => {
const partitionKeyArray = extractPartitionKey(
let partitionKeyArray = extractPartitionKey(
savedDocument,
this._getPartitionKeyDefinition() as PartitionKeyDefinition
);
const partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
let partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
const id = new ObjectId(this, savedDocument, partitionKeyValue);
const ids = this.documentIds();
let id = new ObjectId(this, savedDocument, partitionKeyValue);
let ids = this.documentIds();
ids.push(id);
delete savedDocument._self;
const value: string = this.renderObjectForEditor(savedDocument || {}, null, 4);
let value: string = this.renderObjectForEditor(savedDocument || {}, null, 4);
this.selectedDocumentContent.setBaseline(value);
this.selectedDocumentId(id);
@@ -129,7 +128,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
.finally(() => this.isExecuting(false));
};
public onSaveExisitingDocumentClick = (): Promise<void> => {
public onSaveExisitingDocumentClick = (): Promise<any> => {
const selectedDocumentId = this.selectedDocumentId();
const documentContent = this.selectedDocumentContent();
this.isExecutionError(false);
@@ -142,7 +141,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
return updateDocument(this.collection.databaseId, this.collection, selectedDocumentId, documentContent)
.then(
(updatedDocument: any) => {
const value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
let value: string = this.renderObjectForEditor(updatedDocument || {}, null, 4);
this.selectedDocumentContent.setBaseline(value);
this.documentIds().forEach((documentId: DocumentId) => {
@@ -152,7 +151,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
this._getPartitionKeyDefinition() as PartitionKeyDefinition
);
const partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
let partitionKeyValue = partitionKeyArray && partitionKeyArray[0];
const id = new ObjectId(this, updatedDocument, partitionKeyValue);
documentId.id(id.id());
@@ -197,7 +196,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
this.initDocumentEditor(documentId, content);
}
public loadNextPage(): Q.Promise<void> {
public loadNextPage(): Q.Promise<any> {
this.isExecuting(true);
this.isExecutionError(false);
const filter: string = this.filterContent().trim();
@@ -229,7 +228,7 @@ export default class MongoDocumentsTab extends DocumentsTab {
this.selectedDocumentId(null);
this.editorState(ViewModels.DocumentExplorerState.noDocumentSelected);
}
if (this.onLoadStartKey !== null && this.onLoadStartKey !== undefined) {
if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) {
TelemetryProcessor.traceSuccess(
Action.Tab,
{
@@ -244,8 +243,8 @@ export default class MongoDocumentsTab extends DocumentsTab {
this.onLoadStartKey = null;
}
},
(error: Error) => {
if (this.onLoadStartKey !== null && this.onLoadStartKey !== undefined) {
(error: any) => {
if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) {
TelemetryProcessor.traceFailure(
Action.Tab,
{
@@ -266,13 +265,13 @@ export default class MongoDocumentsTab extends DocumentsTab {
.finally(() => this.isExecuting(false));
}
protected _onEditorContentChange(newContent: string): void {
protected _onEditorContentChange(newContent: string) {
try {
if (
this.editorState() === ViewModels.DocumentExplorerState.newDocumentValid ||
this.editorState() === ViewModels.DocumentExplorerState.newDocumentInvalid
) {
const 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