mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-07-04 02:53:40 +01:00
Async and await implemented for loadEntities
This commit is contained in:
parent
046e6eb5a4
commit
b7cb0b55a6
@ -535,11 +535,11 @@ input::-webkit-inner-spin-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.query-document-detail-list {
|
.query-document-detail-list {
|
||||||
overflow-x: hidden;
|
// overflow-x: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.query-table-clause-container {
|
.query-table-clause-container {
|
||||||
max-height: 80px;
|
max-height: 150px;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
@ -569,6 +569,14 @@ input::-webkit-inner-spin-button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.noData {
|
||||||
|
background-color: #e3e2e6;
|
||||||
|
color: #e3e2e6;
|
||||||
|
padding-top: 1px;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
// .pagination > li > div {
|
// .pagination > li > div {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { IDropdownOption, Image, Label, Stack, Text, TextField } from "@fluentui/react";
|
import { IDropdownOption, Image, Label, Stack, Text, TextField } from "@fluentui/react";
|
||||||
import { useBoolean } from "@fluentui/react-hooks";
|
import { useBoolean } from "@fluentui/react-hooks";
|
||||||
import React, { FunctionComponent, useEffect, useState } from "react";
|
import React, { FunctionComponent, useEffect, useState } from "react";
|
||||||
|
import * as _ from "underscore";
|
||||||
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
||||||
import RevertBackIcon from "../../../../images/RevertBack.svg";
|
import RevertBackIcon from "../../../../images/RevertBack.svg";
|
||||||
|
import { getErrorMessage, handleError } from "../../../Common/ErrorHandlingUtils";
|
||||||
import { TableEntity } from "../../../Common/TableEntity";
|
import { TableEntity } from "../../../Common/TableEntity";
|
||||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
@ -11,6 +13,7 @@ import * as DataTableUtilities from "../../Tables/DataTable/DataTableUtilities";
|
|||||||
import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel";
|
import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel";
|
||||||
import * as Entities from "../../Tables/Entities";
|
import * as Entities from "../../Tables/Entities";
|
||||||
import { CassandraAPIDataClient, CassandraTableKey, TableDataClient } from "../../Tables/TableDataClient";
|
import { CassandraAPIDataClient, CassandraTableKey, TableDataClient } from "../../Tables/TableDataClient";
|
||||||
|
import * as TableEntityProcessor from "../../Tables/TableEntityProcessor";
|
||||||
import * as Utilities from "../../Tables/Utilities";
|
import * as Utilities from "../../Tables/Utilities";
|
||||||
import NewQueryTablesTab from "../../Tabs/QueryTablesTab/QueryTablesTab";
|
import NewQueryTablesTab from "../../Tabs/QueryTablesTab/QueryTablesTab";
|
||||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
@ -115,10 +118,62 @@ export const AddTableEntityPanel: FunctionComponent<AddTableEntityPanelProps> =
|
|||||||
|
|
||||||
setIsExecuting(true);
|
setIsExecuting(true);
|
||||||
const entity: Entities.ITableEntity = entityFromAttributes(entities);
|
const entity: Entities.ITableEntity = entityFromAttributes(entities);
|
||||||
await tableDataClient.createDocument(queryTablesTab.collection, entity);
|
const newEntity: Entities.ITableEntity = await tableDataClient.createDocument(queryTablesTab.collection, entity);
|
||||||
// await tableEntityListViewModel.addEntityToCache(newEntity);
|
try {
|
||||||
reloadEntities();
|
await tableEntityListViewModel.addEntityToCache(newEntity);
|
||||||
closeSidePanel();
|
// if (!tryInsertNewHeaders(tableEntityListViewModel, newEntity)) {
|
||||||
|
// tableEntityListViewModel.redrawTableThrottled();
|
||||||
|
reloadEntities();
|
||||||
|
setFormError("");
|
||||||
|
// }
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = getErrorMessage(error);
|
||||||
|
setFormError(errorMessage);
|
||||||
|
handleError(errorMessage, "AddTableRow");
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
setIsExecuting(false);
|
||||||
|
}
|
||||||
|
// try {
|
||||||
|
// await tableDataClient.createDocument(queryTablesTab.collection, entity);
|
||||||
|
// reloadEntities();
|
||||||
|
// setFormError("");
|
||||||
|
// closeSidePanel();
|
||||||
|
// } catch (error) {
|
||||||
|
// const errorMessage = getErrorMessage(error);
|
||||||
|
// setFormError(errorMessage);
|
||||||
|
// handleError(errorMessage, "AddTableRow");
|
||||||
|
// } finally {
|
||||||
|
// setIsExecuting(false);
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
const tryInsertNewHeaders = (viewModel: TableEntityListViewModel, newEntity: Entities.ITableEntity): boolean => {
|
||||||
|
let newHeaders: string[] = [];
|
||||||
|
const keys = Object.keys(newEntity);
|
||||||
|
keys &&
|
||||||
|
keys.forEach((key: string) => {
|
||||||
|
if (
|
||||||
|
!_.contains(viewModel.headers, key) &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.attachments &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.etag &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.resourceId &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.self &&
|
||||||
|
(!(userContext.apiType === "Cassandra") || key !== TableConstants.EntityKeyNames.RowKey)
|
||||||
|
) {
|
||||||
|
newHeaders.push(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let newHeadersInserted = false;
|
||||||
|
if (newHeaders.length) {
|
||||||
|
if (!DataTableUtilities.checkForDefaultHeader(viewModel.headers)) {
|
||||||
|
newHeaders = viewModel.headers.concat(newHeaders);
|
||||||
|
}
|
||||||
|
viewModel.updateHeaders(newHeaders, /* notifyColumnChanges */ true, /* enablePrompt */ false);
|
||||||
|
newHeadersInserted = true;
|
||||||
|
}
|
||||||
|
return newHeadersInserted;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Add new entity row */
|
/* Add new entity row */
|
||||||
|
@ -4,10 +4,12 @@ import React, { FunctionComponent, useEffect, useState } from "react";
|
|||||||
import * as _ from "underscore";
|
import * as _ from "underscore";
|
||||||
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
||||||
import RevertBackIcon from "../../../../images/RevertBack.svg";
|
import RevertBackIcon from "../../../../images/RevertBack.svg";
|
||||||
|
import { getErrorMessage, handleError } from "../../../Common/ErrorHandlingUtils";
|
||||||
import { TableEntity } from "../../../Common/TableEntity";
|
import { TableEntity } from "../../../Common/TableEntity";
|
||||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||||
import { userContext } from "../../../UserContext";
|
import { userContext } from "../../../UserContext";
|
||||||
import * as TableConstants from "../../Tables/Constants";
|
import * as TableConstants from "../../Tables/Constants";
|
||||||
|
import * as DataTableUtilities from "../../Tables/DataTable/DataTableUtilities";
|
||||||
import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel";
|
import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel";
|
||||||
import * as Entities from "../../Tables/Entities";
|
import * as Entities from "../../Tables/Entities";
|
||||||
import { CassandraAPIDataClient, TableDataClient } from "../../Tables/TableDataClient";
|
import { CassandraAPIDataClient, TableDataClient } from "../../Tables/TableDataClient";
|
||||||
@ -213,9 +215,59 @@ export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps>
|
|||||||
const entity: Entities.ITableEntity = entityFromAttributes(entities);
|
const entity: Entities.ITableEntity = entityFromAttributes(entities);
|
||||||
const newTableDataClient = userContext.apiType === "Cassandra" ? cassandraApiClient : tableDataClient;
|
const newTableDataClient = userContext.apiType === "Cassandra" ? cassandraApiClient : tableDataClient;
|
||||||
const originalDocumentData = userContext.apiType === "Cassandra" ? originalDocument[0] : originalDocument;
|
const originalDocumentData = userContext.apiType === "Cassandra" ? originalDocument[0] : originalDocument;
|
||||||
await newTableDataClient.updateDocument(queryTablesTab.collection, originalDocumentData, entity);
|
// await newTableDataClient.updateDocument(queryTablesTab.collection, originalDocumentData, entity);
|
||||||
reloadEntities();
|
|
||||||
closeSidePanel();
|
try {
|
||||||
|
const newEntity: Entities.ITableEntity = await newTableDataClient.updateDocument(
|
||||||
|
queryTablesTab.collection,
|
||||||
|
originalDocumentData,
|
||||||
|
entity
|
||||||
|
);
|
||||||
|
await tableEntityListViewModel.updateCachedEntity(newEntity);
|
||||||
|
// if (!tryInsertNewHeaders(tableEntityListViewModel, newEntity)) {
|
||||||
|
// tableEntityListViewModel.redrawTableThrottled();
|
||||||
|
reloadEntities();
|
||||||
|
closeSidePanel();
|
||||||
|
// }
|
||||||
|
tableEntityListViewModel.selected.removeAll();
|
||||||
|
tableEntityListViewModel.selected.push(newEntity);
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = getErrorMessage(error);
|
||||||
|
handleError(errorMessage, "EditTableRow");
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
setIsExecuting(false);
|
||||||
|
}
|
||||||
|
// reloadEntities();
|
||||||
|
// closeSidePanel();
|
||||||
|
};
|
||||||
|
|
||||||
|
const tryInsertNewHeaders = (viewModel: TableEntityListViewModel, newEntity: Entities.ITableEntity): boolean => {
|
||||||
|
let newHeaders: string[] = [];
|
||||||
|
const keys = Object.keys(newEntity);
|
||||||
|
keys &&
|
||||||
|
keys.forEach((key: string) => {
|
||||||
|
if (
|
||||||
|
!_.contains(viewModel.headers, key) &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.attachments &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.etag &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.resourceId &&
|
||||||
|
key !== TableEntityProcessor.keyProperties.self &&
|
||||||
|
(!(userContext.apiType === "Cassandra") || key !== TableConstants.EntityKeyNames.RowKey)
|
||||||
|
) {
|
||||||
|
newHeaders.push(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let newHeadersInserted = false;
|
||||||
|
if (newHeaders.length) {
|
||||||
|
if (!DataTableUtilities.checkForDefaultHeader(viewModel.headers)) {
|
||||||
|
newHeaders = viewModel.headers.concat(newHeaders);
|
||||||
|
}
|
||||||
|
viewModel.updateHeaders(newHeaders, /* notifyColumnChanges */ true, /* enablePrompt */ false);
|
||||||
|
newHeadersInserted = true;
|
||||||
|
}
|
||||||
|
return newHeadersInserted;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add new entity row
|
// Add new entity row
|
||||||
|
@ -170,6 +170,10 @@ abstract class DataTableViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected renderPage(startIndex: number, pageSize: number) {
|
protected renderPage(startIndex: number, pageSize: number) {
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: DataTableViewModel.ts ~ line 179 ~ DataTableViewModel ~ renderPage ~ this.cache.data",
|
||||||
|
this.cache.data
|
||||||
|
);
|
||||||
var endIndex = pageSize < 0 ? this.cache.length : startIndex + pageSize;
|
var endIndex = pageSize < 0 ? this.cache.length : startIndex + pageSize;
|
||||||
var renderData = this.cache.data.slice(startIndex, endIndex);
|
var renderData = this.cache.data.slice(startIndex, endIndex);
|
||||||
|
|
||||||
|
@ -148,6 +148,97 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
this.headers = newHeaders;
|
this.headers = newHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async a(): Promise<Entities.ITableEntity[]> {
|
||||||
|
const a = await this.b();
|
||||||
|
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 153 ~ TableEntityListViewModel ~ a ~ a", a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async b(): Promise<Entities.ITableEntity[]> {
|
||||||
|
const b = await this.c();
|
||||||
|
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 157 ~ TableEntityListViewModel ~ b ~ b", b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async c(tableQuery?: Entities.ITableQuery, downloadSize?: number): Promise<any> {
|
||||||
|
var c: any;
|
||||||
|
var d: any;
|
||||||
|
if (this._documentIterator && this.continuationToken) {
|
||||||
|
// TODO handle Cassandra case
|
||||||
|
|
||||||
|
d = await this._documentIterator.fetchNext();
|
||||||
|
let entities: Entities.ITableEntity[] = TableEntityProcessor.convertDocumentsToEntities(d.resources);
|
||||||
|
let finalEntities: IListTableEntitiesSegmentedResult = <IListTableEntitiesSegmentedResult>{
|
||||||
|
Results: entities,
|
||||||
|
ContinuationToken: this._documentIterator.hasMoreResults(),
|
||||||
|
};
|
||||||
|
c = finalEntities;
|
||||||
|
|
||||||
|
// .fetchNext()
|
||||||
|
// .then((response) => response.resources)
|
||||||
|
// .then((documents: any[]) => {
|
||||||
|
// let entities: Entities.ITableEntity[] = TableEntityProcessor.convertDocumentsToEntities(documents);
|
||||||
|
// let finalEntities: IListTableEntitiesSegmentedResult = <IListTableEntitiesSegmentedResult>{
|
||||||
|
// Results: entities,
|
||||||
|
// ContinuationToken: this._documentIterator.hasMoreResults(),
|
||||||
|
// };
|
||||||
|
// return Promise.resolve(finalEntities);
|
||||||
|
// });
|
||||||
|
} else {
|
||||||
|
c = await this.queryTablesTab.container.tableDataClient.queryDocuments(
|
||||||
|
this.queryTablesTab.collection,
|
||||||
|
this.sqlQuery(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const c = await this.queryTablesTab.container.tableDataClient.queryDocuments(
|
||||||
|
// this.queryTablesTab.collection,
|
||||||
|
// this.sqlQuery(),
|
||||||
|
// true
|
||||||
|
// );
|
||||||
|
const result = c;
|
||||||
|
if (result) {
|
||||||
|
if (!this._documentIterator) {
|
||||||
|
this._documentIterator = result.iterator;
|
||||||
|
}
|
||||||
|
var actualDownloadSize: number = 0;
|
||||||
|
var entities = result.Results;
|
||||||
|
actualDownloadSize = entities.length;
|
||||||
|
|
||||||
|
this.continuationToken = this.isCancelled ? null : result.ContinuationToken;
|
||||||
|
|
||||||
|
if (!this.continuationToken) {
|
||||||
|
this.allDownloaded = true;
|
||||||
|
}
|
||||||
|
if (this.isCacheValid(this.tableQuery)) {
|
||||||
|
// Append to cache.
|
||||||
|
this.cache.data = this.cache.data.concat(entities.slice(0));
|
||||||
|
} else {
|
||||||
|
// Create cache.
|
||||||
|
this.cache.data = entities;
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: TableEntityListViewModel.ts ~ line 797 ~ TableEntityListViewModel ~ .then ~ this.cache.data",
|
||||||
|
this.cache.data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cache.tableQuery = this.tableQuery;
|
||||||
|
this.cache.serverCallInProgress = false;
|
||||||
|
|
||||||
|
var nextDownloadSize: number = this.downloadSize - actualDownloadSize;
|
||||||
|
if (nextDownloadSize === 0 && this.tableQuery.top) {
|
||||||
|
this.allDownloaded = true;
|
||||||
|
}
|
||||||
|
if (this.allDownloaded || nextDownloadSize === 0) {
|
||||||
|
return Promise.resolve(this.cache.data);
|
||||||
|
}
|
||||||
|
return this.c(this.tableQuery, nextDownloadSize);
|
||||||
|
}
|
||||||
|
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 161 ~ TableEntityListViewModel ~ c ~ data", c);
|
||||||
|
return this.cache.data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback function called by datatable to fetch the next page of data and render.
|
* This callback function called by datatable to fetch the next page of data and render.
|
||||||
* sSource - ajax URL of data source, ignored in our case as we are not using ajax.
|
* sSource - ajax URL of data source, ignored in our case as we are not using ajax.
|
||||||
@ -155,10 +246,10 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
* fnCallback - is the render callback with data to render.
|
* fnCallback - is the render callback with data to render.
|
||||||
* oSetting: current settings used for table initialization.
|
* oSetting: current settings used for table initialization.
|
||||||
*/
|
*/
|
||||||
public renderNextPageAndupdateCache(sSource?: any, aoData?: any, fnCallback?: any): Promise<void> {
|
|
||||||
var tablePageSize: number = 100;
|
public async renderNextPageAndupdateCache(): Promise<Entities.ITableEntity[]> {
|
||||||
|
var tablePageSize: number;
|
||||||
var prefetchNeeded = true;
|
var prefetchNeeded = true;
|
||||||
// var columnSortOrder: any;
|
|
||||||
// Threshold(pages) for triggering cache prefetch.
|
// Threshold(pages) for triggering cache prefetch.
|
||||||
// If number remaining pages in cache falls below prefetchThreshold prefetch will be triggered.
|
// If number remaining pages in cache falls below prefetchThreshold prefetch will be triggered.
|
||||||
var prefetchThreshold = 10;
|
var prefetchThreshold = 10;
|
||||||
@ -169,12 +260,8 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
// Check if prefetch needed.
|
// Check if prefetch needed.
|
||||||
if (this.tablePageStartIndex + tablePageSize <= this.cache.length || this.allDownloaded) {
|
if (this.tablePageStartIndex + tablePageSize <= this.cache.length || this.allDownloaded) {
|
||||||
prefetchNeeded = false;
|
prefetchNeeded = false;
|
||||||
// if (columnSortOrder && (!this.cache.sortOrder || !_.isEqual(this.cache.sortOrder, columnSortOrder))) {
|
|
||||||
// this.sortColumns(columnSortOrder, oSettings);
|
|
||||||
// }
|
|
||||||
this.tablePageStartIndex = 0;
|
this.tablePageStartIndex = 0;
|
||||||
this.renderPage(this.tablePageStartIndex, tablePageSize);
|
this.renderPage(this.tablePageStartIndex, this.cache.length);
|
||||||
// this.renderPage(0, 100);
|
|
||||||
if (
|
if (
|
||||||
!this.allDownloaded &&
|
!this.allDownloaded &&
|
||||||
this.tablePageStartIndex > 0 && // This is a case now that we can hit this as we re-construct table when we update column
|
this.tablePageStartIndex > 0 && // This is a case now that we can hit this as we re-construct table when we update column
|
||||||
@ -191,24 +278,17 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
|
|
||||||
if (prefetchNeeded) {
|
if (prefetchNeeded) {
|
||||||
var downloadSize = tableQuery.top || this.downloadSize;
|
var downloadSize = tableQuery.top || this.downloadSize;
|
||||||
this.prefetchAndRender(
|
return await this.prefetchAndRender(tableQuery, 0, tablePageSize, downloadSize);
|
||||||
tableQuery,
|
} else {
|
||||||
this.tablePageStartIndex,
|
return this.cache.data;
|
||||||
tablePageSize,
|
|
||||||
downloadSize
|
|
||||||
// draw,
|
|
||||||
// oSettings,
|
|
||||||
// columnSortOrder
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public addEntityToCache(entity: Entities.ITableEntity): Q.Promise<any> {
|
public addEntityToCache(entity: Entities.ITableEntity): Q.Promise<any> {
|
||||||
// Delay the add operation if we are fetching data from server, so as to avoid race condition.
|
// Delay the add operation if we are fetching data from server, so as to avoid race condition.
|
||||||
if (this.cache.serverCallInProgress) {
|
if (this.cache.serverCallInProgress) {
|
||||||
return Utilities.delay(this.pollingInterval).then(() => {
|
Utilities.delay(this.pollingInterval).then(() => {
|
||||||
return this.updateCachedEntity(entity);
|
this.updateCachedEntity(entity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,8 +304,8 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
public updateCachedEntity(entity: Entities.ITableEntity): Q.Promise<any> {
|
public updateCachedEntity(entity: Entities.ITableEntity): Q.Promise<any> {
|
||||||
// Delay the add operation if we are fetching data from server, so as to avoid race condition.
|
// Delay the add operation if we are fetching data from server, so as to avoid race condition.
|
||||||
if (this.cache.serverCallInProgress) {
|
if (this.cache.serverCallInProgress) {
|
||||||
return Utilities.delay(this.pollingInterval).then(() => {
|
Utilities.delay(this.pollingInterval).then(() => {
|
||||||
return this.updateCachedEntity(entity);
|
this.updateCachedEntity(entity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var oldEntityIndex: number = _.findIndex(
|
var oldEntityIndex: number = _.findIndex(
|
||||||
@ -245,8 +325,8 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
|
|
||||||
// Delay the remove operation if we are fetching data from server, so as to avoid race condition.
|
// Delay the remove operation if we are fetching data from server, so as to avoid race condition.
|
||||||
if (this.cache.serverCallInProgress) {
|
if (this.cache.serverCallInProgress) {
|
||||||
return Utilities.delay(this.pollingInterval).then(() => {
|
Utilities.delay(this.pollingInterval).then(() => {
|
||||||
return this.removeEntitiesFromCache(entities);
|
this.removeEntitiesFromCache(entities);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,87 +434,89 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private prefetchAndRender(
|
private async prefetchAndRender(
|
||||||
tableQuery: Entities.ITableQuery,
|
tableQuery: Entities.ITableQuery,
|
||||||
tablePageStartIndex: number,
|
tablePageStartIndex: number,
|
||||||
tablePageSize: number,
|
tablePageSize: number,
|
||||||
downloadSize: number
|
downloadSize: number
|
||||||
// draw: number,/
|
): Promise<Entities.ITableEntity[]> {
|
||||||
// oSettings: any,
|
|
||||||
// columnSortOrder: any
|
|
||||||
): void {
|
|
||||||
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 366 ~ TableEntityListViewModel ~ prefetchAndRender");
|
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 366 ~ TableEntityListViewModel ~ prefetchAndRender");
|
||||||
this.queryErrorMessage(null);
|
this.queryErrorMessage(null);
|
||||||
if (this.cache.serverCallInProgress) {
|
if (this.cache.serverCallInProgress) {
|
||||||
return;
|
return undefined;
|
||||||
}
|
}
|
||||||
this.prefetchData(tableQuery, downloadSize, /* currentRetry */ 0)
|
try {
|
||||||
.then((result: IListTableEntitiesSegmentedResult) => {
|
const result = await this.prefetchData(tableQuery, downloadSize, /* currentRetry */ 0);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return undefined;
|
||||||
|
}
|
||||||
|
// Cache is assigned using prefetchData
|
||||||
|
var entities = this.cache.data;
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: TableEntityListViewModel.ts ~ line 430 ~ TableEntityListViewModel ~ .then ~ entities outside",
|
||||||
|
entities
|
||||||
|
);
|
||||||
|
if (userContext.apiType === "Cassandra" && DataTableUtilities.checkForDefaultHeader(this.headers)) {
|
||||||
|
(<CassandraAPIDataClient>this.queryTablesTab.container.tableDataClient)
|
||||||
|
.getTableSchema(this.queryTablesTab.collection)
|
||||||
|
.then((headers: CassandraTableKey[]) => {
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: TableEntityListViewModel.ts ~ line 438 ~ TableEntityListViewModel ~ .then ~ headers",
|
||||||
|
headers
|
||||||
|
);
|
||||||
|
this.updateHeaders(
|
||||||
|
headers.map((header) => header.property),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: TableEntityListViewModel.ts ~ line 430 ~ TableEntityListViewModel ~ .then ~ entities inside",
|
||||||
|
entities
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var selectedHeadersUnion: string[] = DataTableUtilities.getPropertyIntersectionFromTableEntities(
|
||||||
|
entities,
|
||||||
|
userContext.apiType === "Cassandra"
|
||||||
|
);
|
||||||
|
var newHeaders: string[] = _.difference(selectedHeadersUnion, this.headers);
|
||||||
|
if (newHeaders.length > 0) {
|
||||||
|
// Any new columns found will be added into headers array, which will trigger a re-render of the DataTable.
|
||||||
|
// So there is no need to call it here.
|
||||||
|
this.updateHeaders(newHeaders, /* notifyColumnChanges */ true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
this.renderPage(tablePageStartIndex, entities.length);
|
||||||
|
|
||||||
var entities = this.cache.data;
|
return result;
|
||||||
if (userContext.apiType === "Cassandra" && DataTableUtilities.checkForDefaultHeader(this.headers)) {
|
} catch (error) {
|
||||||
(<CassandraAPIDataClient>this.queryTablesTab.container.tableDataClient)
|
const parsedErrors = parseError(error);
|
||||||
.getTableSchema(this.queryTablesTab.collection)
|
var errors = parsedErrors.map((error) => {
|
||||||
.then((headers: CassandraTableKey[]) => {
|
return <ViewModels.QueryError>{
|
||||||
this.updateHeaders(
|
message: error.message,
|
||||||
headers.map((header) => header.property),
|
start: error.location ? error.location.start : undefined,
|
||||||
true
|
end: error.location ? error.location.end : undefined,
|
||||||
);
|
code: error.code,
|
||||||
});
|
severity: error.severity,
|
||||||
} else {
|
};
|
||||||
var selectedHeadersUnion: string[] = DataTableUtilities.getPropertyIntersectionFromTableEntities(
|
|
||||||
entities,
|
|
||||||
userContext.apiType === "Cassandra"
|
|
||||||
);
|
|
||||||
var newHeaders: string[] = _.difference(selectedHeadersUnion, this.headers);
|
|
||||||
if (newHeaders.length > 0) {
|
|
||||||
// Any new columns found will be added into headers array, which will trigger a re-render of the DataTable.
|
|
||||||
// So there is no need to call it here.
|
|
||||||
this.updateHeaders(newHeaders, /* notifyColumnChanges */ true);
|
|
||||||
} else {
|
|
||||||
if (columnSortOrder) {
|
|
||||||
this.sortColumns(columnSortOrder, oSettings);
|
|
||||||
}
|
|
||||||
// this.renderPage(renderCallBack, draw, tablePageStartIndex, tablePageSize, oSettings);
|
|
||||||
}
|
|
||||||
this.renderPage(0, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.ExceedMaximumRetries) {
|
|
||||||
var message: string = "We are having trouble getting your data. Please try again."; // localize
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error: any) => {
|
|
||||||
const parsedErrors = parseError(error);
|
|
||||||
var errors = parsedErrors.map((error) => {
|
|
||||||
return <ViewModels.QueryError>{
|
|
||||||
message: error.message,
|
|
||||||
start: error.location ? error.location.start : undefined,
|
|
||||||
end: error.location ? error.location.end : undefined,
|
|
||||||
code: error.code,
|
|
||||||
severity: error.severity,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
this.queryErrorMessage(errors[0].message);
|
|
||||||
if (this.queryTablesTab.onLoadStartKey != null && this.queryTablesTab.onLoadStartKey != undefined) {
|
|
||||||
TelemetryProcessor.traceFailure(
|
|
||||||
Action.Tab,
|
|
||||||
{
|
|
||||||
databaseName: this.queryTablesTab.collection.databaseId,
|
|
||||||
collectionName: this.queryTablesTab.collection.id(),
|
|
||||||
dataExplorerArea: Areas.Tab,
|
|
||||||
tabTitle: this.queryTablesTab.tabTitle(),
|
|
||||||
error: error,
|
|
||||||
},
|
|
||||||
this.queryTablesTab.onLoadStartKey
|
|
||||||
);
|
|
||||||
this.queryTablesTab.onLoadStartKey = null;
|
|
||||||
}
|
|
||||||
DataTableUtilities.turnOffProgressIndicator();
|
|
||||||
});
|
});
|
||||||
|
this.queryErrorMessage(errors[0].message);
|
||||||
|
if (this.queryTablesTab.onLoadStartKey != null && this.queryTablesTab.onLoadStartKey != undefined) {
|
||||||
|
TelemetryProcessor.traceFailure(
|
||||||
|
Action.Tab,
|
||||||
|
{
|
||||||
|
databaseName: this.queryTablesTab.collection.databaseId,
|
||||||
|
collectionName: this.queryTablesTab.collection.id(),
|
||||||
|
dataExplorerArea: Areas.Tab,
|
||||||
|
tabTitle: this.queryTablesTab.tabTitle(),
|
||||||
|
error: error,
|
||||||
|
},
|
||||||
|
this.queryTablesTab.onLoadStartKey
|
||||||
|
);
|
||||||
|
this.queryTablesTab.onLoadStartKey = null;
|
||||||
|
}
|
||||||
|
DataTableUtilities.turnOffProgressIndicator();
|
||||||
|
}
|
||||||
|
// return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -448,52 +530,54 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
* Note that this also means that we can get less entities than the requested download size in a successful call.
|
* Note that this also means that we can get less entities than the requested download size in a successful call.
|
||||||
* See Microsoft Azure API Documentation at: https://msdn.microsoft.com/en-us/library/azure/dd135718.aspx
|
* See Microsoft Azure API Documentation at: https://msdn.microsoft.com/en-us/library/azure/dd135718.aspx
|
||||||
*/
|
*/
|
||||||
private prefetchData(
|
|
||||||
|
private async prefetchData(
|
||||||
tableQuery: Entities.ITableQuery,
|
tableQuery: Entities.ITableQuery,
|
||||||
downloadSize: number,
|
downloadSize: number,
|
||||||
currentRetry: number = 0
|
currentRetry: number = 0
|
||||||
): Q.Promise<any> {
|
): Promise<any> {
|
||||||
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 456 ~ TableEntityListViewModel ~ prefetchData");
|
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 456 ~ TableEntityListViewModel ~ prefetchData");
|
||||||
|
var entities: any;
|
||||||
if (!this.cache.serverCallInProgress) {
|
if (!this.cache.serverCallInProgress) {
|
||||||
this.cache.serverCallInProgress = true;
|
this.cache.serverCallInProgress = true;
|
||||||
this.allDownloaded = false;
|
this.allDownloaded = false;
|
||||||
this.lastPrefetchTime = new Date().getTime();
|
this.lastPrefetchTime = new Date().getTime();
|
||||||
var time = this.lastPrefetchTime;
|
var time = this.lastPrefetchTime;
|
||||||
|
|
||||||
var promise: Q.Promise<IListTableEntitiesSegmentedResult>;
|
var promise: Promise<IListTableEntitiesSegmentedResult>;
|
||||||
if (this._documentIterator && this.continuationToken) {
|
try {
|
||||||
// TODO handle Cassandra case
|
if (this._documentIterator && this.continuationToken) {
|
||||||
|
// TODO handle Cassandra case
|
||||||
promise = Q(this._documentIterator.fetchNext().then((response) => response.resources)).then(
|
const fetchNext = await this._documentIterator.fetchNext();
|
||||||
(documents: any[]) => {
|
let fetchNextEntities: Entities.ITableEntity[] = TableEntityProcessor.convertDocumentsToEntities(
|
||||||
let entities: Entities.ITableEntity[] = TableEntityProcessor.convertDocumentsToEntities(documents);
|
fetchNext.resources
|
||||||
let finalEntities: IListTableEntitiesSegmentedResult = <IListTableEntitiesSegmentedResult>{
|
);
|
||||||
Results: entities,
|
let finalEntities: IListTableEntitiesSegmentedResult = <IListTableEntitiesSegmentedResult>{
|
||||||
ContinuationToken: this._documentIterator.hasMoreResults(),
|
Results: fetchNextEntities,
|
||||||
};
|
ContinuationToken: this._documentIterator.hasMoreResults(),
|
||||||
return Q.resolve(finalEntities);
|
};
|
||||||
}
|
entities = finalEntities;
|
||||||
);
|
} else if (this.continuationToken && userContext.apiType === "Cassandra") {
|
||||||
} else if (this.continuationToken && userContext.apiType === "Cassandra") {
|
entities = this.queryTablesTab.container.tableDataClient.queryDocuments(
|
||||||
promise = Q(
|
|
||||||
this.queryTablesTab.container.tableDataClient.queryDocuments(
|
|
||||||
this.queryTablesTab.collection,
|
this.queryTablesTab.collection,
|
||||||
this.cqlQuery(),
|
this.cqlQuery(),
|
||||||
true,
|
true,
|
||||||
this.continuationToken
|
this.continuationToken
|
||||||
)
|
);
|
||||||
);
|
} else {
|
||||||
} else {
|
let query = this.sqlQuery();
|
||||||
let query = this.sqlQuery();
|
if (userContext.apiType === "Cassandra") {
|
||||||
if (userContext.apiType === "Cassandra") {
|
query = this.cqlQuery();
|
||||||
query = this.cqlQuery();
|
}
|
||||||
|
entities = await this.queryTablesTab.container.tableDataClient.queryDocuments(
|
||||||
|
this.queryTablesTab.collection,
|
||||||
|
query,
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
promise = Q(
|
|
||||||
this.queryTablesTab.container.tableDataClient.queryDocuments(this.queryTablesTab.collection, query, true)
|
const result = entities;
|
||||||
);
|
if (result) {
|
||||||
}
|
|
||||||
return promise
|
|
||||||
.then((result: IListTableEntitiesSegmentedResult) => {
|
|
||||||
if (!this._documentIterator) {
|
if (!this._documentIterator) {
|
||||||
this._documentIterator = result.iterator;
|
this._documentIterator = result.iterator;
|
||||||
}
|
}
|
||||||
@ -503,14 +587,14 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
// And as another service call is during process, we don't set serverCallInProgress to false here.
|
// And as another service call is during process, we don't set serverCallInProgress to false here.
|
||||||
// Thus, end the prefetch.
|
// Thus, end the prefetch.
|
||||||
if (this.lastPrefetchTime !== time) {
|
if (this.lastPrefetchTime !== time) {
|
||||||
return Q.resolve(null);
|
return Promise.resolve(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
var entities = result.Results;
|
var entities = result.Results;
|
||||||
actualDownloadSize = entities.length;
|
actualDownloadSize = entities.length;
|
||||||
|
|
||||||
// Queries can fetch no results and still return a continuation header. See prefetchAndRender() method.
|
// Queries can fetch no results and still return a continuation header. See prefetchAndRender() method.
|
||||||
this.continuationToken = this.isCancelled ? null : result.ContinuationToken;
|
this.continuationToken = this.isCancelled ? undefined : result.ContinuationToken;
|
||||||
|
|
||||||
if (!this.continuationToken) {
|
if (!this.continuationToken) {
|
||||||
this.allDownloaded = true;
|
this.allDownloaded = true;
|
||||||
@ -519,9 +603,23 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
if (this.isCacheValid(tableQuery)) {
|
if (this.isCacheValid(tableQuery)) {
|
||||||
// Append to cache.
|
// Append to cache.
|
||||||
this.cache.data = this.cache.data.concat(entities.slice(0));
|
this.cache.data = this.cache.data.concat(entities.slice(0));
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: TableEntityListViewModel.ts ~ line 667 ~ TableEntityListViewModel ~ .then ~ this.cache.data",
|
||||||
|
this.cache.data
|
||||||
|
);
|
||||||
|
var p = new Promise<Entities.ITableEntity[]>((resolve) => {
|
||||||
|
if (this.cache.data) {
|
||||||
|
resolve(this.cache.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return p;
|
||||||
} else {
|
} else {
|
||||||
// Create cache.
|
// Create cache.
|
||||||
this.cache.data = entities;
|
this.cache.data = entities;
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: TableEntityListViewModel.ts ~ line 671 ~ TableEntityListViewModel ~ .then ~ this.cache.data",
|
||||||
|
this.cache.data
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cache.tableQuery = tableQuery;
|
this.cache.tableQuery = tableQuery;
|
||||||
@ -532,30 +630,20 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
|||||||
this.allDownloaded = true;
|
this.allDownloaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are three possible results for a prefetch:
|
|
||||||
// 1. Continuation token is null or fetched items' size reaches predefined.
|
|
||||||
// 2. Continuation token is not null and fetched items' size hasn't reach predefined.
|
|
||||||
// 2.1 Retry times has reached predefined maximum.
|
|
||||||
// 2.2 Retry times hasn't reached predefined maximum.
|
|
||||||
// Correspondingly,
|
|
||||||
// For #1, end prefetch.
|
|
||||||
// For #2.1, set prefetch exceeds maximum retry number and end prefetch.
|
|
||||||
// For #2.2, go to next round prefetch.
|
|
||||||
if (this.allDownloaded || nextDownloadSize === 0) {
|
if (this.allDownloaded || nextDownloadSize === 0) {
|
||||||
return Q.resolve(result);
|
return Promise.resolve(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentRetry >= TableEntityListViewModel._maximumNumberOfPrefetchRetries) {
|
if (currentRetry >= TableEntityListViewModel._maximumNumberOfPrefetchRetries) {
|
||||||
result.ExceedMaximumRetries = true;
|
result.ExceedMaximumRetries = true;
|
||||||
return Q.resolve(result);
|
return Promise.resolve(result);
|
||||||
}
|
}
|
||||||
return this.prefetchData(tableQuery, nextDownloadSize, currentRetry + 1);
|
return this.prefetchData(tableQuery, nextDownloadSize, currentRetry + 1);
|
||||||
})
|
}
|
||||||
.catch((error: Error) => {
|
} catch (error) {
|
||||||
this.cache.serverCallInProgress = false;
|
this.cache.serverCallInProgress = false;
|
||||||
return Q.reject(error);
|
return Promise.reject(error);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,10 @@ export default class QueryViewModel {
|
|||||||
this._tableEntityListViewModel.oDataQuery(filter);
|
this._tableEntityListViewModel.oDataQuery(filter);
|
||||||
this._tableEntityListViewModel.sqlQuery(this.setSqlFilter(queryTableRows));
|
this._tableEntityListViewModel.sqlQuery(this.setSqlFilter(queryTableRows));
|
||||||
this._tableEntityListViewModel.cqlQuery(filter);
|
this._tableEntityListViewModel.cqlQuery(filter);
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: QueryViewModel.tsx ~ line 165 ~ QueryViewModel ~ this._tableEntityListViewModel.sqlQuery()",
|
||||||
|
this._tableEntityListViewModel.sqlQuery()
|
||||||
|
);
|
||||||
|
|
||||||
return userContext.apiType !== "Cassandra"
|
return userContext.apiType !== "Cassandra"
|
||||||
? this._tableEntityListViewModel.sqlQuery()
|
? this._tableEntityListViewModel.sqlQuery()
|
||||||
|
@ -1,285 +0,0 @@
|
|||||||
import * as ko from "knockout";
|
|
||||||
import React from "react";
|
|
||||||
import AddEntityIcon from "../../../images/AddEntity.svg";
|
|
||||||
import DeleteEntitiesIcon from "../../../images/DeleteEntities.svg";
|
|
||||||
import EditEntityIcon from "../../../images/Edit-entity.svg";
|
|
||||||
import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg";
|
|
||||||
import QueryBuilderIcon from "../../../images/Query-Builder.svg";
|
|
||||||
import QueryTextIcon from "../../../images/Query-Text.svg";
|
|
||||||
import * as ViewModels from "../../Contracts/ViewModels";
|
|
||||||
import { useSidePanel } from "../../hooks/useSidePanel";
|
|
||||||
import { userContext } from "../../UserContext";
|
|
||||||
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
|
|
||||||
import Explorer from "../Explorer";
|
|
||||||
import { AddTableEntityPanel } from "../Panes/Tables/AddTableEntityPanel";
|
|
||||||
import { EditTableEntityPanel } from "../Panes/Tables/EditTableEntityPanel";
|
|
||||||
import TableCommands from "../Tables/DataTable/TableCommands";
|
|
||||||
import TableEntityListViewModel from "../Tables/DataTable/TableEntityListViewModel";
|
|
||||||
import QueryViewModel from "../Tables/QueryBuilder/QueryViewModel";
|
|
||||||
import { CassandraAPIDataClient, TableDataClient } from "../Tables/TableDataClient";
|
|
||||||
import template from "./QueryTablesTab.html";
|
|
||||||
import TabsBase from "./TabsBase";
|
|
||||||
|
|
||||||
// Will act as table explorer class
|
|
||||||
export default class QueryTablesTab extends TabsBase {
|
|
||||||
public readonly html = template;
|
|
||||||
public collection: ViewModels.Collection;
|
|
||||||
public tableEntityListViewModel = ko.observable<TableEntityListViewModel>();
|
|
||||||
public queryViewModel = ko.observable<QueryViewModel>();
|
|
||||||
public tableCommands: TableCommands;
|
|
||||||
public tableDataClient: TableDataClient;
|
|
||||||
|
|
||||||
public queryText = ko.observable("PartitionKey eq 'partitionKey1'"); // Start out with an example they can modify
|
|
||||||
public selectedQueryText = ko.observable("").extend({ notify: "always" });
|
|
||||||
|
|
||||||
public executeQueryButton: ViewModels.Button;
|
|
||||||
public addEntityButton: ViewModels.Button;
|
|
||||||
public editEntityButton: ViewModels.Button;
|
|
||||||
public deleteEntityButton: ViewModels.Button;
|
|
||||||
public queryBuilderButton: ViewModels.Button;
|
|
||||||
public queryTextButton: ViewModels.Button;
|
|
||||||
public container: Explorer;
|
|
||||||
|
|
||||||
constructor(options: ViewModels.TabOptions) {
|
|
||||||
super(options);
|
|
||||||
|
|
||||||
this.container = options.collection && options.collection.container;
|
|
||||||
this.tableCommands = new TableCommands(this.container);
|
|
||||||
this.tableDataClient = this.container.tableDataClient;
|
|
||||||
this.tableEntityListViewModel(new TableEntityListViewModel(this.tableCommands, this));
|
|
||||||
this.tableEntityListViewModel().queryTablesTab = this;
|
|
||||||
this.queryViewModel(new QueryViewModel(this));
|
|
||||||
const sampleQuerySubscription = this.tableEntityListViewModel().items.subscribe(() => {
|
|
||||||
if (this.tableEntityListViewModel().items().length > 0 && userContext.apiType === "Tables") {
|
|
||||||
this.queryViewModel().queryBuilderViewModel().setExample();
|
|
||||||
}
|
|
||||||
sampleQuerySubscription.dispose();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.executeQueryButton = {
|
|
||||||
enabled: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
|
|
||||||
visible: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.queryBuilderButton = {
|
|
||||||
enabled: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
|
|
||||||
visible: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
|
|
||||||
isSelected: ko.computed<boolean>(() => {
|
|
||||||
return this.queryViewModel() ? this.queryViewModel().isHelperActive() : false;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.queryTextButton = {
|
|
||||||
enabled: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
|
|
||||||
visible: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
|
|
||||||
isSelected: ko.computed<boolean>(() => {
|
|
||||||
return this.queryViewModel() ? this.queryViewModel().isEditorActive() : false;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.addEntityButton = {
|
|
||||||
enabled: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
|
|
||||||
visible: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.editEntityButton = {
|
|
||||||
enabled: ko.computed<boolean>(() => {
|
|
||||||
return this.tableCommands.isEnabled(
|
|
||||||
TableCommands.editEntityCommand,
|
|
||||||
this.tableEntityListViewModel().selected()
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
|
|
||||||
visible: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.deleteEntityButton = {
|
|
||||||
enabled: ko.computed<boolean>(() => {
|
|
||||||
return this.tableCommands.isEnabled(
|
|
||||||
TableCommands.deleteEntitiesCommand,
|
|
||||||
this.tableEntityListViewModel().selected()
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
|
|
||||||
visible: ko.computed<boolean>(() => {
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.buildCommandBarOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onAddEntityClick = (): void => {
|
|
||||||
useSidePanel
|
|
||||||
.getState()
|
|
||||||
.openSidePanel(
|
|
||||||
"Add Table Row",
|
|
||||||
<AddTableEntityPanel
|
|
||||||
tableDataClient={this.tableDataClient}
|
|
||||||
queryTablesTab={this}
|
|
||||||
tableEntityListViewModel={this.tableEntityListViewModel()}
|
|
||||||
cassandraApiClient={new CassandraAPIDataClient()}
|
|
||||||
/>,
|
|
||||||
"700px"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
public onEditEntityClick = (): void => {
|
|
||||||
useSidePanel
|
|
||||||
.getState()
|
|
||||||
.openSidePanel(
|
|
||||||
"Edit Table Entity",
|
|
||||||
<EditTableEntityPanel
|
|
||||||
tableDataClient={this.tableDataClient}
|
|
||||||
queryTablesTab={this}
|
|
||||||
tableEntityListViewModel={this.tableEntityListViewModel()}
|
|
||||||
cassandraApiClient={new CassandraAPIDataClient()}
|
|
||||||
/>,
|
|
||||||
"700px"
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
public onDeleteEntityClick = (): void => {
|
|
||||||
this.tableCommands.deleteEntitiesCommand(this.tableEntityListViewModel());
|
|
||||||
};
|
|
||||||
|
|
||||||
public onActivate(): void {
|
|
||||||
super.onActivate();
|
|
||||||
const columns =
|
|
||||||
!!this.tableEntityListViewModel() &&
|
|
||||||
!!this.tableEntityListViewModel().table &&
|
|
||||||
this.tableEntityListViewModel().table.columns;
|
|
||||||
if (columns) {
|
|
||||||
columns.adjust();
|
|
||||||
$(window).resize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getTabsButtons(): CommandButtonComponentProps[] {
|
|
||||||
const buttons: CommandButtonComponentProps[] = [];
|
|
||||||
if (this.queryBuilderButton.visible()) {
|
|
||||||
const label = userContext.apiType === "Cassandra" ? "CQL Query Builder" : "Query Builder";
|
|
||||||
buttons.push({
|
|
||||||
iconSrc: QueryBuilderIcon,
|
|
||||||
iconAlt: label,
|
|
||||||
onCommandClick: () => this.queryViewModel().selectHelper(),
|
|
||||||
commandButtonLabel: label,
|
|
||||||
ariaLabel: label,
|
|
||||||
hasPopup: false,
|
|
||||||
disabled: !this.queryBuilderButton.enabled(),
|
|
||||||
isSelected: this.queryBuilderButton.isSelected(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.queryTextButton.visible()) {
|
|
||||||
const label = userContext.apiType === "Cassandra" ? "CQL Query Text" : "Query Text";
|
|
||||||
buttons.push({
|
|
||||||
iconSrc: QueryTextIcon,
|
|
||||||
iconAlt: label,
|
|
||||||
onCommandClick: () => this.queryViewModel().selectEditor(),
|
|
||||||
commandButtonLabel: label,
|
|
||||||
ariaLabel: label,
|
|
||||||
hasPopup: false,
|
|
||||||
disabled: !this.queryTextButton.enabled(),
|
|
||||||
isSelected: this.queryTextButton.isSelected(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.executeQueryButton.visible()) {
|
|
||||||
const label = "Run Query";
|
|
||||||
buttons.push({
|
|
||||||
iconSrc: ExecuteQueryIcon,
|
|
||||||
iconAlt: label,
|
|
||||||
onCommandClick: () => this.queryViewModel().runQuery(),
|
|
||||||
commandButtonLabel: label,
|
|
||||||
ariaLabel: label,
|
|
||||||
hasPopup: false,
|
|
||||||
disabled: !this.executeQueryButton.enabled(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.addEntityButton.visible()) {
|
|
||||||
const label = userContext.apiType === "Cassandra" ? "Add Row" : "Add Entity";
|
|
||||||
buttons.push({
|
|
||||||
iconSrc: AddEntityIcon,
|
|
||||||
iconAlt: label,
|
|
||||||
onCommandClick: this.onAddEntityClick,
|
|
||||||
commandButtonLabel: label,
|
|
||||||
ariaLabel: label,
|
|
||||||
hasPopup: true,
|
|
||||||
disabled: !this.addEntityButton.enabled(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.editEntityButton.visible()) {
|
|
||||||
const label = userContext.apiType === "Cassandra" ? "Edit Row" : "Edit Entity";
|
|
||||||
buttons.push({
|
|
||||||
iconSrc: EditEntityIcon,
|
|
||||||
iconAlt: label,
|
|
||||||
onCommandClick: this.onEditEntityClick,
|
|
||||||
commandButtonLabel: label,
|
|
||||||
ariaLabel: label,
|
|
||||||
hasPopup: true,
|
|
||||||
disabled: !this.editEntityButton.enabled(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.deleteEntityButton.visible()) {
|
|
||||||
const label = userContext.apiType === "Cassandra" ? "Delete Rows" : "Delete Entities";
|
|
||||||
buttons.push({
|
|
||||||
iconSrc: DeleteEntitiesIcon,
|
|
||||||
iconAlt: label,
|
|
||||||
onCommandClick: this.onDeleteEntityClick,
|
|
||||||
commandButtonLabel: label,
|
|
||||||
ariaLabel: label,
|
|
||||||
hasPopup: true,
|
|
||||||
disabled: !this.deleteEntityButton.enabled(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected buildCommandBarOptions(): void {
|
|
||||||
ko.computed(() =>
|
|
||||||
ko.toJSON([
|
|
||||||
this.queryBuilderButton.visible,
|
|
||||||
this.queryBuilderButton.enabled,
|
|
||||||
this.queryTextButton.visible,
|
|
||||||
this.queryTextButton.enabled,
|
|
||||||
this.executeQueryButton.visible,
|
|
||||||
this.executeQueryButton.enabled,
|
|
||||||
this.addEntityButton.visible,
|
|
||||||
this.addEntityButton.enabled,
|
|
||||||
this.editEntityButton.visible,
|
|
||||||
this.editEntityButton.enabled,
|
|
||||||
this.deleteEntityButton.visible,
|
|
||||||
this.deleteEntityButton.enabled,
|
|
||||||
])
|
|
||||||
).subscribe(() => this.updateNavbarWithTabsButtons());
|
|
||||||
this.updateNavbarWithTabsButtons();
|
|
||||||
}
|
|
||||||
}
|
|
@ -63,7 +63,7 @@ export interface Button {
|
|||||||
isSelected?: boolean;
|
isSelected?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PAGESIZE = 10;
|
const PAGESIZE = 100;
|
||||||
|
|
||||||
class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, IQueryTablesTabComponentStates> {
|
class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, IQueryTablesTabComponentStates> {
|
||||||
public collection: ViewModels.Collection;
|
public collection: ViewModels.Collection;
|
||||||
@ -100,12 +100,6 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
this.tableDataClient = this.container.tableDataClient;
|
this.tableDataClient = this.container.tableDataClient;
|
||||||
this.tableEntityListViewModel2(new TableEntityListViewModel(this.tableCommands, props.queryTablesTab));
|
this.tableEntityListViewModel2(new TableEntityListViewModel(this.tableCommands, props.queryTablesTab));
|
||||||
const tableEntityListViewModel = new TableEntityListViewModel(this.tableCommands, props.queryTablesTab);
|
const tableEntityListViewModel = new TableEntityListViewModel(this.tableCommands, props.queryTablesTab);
|
||||||
// const queryBuilderViewModel = new QueryViewModel(this.props.queryTablesTab).queryBuilderViewModel();
|
|
||||||
|
|
||||||
// const entityTypeOptions = queryBuilderViewModel.edmTypes();
|
|
||||||
// const timestampOptions = queryBuilderViewModel.timeOptions();
|
|
||||||
// const operatorsOptions = queryBuilderViewModel.operators();
|
|
||||||
// const operationOptions = queryBuilderViewModel.clauseRules();
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
tableEntityListViewModel,
|
tableEntityListViewModel,
|
||||||
@ -201,7 +195,7 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
this.loadEntities(true);
|
this.loadEntities(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public createSelection = (): Selection => {
|
public createSelection = (): Selection => {
|
||||||
@ -294,33 +288,77 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadEntities(isInitialLoad: boolean): Promise<void> {
|
public async loadEntities(isInitialLoad: boolean, isRunQuery?: boolean): Promise<void> {
|
||||||
const { tableEntityListViewModel, selectedQueryText } = this.state;
|
const { tableEntityListViewModel, selectedQueryText } = this.state;
|
||||||
// tableEntityListViewModel.renderNextPageAndupdateCache();
|
|
||||||
let headers: string[] = [];
|
let headers: string[] = [];
|
||||||
//eslint-disable-next-line
|
//eslint-disable-next-line
|
||||||
let documents: any = {};
|
let documents: any = {};
|
||||||
try {
|
// const data = await tableEntityListViewModel.a();
|
||||||
if (userContext.apiType === "Cassandra") {
|
// console.log(
|
||||||
documents = await this.props.queryTablesTab.container.tableDataClient.queryDocuments(
|
// "🚀 ~ file: QueryTablesTabComponent.tsx ~ line 311 ~ QueryTablesTabComponent ~ loadEntities ~ data",
|
||||||
this.props.queryTablesTab.collection,
|
// data
|
||||||
selectedQueryText,
|
// );
|
||||||
true
|
|
||||||
);
|
// setTimeout(() => {
|
||||||
headers = this.getFormattedHeaders(documents.Results);
|
// console.log("Items > ", this.state.tableEntityListViewModel.items());
|
||||||
this.setupIntialEntities(documents.Results, headers, isInitialLoad);
|
// }, 10000);
|
||||||
} else {
|
// await tableEntityListViewModel.renderNextPageAndupdateCache(selectedQueryText);
|
||||||
const { collection } = this.props;
|
// setTimeout(() => {
|
||||||
documents = await this.getDocuments(collection, selectedQueryText);
|
// // console.log("Processing...");
|
||||||
headers = this.getFormattedHeaders(documents.Results);
|
// this.isEntitiesAvailable(isInitialLoad);
|
||||||
this.setupIntialEntities(documents.Results, headers, isInitialLoad);
|
// }, 0);
|
||||||
|
if (!isRunQuery) {
|
||||||
|
try {
|
||||||
|
documents = await tableEntityListViewModel.renderNextPageAndupdateCache();
|
||||||
|
// setTimeout(() => {
|
||||||
|
// // console.log("Processing...");
|
||||||
|
// this.isEntitiesAvailable(isInitialLoad);
|
||||||
|
// }, 0);
|
||||||
|
// const data = await tableEntityListViewModel.a();
|
||||||
|
if (userContext.apiType === "Cassandra") {
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: QueryTablesTabComponent.tsx ~ line 311 ~ QueryTablesTabComponent ~ loadEntities ~ data",
|
||||||
|
documents.Results
|
||||||
|
);
|
||||||
|
headers = this.getFormattedHeaders(documents.Results);
|
||||||
|
this.setupIntialEntities(headers, documents.Results, isInitialLoad);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
"🚀 ~ file: QueryTablesTabComponent.tsx ~ line 311 ~ QueryTablesTabComponent ~ loadEntities ~ data",
|
||||||
|
documents
|
||||||
|
);
|
||||||
|
headers = this.getFormattedHeaders(documents);
|
||||||
|
this.setupIntialEntities(headers, documents, isInitialLoad);
|
||||||
|
}
|
||||||
|
// this.isEntitiesAvailable(isInitialLoad, data);
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({
|
||||||
|
queryErrorMessage: error.responseText,
|
||||||
|
hasQueryError: true,
|
||||||
|
isLoading: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.setState({
|
} else {
|
||||||
queryErrorMessage: "",
|
try {
|
||||||
hasQueryError: false,
|
if (userContext.apiType === "Cassandra") {
|
||||||
});
|
documents = await this.props.queryTablesTab.container.tableDataClient.queryDocuments(
|
||||||
} catch (error) {
|
this.props.queryTablesTab.collection,
|
||||||
if (error.responseText) {
|
selectedQueryText,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
headers = this.getFormattedHeaders(documents.Results);
|
||||||
|
this.setupIntialEntities(headers, documents.Results, isInitialLoad);
|
||||||
|
} else {
|
||||||
|
const { collection } = this.props;
|
||||||
|
documents = await this.getDocuments(collection, selectedQueryText);
|
||||||
|
headers = this.getFormattedHeaders(documents.Results);
|
||||||
|
this.setupIntialEntities(headers, documents.Results, isInitialLoad);
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
queryErrorMessage: "",
|
||||||
|
hasQueryError: false,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
this.setState({
|
this.setState({
|
||||||
queryErrorMessage: error.responseText,
|
queryErrorMessage: error.responseText,
|
||||||
hasQueryError: true,
|
hasQueryError: true,
|
||||||
@ -331,17 +369,35 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setupIntialEntities = (
|
private setupIntialEntities = (
|
||||||
entities: Entities.ITableEntity[],
|
|
||||||
headers: string[],
|
headers: string[],
|
||||||
isInitialLoad: boolean
|
entities?: Entities.ITableEntity[],
|
||||||
|
isInitialLoad?: boolean
|
||||||
): void => {
|
): void => {
|
||||||
|
let minWidth: number;
|
||||||
|
let maxWidth: number;
|
||||||
|
let documentItems: IDocument[] = [];
|
||||||
|
let filteredItems: IDocument[] = [];
|
||||||
this.columns = [];
|
this.columns = [];
|
||||||
headers.map((header) => {
|
headers.map((header) => {
|
||||||
|
switch (header) {
|
||||||
|
case "PartitionKey":
|
||||||
|
case "RowKey":
|
||||||
|
minWidth = 50;
|
||||||
|
maxWidth = 100;
|
||||||
|
break;
|
||||||
|
case "Timestamp":
|
||||||
|
minWidth = 200;
|
||||||
|
maxWidth = 200;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
minWidth = 30;
|
||||||
|
maxWidth = 50;
|
||||||
|
}
|
||||||
this.columns.push({
|
this.columns.push({
|
||||||
key: header,
|
key: header,
|
||||||
name: header,
|
name: header,
|
||||||
minWidth: 100,
|
minWidth: minWidth,
|
||||||
maxWidth: 200,
|
maxWidth: maxWidth,
|
||||||
data: "string",
|
data: "string",
|
||||||
fieldName: header,
|
fieldName: header,
|
||||||
isResizable: true,
|
isResizable: true,
|
||||||
@ -350,12 +406,14 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
sortAscendingAriaLabel: "Sorted A to Z",
|
sortAscendingAriaLabel: "Sorted A to Z",
|
||||||
sortDescendingAriaLabel: "Sorted Z to A",
|
sortDescendingAriaLabel: "Sorted Z to A",
|
||||||
onColumnClick: this.onColumnClick,
|
onColumnClick: this.onColumnClick,
|
||||||
|
// onRender: (item: Entities.ITableEntity) => {
|
||||||
|
// return <div className={!item[header] ? "noData" : ""}>{item[header] ? item[header] : " "}</div>;
|
||||||
|
// },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const documentItems = this.generateDetailsList(entities);
|
documentItems = this.generateDetailsList(entities);
|
||||||
|
filteredItems = documentItems.slice(0, PAGESIZE);
|
||||||
const filteredItems = documentItems.slice(0, PAGESIZE);
|
|
||||||
|
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
@ -369,6 +427,7 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
queryText: this.state.queryViewModel.queryText(),
|
queryText: this.state.queryViewModel.queryText(),
|
||||||
fromDocument: 0,
|
fromDocument: 0,
|
||||||
toDocument: PAGESIZE,
|
toDocument: PAGESIZE,
|
||||||
|
currentStartIndex: PAGESIZE,
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
if (isInitialLoad && headers.length > 0) {
|
if (isInitialLoad && headers.length > 0) {
|
||||||
@ -379,6 +438,36 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// public isEntitiesAvailable(isInitialLoad: boolean, data?: Entities.ITableEntity[]): void {
|
||||||
|
// let headers: string[] = [];
|
||||||
|
// headers = this.getFormattedHeaders(data);
|
||||||
|
// this.setupIntialEntities(false, headers);
|
||||||
|
|
||||||
|
// const documentItems = this.generateDetailsList(data);
|
||||||
|
// const filteredItems = documentItems.slice(0, PAGESIZE);
|
||||||
|
|
||||||
|
// this.setState(
|
||||||
|
// {
|
||||||
|
// columns: this.columns,
|
||||||
|
// headers,
|
||||||
|
// operators: this.state.queryViewModel.queryBuilderViewModel().operators(),
|
||||||
|
// isLoading: false,
|
||||||
|
// items: filteredItems,
|
||||||
|
// entities: data,
|
||||||
|
// originalItems: documentItems,
|
||||||
|
// queryText: this.state.queryViewModel.queryText(),
|
||||||
|
// fromDocument: 0,
|
||||||
|
// toDocument: PAGESIZE,
|
||||||
|
// },
|
||||||
|
// () => {
|
||||||
|
// if (isInitialLoad && headers.length > 0) {
|
||||||
|
// this.loadFilterExample();
|
||||||
|
// this.onItemsSelectionChanged(true);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
private onColumnClick = (ev: React.MouseEvent<HTMLElement>, column: IColumn): void => {
|
private onColumnClick = (ev: React.MouseEvent<HTMLElement>, column: IColumn): void => {
|
||||||
const { columns, items } = this.state;
|
const { columns, items } = this.state;
|
||||||
const newColumns: IColumn[] = columns.slice();
|
const newColumns: IColumn[] = columns.slice();
|
||||||
@ -444,6 +533,7 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
//eslint-disable-next-line
|
//eslint-disable-next-line
|
||||||
let obj: any;
|
let obj: any;
|
||||||
documents.map((item) => {
|
documents.map((item) => {
|
||||||
|
obj = {};
|
||||||
this.columns.map((col) => {
|
this.columns.map((col) => {
|
||||||
if (item[col.name]) {
|
if (item[col.name]) {
|
||||||
obj = { ...obj, ...{ [col.name]: item[col.name]._ } };
|
obj = { ...obj, ...{ [col.name]: item[col.name]._ } };
|
||||||
@ -458,7 +548,7 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
this.setState({
|
this.setState({
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
});
|
});
|
||||||
this.loadEntities(false);
|
this.loadEntities(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onAddEntityClick = (): void => {
|
public onAddEntityClick = (): void => {
|
||||||
@ -472,7 +562,8 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
tableEntityListViewModel={this.state.tableEntityListViewModel}
|
tableEntityListViewModel={this.state.tableEntityListViewModel}
|
||||||
cassandraApiClient={new CassandraAPIDataClient()}
|
cassandraApiClient={new CassandraAPIDataClient()}
|
||||||
reloadEntities={() => this.reloadEntities()}
|
reloadEntities={() => this.reloadEntities()}
|
||||||
/>
|
/>,
|
||||||
|
"700px"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -492,7 +583,8 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
cassandraApiClient={new CassandraAPIDataClient()}
|
cassandraApiClient={new CassandraAPIDataClient()}
|
||||||
selectedEntity={this.state.selectedItems}
|
selectedEntity={this.state.selectedItems}
|
||||||
reloadEntities={() => this.reloadEntities()}
|
reloadEntities={() => this.reloadEntities()}
|
||||||
/>
|
/>,
|
||||||
|
"700px"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -511,10 +603,12 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
.deleteDocuments(this.state.tableEntityListViewModel.queryTablesTab.collection, entitiesToDelete)
|
.deleteDocuments(this.state.tableEntityListViewModel.queryTablesTab.collection, entitiesToDelete)
|
||||||
//eslint-disable-next-line
|
//eslint-disable-next-line
|
||||||
.then((results: any) => {
|
.then((results: any) => {
|
||||||
this.setState({
|
return this.state.tableEntityListViewModel.removeEntitiesFromCache(entitiesToDelete).then(() => {
|
||||||
isLoading: true,
|
this.setState({
|
||||||
|
isLoading: true,
|
||||||
|
});
|
||||||
|
this.loadEntities(false, false);
|
||||||
});
|
});
|
||||||
this.loadEntities(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -525,7 +619,11 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
selectedQueryText: this.state.queryViewModel.runQuery(queryTableRows),
|
selectedQueryText: this.state.queryViewModel.runQuery(queryTableRows),
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.loadEntities(false);
|
console.log(
|
||||||
|
"🚀 ~ file: QueryTablesTabComponent.tsx ~ line 651 ~ QueryTablesTabComponent ~ runQuery ~ selectedQueryText",
|
||||||
|
this.state.selectedQueryText
|
||||||
|
);
|
||||||
|
this.loadEntities(false, queryTableRows.length > 0 ? true : false);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
this.setState({
|
this.setState({
|
||||||
queryText: this.state.queryViewModel.queryText(),
|
queryText: this.state.queryViewModel.queryText(),
|
||||||
@ -1005,7 +1103,7 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="tablesQueryTab tableContainer">
|
<div className="tablesQueryTab tableContainer" data-is-scrollable="true">
|
||||||
{this.state.isLoading && <Spinner size={SpinnerSize.large} className="spinner" />}
|
{this.state.isLoading && <Spinner size={SpinnerSize.large} className="spinner" />}
|
||||||
{this.state.items.length > 0 && !this.state.isLoading && (
|
{this.state.items.length > 0 && !this.state.isLoading && (
|
||||||
<DetailsList
|
<DetailsList
|
||||||
@ -1018,6 +1116,7 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
|||||||
selection={this.state.selection}
|
selection={this.state.selection}
|
||||||
selectionPreservedOnEmptyClick={true}
|
selectionPreservedOnEmptyClick={true}
|
||||||
checkboxVisibility={CheckboxVisibility.always}
|
checkboxVisibility={CheckboxVisibility.always}
|
||||||
|
onShouldVirtualize={() => false}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.state.items.length === 0 && !this.state.isLoading && (
|
{this.state.items.length === 0 && !this.state.isLoading && (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user