mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-21 11:47:14 +00:00
Merge branch 'master' of https://github.com/Azure/cosmos-explorer into resolve_Constants
This commit is contained in:
commit
f9780ff3ad
@ -81,17 +81,13 @@ src/Explorer/Tables/DataTable/DataTableBindingManager.ts
|
||||
src/Explorer/Tables/DataTable/DataTableBuilder.ts
|
||||
src/Explorer/Tables/DataTable/DataTableContextMenu.ts
|
||||
src/Explorer/Tables/DataTable/DataTableOperationManager.ts
|
||||
src/Explorer/Tables/DataTable/DataTableOperations.ts
|
||||
# src/Explorer/Tables/DataTable/DataTableOperations.ts
|
||||
src/Explorer/Tables/DataTable/DataTableViewModel.ts
|
||||
src/Explorer/Tables/DataTable/TableCommands.ts
|
||||
src/Explorer/Tables/DataTable/TableEntityCache.ts
|
||||
# src/Explorer/Tables/DataTable/TableCommands.ts
|
||||
# src/Explorer/Tables/DataTable/TableEntityCache.ts
|
||||
src/Explorer/Tables/DataTable/TableEntityListViewModel.ts
|
||||
src/Explorer/Tables/Entities.ts
|
||||
src/Explorer/Tables/QueryBuilder/ClauseGroup.ts
|
||||
src/Explorer/Tables/QueryBuilder/ClauseGroupViewModel.ts
|
||||
# src/Explorer/Tables/Entities.ts
|
||||
src/Explorer/Tables/QueryBuilder/CustomTimestampHelper.ts
|
||||
src/Explorer/Tables/QueryBuilder/QueryBuilderViewModel.ts
|
||||
src/Explorer/Tables/QueryBuilder/QueryClauseViewModel.ts
|
||||
src/Explorer/Tables/TableDataClient.ts
|
||||
src/Explorer/Tables/TableEntityProcessor.ts
|
||||
src/Explorer/Tables/Utilities.ts
|
||||
@ -115,15 +111,10 @@ src/Explorer/Tree/ObjectId.ts
|
||||
src/Explorer/Tree/ResourceTokenCollection.ts
|
||||
src/Explorer/Tree/StoredProcedure.ts
|
||||
src/Explorer/Tree/TreeComponents.ts
|
||||
src/Explorer/Tree/Trigger.ts
|
||||
src/Explorer/WaitsForTemplateViewModel.ts
|
||||
src/GitHub/GitHubClient.test.ts
|
||||
src/GitHub/GitHubClient.ts
|
||||
src/GitHub/GitHubConnector.ts
|
||||
src/GitHub/GitHubOAuthService.ts
|
||||
src/Index.ts
|
||||
src/Juno/JunoClient.test.ts
|
||||
src/Juno/JunoClient.ts
|
||||
src/Platform/Hosted/Authorization.ts
|
||||
src/ReactDevTools.ts
|
||||
src/Shared/Constants.ts
|
||||
@ -143,7 +134,7 @@ src/Explorer/Controls/Notebook/NotebookTerminalComponent.tsx
|
||||
src/Explorer/Controls/NotebookViewer/NotebookViewerComponent.tsx
|
||||
src/Explorer/Controls/TreeComponent/TreeComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/GraphExplorer.test.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/GraphExplorer.tsx
|
||||
; src/Explorer/Graph/GraphExplorerComponent/GraphExplorer.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/GraphVizComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/LeftPaneComponent.tsx
|
||||
src/Explorer/Graph/GraphExplorerComponent/MiddlePaneComponent.tsx
|
||||
@ -153,10 +144,10 @@ src/Explorer/Graph/GraphExplorerComponent/ReadOnlyNodePropertiesComponent.test.t
|
||||
src/Explorer/Graph/GraphExplorerComponent/ReadOnlyNodePropertiesComponent.tsx
|
||||
src/Explorer/Menus/CommandBar/CommandBarUtil.tsx
|
||||
src/Explorer/Notebook/NotebookComponent/NotebookComponentAdapter.tsx
|
||||
src/Explorer/Notebook/NotebookComponent/NotebookComponentBootstrapper.tsx
|
||||
; src/Explorer/Notebook/NotebookComponent/NotebookComponentBootstrapper.tsx
|
||||
src/Explorer/Notebook/NotebookComponent/VirtualCommandBarComponent.tsx
|
||||
src/Explorer/Notebook/NotebookComponent/contents/index.tsx
|
||||
src/Explorer/Notebook/NotebookRenderer/NotebookReadOnlyRenderer.tsx
|
||||
; src/Explorer/Notebook/NotebookRenderer/NotebookReadOnlyRenderer.tsx
|
||||
src/Explorer/Notebook/NotebookRenderer/NotebookRenderer.tsx
|
||||
src/Explorer/Notebook/NotebookRenderer/decorators/draggable/index.tsx
|
||||
src/Explorer/Notebook/NotebookRenderer/decorators/hijack-scroll/index.tsx
|
||||
|
@ -39,7 +39,6 @@ module.exports = {
|
||||
"@typescript-eslint/switch-exhaustiveness-check": "error",
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
"@typescript-eslint/no-extraneous-class": "error",
|
||||
"no-null/no-null": "error",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"prefer-arrow/prefer-arrow-functions": ["error", { allowStandaloneDeclarations: true }],
|
||||
eqeqeq: "error",
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -22,5 +22,6 @@
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true,
|
||||
"source.organizeImports": true
|
||||
}
|
||||
},
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative"
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ module.exports = {
|
||||
global: {
|
||||
branches: 25,
|
||||
functions: 25,
|
||||
lines: 29.5,
|
||||
statements: 29.5,
|
||||
lines: 29,
|
||||
statements: 29,
|
||||
},
|
||||
},
|
||||
|
||||
@ -129,6 +129,8 @@ module.exports = {
|
||||
// The test environment that will be used for testing
|
||||
// testEnvironment: "jest-environment-jsdom",
|
||||
|
||||
modulePaths: ["node_modules", "<rootDir>/src"],
|
||||
|
||||
// Options that will be passed to the testEnvironment
|
||||
// testEnvironmentOptions: {},
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { FeedOptions, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
||||
import * as Q from "q";
|
||||
import * as React from "react";
|
||||
@ -294,8 +296,6 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
this.setGremlinParams();
|
||||
}
|
||||
|
||||
const selectedNode = this.state.highlightedNode;
|
||||
|
||||
props.onGraphAccessorCreated({
|
||||
applyFilter: this.submitQuery.bind(this),
|
||||
addVertex: this.addVertex.bind(this),
|
||||
@ -303,7 +303,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
});
|
||||
} // constructor
|
||||
|
||||
public shareIGraphConfig(igraphConfig: IGraphConfig) {
|
||||
public shareIGraphConfig(igraphConfig: IGraphConfig): void {
|
||||
this.setState({
|
||||
igraphConfig: { ...igraphConfig },
|
||||
});
|
||||
@ -330,10 +330,10 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
const partitionKeyProperty = this.props.collectionPartitionKeyProperty;
|
||||
|
||||
// aggregate all the properties, remove dropped ones
|
||||
let finalProperties = editedProperties.existingProperties.concat(editedProperties.addedProperties);
|
||||
const finalProperties = editedProperties.existingProperties.concat(editedProperties.addedProperties);
|
||||
|
||||
// Compose the query
|
||||
let pkId = editedProperties.pkId;
|
||||
const pkId = editedProperties.pkId;
|
||||
let updateQueryFragment = "";
|
||||
|
||||
finalProperties.forEach((p) => {
|
||||
@ -422,7 +422,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
* Called from ko binding
|
||||
* @param id
|
||||
*/
|
||||
public selectNode(id: string) {
|
||||
public selectNode(id: string): void {
|
||||
if (!this.d3ForceGraph) {
|
||||
console.warn("Attempting to select node, but d3ForceGraph not initialized, yet.");
|
||||
return;
|
||||
@ -431,7 +431,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
this.d3ForceGraph.selectNode(id);
|
||||
}
|
||||
|
||||
public deleteHighlightedNode() {
|
||||
public deleteHighlightedNode(): void {
|
||||
if (!this.state.highlightedNode) {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, "No highlighted node to remove.");
|
||||
return;
|
||||
@ -467,23 +467,23 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
* Is of type: {e: GremlinEdge, v: GremlinVertex}[]
|
||||
* @param data
|
||||
*/
|
||||
public static isEdgeVertexPairArray(data: any) {
|
||||
public static isEdgeVertexPairArray(data: any): boolean {
|
||||
if (!(data instanceof Array)) {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Info, "Query result not an array", data);
|
||||
return false;
|
||||
}
|
||||
|
||||
let pairs: any[] = data;
|
||||
const pairs: any[] = data;
|
||||
for (let i = 0; i < pairs.length; i++) {
|
||||
const item = pairs[i];
|
||||
if (
|
||||
!item.hasOwnProperty("e") ||
|
||||
!item.hasOwnProperty("v") ||
|
||||
!item["e"].hasOwnProperty("id") ||
|
||||
!item["e"].hasOwnProperty("type") ||
|
||||
!Object.prototype.hasOwnProperty.call(item, "e") ||
|
||||
!Object.prototype.hasOwnProperty.call(item, "v") ||
|
||||
!Object.prototype.hasOwnProperty.call(item["e"], "id") ||
|
||||
!Object.prototype.hasOwnProperty.call(item["e"], "type") ||
|
||||
item["e"].type !== "edge" ||
|
||||
!item["v"].hasOwnProperty("id") ||
|
||||
!item["v"].hasOwnProperty("type") ||
|
||||
!Object.prototype.hasOwnProperty.call(item["v"], "id") ||
|
||||
!Object.prototype.hasOwnProperty.call(item["e"], "type") ||
|
||||
item["v"].type !== "vertex"
|
||||
) {
|
||||
return false;
|
||||
@ -514,7 +514,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
// Try hitting cache first
|
||||
const cache = outE ? this.outECache : this.inECache;
|
||||
const pairs = cache.retrieve(vertex.id, startIndex, pageSize);
|
||||
if (pairs != null && pairs.length === pageSize) {
|
||||
if (pairs !== null && pairs.length === pageSize) {
|
||||
const msg = `Retrieved ${pairs.length} ${outE ? "outE" : "inE"} edges from cache for vertex id: ${vertex.id}`;
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Info, msg);
|
||||
return Q.resolve(pairs);
|
||||
@ -588,7 +588,6 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
vertex._outEAllLoaded &&
|
||||
vertex._inEAllLoaded
|
||||
) {
|
||||
console.info("No more edges to load for vertex " + vertex.id);
|
||||
updateGraphData();
|
||||
return Q.resolve(graphData);
|
||||
}
|
||||
@ -668,7 +667,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
}
|
||||
);
|
||||
|
||||
return promise.then((nbPairsFetched: number) => {
|
||||
return promise.then(() => {
|
||||
if (offsetIndex >= GraphExplorer.LOAD_PAGE_SIZE || !vertex._outEAllLoaded || !vertex._inEAllLoaded) {
|
||||
vertex._pagination = {
|
||||
total:
|
||||
@ -754,7 +753,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
* Create a new edge in docdb and update graph
|
||||
* @param e
|
||||
*/
|
||||
public createNewEdge(e: GraphNewEdgeData): Q.Promise<any> {
|
||||
public createNewEdge(e: GraphNewEdgeData): Q.Promise<unknown> {
|
||||
const q = `g.V('${GraphUtil.escapeSingleQuotes(e.inputOutV)}').addE('${GraphUtil.escapeSingleQuotes(
|
||||
e.label
|
||||
)}').To(g.V('${GraphUtil.escapeSingleQuotes(e.inputInV)}'))`;
|
||||
@ -772,8 +771,8 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
return;
|
||||
}
|
||||
|
||||
let edge = edges[0];
|
||||
let graphData = this.originalGraphData;
|
||||
const edge = edges[0];
|
||||
const graphData = this.originalGraphData;
|
||||
graphData.addEdge(edge);
|
||||
|
||||
// Allow loadNeighbors to load list new edge
|
||||
@ -800,10 +799,10 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
* Manually update in-memory graph.
|
||||
* @param edgeId
|
||||
*/
|
||||
public removeEdge(edgeId: string): Q.Promise<any> {
|
||||
public removeEdge(edgeId: string): Q.Promise<unknown> {
|
||||
return this.submitToBackend(`g.E('${GraphUtil.escapeSingleQuotes(edgeId)}').drop()`).then(
|
||||
() => {
|
||||
let graphData = this.originalGraphData;
|
||||
const graphData = this.originalGraphData;
|
||||
graphData.removeEdge(edgeId, false);
|
||||
this.updateGraphData(graphData, this.state.igraphConfig);
|
||||
},
|
||||
@ -826,10 +825,14 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
return false;
|
||||
}
|
||||
|
||||
let vertices: any[] = data;
|
||||
const vertices: any[] = data;
|
||||
if (vertices.length > 0) {
|
||||
let v0 = vertices[0];
|
||||
if (!v0.hasOwnProperty("id") || !v0.hasOwnProperty("type") || v0.type !== "vertex") {
|
||||
const v0 = vertices[0];
|
||||
if (
|
||||
!Object.prototype.hasOwnProperty.call(v0, "id") ||
|
||||
!Object.prototype.hasOwnProperty.call(v0, "type") ||
|
||||
v0.type !== "vertex"
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -837,7 +840,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
}
|
||||
|
||||
public processGremlinQueryResults(result: GremlinClient.GremlinRequestResult): void {
|
||||
const data = result.data as any;
|
||||
const data = result.data as GraphData.GremlinVertex[];
|
||||
this.setFilterQueryStatus(FilterQueryStatus.GraphEmptyResult);
|
||||
|
||||
if (data === null) {
|
||||
@ -927,13 +930,13 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
throw { title: err };
|
||||
}
|
||||
|
||||
if (vertices == null || vertices.length < 1) {
|
||||
if (vertices === null || vertices.length < 1) {
|
||||
const err = "Failed to create vertex (no vertex in response)";
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, err, vertices);
|
||||
throw { title: err };
|
||||
}
|
||||
|
||||
let vertex = vertices[0];
|
||||
const vertex = vertices[0];
|
||||
const graphData = this.originalGraphData;
|
||||
graphData.addVertex(vertex);
|
||||
this.updateGraphData(graphData, this.state.igraphConfig);
|
||||
@ -1022,7 +1025,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
this.gremlinClient.destroy();
|
||||
}
|
||||
public componentDidMount(): void {
|
||||
if (this.props.onLoadStartKey != null && this.props.onLoadStartKey != undefined) {
|
||||
if (this.props.onLoadStartKey !== null && this.props.onLoadStartKey !== undefined) {
|
||||
TelemetryProcessor.traceSuccess(
|
||||
Action.Tab,
|
||||
{
|
||||
@ -1082,7 +1085,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
public static reportToConsole(type: ConsoleDataType.Info, msg: string, ...errorData: any[]): void;
|
||||
public static reportToConsole(type: ConsoleDataType.Error, msg: string, ...errorData: any[]): void;
|
||||
public static reportToConsole(type: ConsoleDataType, msg: string, ...errorData: any[]): void | (() => void) {
|
||||
let errorDataStr: string = "";
|
||||
let errorDataStr = "";
|
||||
if (errorData && errorData.length > 0) {
|
||||
console.error(msg, errorData);
|
||||
errorDataStr = ": " + JSON.stringify(errorData);
|
||||
@ -1161,12 +1164,15 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
)}"`
|
||||
).then(
|
||||
(documents: DataModels.DocumentId[]) => {
|
||||
$.each(documents, (index: number, doc: any) => {
|
||||
newIconsMap[doc["_graph_icon_property_value"]] = {
|
||||
data: doc["icon"],
|
||||
format: doc["format"],
|
||||
};
|
||||
});
|
||||
$.each(
|
||||
documents,
|
||||
(index: number, doc: { _graph_icon_property_value: string; icon: string; format: string }) => {
|
||||
newIconsMap[doc["_graph_icon_property_value"]] = {
|
||||
data: doc["icon"],
|
||||
format: doc["format"],
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// Update graph configuration
|
||||
this.setState({
|
||||
@ -1223,8 +1229,8 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
const key = this.state.igraphConfig.nodeCaption;
|
||||
return $.map(
|
||||
this.state.rootMap,
|
||||
(value: any, index: number): LeftPane.CaptionId => {
|
||||
let result = GraphData.GraphData.getNodePropValue(value, key);
|
||||
(value: any): LeftPane.CaptionId => {
|
||||
const result = GraphData.GraphData.getNodePropValue(value, key);
|
||||
return {
|
||||
caption: result !== undefined ? result : value.id,
|
||||
id: value.id,
|
||||
@ -1237,7 +1243,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
* Selecting a root node means
|
||||
* @param node
|
||||
*/
|
||||
private selectRootNode(id: string): Q.Promise<any> {
|
||||
private selectRootNode(id: string): Q.Promise<unknown> {
|
||||
if (!this.d3ForceGraph) {
|
||||
console.warn("Attempting to reset zoom, but d3ForceGraph not initialized, yet.");
|
||||
} else {
|
||||
@ -1282,7 +1288,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
this.collectNodeProperties(this.originalGraphData.vertices);
|
||||
this.updatePropertiesPane(id);
|
||||
},
|
||||
(reason: any) => {
|
||||
(reason: string) => {
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, `Failed to select root node. Reason:${reason}`);
|
||||
}
|
||||
);
|
||||
@ -1349,10 +1355,10 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
private getPkIdFromVertex(v: GraphData.GremlinVertex): string {
|
||||
if (
|
||||
this.props.collectionPartitionKeyProperty &&
|
||||
v.hasOwnProperty("properties") &&
|
||||
v.properties.hasOwnProperty(this.props.collectionPartitionKeyProperty) &&
|
||||
Object.prototype.hasOwnProperty.call(v, "properties") &&
|
||||
Object.prototype.hasOwnProperty.call(v.properties, this.props.collectionPartitionKeyProperty) &&
|
||||
v.properties[this.props.collectionPartitionKeyProperty].length > 0 &&
|
||||
v.properties[this.props.collectionPartitionKeyProperty][0].hasOwnProperty("value")
|
||||
Object.prototype.hasOwnProperty.call(v.properties[this.props.collectionPartitionKeyProperty][0], "value")
|
||||
) {
|
||||
const pk = v.properties[this.props.collectionPartitionKeyProperty][0].value;
|
||||
return GraphExplorer.generatePkIdPair(pk, v.id);
|
||||
@ -1370,8 +1376,8 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
private getPkIdFromNodeData(v: GraphHighlightedNodeData): string {
|
||||
if (
|
||||
this.props.collectionPartitionKeyProperty &&
|
||||
v.hasOwnProperty("properties") &&
|
||||
v.properties.hasOwnProperty(this.props.collectionPartitionKeyProperty)
|
||||
Object.prototype.hasOwnProperty.call(v, "properties") &&
|
||||
Object.prototype.hasOwnProperty.call(v.properties, this.props.collectionPartitionKeyProperty)
|
||||
) {
|
||||
const pk = v.properties[this.props.collectionPartitionKeyProperty];
|
||||
return GraphExplorer.generatePkIdPair(pk[0] as PartitionKeyValueType, v.id);
|
||||
@ -1388,14 +1394,14 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
* @return id
|
||||
*/
|
||||
public static getPkIdFromDocumentId(d: DataModels.DocumentId, collectionPartitionKeyProperty: string): string {
|
||||
let { id } = d;
|
||||
const { id } = d;
|
||||
if (typeof id !== "string") {
|
||||
const error = `Vertex id is not a string: ${JSON.stringify(id)}.`;
|
||||
logConsoleError(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
if (collectionPartitionKeyProperty && d.hasOwnProperty(collectionPartitionKeyProperty)) {
|
||||
if (collectionPartitionKeyProperty && Object.prototype.hasOwnProperty.call(d, collectionPartitionKeyProperty)) {
|
||||
let pk = (d as any)[collectionPartitionKeyProperty];
|
||||
if (typeof pk !== "string" && typeof pk !== "number" && typeof pk !== "boolean") {
|
||||
if (Array.isArray(pk) && pk.length > 0) {
|
||||
@ -1425,7 +1431,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
}"] AS p FROM c WHERE NOT IS_DEFINED(c._isEdge)`;
|
||||
return this.executeNonPagedDocDbQuery(q).then(
|
||||
(documents: DataModels.DocumentId[]) => {
|
||||
let possibleVertices = [] as PossibleVertex[];
|
||||
const possibleVertices = [] as PossibleVertex[];
|
||||
$.each(documents, (index: number, item: any) => {
|
||||
if (highlightedNodeId && item.id === highlightedNodeId) {
|
||||
// Exclude highlighed node in the list
|
||||
@ -1439,7 +1445,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
caption: item.p,
|
||||
});
|
||||
} else {
|
||||
if (item.hasOwnProperty("p")) {
|
||||
if (Object.prototype.hasOwnProperty.call(item, "p")) {
|
||||
possibleVertices.push({
|
||||
value: item.id,
|
||||
caption: item.p[0]["_value"],
|
||||
@ -1462,17 +1468,17 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
* @param addedEdges
|
||||
* @return promise when done
|
||||
*/
|
||||
private editGraphEdges(editedEdges: EditedEdges): Q.Promise<any> {
|
||||
let promises = [];
|
||||
private editGraphEdges(editedEdges: EditedEdges): Q.Promise<unknown> {
|
||||
const promises = [];
|
||||
// Drop edges
|
||||
for (let i = 0; i < editedEdges.droppedIds.length; i++) {
|
||||
let id = editedEdges.droppedIds[i];
|
||||
const id = editedEdges.droppedIds[i];
|
||||
promises.push(this.removeEdge(id));
|
||||
}
|
||||
|
||||
// Add edges
|
||||
for (let i = 0; i < editedEdges.addedEdges.length; i++) {
|
||||
let e = editedEdges.addedEdges[i];
|
||||
const e = editedEdges.addedEdges[i];
|
||||
promises.push(
|
||||
this.createNewEdge(e).then(() => {
|
||||
// Reload neighbors in case we linked to a vertex that isn't loaded in the graph
|
||||
@ -1525,7 +1531,9 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
/**
|
||||
* For unit testing purposes
|
||||
*/
|
||||
public onGraphUpdated(timestamp: number): void {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public onGraphUpdated(_timestamp: number): void {}
|
||||
|
||||
/**
|
||||
* Get node properties for styling purposes. Result is the union of all properties of all nodes.
|
||||
@ -1533,17 +1541,17 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
private collectNodeProperties(vertices: GraphData.GremlinVertex[]) {
|
||||
const props = {} as any; // Hashset
|
||||
$.each(vertices, (index: number, item: GraphData.GremlinVertex) => {
|
||||
for (var p in item) {
|
||||
for (const p in item) {
|
||||
// DocDB: Exclude type because it's always 'vertex'
|
||||
if (p !== "type" && typeof (item as any)[p] === "string") {
|
||||
props[p] = true;
|
||||
}
|
||||
}
|
||||
// Inspect properties
|
||||
if (item.hasOwnProperty("properties")) {
|
||||
if (Object.prototype.hasOwnProperty.call(item, "properties")) {
|
||||
// TODO This is DocDB-graph specific
|
||||
// Assume each property value is [{value:... }]
|
||||
for (var f in item.properties) {
|
||||
for (const f in item.properties) {
|
||||
props[f] = true;
|
||||
}
|
||||
}
|
||||
@ -1570,21 +1578,21 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
return;
|
||||
}
|
||||
|
||||
let data = this.originalGraphData.getVertexById(id);
|
||||
const data = this.originalGraphData.getVertexById(id);
|
||||
|
||||
// A bit of translation to make it easier to display
|
||||
let props: { [id: string]: ViewModels.GremlinPropertyValueType[] } = {};
|
||||
for (let p in data.properties) {
|
||||
const props: { [id: string]: ViewModels.GremlinPropertyValueType[] } = {};
|
||||
for (const p in data.properties) {
|
||||
props[p] = data.properties[p].map((gremlinProperty) => gremlinProperty.value);
|
||||
}
|
||||
|
||||
// update neighbors
|
||||
let sources: NeighborVertexBasicInfo[] = [];
|
||||
let targets: NeighborVertexBasicInfo[] = [];
|
||||
const sources: NeighborVertexBasicInfo[] = [];
|
||||
const targets: NeighborVertexBasicInfo[] = [];
|
||||
this.props.onResetDefaultGraphConfigValues();
|
||||
let nodeCaption = this.state.igraphConfigUiData.nodeCaptionChoice;
|
||||
const nodeCaption = this.state.igraphConfigUiData.nodeCaptionChoice;
|
||||
this.updateSelectedNodeNeighbors(data.id, nodeCaption, sources, targets);
|
||||
let sData: GraphHighlightedNodeData = {
|
||||
const sData: GraphHighlightedNodeData = {
|
||||
id: data.id,
|
||||
label: data.label,
|
||||
properties: props,
|
||||
@ -1611,16 +1619,16 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
targets: NeighborVertexBasicInfo[]
|
||||
): void {
|
||||
// update neighbors
|
||||
let gd = this.originalGraphData;
|
||||
let v = gd.getVertexById(id);
|
||||
const gd = this.originalGraphData;
|
||||
const v = gd.getVertexById(id);
|
||||
|
||||
// Clear the array while keeping the references
|
||||
sources.length = 0;
|
||||
targets.length = 0;
|
||||
|
||||
let possibleEdgeLabels = {} as any; // Collect all edge labels in a hashset
|
||||
const possibleEdgeLabels = {} as any; // Collect all edge labels in a hashset
|
||||
|
||||
for (let p in v.inE) {
|
||||
for (const p in v.inE) {
|
||||
possibleEdgeLabels[p] = true;
|
||||
const edges = v.inE[p];
|
||||
$.each(edges, (index: number, edge: GraphData.GremlinShortInEdge) => {
|
||||
@ -1629,7 +1637,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
// If id not known, it must be an edge node whose neighbor hasn't been loaded into the graph, yet
|
||||
return;
|
||||
}
|
||||
let caption = GraphData.GraphData.getNodePropValue(gd.getVertexById(neighborId), nodeCaption) as string;
|
||||
const caption = GraphData.GraphData.getNodePropValue(gd.getVertexById(neighborId), nodeCaption) as string;
|
||||
sources.push({
|
||||
name: caption,
|
||||
id: neighborId,
|
||||
@ -1639,7 +1647,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
});
|
||||
}
|
||||
|
||||
for (let p in v.outE) {
|
||||
for (const p in v.outE) {
|
||||
possibleEdgeLabels[p] = true;
|
||||
const edges = v.outE[p];
|
||||
$.each(edges, (index: number, edge: GraphData.GremlinShortOutEdge) => {
|
||||
@ -1648,7 +1656,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
// If id not known, it must be an edge node whose neighbor hasn't been loaded into the graph, yet
|
||||
return;
|
||||
}
|
||||
let caption = GraphData.GraphData.getNodePropValue(gd.getVertexById(neighborId), nodeCaption) as string;
|
||||
const caption = GraphData.GraphData.getNodePropValue(gd.getVertexById(neighborId), nodeCaption) as string;
|
||||
targets.push({
|
||||
name: caption,
|
||||
id: neighborId,
|
||||
@ -1660,7 +1668,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
|
||||
this.setState({
|
||||
possibleEdgeLabels: Object.keys(possibleEdgeLabels).map(
|
||||
(value: string, index: number, array: string[]): InputTypeaheadComponent.Item => {
|
||||
(value: string): InputTypeaheadComponent.Item => {
|
||||
return { caption: value, value: value };
|
||||
}
|
||||
),
|
||||
@ -1681,20 +1689,20 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
return;
|
||||
}
|
||||
|
||||
let updatedVertex = vertices[0];
|
||||
const updatedVertex = vertices[0];
|
||||
if (this.originalGraphData.hasVertexId(updatedVertex.id)) {
|
||||
let currentVertex = this.originalGraphData.getVertexById(updatedVertex.id);
|
||||
const currentVertex = this.originalGraphData.getVertexById(updatedVertex.id);
|
||||
// Copy updated properties
|
||||
if (currentVertex.hasOwnProperty("properties")) {
|
||||
if (Object.prototype.hasOwnProperty.call(currentVertex, "properties")) {
|
||||
delete currentVertex["properties"];
|
||||
}
|
||||
for (var p in updatedVertex) {
|
||||
for (const p in updatedVertex) {
|
||||
(currentVertex as any)[p] = updatedVertex[p];
|
||||
}
|
||||
}
|
||||
|
||||
// TODO This kind of assumes saveVertexProperty is done from property panes.
|
||||
let hn = this.state.highlightedNode;
|
||||
const hn = this.state.highlightedNode;
|
||||
if (hn && hn.id === updatedVertex.id) {
|
||||
this.updatePropertiesPane(hn.id);
|
||||
}
|
||||
@ -1708,7 +1716,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
igraphConfig?: IGraphConfig
|
||||
) {
|
||||
this.originalGraphData = graphData;
|
||||
let gd = JSON.parse(JSON.stringify(this.originalGraphData));
|
||||
const gd = JSON.parse(JSON.stringify(this.originalGraphData));
|
||||
if (!this.d3ForceGraph) {
|
||||
console.warn("Attempting to update graph, but d3ForceGraph not initialized, yet.");
|
||||
return;
|
||||
@ -1873,7 +1881,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
|
||||
|
||||
promise
|
||||
.then((result: GremlinClient.GremlinRequestResult) => this.processGremlinQueryResults(result))
|
||||
.catch((error: any) => {
|
||||
.catch((error: Error) => {
|
||||
const errorMsg = `Failed to process query result: ${getErrorMessage(error)}`;
|
||||
GraphExplorer.reportToConsole(ConsoleDataType.Error, errorMsg);
|
||||
this.setState({
|
||||
|
@ -307,11 +307,18 @@ 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} />),
|
||||
useSidePanel
|
||||
.getState()
|
||||
.openSidePanel(
|
||||
"New " + getDatabaseName(),
|
||||
<AddDatabasePanel explorer={container} buttonElement={newDatabaseButton} />
|
||||
),
|
||||
commandButtonLabel: label,
|
||||
ariaLabel: label,
|
||||
hasPopup: true,
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { CellId, CellType, ImmutableNotebook } from "@nteract/commutable";
|
||||
// Vendor modules
|
||||
import {
|
||||
@ -30,6 +31,19 @@ export interface NotebookComponentBootstrapperOptions {
|
||||
contentRef: ContentRef;
|
||||
}
|
||||
|
||||
interface IWrapModel {
|
||||
name: string;
|
||||
path: string;
|
||||
last_modified: Date;
|
||||
created: string;
|
||||
content: unknown;
|
||||
format: string;
|
||||
mimetype: unknown;
|
||||
size: number;
|
||||
writeable: boolean;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export class NotebookComponentBootstrapper {
|
||||
public contentRef: ContentRef;
|
||||
protected renderExtraComponent: () => JSX.Element;
|
||||
@ -41,7 +55,7 @@ export class NotebookComponentBootstrapper {
|
||||
this.contentRef = options.contentRef;
|
||||
}
|
||||
|
||||
protected static wrapModelIntoContent(name: string, path: string, content: any) {
|
||||
protected static wrapModelIntoContent(name: string, path: string, content: unknown): IWrapModel {
|
||||
return {
|
||||
name,
|
||||
path,
|
||||
@ -49,7 +63,7 @@ export class NotebookComponentBootstrapper {
|
||||
created: "",
|
||||
content,
|
||||
format: "json",
|
||||
mimetype: null as any,
|
||||
mimetype: undefined,
|
||||
size: 0,
|
||||
writeable: false,
|
||||
type: "notebook",
|
||||
@ -85,7 +99,7 @@ export class NotebookComponentBootstrapper {
|
||||
};
|
||||
}
|
||||
|
||||
public setContent(name: string, content: any): void {
|
||||
public setContent(name: string, content: unknown): void {
|
||||
this.getStore().dispatch(
|
||||
actions.fetchContentFulfilled({
|
||||
filepath: undefined,
|
||||
@ -270,7 +284,6 @@ export class NotebookComponentBootstrapper {
|
||||
public isContentDirty(): boolean {
|
||||
const content = selectors.content(this.getStore().getState(), { contentRef: this.contentRef });
|
||||
if (!content) {
|
||||
console.log("No error");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,10 @@ import "./NotebookReadOnlyRenderer.less";
|
||||
import SandboxOutputs from "./outputs/SandboxOutputs";
|
||||
|
||||
export interface NotebookRendererProps {
|
||||
contentRef: any;
|
||||
contentRef: ContentRef;
|
||||
hideInputs?: boolean;
|
||||
hidePrompts?: boolean;
|
||||
addTransform: (component: React.ComponentType & { MIMETYPE: string }) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -27,7 +28,7 @@ export interface NotebookRendererProps {
|
||||
class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
||||
componentDidMount() {
|
||||
if (!userContext.features.sandboxNotebookOutputs) {
|
||||
loadTransform(this.props as any);
|
||||
loadTransform(this.props as NotebookRendererProps);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +60,7 @@ class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
||||
<div className="NotebookReadOnlyRender">
|
||||
<Cells contentRef={this.props.contentRef}>
|
||||
{{
|
||||
code: ({ id, contentRef }: { id: any; contentRef: ContentRef }) => (
|
||||
code: ({ id, contentRef }: { id: string; contentRef: ContentRef }) => (
|
||||
<CodeCell id={id} contentRef={contentRef}>
|
||||
{{
|
||||
prompt: (props: { id: string; contentRef: string }) => this.renderPrompt(props.id, props.contentRef),
|
||||
@ -73,14 +74,14 @@ class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
||||
}}
|
||||
</CodeCell>
|
||||
),
|
||||
markdown: ({ id, contentRef }: { id: any; contentRef: ContentRef }) => (
|
||||
markdown: ({ id, contentRef }: { id: string; contentRef: ContentRef }) => (
|
||||
<MarkdownCell id={id} contentRef={contentRef} cell_type="markdown">
|
||||
{{
|
||||
editor: {},
|
||||
}}
|
||||
</MarkdownCell>
|
||||
),
|
||||
raw: ({ id, contentRef }: { id: any; contentRef: ContentRef }) => (
|
||||
raw: ({ id, contentRef }: { id: string; contentRef: ContentRef }) => (
|
||||
<RawCell id={id} contentRef={contentRef} cell_type="raw">
|
||||
{{
|
||||
editor: {
|
||||
@ -98,6 +99,7 @@ class NotebookReadOnlyRenderer extends React.Component<NotebookRendererProps> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const makeMapDispatchToProps = (initialDispatch: Dispatch, initialProps: NotebookRendererProps) => {
|
||||
const mapDispatchToProps = (dispatch: Dispatch) => {
|
||||
return {
|
||||
@ -114,4 +116,4 @@ const makeMapDispatchToProps = (initialDispatch: Dispatch, initialProps: Noteboo
|
||||
return mapDispatchToProps;
|
||||
};
|
||||
|
||||
export default connect(null, makeMapDispatchToProps)(NotebookReadOnlyRenderer);
|
||||
export default connect(undefined, makeMapDispatchToProps)(NotebookReadOnlyRenderer);
|
||||
|
@ -13,21 +13,21 @@ import {
|
||||
Text,
|
||||
TooltipHost,
|
||||
} from "@fluentui/react";
|
||||
import * as Constants from "Common/Constants";
|
||||
import { createCollection } from "Common/dataAccess/createCollection";
|
||||
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
|
||||
import { configContext, Platform } from "ConfigContext";
|
||||
import * as DataModels from "Contracts/DataModels";
|
||||
import { SubscriptionType } from "Contracts/SubscriptionType";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import React from "react";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { createCollection } from "../../Common/dataAccess/createCollection";
|
||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||
import { configContext, Platform } from "../../ConfigContext";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import { SubscriptionType } from "../../Contracts/SubscriptionType";
|
||||
import { useSidePanel } from "../../hooks/useSidePanel";
|
||||
import { CollectionCreation } from "../../Shared/Constants";
|
||||
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { getCollectionName } from "../../Utils/APITypeUtils";
|
||||
import { isCapabilityEnabled, isServerlessAccount } from "../../Utils/CapabilityUtils";
|
||||
import { getUpsellMessage } from "../../Utils/PricingUtils";
|
||||
import { CollectionCreation } from "Shared/Constants";
|
||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
import { getCollectionName } from "Utils/APITypeUtils";
|
||||
import { isCapabilityEnabled, isServerlessAccount } from "Utils/CapabilityUtils";
|
||||
import { getUpsellMessage } from "Utils/PricingUtils";
|
||||
import { CollapsibleSectionComponent } from "../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
||||
import { ThroughputInput } from "../Controls/ThroughputInput/ThroughputInput";
|
||||
import Explorer from "../Explorer";
|
||||
@ -999,7 +999,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||
|
||||
const collectionId: string = this.state.collectionId.trim();
|
||||
let databaseId = this.state.createNewDatabase ? this.state.newDatabaseId.trim() : this.state.selectedDatabaseId;
|
||||
let partitionKeyString = this.state.partitionKey.trim();
|
||||
let partitionKeyString = this.state.isSharded ? this.state.partitionKey.trim() : undefined;
|
||||
|
||||
if (userContext.apiType === "Tables") {
|
||||
// Table require fixed Database: TablesDB, and fixed Partition Key: /'$pk'
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Checkbox, Dropdown, IDropdownOption, Link, Stack, Text, TextField } from "@fluentui/react";
|
||||
import * as Constants from "Common/Constants";
|
||||
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
|
||||
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import React, { FunctionComponent, useState } from "react";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
||||
import { InfoTooltip } from "../../../Common/Tooltip/InfoTooltip";
|
||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||
import * as SharedConstants from "../../../Shared/Constants";
|
||||
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { isServerlessAccount } from "../../../Utils/CapabilityUtils";
|
||||
import * as SharedConstants from "Shared/Constants";
|
||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
import { isServerlessAccount } from "Utils/CapabilityUtils";
|
||||
import { ThroughputInput } from "../../Controls/ThroughputInput/ThroughputInput";
|
||||
import Explorer from "../../Explorer";
|
||||
import { CassandraAPIDataClient } from "../../Tables/TableDataClient";
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { Text, TextField } from "@fluentui/react";
|
||||
import { Areas } from "Common/Constants";
|
||||
import { deleteCollection } from "Common/dataAccess/deleteCollection";
|
||||
import DeleteFeedback from "Common/DeleteFeedback";
|
||||
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
|
||||
import { Collection } from "Contracts/ViewModels";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import React, { FunctionComponent, useState } from "react";
|
||||
import { Areas } from "../../../Common/Constants";
|
||||
import { deleteCollection } from "../../../Common/dataAccess/deleteCollection";
|
||||
import DeleteFeedback from "../../../Common/DeleteFeedback";
|
||||
import { getErrorMessage, getErrorStack } from "../../../Common/ErrorHandlingUtils";
|
||||
import { Collection } from "../../../Contracts/ViewModels";
|
||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||
import { useTabs } from "../../../hooks/useTabs";
|
||||
import { DefaultExperienceUtility } from "../../../Shared/DefaultExperienceUtility";
|
||||
import { Action, ActionModifiers } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { getCollectionName } from "../../../Utils/APITypeUtils";
|
||||
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
|
||||
import { DefaultExperienceUtility } from "Shared/DefaultExperienceUtility";
|
||||
import { Action, ActionModifiers } from "Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
import { getCollectionName } from "Utils/APITypeUtils";
|
||||
import * as NotificationConsoleUtils from "Utils/NotificationConsoleUtils";
|
||||
import { useDatabases } from "../../useDatabases";
|
||||
import { useSelectedNode } from "../../useSelectedNode";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
|
@ -1,18 +1,18 @@
|
||||
import { Text, TextField } from "@fluentui/react";
|
||||
import { useBoolean } from "@fluentui/react-hooks";
|
||||
import { Areas } from "Common/Constants";
|
||||
import { deleteDatabase } from "Common/dataAccess/deleteDatabase";
|
||||
import DeleteFeedback from "Common/DeleteFeedback";
|
||||
import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
|
||||
import { Collection, Database } from "Contracts/ViewModels";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import React, { FunctionComponent, useState } from "react";
|
||||
import { Areas } from "../../Common/Constants";
|
||||
import { deleteDatabase } from "../../Common/dataAccess/deleteDatabase";
|
||||
import DeleteFeedback from "../../Common/DeleteFeedback";
|
||||
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
|
||||
import { Collection, Database } from "../../Contracts/ViewModels";
|
||||
import { useSidePanel } from "../../hooks/useSidePanel";
|
||||
import { useTabs } from "../../hooks/useTabs";
|
||||
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { logConsoleError } from "../../Utils/NotificationConsoleUtils";
|
||||
import { DefaultExperienceUtility } from "Shared/DefaultExperienceUtility";
|
||||
import { Action, ActionModifiers } from "Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "UserContext";
|
||||
import { logConsoleError } from "Utils/NotificationConsoleUtils";
|
||||
import { useDatabases } from "../useDatabases";
|
||||
import { useSelectedNode } from "../useSelectedNode";
|
||||
import { PanelInfoErrorComponent, PanelInfoErrorProps } from "./PanelInfoErrorComponent";
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Checkbox, ChoiceGroup, IChoiceGroupOption, SpinButton } from "@fluentui/react";
|
||||
import * as Constants from "Common/Constants";
|
||||
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
|
||||
import { configContext } from "ConfigContext";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import React, { FunctionComponent, MouseEvent, useState } from "react";
|
||||
import * as Constants from "../../../Common/Constants";
|
||||
import { InfoTooltip } from "../../../Common/Tooltip/InfoTooltip";
|
||||
import { configContext } from "../../../ConfigContext";
|
||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||
import { LocalStorageUtility, StorageKey } from "../../../Shared/StorageUtility";
|
||||
import * as StringUtility from "../../../Shared/StringUtility";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import { logConsoleInfo } from "../../../Utils/NotificationConsoleUtils";
|
||||
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||
import * as StringUtility from "Shared/StringUtility";
|
||||
import { userContext } from "UserContext";
|
||||
import { logConsoleInfo } from "Utils/NotificationConsoleUtils";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
|
||||
export const SettingsPane: FunctionComponent = () => {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { TextField } from "@fluentui/react";
|
||||
import * as ViewModels from "Contracts/ViewModels";
|
||||
import { useTabs } from "hooks/useTabs";
|
||||
import React, { FormEvent, FunctionComponent, useState } from "react";
|
||||
import * as ViewModels from "../../../Contracts/ViewModels";
|
||||
import { useTabs } from "../../../hooks/useTabs";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "Utils/NotificationConsoleUtils";
|
||||
import * as FileSystemUtil from "../../Notebook/FileSystemUtil";
|
||||
import { NotebookContentItem } from "../../Notebook/NotebookContentItem";
|
||||
import NotebookV2Tab from "../../Tabs/NotebookV2Tab";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Upload } from "Common/Upload/Upload";
|
||||
import { useSidePanel } from "hooks/useSidePanel";
|
||||
import React, { ChangeEvent, FunctionComponent, useState } from "react";
|
||||
import { Upload } from "../../../Common/Upload/Upload";
|
||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../../Utils/NotificationConsoleUtils";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "Utils/NotificationConsoleUtils";
|
||||
import { NotebookContentItem } from "../../Notebook/NotebookContentItem";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { DetailsList, DetailsListLayoutMode, IColumn, SelectionMode } from "@fluentui/react";
|
||||
import { Upload } from "Common/Upload/Upload";
|
||||
import { UploadDetailsRecord } from "Contracts/ViewModels";
|
||||
import React, { ChangeEvent, FunctionComponent, useState } from "react";
|
||||
import { Upload } from "../../../Common/Upload/Upload";
|
||||
import { UploadDetailsRecord } from "../../../Contracts/ViewModels";
|
||||
import { logConsoleError } from "../../../Utils/NotificationConsoleUtils";
|
||||
import { logConsoleError } from "Utils/NotificationConsoleUtils";
|
||||
import { getErrorMessage } from "../../Tables/Utilities";
|
||||
import { useSelectedNode } from "../../useSelectedNode";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
|
@ -1,12 +1,11 @@
|
||||
import _ from "underscore";
|
||||
import Q from "q";
|
||||
|
||||
import * as Entities from "../Entities";
|
||||
import _ from "underscore";
|
||||
import * as QueryBuilderConstants from "../Constants";
|
||||
import * as Entities from "../Entities";
|
||||
import * as Utilities from "../Utilities";
|
||||
|
||||
export function getRowSelector(selectorSchema: Entities.IProperty[]): string {
|
||||
var selector: string = "";
|
||||
let selector = "";
|
||||
selectorSchema &&
|
||||
selectorSchema.forEach((p: Entities.IProperty) => {
|
||||
selector += "[" + p.key + '="' + Utilities.jQuerySelectorEscape(p.value) + '"]';
|
||||
@ -15,10 +14,10 @@ export function getRowSelector(selectorSchema: Entities.IProperty[]): string {
|
||||
}
|
||||
|
||||
export function isRowVisible(dataTableScrollBodyQuery: JQuery, element: HTMLElement): boolean {
|
||||
var isVisible = false;
|
||||
let isVisible = false;
|
||||
|
||||
if (dataTableScrollBodyQuery.length && element) {
|
||||
var elementRect: ClientRect = element.getBoundingClientRect(),
|
||||
const elementRect: ClientRect = element.getBoundingClientRect(),
|
||||
dataTableScrollBodyRect: ClientRect = dataTableScrollBodyQuery.get(0).getBoundingClientRect();
|
||||
|
||||
isVisible = elementRect.bottom <= dataTableScrollBodyRect.bottom && dataTableScrollBodyRect.top <= elementRect.top;
|
||||
@ -29,17 +28,17 @@ export function isRowVisible(dataTableScrollBodyQuery: JQuery, element: HTMLElem
|
||||
|
||||
export function scrollToRowIfNeeded(dataTableRows: JQuery, currentIndex: number, isScrollUp: boolean): void {
|
||||
if (dataTableRows.length) {
|
||||
var dataTableScrollBodyQuery: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector),
|
||||
const dataTableScrollBodyQuery: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector),
|
||||
selectedRowElement: HTMLElement = dataTableRows.get(currentIndex);
|
||||
|
||||
if (dataTableScrollBodyQuery.length && selectedRowElement) {
|
||||
var isVisible: boolean = isRowVisible(dataTableScrollBodyQuery, selectedRowElement);
|
||||
const isVisible: boolean = isRowVisible(dataTableScrollBodyQuery, selectedRowElement);
|
||||
|
||||
if (!isVisible) {
|
||||
var selectedRowQuery: JQuery = $(selectedRowElement),
|
||||
const selectedRowQuery: JQuery = $(selectedRowElement),
|
||||
scrollPosition: number = dataTableScrollBodyQuery.scrollTop(),
|
||||
selectedElementPosition: number = selectedRowQuery.position().top,
|
||||
newScrollPosition: number = 0;
|
||||
selectedElementPosition: number = selectedRowQuery.position().top;
|
||||
let newScrollPosition = 0;
|
||||
|
||||
if (isScrollUp) {
|
||||
newScrollPosition = scrollPosition + selectedElementPosition;
|
||||
@ -55,7 +54,7 @@ export function scrollToRowIfNeeded(dataTableRows: JQuery, currentIndex: number,
|
||||
}
|
||||
|
||||
export function scrollToTopIfNeeded(): void {
|
||||
var $dataTableRows: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector),
|
||||
const $dataTableRows: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector),
|
||||
$dataTableScrollBody: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector);
|
||||
|
||||
if ($dataTableRows.length && $dataTableScrollBody.length) {
|
||||
@ -88,13 +87,14 @@ export function reorderColumns(
|
||||
table: DataTables.DataTable,
|
||||
targetOrder: number[],
|
||||
currentOrder?: number[]
|
||||
//eslint-disable-next-line
|
||||
): Q.Promise<any> {
|
||||
var columnsCount: number = targetOrder.length;
|
||||
var isCurrentOrderPassedIn: boolean = !!currentOrder;
|
||||
const columnsCount: number = targetOrder.length;
|
||||
const isCurrentOrderPassedIn = !!currentOrder;
|
||||
if (!isCurrentOrderPassedIn) {
|
||||
currentOrder = getInitialOrder(columnsCount);
|
||||
}
|
||||
var isSameOrder: boolean = Utilities.isEqual(currentOrder, targetOrder);
|
||||
const isSameOrder: boolean = Utilities.isEqual(currentOrder, targetOrder);
|
||||
|
||||
// if the targetOrder is the same as current order, do nothing.
|
||||
if (!isSameOrder) {
|
||||
@ -104,7 +104,7 @@ export function reorderColumns(
|
||||
// Then the transformation order will be the same as target order.
|
||||
// If current order is specified, then a transformation order is calculated.
|
||||
// Refer to calculateTransformationOrder for details about transformation order.
|
||||
var transformationOrder: number[] = isCurrentOrderPassedIn
|
||||
const transformationOrder: number[] = isCurrentOrderPassedIn
|
||||
? calculateTransformationOrder(currentOrder, targetOrder)
|
||||
: targetOrder;
|
||||
try {
|
||||
@ -143,7 +143,7 @@ export function getCurrentOrder(table: DataTables.DataTable): number[] {
|
||||
* Result: [0, 1, 2, 5, 6, 7, 3, 4, 8]
|
||||
*/
|
||||
export function invertIndexValues(inputArray: number[]): number[] {
|
||||
var invertedArray: number[] = [];
|
||||
const invertedArray: number[] = [];
|
||||
if (inputArray) {
|
||||
inputArray.forEach((value: number, index: number) => {
|
||||
invertedArray[inputArray[index]] = index;
|
||||
@ -170,20 +170,21 @@ export function invertIndexValues(inputArray: number[]): number[] {
|
||||
* transformation order: Trans = [0, 1, 2, 7, 3, 4, 8, 5, 6]
|
||||
*/
|
||||
export function calculateTransformationOrder(currentOrder: number[], targetOrder: number[]): number[] {
|
||||
var transformationOrder: number[] = [];
|
||||
let transformationOrder: number[] = [];
|
||||
if (currentOrder && targetOrder && currentOrder.length === targetOrder.length) {
|
||||
var invertedCurrentOrder: number[] = invertIndexValues(currentOrder);
|
||||
const invertedCurrentOrder: number[] = invertIndexValues(currentOrder);
|
||||
transformationOrder = targetOrder.map((value: number) => invertedCurrentOrder[value]);
|
||||
}
|
||||
return transformationOrder;
|
||||
}
|
||||
|
||||
export function getDataTableHeaders(table: DataTables.DataTable): string[] {
|
||||
var columns: DataTables.ColumnsMethods = table.columns();
|
||||
var headers: string[] = [];
|
||||
const columns: DataTables.ColumnsMethods = table.columns();
|
||||
let headers: string[] = [];
|
||||
if (columns) {
|
||||
// table.columns() return ColumnsMethods which is an array of arrays
|
||||
var columnIndexes: number[] = (<any>columns)[0];
|
||||
//eslint-disable-next-line
|
||||
const columnIndexes: number[] = (<any>columns)[0];
|
||||
if (columnIndexes) {
|
||||
headers = columnIndexes.map((value: number) => $(table.columns(value).header()).html());
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ import TableEntityListViewModel from "./TableEntityListViewModel";
|
||||
|
||||
export default class TableCommands {
|
||||
// Command Ids
|
||||
public static editEntityCommand: string = "edit";
|
||||
public static deleteEntitiesCommand: string = "delete";
|
||||
public static reorderColumnsCommand: string = "reorder";
|
||||
public static resetColumnsCommand: string = "reset";
|
||||
public static customizeColumnsCommand: string = "customizeColumns";
|
||||
public static editEntityCommand = "edit";
|
||||
public static deleteEntitiesCommand = "delete";
|
||||
public static reorderColumnsCommand = "reorder";
|
||||
public static resetColumnsCommand = "reset";
|
||||
public static customizeColumnsCommand = "customizeColumns";
|
||||
|
||||
private _container: Explorer;
|
||||
|
||||
@ -21,8 +21,8 @@ export default class TableCommands {
|
||||
}
|
||||
|
||||
public isEnabled(commandName: string, selectedEntites: Entities.ITableEntity[]): boolean {
|
||||
var singleItemSelected: boolean = DataTableUtilities.containSingleItem(selectedEntites);
|
||||
var atLeastOneItemSelected: boolean = DataTableUtilities.containItems(selectedEntites);
|
||||
const singleItemSelected = DataTableUtilities.containSingleItem(selectedEntites);
|
||||
const atLeastOneItemSelected = DataTableUtilities.containItems(selectedEntites);
|
||||
switch (commandName) {
|
||||
case TableCommands.editEntityCommand:
|
||||
return singleItemSelected;
|
||||
@ -47,6 +47,7 @@ export default class TableCommands {
|
||||
/**
|
||||
* Edit entity
|
||||
*/
|
||||
//eslint-disable-next-line
|
||||
public editEntityCommand(viewModel: TableEntityListViewModel): Q.Promise<any> {
|
||||
if (!viewModel) {
|
||||
return null; // Error
|
||||
@ -56,12 +57,9 @@ export default class TableCommands {
|
||||
return null; // Erorr
|
||||
}
|
||||
|
||||
var entityToUpdate: Entities.ITableEntity = viewModel.selected()[0];
|
||||
var originalNumberOfProperties = entityToUpdate ? 0 : Object.keys(entityToUpdate).length - 1; // .metadata is always a property for etag
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
public deleteEntitiesCommand(viewModel: TableEntityListViewModel): Q.Promise<any> {
|
||||
if (!viewModel) {
|
||||
return null; // Error
|
||||
@ -69,7 +67,7 @@ export default class TableCommands {
|
||||
if (!DataTableUtilities.containItems(viewModel.selected())) {
|
||||
return null; // Error
|
||||
}
|
||||
var entitiesToDelete: Entities.ITableEntity[] = viewModel.selected();
|
||||
const entitiesToDelete: Entities.ITableEntity[] = viewModel.selected();
|
||||
const deleteMessage: string =
|
||||
userContext.apiType === "Cassandra"
|
||||
? "Are you sure you want to delete the selected rows?"
|
||||
@ -82,7 +80,7 @@ export default class TableCommands {
|
||||
() => {
|
||||
viewModel.queryTablesTab.container.tableDataClient
|
||||
.deleteDocuments(viewModel.queryTablesTab.collection, entitiesToDelete)
|
||||
.then((results: any) => {
|
||||
.then(() => {
|
||||
return viewModel.removeEntitiesFromCache(entitiesToDelete).then(() => {
|
||||
viewModel.redrawTableThrottled();
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as Utilities from "../Utilities";
|
||||
import * as Entities from "../Entities";
|
||||
import * as Utilities from "../Utilities";
|
||||
import CacheBase from "./CacheBase";
|
||||
|
||||
export default class TableEntityCache extends CacheBase<Entities.ITableEntity> {
|
||||
@ -21,7 +21,7 @@ export default class TableEntityCache extends CacheBase<Entities.ITableEntity> {
|
||||
this._tableQuery = Utilities.copyTableQuery(tableQuery);
|
||||
}
|
||||
|
||||
public preClear() {
|
||||
public preClear(): void {
|
||||
this.tableQuery = null;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { QueryIterator, ItemDefinition, Resource } from "@azure/cosmos";
|
||||
import { ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
||||
|
||||
export interface ITableEntity {
|
||||
[property: string]: ITableEntityAttribute;
|
||||
@ -17,6 +17,7 @@ export interface ITableEntityAttribute {
|
||||
|
||||
export interface IListTableEntitiesResult {
|
||||
Results: ITableEntity[];
|
||||
//eslint-disable-next-line
|
||||
ContinuationToken: any;
|
||||
iterator?: QueryIterator<ItemDefinition & Resource>;
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import QueryClauseViewModel from "./QueryClauseViewModel";
|
||||
import * as Utilities from "../Utilities";
|
||||
import QueryClauseViewModel from "./QueryClauseViewModel";
|
||||
|
||||
export default class ClauseGroup {
|
||||
public isRootGroup: boolean;
|
||||
//eslint-disable-next-line
|
||||
public children = new Array();
|
||||
public parentGroup: ClauseGroup;
|
||||
private _id: string;
|
||||
@ -17,7 +18,7 @@ export default class ClauseGroup {
|
||||
* Flattens the clause tree into an array, depth-first, left to right.
|
||||
*/
|
||||
public flattenClauses(targetArray: ko.ObservableArray<QueryClauseViewModel>): void {
|
||||
var tempArray = new Array<QueryClauseViewModel>();
|
||||
const tempArray = new Array<QueryClauseViewModel>();
|
||||
|
||||
this.flattenClausesImpl(this, tempArray);
|
||||
targetArray.removeAll();
|
||||
@ -31,10 +32,10 @@ export default class ClauseGroup {
|
||||
newClause.clauseGroup = this;
|
||||
this.children.push(newClause);
|
||||
} else {
|
||||
var targetGroup = insertBefore.clauseGroup;
|
||||
const targetGroup = insertBefore.clauseGroup;
|
||||
|
||||
if (targetGroup) {
|
||||
var insertBeforeIndex = targetGroup.children.indexOf(insertBefore);
|
||||
const insertBeforeIndex = targetGroup.children.indexOf(insertBefore);
|
||||
newClause.clauseGroup = targetGroup;
|
||||
targetGroup.children.splice(insertBeforeIndex, 0, newClause);
|
||||
}
|
||||
@ -42,19 +43,19 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
public deleteClause(clause: QueryClauseViewModel): void {
|
||||
var targetGroup = clause.clauseGroup;
|
||||
const targetGroup = clause.clauseGroup;
|
||||
|
||||
if (targetGroup) {
|
||||
var index = targetGroup.children.indexOf(clause);
|
||||
const index = targetGroup.children.indexOf(clause);
|
||||
targetGroup.children.splice(index, 1);
|
||||
clause.dispose();
|
||||
|
||||
if (targetGroup.children.length <= 1 && !targetGroup.isRootGroup) {
|
||||
var parent = targetGroup.parentGroup;
|
||||
var targetGroupIndex = parent.children.indexOf(targetGroup);
|
||||
const parent = targetGroup.parentGroup;
|
||||
const targetGroupIndex = parent.children.indexOf(targetGroup);
|
||||
|
||||
if (targetGroup.children.length === 1) {
|
||||
var orphan = targetGroup.children.shift();
|
||||
const orphan = targetGroup.children.shift();
|
||||
|
||||
if (orphan instanceof QueryClauseViewModel) {
|
||||
(<QueryClauseViewModel>orphan).clauseGroup = parent;
|
||||
@ -71,14 +72,14 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
public removeAll(): void {
|
||||
var allClauses: QueryClauseViewModel[] = new Array<QueryClauseViewModel>();
|
||||
const allClauses: QueryClauseViewModel[] = new Array<QueryClauseViewModel>();
|
||||
|
||||
this.flattenClausesImpl(this, allClauses);
|
||||
|
||||
while (allClauses.length > 0) {
|
||||
allClauses.shift().dispose();
|
||||
}
|
||||
|
||||
//eslint-disable-next-line
|
||||
this.children = new Array<any>();
|
||||
}
|
||||
|
||||
@ -87,12 +88,12 @@ export default class ClauseGroup {
|
||||
*/
|
||||
public groupSelectedItems(): boolean {
|
||||
// Find the selection start & end, also check for gaps between selected items (if found, cannot proceed).
|
||||
var selection = this.getCheckedItemsInfo();
|
||||
const selection = this.getCheckedItemsInfo();
|
||||
|
||||
if (selection.canGroup) {
|
||||
var newGroup = new ClauseGroup(false, this);
|
||||
const newGroup = new ClauseGroup(false, this);
|
||||
// Replace the selected items with the new group, and then move the selected items into the new group.
|
||||
var groupedItems = this.children.splice(selection.begin, selection.end - selection.begin + 1, newGroup);
|
||||
const groupedItems = this.children.splice(selection.begin, selection.end - selection.begin + 1, newGroup);
|
||||
|
||||
groupedItems &&
|
||||
groupedItems.forEach((element) => {
|
||||
@ -118,13 +119,13 @@ export default class ClauseGroup {
|
||||
return;
|
||||
}
|
||||
|
||||
var parentGroup = this.parentGroup;
|
||||
var index = parentGroup.children.indexOf(this);
|
||||
const parentGroup = this.parentGroup;
|
||||
let index = parentGroup.children.indexOf(this);
|
||||
|
||||
if (index >= 0) {
|
||||
parentGroup.children.splice(index, 1);
|
||||
|
||||
var toPromote = this.children.splice(0, this.children.length);
|
||||
const toPromote = this.children.splice(0, this.children.length);
|
||||
|
||||
// Move all children one level up.
|
||||
toPromote &&
|
||||
@ -146,16 +147,16 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
public findDeepestGroupInChildren(skipIndex?: number): ClauseGroup {
|
||||
var deepest: ClauseGroup = this;
|
||||
var level: number = 0;
|
||||
var func = (currentGroup: ClauseGroup): void => {
|
||||
let deepest = <ClauseGroup>this;
|
||||
let level = 0;
|
||||
const func = (currentGroup: ClauseGroup): void => {
|
||||
level++;
|
||||
if (currentGroup.getCurrentGroupDepth() > deepest.getCurrentGroupDepth()) {
|
||||
deepest = currentGroup;
|
||||
}
|
||||
|
||||
for (var i = 0; i < currentGroup.children.length; i++) {
|
||||
var currentItem = currentGroup.children[i];
|
||||
for (let i = 0; i < currentGroup.children.length; i++) {
|
||||
const currentItem = currentGroup.children[i];
|
||||
|
||||
if ((i !== skipIndex || level > 1) && currentItem instanceof ClauseGroup) {
|
||||
func(currentItem);
|
||||
@ -170,16 +171,16 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
private getCheckedItemsInfo(): { canGroup: boolean; begin: number; end: number } {
|
||||
var beginIndex = -1;
|
||||
var endIndex = -1;
|
||||
let beginIndex = -1;
|
||||
let endIndex = -1;
|
||||
// In order to perform group, all selected items must be next to each other.
|
||||
// If one or more items are not selected between the first and the last selected item, the gapFlag will be set to True, meaning cannot perform group.
|
||||
var gapFlag = false;
|
||||
var count = 0;
|
||||
let gapFlag = false;
|
||||
let count = 0;
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var currentItem = this.children[i];
|
||||
var subGroupSelectionState: { allSelected: boolean; partiallySelected: boolean; nonSelected: boolean };
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
const currentItem = this.children[i];
|
||||
let subGroupSelectionState: { allSelected: boolean; partiallySelected: boolean; nonSelected: boolean };
|
||||
|
||||
if (currentItem instanceof ClauseGroup) {
|
||||
subGroupSelectionState = (<ClauseGroup>currentItem).getSelectionState();
|
||||
@ -235,10 +236,10 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
private getSelectionState(): { allSelected: boolean; partiallySelected: boolean; nonSelected: boolean } {
|
||||
var selectedCount = 0;
|
||||
let selectedCount = 0;
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var currentItem = this.children[i];
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
const currentItem = this.children[i];
|
||||
|
||||
if (currentItem instanceof ClauseGroup && (<ClauseGroup>currentItem).getSelectionState().allSelected) {
|
||||
selectedCount++;
|
||||
@ -260,8 +261,8 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
private unselectAll(): void {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var currentItem = this.children[i];
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
const currentItem = this.children[i];
|
||||
|
||||
if (currentItem instanceof ClauseGroup) {
|
||||
(<ClauseGroup>currentItem).unselectAll();
|
||||
@ -278,8 +279,8 @@ export default class ClauseGroup {
|
||||
targetArray.splice(0, targetArray.length);
|
||||
}
|
||||
|
||||
for (var i = 0; i < queryGroup.children.length; i++) {
|
||||
var currentItem = queryGroup.children[i];
|
||||
for (let i = 0; i < queryGroup.children.length; i++) {
|
||||
const currentItem = queryGroup.children[i];
|
||||
|
||||
if (currentItem instanceof ClauseGroup) {
|
||||
this.flattenClausesImpl(currentItem, targetArray);
|
||||
@ -292,13 +293,13 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
public getTreeDepth(): number {
|
||||
var currentDepth = this.getCurrentGroupDepth();
|
||||
let currentDepth = this.getCurrentGroupDepth();
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var currentItem = this.children[i];
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
const currentItem = this.children[i];
|
||||
|
||||
if (currentItem instanceof ClauseGroup) {
|
||||
var newDepth = (<ClauseGroup>currentItem).getTreeDepth();
|
||||
const newDepth = (<ClauseGroup>currentItem).getTreeDepth();
|
||||
|
||||
if (newDepth > currentDepth) {
|
||||
currentDepth = newDepth;
|
||||
@ -310,8 +311,8 @@ export default class ClauseGroup {
|
||||
}
|
||||
|
||||
public getCurrentGroupDepth(): number {
|
||||
var group = <ClauseGroup>this;
|
||||
var depth = 0;
|
||||
let group = <ClauseGroup>this;
|
||||
let depth = 0;
|
||||
|
||||
while (!group.isRootGroup) {
|
||||
depth++;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import * as ko from "knockout";
|
||||
import * as Constants from "../Constants";
|
||||
import ClauseGroup from "./ClauseGroup";
|
||||
import QueryBuilderViewModel from "./QueryBuilderViewModel";
|
||||
import * as Constants from "../Constants";
|
||||
|
||||
/**
|
||||
* View model for showing group indicators on UI, contains information such as group color and border styles.
|
||||
@ -38,7 +38,7 @@ export default class ClauseGroupViewModel {
|
||||
};
|
||||
|
||||
private getGroupBackgroundColor(group: ClauseGroup): string {
|
||||
var colorCount = Constants.clauseGroupColors.length;
|
||||
const colorCount = Constants.clauseGroupColors.length;
|
||||
|
||||
if (group.isRootGroup) {
|
||||
return Constants.transparentColor;
|
||||
|
@ -29,7 +29,7 @@ export default class QueryBuilderViewModel {
|
||||
public removeThisFilterLine = "Remove this filter line"; // localize
|
||||
public groupSelectedClauses = "Group selected clauses"; // localize
|
||||
public clauseArray = ko.observableArray<QueryClauseViewModel>(); // This is for storing the clauses in flattened form queryClauses for easier UI data binding.
|
||||
public queryClauses = new ClauseGroup(true, null); // The actual data structure containing the clause information.
|
||||
public queryClauses = new ClauseGroup(true, undefined); // The actual data structure containing the clause information.
|
||||
public columnOptions: ko.ObservableArray<string>;
|
||||
public canGroupClauses = ko.observable<boolean>(false);
|
||||
|
||||
@ -107,7 +107,7 @@ export default class QueryBuilderViewModel {
|
||||
}
|
||||
|
||||
public setExample() {
|
||||
var example1 = new QueryClauseViewModel(
|
||||
const example1 = new QueryClauseViewModel(
|
||||
this,
|
||||
"",
|
||||
"PartitionKey",
|
||||
@ -121,7 +121,7 @@ export default class QueryBuilderViewModel {
|
||||
//null,
|
||||
true
|
||||
);
|
||||
var example2 = new QueryClauseViewModel(
|
||||
const example2 = new QueryClauseViewModel(
|
||||
this,
|
||||
"And",
|
||||
"RowKey",
|
||||
@ -140,13 +140,13 @@ export default class QueryBuilderViewModel {
|
||||
}
|
||||
|
||||
public getODataFilterFromClauses = (): string => {
|
||||
var filterString: string = "";
|
||||
var treeTraversal = (group: ClauseGroup): void => {
|
||||
for (var i = 0; i < group.children.length; i++) {
|
||||
var currentItem = group.children[i];
|
||||
let filterString = "";
|
||||
const treeTraversal = (group: ClauseGroup): void => {
|
||||
for (let i = 0; i < group.children.length; i++) {
|
||||
const currentItem = group.children[i];
|
||||
|
||||
if (currentItem instanceof QueryClauseViewModel) {
|
||||
var clause = <QueryClauseViewModel>currentItem;
|
||||
const clause = <QueryClauseViewModel>currentItem;
|
||||
this.timestampToValue(clause);
|
||||
filterString = filterString.concat(
|
||||
this.constructODataClause(
|
||||
@ -173,7 +173,7 @@ export default class QueryBuilderViewModel {
|
||||
};
|
||||
|
||||
public getSqlFilterFromClauses = (): string => {
|
||||
var filterString: string = "SELECT * FROM c";
|
||||
let filterString = "SELECT * FROM c";
|
||||
if (this._queryViewModel.selectText() && this._queryViewModel.selectText().length > 0) {
|
||||
filterString = "SELECT";
|
||||
const selectText = this._queryViewModel && this._queryViewModel.selectText && this._queryViewModel.selectText();
|
||||
@ -199,15 +199,15 @@ export default class QueryBuilderViewModel {
|
||||
return filterString;
|
||||
}
|
||||
filterString = filterString.concat(" WHERE");
|
||||
var first = true;
|
||||
var treeTraversal = (group: ClauseGroup): void => {
|
||||
for (var i = 0; i < group.children.length; i++) {
|
||||
var currentItem = group.children[i];
|
||||
let first = true;
|
||||
const treeTraversal = (group: ClauseGroup): void => {
|
||||
for (let i = 0; i < group.children.length; i++) {
|
||||
const currentItem = group.children[i];
|
||||
|
||||
if (currentItem instanceof QueryClauseViewModel) {
|
||||
var clause = <QueryClauseViewModel>currentItem;
|
||||
let timeStampValue: string = this.timestampToSqlValue(clause);
|
||||
var value = clause.value();
|
||||
const clause = <QueryClauseViewModel>currentItem;
|
||||
const timeStampValue: string = this.timestampToSqlValue(clause);
|
||||
let value = clause.value();
|
||||
if (!clause.isValue()) {
|
||||
value = timeStampValue;
|
||||
}
|
||||
@ -240,7 +240,7 @@ export default class QueryBuilderViewModel {
|
||||
const databaseId = this._queryViewModel.queryTablesTab.collection.databaseId;
|
||||
const collectionId = this._queryViewModel.queryTablesTab.collection.id();
|
||||
const tableToQuery = `${getQuotedCqlIdentifier(databaseId)}.${getQuotedCqlIdentifier(collectionId)}`;
|
||||
var filterString: string = `SELECT * FROM ${tableToQuery}`;
|
||||
let filterString = `SELECT * FROM ${tableToQuery}`;
|
||||
if (this._queryViewModel.selectText() && this._queryViewModel.selectText().length > 0) {
|
||||
filterString = "SELECT";
|
||||
const selectText = this._queryViewModel && this._queryViewModel.selectText && this._queryViewModel.selectText();
|
||||
@ -255,15 +255,15 @@ export default class QueryBuilderViewModel {
|
||||
return filterString;
|
||||
}
|
||||
filterString = filterString.concat(" WHERE");
|
||||
var first = true;
|
||||
var treeTraversal = (group: ClauseGroup): void => {
|
||||
for (var i = 0; i < group.children.length; i++) {
|
||||
var currentItem = group.children[i];
|
||||
let first = true;
|
||||
const treeTraversal = (group: ClauseGroup): void => {
|
||||
for (let i = 0; i < group.children.length; i++) {
|
||||
const currentItem = group.children[i];
|
||||
|
||||
if (currentItem instanceof QueryClauseViewModel) {
|
||||
var clause = <QueryClauseViewModel>currentItem;
|
||||
let timeStampValue: string = this.timestampToSqlValue(clause);
|
||||
var value = clause.value();
|
||||
const clause = <QueryClauseViewModel>currentItem;
|
||||
const timeStampValue = this.timestampToSqlValue(clause);
|
||||
let value = clause.value();
|
||||
if (!clause.isValue()) {
|
||||
value = timeStampValue;
|
||||
}
|
||||
@ -293,13 +293,13 @@ export default class QueryBuilderViewModel {
|
||||
};
|
||||
|
||||
public updateColumnOptions = (): void => {
|
||||
let originalHeaders = this.columnOptions();
|
||||
let newHeaders = this.tableEntityListViewModel.headers;
|
||||
// let originalHeaders = this.columnOptions();
|
||||
const newHeaders = this.tableEntityListViewModel.headers;
|
||||
this.columnOptions(newHeaders.sort(DataTableUtilities.compareTableColumns));
|
||||
};
|
||||
|
||||
private generateLeftParentheses(clause: QueryClauseViewModel): string {
|
||||
var result = "";
|
||||
let result = "";
|
||||
|
||||
if (clause.clauseGroup.isRootGroup || clause.clauseGroup.children.indexOf(clause) !== 0) {
|
||||
return result;
|
||||
@ -307,7 +307,7 @@ export default class QueryBuilderViewModel {
|
||||
result = result.concat("(");
|
||||
}
|
||||
|
||||
var currentGroup: ClauseGroup = clause.clauseGroup;
|
||||
let currentGroup: ClauseGroup = clause.clauseGroup;
|
||||
|
||||
while (
|
||||
!currentGroup.isRootGroup &&
|
||||
@ -322,7 +322,7 @@ export default class QueryBuilderViewModel {
|
||||
}
|
||||
|
||||
private generateRightParentheses(clause: QueryClauseViewModel): string {
|
||||
var result = "";
|
||||
let result = "";
|
||||
|
||||
if (
|
||||
clause.clauseGroup.isRootGroup ||
|
||||
@ -333,7 +333,7 @@ export default class QueryBuilderViewModel {
|
||||
result = result.concat(")");
|
||||
}
|
||||
|
||||
var currentGroup: ClauseGroup = clause.clauseGroup;
|
||||
let currentGroup: ClauseGroup = clause.clauseGroup;
|
||||
|
||||
while (
|
||||
!currentGroup.isRootGroup &&
|
||||
@ -364,14 +364,17 @@ export default class QueryBuilderViewModel {
|
||||
case Constants.TableType.String:
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}${propertyName} ${this.operatorConverter(
|
||||
operator
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
)} \'${value}\'${rightParentheses}`;
|
||||
case Constants.TableType.Guid:
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}${propertyName} ${this.operatorConverter(
|
||||
operator
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
)} guid\'${value}\'${rightParentheses}`;
|
||||
case Constants.TableType.Binary:
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}${propertyName} ${this.operatorConverter(
|
||||
operator
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
)} binary\'${value}\'${rightParentheses}`;
|
||||
default:
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}${propertyName} ${this.operatorConverter(
|
||||
@ -391,9 +394,11 @@ export default class QueryBuilderViewModel {
|
||||
): string => {
|
||||
if (propertyName === Constants.EntityKeyNames.PartitionKey) {
|
||||
propertyName = TableEntityProcessor.keyProperties.PartitionKey;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}c["${propertyName}"] ${operator} \'${value}\'${rightParentheses}`;
|
||||
} else if (propertyName === Constants.EntityKeyNames.RowKey) {
|
||||
propertyName = TableEntityProcessor.keyProperties.Id;
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}c.${propertyName} ${operator} \'${value}\'${rightParentheses}`;
|
||||
} else if (propertyName === Constants.EntityKeyNames.Timestamp) {
|
||||
propertyName = TableEntityProcessor.keyProperties.Timestamp;
|
||||
@ -403,16 +408,21 @@ export default class QueryBuilderViewModel {
|
||||
}
|
||||
switch (type) {
|
||||
case Constants.TableType.DateTime:
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}c.${propertyName}["$v"] ${operator} \'${DateTimeUtilities.convertJSDateToTicksWithPadding(
|
||||
value
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
)}\'${rightParentheses}`;
|
||||
case Constants.TableType.Int64:
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}c.${propertyName}["$v"] ${operator} \'${Utilities.padLongWithZeros(
|
||||
value
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
)}\'${rightParentheses}`;
|
||||
case Constants.TableType.String:
|
||||
case Constants.TableType.Guid:
|
||||
case Constants.TableType.Binary:
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}c.${propertyName}["$v"] ${operator} \'${value}\'${rightParentheses}`;
|
||||
default:
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses}c.${propertyName}["$v"] ${operator} ${value}${rightParentheses}`;
|
||||
@ -434,6 +444,7 @@ export default class QueryBuilderViewModel {
|
||||
type === Constants.CassandraType.Ascii ||
|
||||
type === Constants.CassandraType.Varchar
|
||||
) {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses} ${propertyName} ${operator} \'${value}\'${rightParentheses}`;
|
||||
}
|
||||
return ` ${clauseRule.toLowerCase()} ${leftParentheses} ${propertyName} ${operator} ${value}${rightParentheses}`;
|
||||
@ -454,7 +465,7 @@ export default class QueryBuilderViewModel {
|
||||
case Constants.Operator.NotEqualTo:
|
||||
return Constants.ODataOperator.NotEqualTo;
|
||||
}
|
||||
return null;
|
||||
return undefined;
|
||||
};
|
||||
|
||||
public groupClauses = (): void => {
|
||||
@ -463,11 +474,11 @@ export default class QueryBuilderViewModel {
|
||||
this.updateCanGroupClauses();
|
||||
};
|
||||
|
||||
public addClauseIndex = (index: number, data: any): void => {
|
||||
public addClauseIndex = (index: number): void => {
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
var newClause = new QueryClauseViewModel(
|
||||
const newClause = new QueryClauseViewModel(
|
||||
this,
|
||||
"And",
|
||||
"",
|
||||
@ -492,28 +503,28 @@ export default class QueryBuilderViewModel {
|
||||
|
||||
// adds a new clause to the end of the array
|
||||
public addNewClause = (): void => {
|
||||
this.addClauseIndex(this.clauseArray().length, null);
|
||||
this.addClauseIndex(this.clauseArray().length);
|
||||
};
|
||||
|
||||
public onAddClauseKeyDown = (index: number, data: any, event: KeyboardEvent, source: any): boolean => {
|
||||
public onAddClauseKeyDown = (index: number, event: KeyboardEvent): boolean => {
|
||||
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
|
||||
this.addClauseIndex(index, data);
|
||||
this.addClauseIndex(index);
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
public onAddNewClauseKeyDown = (source: any, event: KeyboardEvent): boolean => {
|
||||
public onAddNewClauseKeyDown = (event: KeyboardEvent): boolean => {
|
||||
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
|
||||
this.addClauseIndex(this.clauseArray().length - 1, null);
|
||||
this.addClauseIndex(this.clauseArray().length - 1);
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
public deleteClause = (index: number, data: any): void => {
|
||||
public deleteClause = (index: number): void => {
|
||||
this.deleteClauseImpl(index);
|
||||
if (this.clauseArray().length !== 0) {
|
||||
this.clauseArray()[0].and_or("");
|
||||
@ -523,9 +534,9 @@ export default class QueryBuilderViewModel {
|
||||
$(window).resize();
|
||||
};
|
||||
|
||||
public onDeleteClauseKeyDown = (index: number, data: any, event: KeyboardEvent, source: any): boolean => {
|
||||
public onDeleteClauseKeyDown = (index: number, event: KeyboardEvent): boolean => {
|
||||
if (event.keyCode === KeyCodes.Enter || event.keyCode === KeyCodes.Space) {
|
||||
this.deleteClause(index, data);
|
||||
this.deleteClause(index);
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
@ -539,25 +550,26 @@ export default class QueryBuilderViewModel {
|
||||
* (transparent) or its parent group view models.
|
||||
*/
|
||||
public getClauseGroupViewModels = (clause: QueryClauseViewModel): ClauseGroupViewModel[] => {
|
||||
var placeHolderGroupViewModel = new ClauseGroupViewModel(this.queryClauses, false, this);
|
||||
var treeDepth = this.queryClauses.getTreeDepth();
|
||||
var groupViewModels = new Array<ClauseGroupViewModel>(treeDepth);
|
||||
const placeHolderGroupViewModel = new ClauseGroupViewModel(this.queryClauses, false, this);
|
||||
const treeDepth = this.queryClauses.getTreeDepth();
|
||||
const groupViewModels = new Array<ClauseGroupViewModel>(treeDepth);
|
||||
|
||||
// Prefill the arry with placeholders.
|
||||
for (var i = 0; i < groupViewModels.length; i++) {
|
||||
for (let i = 0; i < groupViewModels.length; i++) {
|
||||
groupViewModels[i] = placeHolderGroupViewModel;
|
||||
}
|
||||
|
||||
var currentGroup = clause.clauseGroup;
|
||||
let currentGroup = clause.clauseGroup;
|
||||
|
||||
// This function determines whether the path from clause to the current group is on the left most.
|
||||
var isLeftMostPath = (): boolean => {
|
||||
var group = clause.clauseGroup;
|
||||
const isLeftMostPath = (): boolean => {
|
||||
let group = clause.clauseGroup;
|
||||
|
||||
if (group.children.indexOf(clause) !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
if (group.getId() === currentGroup.getId()) {
|
||||
break;
|
||||
@ -573,13 +585,14 @@ export default class QueryBuilderViewModel {
|
||||
};
|
||||
|
||||
// This function determines whether the path from clause to the current group is on the right most.
|
||||
var isRightMostPath = (): boolean => {
|
||||
var group = clause.clauseGroup;
|
||||
const isRightMostPath = (): boolean => {
|
||||
let group = clause.clauseGroup;
|
||||
|
||||
if (group.children.indexOf(clause) !== group.children.length - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
if (group.getId() === currentGroup.getId()) {
|
||||
break;
|
||||
@ -594,26 +607,26 @@ export default class QueryBuilderViewModel {
|
||||
return true;
|
||||
};
|
||||
|
||||
var vmIndex = groupViewModels.length - 1;
|
||||
var skipIndex = -1;
|
||||
var lastDepth = clause.groupDepth;
|
||||
let vmIndex = groupViewModels.length - 1;
|
||||
let skipIndex = -1;
|
||||
let lastDepth = clause.groupDepth;
|
||||
|
||||
while (!currentGroup.isRootGroup) {
|
||||
// The current group will be rendered at least once, and if there are any sibling groups deeper
|
||||
// than the current group, we will repeat rendering the current group to fill up the gap between
|
||||
// current & deepest sibling.
|
||||
var deepestInSiblings = currentGroup.findDeepestGroupInChildren(skipIndex).getCurrentGroupDepth();
|
||||
const deepestInSiblings = currentGroup.findDeepestGroupInChildren(skipIndex).getCurrentGroupDepth();
|
||||
// Find out the depth difference between the deepest group under the siblings of currentGroup and
|
||||
// the deepest group under currentGroup. If the result n is a positive number, it means there are
|
||||
// deeper groups in siblings and we need to draw n + 1 group blocks on UI to fill up the depth
|
||||
// differences. If the result n is a negative number, it means current group contains the deepest
|
||||
// sub-group, we only need to draw the group block once.
|
||||
var repeatCount = Math.max(deepestInSiblings - lastDepth, 0);
|
||||
const repeatCount = Math.max(deepestInSiblings - lastDepth, 0);
|
||||
|
||||
for (var i = 0; i <= repeatCount; i++) {
|
||||
var isLeftMost = isLeftMostPath();
|
||||
var isRightMost = isRightMostPath();
|
||||
var groupViewModel = new ClauseGroupViewModel(currentGroup, i === 0 && isLeftMost, this);
|
||||
for (let i = 0; i <= repeatCount; i++) {
|
||||
const isLeftMost = isLeftMostPath();
|
||||
const isRightMost = isRightMostPath();
|
||||
const groupViewModel = new ClauseGroupViewModel(currentGroup, i === 0 && isLeftMost, this);
|
||||
|
||||
groupViewModel.showTopBorder(isLeftMost);
|
||||
groupViewModel.showBottomBorder(isRightMost);
|
||||
@ -635,9 +648,9 @@ export default class QueryBuilderViewModel {
|
||||
};
|
||||
|
||||
public addCustomRange(timestamp: CustomTimestampHelper.ITimestampQuery, clauseToAdd: QueryClauseViewModel): void {
|
||||
var index = this.clauseArray.peek().indexOf(clauseToAdd);
|
||||
const index = this.clauseArray.peek().indexOf(clauseToAdd);
|
||||
|
||||
var newClause = new QueryClauseViewModel(
|
||||
const newClause = new QueryClauseViewModel(
|
||||
this,
|
||||
//this._tableEntityListViewModel.tableExplorerContext.hostProxy,
|
||||
"And",
|
||||
@ -662,10 +675,10 @@ export default class QueryBuilderViewModel {
|
||||
}
|
||||
|
||||
private scrollToBottom(): void {
|
||||
var scrollBox = document.getElementById("scroll");
|
||||
const scrollBox = document.getElementById("scroll");
|
||||
if (!this.scrollEventListener) {
|
||||
scrollBox.addEventListener("scroll", function () {
|
||||
var translate = "translate(0," + this.scrollTop + "px)";
|
||||
const translate = "translate(0," + this.scrollTop + "px)";
|
||||
const allTh = <NodeListOf<HTMLElement>>this.querySelectorAll("thead td");
|
||||
for (let i = 0; i < allTh.length; i++) {
|
||||
allTh[i].style.transform = translate;
|
||||
@ -673,7 +686,7 @@ export default class QueryBuilderViewModel {
|
||||
});
|
||||
this.scrollEventListener = true;
|
||||
}
|
||||
var isScrolledToBottom = scrollBox.scrollHeight - scrollBox.clientHeight <= scrollBox.scrollHeight + 1;
|
||||
const isScrolledToBottom = scrollBox.scrollHeight - scrollBox.clientHeight <= scrollBox.scrollHeight + 1;
|
||||
if (isScrolledToBottom) {
|
||||
scrollBox.scrollTop = scrollBox.scrollHeight - scrollBox.clientHeight;
|
||||
}
|
||||
@ -685,8 +698,8 @@ export default class QueryBuilderViewModel {
|
||||
}
|
||||
|
||||
private deleteClauseImpl(index: number): void {
|
||||
var clause = this.clauseArray()[index];
|
||||
var previousClause = index === 0 ? 0 : index - 1;
|
||||
const clause = this.clauseArray()[index];
|
||||
const previousClause = index === 0 ? 0 : index - 1;
|
||||
this.queryClauses.deleteClause(clause);
|
||||
this.updateClauseArray();
|
||||
if (this.clauseArray()[previousClause]) {
|
||||
@ -731,7 +744,7 @@ export default class QueryBuilderViewModel {
|
||||
|
||||
private timestampToSqlValue(clause: QueryClauseViewModel): string {
|
||||
if (clause.isValue()) {
|
||||
return null;
|
||||
return undefined;
|
||||
} else if (clause.isTimestamp()) {
|
||||
return this.getTimeStampToSqlQuery(clause);
|
||||
// } else if (clause.isCustomLastTimestamp()) {
|
||||
@ -743,7 +756,7 @@ export default class QueryBuilderViewModel {
|
||||
return clause.customTimeValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private getTimeStampToQuery(clause: QueryClauseViewModel): void {
|
||||
@ -789,7 +802,7 @@ export default class QueryBuilderViewModel {
|
||||
case Constants.timeOptions.currentYear:
|
||||
return CustomTimestampHelper._queryCurrentYearLocal();
|
||||
}
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public checkIfClauseChanged(): void {
|
||||
|
@ -14,7 +14,7 @@ export default class QueryClauseViewModel {
|
||||
public field: ko.Observable<string>;
|
||||
public type: ko.Observable<string>;
|
||||
public operator: ko.Observable<string>;
|
||||
public value: ko.Observable<any>;
|
||||
public value: ko.Observable<string>;
|
||||
public timeValue: ko.Observable<string>;
|
||||
public customTimeValue: ko.Observable<string>;
|
||||
public canAnd: ko.Observable<boolean>;
|
||||
@ -39,7 +39,7 @@ export default class QueryClauseViewModel {
|
||||
field: string,
|
||||
type: string,
|
||||
operator: string,
|
||||
value: any,
|
||||
value: string,
|
||||
canAnd: boolean,
|
||||
timeValue: string,
|
||||
customTimeValue: string,
|
||||
@ -88,30 +88,30 @@ export default class QueryClauseViewModel {
|
||||
userContext.apiType !== "Cassandra"
|
||||
);
|
||||
|
||||
this.and_or.subscribe((value) => {
|
||||
this.and_or.subscribe(() => {
|
||||
this._queryBuilderViewModel.checkIfClauseChanged();
|
||||
});
|
||||
this.field.subscribe((value) => {
|
||||
this.field.subscribe(() => {
|
||||
this.changeField();
|
||||
});
|
||||
this.type.subscribe((value) => {
|
||||
this.type.subscribe(() => {
|
||||
this.changeType();
|
||||
});
|
||||
this.timeValue.subscribe((value) => {
|
||||
this.timeValue.subscribe(() => {
|
||||
// if (this.timeValue() === QueryBuilderConstants.timeOptions.custom) {
|
||||
// this.customTimestampDialog();
|
||||
// }
|
||||
});
|
||||
this.customTimeValue.subscribe((value) => {
|
||||
this.customTimeValue.subscribe(() => {
|
||||
this._queryBuilderViewModel.checkIfClauseChanged();
|
||||
});
|
||||
this.value.subscribe((value) => {
|
||||
this.value.subscribe(() => {
|
||||
this._queryBuilderViewModel.checkIfClauseChanged();
|
||||
});
|
||||
this.operator.subscribe((value) => {
|
||||
this.operator.subscribe(() => {
|
||||
this._queryBuilderViewModel.checkIfClauseChanged();
|
||||
});
|
||||
this._groupCheckSubscription = this.checkedForGrouping.subscribe((value) => {
|
||||
this._groupCheckSubscription = this.checkedForGrouping.subscribe(() => {
|
||||
this._queryBuilderViewModel.updateCanGroupClauses();
|
||||
});
|
||||
this.isAndOrFocused = ko.observable<boolean>(false);
|
||||
@ -280,7 +280,7 @@ export default class QueryClauseViewModel {
|
||||
this._groupCheckSubscription.dispose();
|
||||
}
|
||||
|
||||
this.clauseGroup = null;
|
||||
this._queryBuilderViewModel = null;
|
||||
this.clauseGroup = undefined;
|
||||
this._queryBuilderViewModel = undefined;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ export default class Trigger {
|
||||
public triggerType: ko.Observable<string>;
|
||||
public triggerOperation: ko.Observable<string>;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
constructor(container: Explorer, collection: ViewModels.Collection, data: any) {
|
||||
this.nodeKind = "Trigger";
|
||||
this.container = container;
|
||||
@ -34,7 +35,7 @@ export default class Trigger {
|
||||
this.triggerType = ko.observable(data.triggerType);
|
||||
}
|
||||
|
||||
public select() {
|
||||
public select(): void {
|
||||
useSelectedNode.getState().setSelectedNode(this);
|
||||
TelemetryProcessor.trace(Action.SelectItem, ActionModifiers.Mark, {
|
||||
description: "Trigger node",
|
||||
@ -43,7 +44,8 @@ export default class Trigger {
|
||||
});
|
||||
}
|
||||
|
||||
public static create(source: ViewModels.Collection, event: MouseEvent) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public static create(source: ViewModels.Collection, _event: MouseEvent): void {
|
||||
const id = useTabs.getState().getTabs(ViewModels.CollectionTabKind.Triggers).length + 1;
|
||||
const trigger = <StoredProcedureDefinition>{
|
||||
id: "",
|
||||
@ -99,7 +101,7 @@ export default class Trigger {
|
||||
}
|
||||
};
|
||||
|
||||
public delete() {
|
||||
public delete(): void {
|
||||
useDialog.getState().showOkCancelModalDialog(
|
||||
"Confirm delete",
|
||||
"Are you sure you want to delete the trigger?",
|
||||
@ -110,7 +112,8 @@ export default class Trigger {
|
||||
useTabs.getState().closeTabsByComparator((tab) => tab.node && tab.node.rid === this.rid);
|
||||
this.collection.children.remove(this);
|
||||
},
|
||||
(reason) => {}
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
() => {}
|
||||
);
|
||||
},
|
||||
"Cancel",
|
||||
|
@ -64,7 +64,7 @@ export class GitHubOAuthService {
|
||||
return params.state;
|
||||
}
|
||||
|
||||
public async finishOAuth(params: IGitHubConnectorParams) {
|
||||
public async finishOAuth(params: IGitHubConnectorParams): Promise<void> {
|
||||
try {
|
||||
this.validateState(params.state);
|
||||
const response = await this.junoClient.getGitHubToken(params.code);
|
||||
@ -113,7 +113,7 @@ export class GitHubOAuthService {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public resetToken() {
|
||||
public resetToken(): void {
|
||||
this.token(undefined);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,8 @@ describe("Pinned repos", () => {
|
||||
});
|
||||
|
||||
it("updatePinnedRepos invokes pinned repos subscribers", async () => {
|
||||
const callback = jest.fn().mockImplementation((pinnedRepos: IPinnedRepo[]) => {});
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
const callback = jest.fn().mockImplementation(() => {});
|
||||
|
||||
junoClient.subscribeToPinnedRepos(callback);
|
||||
const response = await junoClient.updatePinnedRepos(samplePinnedRepos);
|
||||
@ -60,7 +61,8 @@ describe("Pinned repos", () => {
|
||||
});
|
||||
|
||||
it("getPinnedRepos invokes pinned repos subscribers", async () => {
|
||||
const callback = jest.fn().mockImplementation((pinnedRepos: IPinnedRepo[]) => {});
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
const callback = jest.fn().mockImplementation(() => {});
|
||||
|
||||
junoClient.subscribeToPinnedRepos(callback);
|
||||
const response = await junoClient.getPinnedRepos("scope");
|
||||
@ -153,7 +155,7 @@ describe("Gallery", () => {
|
||||
it("getSampleNotebooks", async () => {
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.getSampleNotebooks();
|
||||
@ -165,7 +167,7 @@ describe("Gallery", () => {
|
||||
it("getPublicNotebooks", async () => {
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.getPublicNotebooks();
|
||||
@ -178,7 +180,7 @@ describe("Gallery", () => {
|
||||
const id = "id";
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.getNotebookInfo(id);
|
||||
@ -191,7 +193,7 @@ describe("Gallery", () => {
|
||||
const id = "id";
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
text: () => undefined as any,
|
||||
text: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.getNotebookContent(id);
|
||||
@ -204,7 +206,7 @@ describe("Gallery", () => {
|
||||
const id = "id";
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
const response = await junoClient.increaseNotebookViews(id);
|
||||
|
||||
@ -218,7 +220,7 @@ describe("Gallery", () => {
|
||||
const id = "id";
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.increaseNotebookDownloadCount(id);
|
||||
@ -243,7 +245,7 @@ describe("Gallery", () => {
|
||||
const id = "id";
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.favoriteNotebook(id);
|
||||
@ -268,7 +270,7 @@ describe("Gallery", () => {
|
||||
const id = "id";
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.unfavoriteNotebook(id);
|
||||
@ -292,7 +294,7 @@ describe("Gallery", () => {
|
||||
it("getFavoriteNotebooks", async () => {
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.getFavoriteNotebooks();
|
||||
@ -315,7 +317,7 @@ describe("Gallery", () => {
|
||||
it("getPublishedNotebooks", async () => {
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.getPublishedNotebooks();
|
||||
@ -339,7 +341,7 @@ describe("Gallery", () => {
|
||||
const id = "id";
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.deleteNotebook(id);
|
||||
@ -369,7 +371,7 @@ describe("Gallery", () => {
|
||||
const addLinkToNotebookViewer = true;
|
||||
window.fetch = jest.fn().mockReturnValue({
|
||||
status: HttpStatusCodes.OK,
|
||||
json: () => undefined as any,
|
||||
json: () => undefined as undefined,
|
||||
});
|
||||
|
||||
const response = await junoClient.publishNotebook(name, description, tags, thumbnailUrl, content);
|
||||
|
@ -62,7 +62,7 @@ export interface IPublishNotebookRequest {
|
||||
description: string;
|
||||
tags: string[];
|
||||
thumbnailUrl: string;
|
||||
content: any;
|
||||
content: unknown;
|
||||
addLinkToNotebookViewer: boolean;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ describe("GalleryUtils", () => {
|
||||
});
|
||||
|
||||
it("downloadItem shows dialog in data explorer", () => {
|
||||
const container = {} as Explorer;
|
||||
const container = new Explorer();
|
||||
GalleryUtils.downloadItem(container, undefined, galleryItem, undefined);
|
||||
|
||||
expect(useDialog.getState().visible).toBe(true);
|
||||
|
@ -69,7 +69,11 @@ export const useTabs: UseStore<TabsState> = create((set, get) => ({
|
||||
if (tab.tabId === activeTab.tabId && tabIndex !== -1) {
|
||||
const tabToTheRight = updatedTabs[tabIndex];
|
||||
const lastOpenTab = updatedTabs[updatedTabs.length - 1];
|
||||
set({ activeTab: tabToTheRight || lastOpenTab });
|
||||
const newActiveTab = tabToTheRight ?? lastOpenTab;
|
||||
set({ activeTab: newActiveTab });
|
||||
if (newActiveTab) {
|
||||
newActiveTab.onActivate();
|
||||
}
|
||||
}
|
||||
|
||||
set({ openedTabs: updatedTabs });
|
||||
|
@ -15,18 +15,13 @@
|
||||
"target": "es2017",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"lib": [
|
||||
"es5",
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"lib": ["es5", "es6", "dom"],
|
||||
"jsx": "react",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"noEmit": true,
|
||||
"types": [
|
||||
"jest"
|
||||
]
|
||||
"types": ["jest"],
|
||||
"baseUrl": "src"
|
||||
},
|
||||
"typedocOptions": {
|
||||
"entryPoints": [
|
||||
@ -42,11 +37,6 @@
|
||||
"includes": "./src/SelfServe/Documentation",
|
||||
"disableSources": true
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*",
|
||||
"./utils/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"./src/**/__mocks__/**/*"
|
||||
]
|
||||
}
|
||||
"include": ["src", "./src/**/*", "./utils/**/*"],
|
||||
"exclude": ["./src/**/__mocks__/**/*"]
|
||||
}
|
||||
|
@ -227,6 +227,7 @@ module.exports = function (_env = {}, argv = {}) {
|
||||
rules,
|
||||
},
|
||||
resolve: {
|
||||
modules: [path.resolve(__dirname, "src"), "node_modules"],
|
||||
alias: {
|
||||
process: "process/browser",
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user