mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-04-13 21:32:26 +01:00
Code clean up round 2
This commit is contained in:
parent
884f06a729
commit
27e99d7f2f
@ -107,8 +107,8 @@ src/Explorer/Tables/DataTable/CacheBase.ts
|
||||
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/DataTableOperationManager.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
|
||||
|
@ -94,12 +94,13 @@
|
||||
overflow: hidden;
|
||||
.flex-display();
|
||||
.flex-direction();
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tablesQueryTab {
|
||||
padding-left: @MediumSpace;
|
||||
width: 100%;
|
||||
margin-bottom: 100px;
|
||||
margin-bottom: 60px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
@ -535,7 +536,6 @@ input::-webkit-inner-spin-button {
|
||||
}
|
||||
|
||||
.query-document-detail-list {
|
||||
// overflow-x: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
.query-table-clause-container {
|
||||
@ -545,14 +545,19 @@ input::-webkit-inner-spin-button {
|
||||
}
|
||||
.query-tab-document-pagination {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-direction: row;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
padding-left: @MediumSpace;
|
||||
padding-bottom: 45px;
|
||||
padding-left: 12px;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
height: 60px;
|
||||
}
|
||||
.pagination {
|
||||
margin: 15px 0 !important;
|
||||
order: 2;
|
||||
padding-right: 15px;
|
||||
li > .item-link {
|
||||
position: relative;
|
||||
float: left;
|
||||
@ -577,8 +582,6 @@ input::-webkit-inner-spin-button {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
// .pagination > li > div {
|
||||
// }
|
||||
|
||||
/*
|
||||
@media only screen and (max-width: 1200px) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { IDropdownOption, Image, Label, Stack, Text, TextField } from "@fluentui/react";
|
||||
import { useBoolean } from "@fluentui/react-hooks";
|
||||
import React, { FunctionComponent, useEffect, useState } from "react";
|
||||
import * as _ from "underscore";
|
||||
import AddPropertyIcon from "../../../../images/Add-property.svg";
|
||||
import RevertBackIcon from "../../../../images/RevertBack.svg";
|
||||
import { getErrorMessage, handleError } from "../../../Common/ErrorHandlingUtils";
|
||||
@ -13,7 +12,6 @@ import * as DataTableUtilities from "../../Tables/DataTable/DataTableUtilities";
|
||||
import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel";
|
||||
import * as Entities from "../../Tables/Entities";
|
||||
import { CassandraAPIDataClient, CassandraTableKey, TableDataClient } from "../../Tables/TableDataClient";
|
||||
import * as TableEntityProcessor from "../../Tables/TableEntityProcessor";
|
||||
import * as Utilities from "../../Tables/Utilities";
|
||||
import NewQueryTablesTab from "../../Tabs/QueryTablesTab/QueryTablesTab";
|
||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||
@ -123,11 +121,8 @@ export const AddTableEntityPanel: FunctionComponent<AddTableEntityPanelProps> =
|
||||
const newEntity: Entities.ITableEntity = await tableDataClient.createDocument(queryTablesTab.collection, entity);
|
||||
try {
|
||||
await tableEntityListViewModel.addEntityToCache(newEntity);
|
||||
// if (!tryInsertNewHeaders(tableEntityListViewModel, newEntity)) {
|
||||
// tableEntityListViewModel.redrawTableThrottled();
|
||||
reloadEntities();
|
||||
setFormError("");
|
||||
// }
|
||||
} catch (error) {
|
||||
const errorMessage = getErrorMessage(error);
|
||||
setFormError(errorMessage);
|
||||
@ -136,46 +131,6 @@ export const AddTableEntityPanel: FunctionComponent<AddTableEntityPanelProps> =
|
||||
} 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 */
|
||||
|
@ -9,7 +9,6 @@ import { TableEntity } from "../../../Common/TableEntity";
|
||||
import { useSidePanel } from "../../../hooks/useSidePanel";
|
||||
import { userContext } from "../../../UserContext";
|
||||
import * as TableConstants from "../../Tables/Constants";
|
||||
import * as DataTableUtilities from "../../Tables/DataTable/DataTableUtilities";
|
||||
import TableEntityListViewModel from "../../Tables/DataTable/TableEntityListViewModel";
|
||||
import * as Entities from "../../Tables/Entities";
|
||||
import { CassandraAPIDataClient, TableDataClient } from "../../Tables/TableDataClient";
|
||||
@ -215,7 +214,6 @@ export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps>
|
||||
const entity: Entities.ITableEntity = entityFromAttributes(entities);
|
||||
const newTableDataClient = userContext.apiType === "Cassandra" ? cassandraApiClient : tableDataClient;
|
||||
const originalDocumentData = userContext.apiType === "Cassandra" ? originalDocument[0] : originalDocument;
|
||||
// await newTableDataClient.updateDocument(queryTablesTab.collection, originalDocumentData, entity);
|
||||
|
||||
try {
|
||||
const newEntity: Entities.ITableEntity = await newTableDataClient.updateDocument(
|
||||
@ -224,11 +222,8 @@ export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps>
|
||||
entity
|
||||
);
|
||||
await tableEntityListViewModel.updateCachedEntity(newEntity);
|
||||
// if (!tryInsertNewHeaders(tableEntityListViewModel, newEntity)) {
|
||||
// tableEntityListViewModel.redrawTableThrottled();
|
||||
reloadEntities();
|
||||
closeSidePanel();
|
||||
// }
|
||||
tableEntityListViewModel.selected.removeAll();
|
||||
tableEntityListViewModel.selected.push(newEntity);
|
||||
} catch (error) {
|
||||
@ -238,36 +233,6 @@ export const EditTableEntityPanel: FunctionComponent<EditTableEntityPanelProps>
|
||||
} 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
|
||||
|
@ -1,52 +0,0 @@
|
||||
import * as Utilities from "../Utilities";
|
||||
|
||||
/**
|
||||
* Wrapper function for creating data tables. Call this method, not the
|
||||
* data tables constructor when you want to create a data table. This
|
||||
* function makes sure that content without a render function is properly
|
||||
* encoded to prevent XSS.
|
||||
* @param{$dataTableElem} JQuery data table element
|
||||
* @param{$settings} Settings to use when creating the data table
|
||||
*/
|
||||
export function createDataTable($dataTableElem: JQuery, settings: any): DataTables.DataTable {
|
||||
return $dataTableElem.DataTable(applyDefaultRendering(settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through the settings for a data table and apply a simple HTML encode to any column
|
||||
* without a render function to prevent XSS.
|
||||
* @param{settings} The settings to check
|
||||
* @return The given settings with all columns having a rendering function
|
||||
*/
|
||||
function applyDefaultRendering(settings: any): DataTables.SettingsLegacy {
|
||||
var tableColumns: DataTables.ColumnLegacy[] = null;
|
||||
|
||||
if (settings.aoColumns) {
|
||||
tableColumns = settings.aoColumns;
|
||||
} else if (settings.aoColumnDefs) {
|
||||
// for tables we use aoColumnDefs instead of aoColumns
|
||||
tableColumns = settings.aoColumnDefs;
|
||||
}
|
||||
|
||||
// either the settings had no columns defined, or they were called
|
||||
// by a property name which we have not used before
|
||||
if (!tableColumns) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tableColumns.length; i++) {
|
||||
// the column does not have a render function
|
||||
if (!tableColumns[i].mRender) {
|
||||
tableColumns[i].mRender = defaultDataRender;
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default data render function, whatever is done to data in here
|
||||
* will be done to any data which we do not specify a render for.
|
||||
*/
|
||||
function defaultDataRender(data: any, type: string, full: any) {
|
||||
return Utilities.htmlEncode(data);
|
||||
}
|
@ -1,300 +0,0 @@
|
||||
import ko from "knockout";
|
||||
|
||||
import * as DataTableOperations from "./DataTableOperations";
|
||||
import * as Constants from "../Constants";
|
||||
import TableCommands from "./TableCommands";
|
||||
import TableEntityListViewModel from "./TableEntityListViewModel";
|
||||
import * as Utilities from "../Utilities";
|
||||
import * as Entities from "../Entities";
|
||||
|
||||
/*
|
||||
* Base class for data table row selection.
|
||||
*/
|
||||
export default class DataTableOperationManager {
|
||||
private _tableEntityListViewModel: TableEntityListViewModel;
|
||||
private _tableCommands: TableCommands;
|
||||
private dataTable: JQuery;
|
||||
|
||||
constructor(table: JQuery, viewModel: TableEntityListViewModel, tableCommands: TableCommands) {
|
||||
this.dataTable = table;
|
||||
this._tableEntityListViewModel = viewModel;
|
||||
this._tableCommands = tableCommands;
|
||||
|
||||
this.bind();
|
||||
this._tableEntityListViewModel.bind(this);
|
||||
}
|
||||
|
||||
private click = (event: JQueryEventObject) => {
|
||||
var elem: JQuery = $(event.currentTarget);
|
||||
this.updateLastSelectedItem(elem, event.shiftKey);
|
||||
|
||||
if (Utilities.isEnvironmentCtrlPressed(event)) {
|
||||
this.applyCtrlSelection(elem);
|
||||
} else if (event.shiftKey) {
|
||||
this.applyShiftSelection(elem);
|
||||
} else {
|
||||
this.applySingleSelection(elem);
|
||||
}
|
||||
};
|
||||
|
||||
private doubleClick = (event: JQueryEventObject) => {
|
||||
this.tryOpenEditor();
|
||||
};
|
||||
|
||||
private keyDown = (event: JQueryEventObject): boolean => {
|
||||
var isUpArrowKey: boolean = event.keyCode === Constants.keyCodes.UpArrow,
|
||||
isDownArrowKey: boolean = event.keyCode === Constants.keyCodes.DownArrow,
|
||||
handled: boolean = false;
|
||||
|
||||
if (isUpArrowKey || isDownArrowKey) {
|
||||
var lastSelectedItem: Entities.ITableEntity = this._tableEntityListViewModel.lastSelectedItem;
|
||||
var dataTableRows: JQuery = $(Constants.htmlSelectors.dataTableAllRowsSelector);
|
||||
var maximumIndex = dataTableRows.length - 1;
|
||||
|
||||
// If can't find an index for lastSelectedItem, then either no item is previously selected or it goes across page.
|
||||
// Simply select the first item in this case.
|
||||
var lastSelectedItemIndex = lastSelectedItem
|
||||
? this._tableEntityListViewModel.getItemIndexFromCurrentPage(
|
||||
this._tableEntityListViewModel.getTableEntityKeys(lastSelectedItem.RowKey._)
|
||||
)
|
||||
: -1;
|
||||
var nextIndex: number = isUpArrowKey ? lastSelectedItemIndex - 1 : lastSelectedItemIndex + 1;
|
||||
var safeIndex: number = Utilities.ensureBetweenBounds(nextIndex, 0, maximumIndex);
|
||||
var selectedRowElement: JQuery = dataTableRows.eq(safeIndex);
|
||||
|
||||
if (selectedRowElement) {
|
||||
if (event.shiftKey) {
|
||||
this.applyShiftSelection(selectedRowElement);
|
||||
} else {
|
||||
this.applySingleSelection(selectedRowElement);
|
||||
}
|
||||
|
||||
this.updateLastSelectedItem(selectedRowElement, event.shiftKey);
|
||||
handled = true;
|
||||
DataTableOperations.scrollToRowIfNeeded(dataTableRows, safeIndex, isUpArrowKey);
|
||||
}
|
||||
} else if (
|
||||
Utilities.isEnvironmentCtrlPressed(event) &&
|
||||
!Utilities.isEnvironmentShiftPressed(event) &&
|
||||
!Utilities.isEnvironmentAltPressed(event) &&
|
||||
event.keyCode === Constants.keyCodes.A
|
||||
) {
|
||||
this.applySelectAll();
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return !handled;
|
||||
};
|
||||
|
||||
// Note: There is one key up event each time a key is pressed;
|
||||
// in contrast, there may be more than one key down and key
|
||||
// pressed events.
|
||||
private keyUp = (event: JQueryEventObject): boolean => {
|
||||
var handled: boolean = false;
|
||||
|
||||
switch (event.keyCode) {
|
||||
case Constants.keyCodes.Enter:
|
||||
handled = this.tryOpenEditor();
|
||||
break;
|
||||
case Constants.keyCodes.Delete:
|
||||
handled = this.tryHandleDeleteSelected();
|
||||
break;
|
||||
}
|
||||
|
||||
return !handled;
|
||||
};
|
||||
|
||||
private itemDropped = (event: JQueryEventObject): boolean => {
|
||||
var handled: boolean = false;
|
||||
var items = (<any>event.originalEvent).dataTransfer.items;
|
||||
|
||||
if (!items) {
|
||||
// On browsers outside of Chromium
|
||||
// we can't discern between dirs and files
|
||||
// so we will disable drag & drop for now
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
var entry = item.webkitGetAsEntry();
|
||||
|
||||
if (entry.isFile) {
|
||||
// TODO: parse the file and insert content as entities
|
||||
}
|
||||
}
|
||||
|
||||
return !handled;
|
||||
};
|
||||
|
||||
private tryOpenEditor(): boolean {
|
||||
return this._tableCommands.tryOpenEntityEditor(this._tableEntityListViewModel);
|
||||
}
|
||||
|
||||
private tryHandleDeleteSelected(): boolean {
|
||||
var selectedEntities: Entities.ITableEntity[] = this._tableEntityListViewModel.selected();
|
||||
var handled: boolean = false;
|
||||
|
||||
if (selectedEntities && selectedEntities.length) {
|
||||
this._tableCommands.deleteEntitiesCommand(this._tableEntityListViewModel);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
private getEntityIdentity($elem: JQuery): Entities.ITableEntityIdentity {
|
||||
return {
|
||||
RowKey: $elem.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr),
|
||||
};
|
||||
}
|
||||
|
||||
private updateLastSelectedItem($elem: JQuery, isShiftSelect: boolean) {
|
||||
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
|
||||
var entity = this._tableEntityListViewModel.getItemFromCurrentPage(
|
||||
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey)
|
||||
);
|
||||
|
||||
this._tableEntityListViewModel.lastSelectedItem = entity;
|
||||
|
||||
if (!isShiftSelect) {
|
||||
this._tableEntityListViewModel.lastSelectedAnchorItem = entity;
|
||||
}
|
||||
}
|
||||
|
||||
private applySingleSelection($elem: JQuery) {
|
||||
if ($elem) {
|
||||
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
|
||||
|
||||
this._tableEntityListViewModel.clearSelection();
|
||||
this.addToSelection(entityIdentity.RowKey);
|
||||
}
|
||||
}
|
||||
|
||||
private applySelectAll() {
|
||||
this._tableEntityListViewModel.clearSelection();
|
||||
ko.utils.arrayPushAll<Entities.ITableEntity>(
|
||||
this._tableEntityListViewModel.selected,
|
||||
this._tableEntityListViewModel.getAllItemsInCurrentPage()
|
||||
);
|
||||
}
|
||||
|
||||
private applyCtrlSelection($elem: JQuery): void {
|
||||
var koSelected: ko.ObservableArray<Entities.ITableEntity> = this._tableEntityListViewModel
|
||||
? this._tableEntityListViewModel.selected
|
||||
: null;
|
||||
|
||||
if (koSelected) {
|
||||
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
|
||||
|
||||
if (
|
||||
!this._tableEntityListViewModel.isItemSelected(
|
||||
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey)
|
||||
)
|
||||
) {
|
||||
// Adding item not previously in selection
|
||||
this.addToSelection(entityIdentity.RowKey);
|
||||
} else {
|
||||
koSelected.remove((item: Entities.ITableEntity) => item.RowKey._ === entityIdentity.RowKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private applyShiftSelection($elem: JQuery): void {
|
||||
var anchorItem = this._tableEntityListViewModel.lastSelectedAnchorItem;
|
||||
|
||||
// If anchor item doesn't exist, use the first available item of current page instead
|
||||
if (!anchorItem && this._tableEntityListViewModel.items().length > 0) {
|
||||
anchorItem = this._tableEntityListViewModel.items()[0];
|
||||
}
|
||||
|
||||
if (anchorItem) {
|
||||
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
|
||||
var elementIndex = this._tableEntityListViewModel.getItemIndexFromAllPages(
|
||||
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey)
|
||||
);
|
||||
var anchorIndex = this._tableEntityListViewModel.getItemIndexFromAllPages(
|
||||
this._tableEntityListViewModel.getTableEntityKeys(anchorItem.RowKey._)
|
||||
);
|
||||
|
||||
var startIndex = Math.min(elementIndex, anchorIndex);
|
||||
var endIndex = Math.max(elementIndex, anchorIndex);
|
||||
|
||||
this._tableEntityListViewModel.clearSelection();
|
||||
ko.utils.arrayPushAll<Entities.ITableEntity>(
|
||||
this._tableEntityListViewModel.selected,
|
||||
this._tableEntityListViewModel.getItemsFromAllPagesWithinRange(startIndex, endIndex + 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private applyContextMenuSelection($elem: JQuery) {
|
||||
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
|
||||
|
||||
if (
|
||||
!this._tableEntityListViewModel.isItemSelected(
|
||||
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey)
|
||||
)
|
||||
) {
|
||||
if (this._tableEntityListViewModel.selected().length) {
|
||||
this._tableEntityListViewModel.clearSelection();
|
||||
}
|
||||
this.addToSelection(entityIdentity.RowKey);
|
||||
}
|
||||
}
|
||||
|
||||
private addToSelection(rowKey: string) {
|
||||
var selectedEntity: Entities.ITableEntity = this._tableEntityListViewModel.getItemFromCurrentPage(
|
||||
this._tableEntityListViewModel.getTableEntityKeys(rowKey)
|
||||
);
|
||||
|
||||
if (selectedEntity != null) {
|
||||
this._tableEntityListViewModel.selected.push(selectedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// Selecting first row if the selection is empty.
|
||||
public selectFirstIfNeeded(): void {
|
||||
var koSelected: ko.ObservableArray<Entities.ITableEntity> = this._tableEntityListViewModel
|
||||
? this._tableEntityListViewModel.selected
|
||||
: null;
|
||||
var koEntities: ko.ObservableArray<Entities.ITableEntity> = this._tableEntityListViewModel
|
||||
? this._tableEntityListViewModel.items
|
||||
: null;
|
||||
|
||||
if (!koSelected().length && koEntities().length) {
|
||||
var firstEntity: Entities.ITableEntity = koEntities()[0];
|
||||
|
||||
// Clear last selection: lastSelectedItem and lastSelectedAnchorItem
|
||||
this._tableEntityListViewModel.clearLastSelected();
|
||||
|
||||
this.addToSelection(firstEntity.RowKey._);
|
||||
|
||||
// Update last selection
|
||||
this._tableEntityListViewModel.lastSelectedItem = firstEntity;
|
||||
|
||||
// Finally, make sure first row is visible
|
||||
DataTableOperations.scrollToTopIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
public bind() {
|
||||
this.dataTable.on("click", "tr", this.click);
|
||||
this.dataTable.on("dblclick", "tr", this.doubleClick);
|
||||
this.dataTable.on("keydown", "td", this.keyDown);
|
||||
this.dataTable.on("keyup", "td", this.keyUp);
|
||||
|
||||
// Keyboard navigation - selecting first row if the selection is empty when the table gains focus.
|
||||
this.dataTable.on("focus", () => {
|
||||
this.selectFirstIfNeeded();
|
||||
return true;
|
||||
});
|
||||
|
||||
// Bind drag & drop behavior
|
||||
$("body").on("drop", this.itemDropped);
|
||||
}
|
||||
|
||||
public focusTable(): void {
|
||||
this.dataTable.focus();
|
||||
}
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
import _ from "underscore";
|
||||
import Q from "q";
|
||||
|
||||
import * as Entities from "../Entities";
|
||||
import * as QueryBuilderConstants from "../Constants";
|
||||
import * as Utilities from "../Utilities";
|
||||
|
||||
export function getRowSelector(selectorSchema: Entities.IProperty[]): string {
|
||||
var selector: string = "";
|
||||
selectorSchema &&
|
||||
selectorSchema.forEach((p: Entities.IProperty) => {
|
||||
selector += "[" + p.key + '="' + Utilities.jQuerySelectorEscape(p.value) + '"]';
|
||||
});
|
||||
return QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector + selector;
|
||||
}
|
||||
|
||||
export function isRowVisible(dataTableScrollBodyQuery: JQuery, element: HTMLElement): boolean {
|
||||
var isVisible = false;
|
||||
|
||||
if (dataTableScrollBodyQuery.length && element) {
|
||||
var elementRect: ClientRect = element.getBoundingClientRect(),
|
||||
dataTableScrollBodyRect: ClientRect = dataTableScrollBodyQuery.get(0).getBoundingClientRect();
|
||||
|
||||
isVisible = elementRect.bottom <= dataTableScrollBodyRect.bottom && dataTableScrollBodyRect.top <= elementRect.top;
|
||||
}
|
||||
|
||||
return isVisible;
|
||||
}
|
||||
|
||||
export function scrollToRowIfNeeded(dataTableRows: JQuery, currentIndex: number, isScrollUp: boolean): void {
|
||||
if (dataTableRows.length) {
|
||||
var dataTableScrollBodyQuery: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector),
|
||||
selectedRowElement: HTMLElement = dataTableRows.get(currentIndex);
|
||||
|
||||
if (dataTableScrollBodyQuery.length && selectedRowElement) {
|
||||
var isVisible: boolean = isRowVisible(dataTableScrollBodyQuery, selectedRowElement);
|
||||
|
||||
if (!isVisible) {
|
||||
var selectedRowQuery: JQuery = $(selectedRowElement),
|
||||
scrollPosition: number = dataTableScrollBodyQuery.scrollTop(),
|
||||
selectedElementPosition: number = selectedRowQuery.position().top,
|
||||
newScrollPosition: number = 0;
|
||||
|
||||
if (isScrollUp) {
|
||||
newScrollPosition = scrollPosition + selectedElementPosition;
|
||||
} else {
|
||||
newScrollPosition =
|
||||
scrollPosition + (selectedElementPosition + selectedRowQuery.height() - dataTableScrollBodyQuery.height());
|
||||
}
|
||||
|
||||
dataTableScrollBodyQuery.scrollTop(newScrollPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function scrollToTopIfNeeded(): void {
|
||||
var $dataTableRows: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector),
|
||||
$dataTableScrollBody: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector);
|
||||
|
||||
if ($dataTableRows.length && $dataTableScrollBody.length) {
|
||||
$dataTableScrollBody.scrollTop(0);
|
||||
}
|
||||
}
|
||||
|
||||
export function setPaginationButtonEventHandlers(): void {
|
||||
$(QueryBuilderConstants.htmlSelectors.dataTablePaginationButtonSelector)
|
||||
.on("mousedown", (event: JQueryEventObject) => {
|
||||
// Prevents the table contents from briefly jumping when clicking on "Load more"
|
||||
event.preventDefault();
|
||||
})
|
||||
.attr("role", "button");
|
||||
}
|
||||
|
||||
export function filterColumns(table: DataTables.DataTable, settings: boolean[]): void {
|
||||
settings &&
|
||||
settings.forEach((value: boolean, index: number) => {
|
||||
table.column(index).visible(value, false);
|
||||
});
|
||||
table.columns.adjust().draw(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder columns based on current order.
|
||||
* If no current order is specified, reorder the columns based on intial order.
|
||||
*/
|
||||
export function reorderColumns(
|
||||
table: DataTables.DataTable,
|
||||
targetOrder: number[],
|
||||
currentOrder?: number[]
|
||||
): Q.Promise<any> {
|
||||
var columnsCount: number = targetOrder.length;
|
||||
var isCurrentOrderPassedIn: boolean = !!currentOrder;
|
||||
if (!isCurrentOrderPassedIn) {
|
||||
currentOrder = getInitialOrder(columnsCount);
|
||||
}
|
||||
var isSameOrder: boolean = Utilities.isEqual(currentOrder, targetOrder);
|
||||
|
||||
// if the targetOrder is the same as current order, do nothing.
|
||||
if (!isSameOrder) {
|
||||
// Otherwise, calculate the transformation order.
|
||||
// If current order not specified, then it'll be set to initial order,
|
||||
// i.e., either no reorder happened before or reordering to its initial order,
|
||||
// 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
|
||||
? calculateTransformationOrder(currentOrder, targetOrder)
|
||||
: targetOrder;
|
||||
try {
|
||||
$.fn.dataTable.ColReorder(table).fnOrder(transformationOrder);
|
||||
} catch (err) {
|
||||
return Q.reject(err);
|
||||
}
|
||||
}
|
||||
return Q.resolve(null);
|
||||
}
|
||||
|
||||
export function resetColumns(table: DataTables.DataTable): void {
|
||||
$.fn.dataTable.ColReorder(table).fnReset();
|
||||
}
|
||||
|
||||
/**
|
||||
* A table's initial order is described in the form of a natural ascending order.
|
||||
* E.g., for a table with 9 columns, the initial order will be: [0, 1, 2, 3, 4, 5, 6, 7, 8]
|
||||
*/
|
||||
export function getInitialOrder(columnsCount: number): number[] {
|
||||
return _.range(columnsCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current table's column order which is described based on initial table. E.g.,
|
||||
* Initial order: I = [0, 1, 2, 3, 4, 5, 6, 7, 8] <----> {prop0, prop1, prop2, prop3, prop4, prop5, prop6, prop7, prop8}
|
||||
* Current order: C = [0, 1, 2, 6, 7, 3, 4, 5, 8] <----> {prop0, prop1, prop2, prop6, prop7, prop3, prop4, prop5, prop8}
|
||||
*/
|
||||
export function getCurrentOrder(table: DataTables.DataTable): number[] {
|
||||
return $.fn.dataTable.ColReorder(table).fnOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch the index and value for each element of an array. e.g.,
|
||||
* InputArray: [0, 1, 2, 6, 7, 3, 4, 5, 8]
|
||||
* Result: [0, 1, 2, 5, 6, 7, 3, 4, 8]
|
||||
*/
|
||||
export function invertIndexValues(inputArray: number[]): number[] {
|
||||
var invertedArray: number[] = [];
|
||||
if (inputArray) {
|
||||
inputArray.forEach((value: number, index: number) => {
|
||||
invertedArray[inputArray[index]] = index;
|
||||
});
|
||||
}
|
||||
|
||||
return invertedArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTable fnOrder API is based on the current table. So we need to map the order targeting original table to targeting current table.
|
||||
* An detailed example for this. Assume the table has 9 columns.
|
||||
* Initial order (order of the initial table): I = [0, 1, 2, 3, 4, 5, 6, 7, 8] <----> {prop0, prop1, prop2, prop3, prop4, prop5, prop6, prop7, prop8}
|
||||
* Current order (order of the current table): C = [0, 1, 2, 6, 7, 3, 4, 5, 8] <----> {prop0, prop1, prop2, prop6, prop7, prop3, prop4, prop5, prop8}
|
||||
* Target order (order of the targeting table): T = [0, 1, 2, 5, 6, 7, 8, 3, 4] <----> {prop0, prop1, prop2, prop5, prop6, prop7, prop8, prop3, prop4}
|
||||
* Transformation order: an order passed to fnOrder API that transforms table from current order to target order.
|
||||
* When the table is constructed, it has the intial order. After an reordering with current order array, now the table is shown in current order, e.g.,
|
||||
* column 3 in the current table is actually column C[3]=6 in the intial table, both indicate the column with header prop6.
|
||||
* Now we want to continue to do another reorder to make the target table in the target order. Directly invoking API with the new order won't work as
|
||||
* the API only do reorder based on the current table like the first time we invoke the API. So an order based on the current table needs to be calulated.
|
||||
* Here is an example of how to calculate the transformation order:
|
||||
* In target table, column 3 should be column T[3]=5 in the intial table with header prop5, while in current table, column with header prop5 is column 7 as C[7]=5.
|
||||
* As a result, in transformation order, column 3 in the target table should be column 7 in the current table, Trans[3] = 7. In the same manner, we can get the
|
||||
* transformation order: Trans = [0, 1, 2, 7, 3, 4, 8, 5, 6]
|
||||
*/
|
||||
export function calculateTransformationOrder(currentOrder: number[], targetOrder: number[]): number[] {
|
||||
var transformationOrder: number[] = [];
|
||||
if (currentOrder && targetOrder && currentOrder.length === targetOrder.length) {
|
||||
var 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[] = [];
|
||||
if (columns) {
|
||||
// table.columns() return ColumnsMethods which is an array of arrays
|
||||
var columnIndexes: number[] = (<any>columns)[0];
|
||||
if (columnIndexes) {
|
||||
headers = columnIndexes.map((value: number) => $(table.columns(value).header()).html());
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
@ -123,10 +123,3 @@ export function checkForDefaultHeader(headers: string[]): boolean {
|
||||
export function forceRecalculateTableSize(): void {
|
||||
$("body").trigger("resize");
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off the spinning progress indicator on the data table.
|
||||
*/
|
||||
export function turnOffProgressIndicator(): void {
|
||||
$("div.dataTables_processing").hide();
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import * as CommonConstants from "../../../Common/Constants";
|
||||
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
|
||||
import NewQueryTablesTab from "../../Tabs/QueryTablesTab/QueryTablesTab";
|
||||
import * as Constants from "../Constants";
|
||||
import * as Entities from "../Entities";
|
||||
import CacheBase from "./CacheBase";
|
||||
|
||||
@ -46,19 +45,11 @@ abstract class DataTableViewModel {
|
||||
private pendingRedraw = false;
|
||||
private lastRedrawTime = new Date().getTime();
|
||||
|
||||
private dataTableOperationManager: IDataTableOperation;
|
||||
|
||||
public queryTablesTab: NewQueryTablesTab;
|
||||
|
||||
constructor() {
|
||||
this.items([]);
|
||||
this.selected([]);
|
||||
// Late bound
|
||||
this.dataTableOperationManager = null;
|
||||
}
|
||||
|
||||
public bind(dataTableOperationManager: IDataTableOperation): void {
|
||||
this.dataTableOperationManager = dataTableOperationManager;
|
||||
}
|
||||
|
||||
public clearLastSelected(): void {
|
||||
@ -100,10 +91,6 @@ abstract class DataTableViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
public focusDataTable(): void {
|
||||
this.dataTableOperationManager.focusTable();
|
||||
}
|
||||
|
||||
public getItemFromSelectedItems(itemKeys: Entities.IProperty[]): Entities.ITableEntity {
|
||||
return _.find(this.selected(), (item: Entities.ITableEntity) => {
|
||||
return this.matchesKeys(item, itemKeys);
|
||||
@ -170,10 +157,6 @@ abstract class DataTableViewModel {
|
||||
}
|
||||
|
||||
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 renderData = this.cache.data.slice(startIndex, endIndex);
|
||||
|
||||
@ -208,27 +191,6 @@ abstract class DataTableViewModel {
|
||||
protected stringCompare(s1: string, s2: string): boolean {
|
||||
return s1 === s2;
|
||||
}
|
||||
|
||||
private updatePaginationControls(oSettings: any) {
|
||||
var pageInfo = this.table.page.info();
|
||||
var pageSize = pageInfo.length;
|
||||
var paginateElement = $(oSettings.nTableWrapper).find(Constants.htmlSelectors.paginateSelector);
|
||||
|
||||
if (this.allDownloaded) {
|
||||
if (this.cache.length <= pageSize) {
|
||||
// Hide pagination controls if everything fits in one page!.
|
||||
paginateElement.hide();
|
||||
} else {
|
||||
// Enable pagination controls.
|
||||
paginateElement.show();
|
||||
oSettings.oLanguage.oPaginate.sLast = DataTableViewModel.lastPageLabel;
|
||||
}
|
||||
} else {
|
||||
// Enable pagination controls and show load more button.
|
||||
paginateElement.show();
|
||||
oSettings.oLanguage.oPaginate.sLast = DataTableViewModel.loadMoreLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IDataTableOperation {
|
||||
|
@ -94,8 +94,4 @@ export default class TableCommands {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public resetColumns(viewModel: TableEntityListViewModel): void {
|
||||
viewModel.reloadTable();
|
||||
}
|
||||
}
|
||||
|
@ -132,113 +132,10 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
return [{ key: Constants.EntityKeyNames.RowKey, value: rowKey }];
|
||||
}
|
||||
|
||||
public reloadTable(useSetting: boolean = true, resetHeaders: boolean = true): DataTables.DataTable {
|
||||
this.clearCache();
|
||||
this.clearSelection();
|
||||
this.isCancelled = false;
|
||||
|
||||
this.useSetting = useSetting;
|
||||
if (resetHeaders) {
|
||||
this.updateHeaders([Constants.defaultHeader]);
|
||||
}
|
||||
return this.table.ajax.reload();
|
||||
}
|
||||
|
||||
public updateHeaders(newHeaders: string[], notifyColumnChanges: boolean = false, enablePrompt: boolean = true): void {
|
||||
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.
|
||||
* sSource - ajax URL of data source, ignored in our case as we are not using ajax.
|
||||
@ -440,7 +337,6 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
tablePageSize: number,
|
||||
downloadSize: number
|
||||
): Promise<Entities.ITableEntity[]> {
|
||||
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 366 ~ TableEntityListViewModel ~ prefetchAndRender");
|
||||
this.queryErrorMessage(null);
|
||||
if (this.cache.serverCallInProgress) {
|
||||
return undefined;
|
||||
@ -452,27 +348,15 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
}
|
||||
// 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,
|
||||
@ -514,9 +398,8 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
);
|
||||
this.queryTablesTab.onLoadStartKey = null;
|
||||
}
|
||||
DataTableUtilities.turnOffProgressIndicator();
|
||||
}
|
||||
// return undefined;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -536,7 +419,6 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
downloadSize: number,
|
||||
currentRetry: number = 0
|
||||
): Promise<any> {
|
||||
console.log("🚀 ~ file: TableEntityListViewModel.ts ~ line 456 ~ TableEntityListViewModel ~ prefetchData");
|
||||
var entities: any;
|
||||
if (!this.cache.serverCallInProgress) {
|
||||
this.cache.serverCallInProgress = true;
|
||||
@ -544,7 +426,6 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
this.lastPrefetchTime = new Date().getTime();
|
||||
var time = this.lastPrefetchTime;
|
||||
|
||||
var promise: Promise<IListTableEntitiesSegmentedResult>;
|
||||
try {
|
||||
if (this._documentIterator && this.continuationToken) {
|
||||
// TODO handle Cassandra case
|
||||
@ -558,7 +439,7 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
};
|
||||
entities = finalEntities;
|
||||
} else if (this.continuationToken && userContext.apiType === "Cassandra") {
|
||||
entities = this.queryTablesTab.container.tableDataClient.queryDocuments(
|
||||
entities = await this.queryTablesTab.container.tableDataClient.queryDocuments(
|
||||
this.queryTablesTab.collection,
|
||||
this.cqlQuery(),
|
||||
true,
|
||||
@ -603,10 +484,6 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
if (this.isCacheValid(tableQuery)) {
|
||||
// Append to cache.
|
||||
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);
|
||||
@ -616,10 +493,6 @@ export default class TableEntityListViewModel extends DataTableViewModel {
|
||||
} else {
|
||||
// Create cache.
|
||||
this.cache.data = entities;
|
||||
console.log(
|
||||
"🚀 ~ file: TableEntityListViewModel.ts ~ line 671 ~ TableEntityListViewModel ~ .then ~ this.cache.data",
|
||||
this.cache.data
|
||||
);
|
||||
}
|
||||
|
||||
this.cache.tableQuery = tableQuery;
|
||||
|
@ -170,17 +170,13 @@ export default class QueryViewModel {
|
||||
this._tableEntityListViewModel.oDataQuery(filter);
|
||||
this._tableEntityListViewModel.sqlQuery(this.setSqlFilter(queryTableRows));
|
||||
this._tableEntityListViewModel.cqlQuery(filter);
|
||||
console.log(
|
||||
"🚀 ~ file: QueryViewModel.tsx ~ line 165 ~ QueryViewModel ~ this._tableEntityListViewModel.sqlQuery()",
|
||||
this._tableEntityListViewModel.sqlQuery()
|
||||
);
|
||||
|
||||
return userContext.apiType !== "Cassandra"
|
||||
? this._tableEntityListViewModel.sqlQuery()
|
||||
: this._tableEntityListViewModel.cqlQuery();
|
||||
};
|
||||
|
||||
public clearQuery = (): DataTables.DataTable => {
|
||||
public clearQuery = (): void => {
|
||||
this.queryText();
|
||||
this.topValue();
|
||||
this.selectText();
|
||||
@ -198,7 +194,6 @@ export default class QueryViewModel {
|
||||
this.queryTablesTab.collection.id()
|
||||
)}`
|
||||
);
|
||||
return this._tableEntityListViewModel.reloadTable(false);
|
||||
};
|
||||
|
||||
public selectQueryOptions(headers: string[], getSelectMessage: (selectMessage: string) => void): void {
|
||||
|
@ -243,7 +243,6 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
||||
public loadFilterExample(): void {
|
||||
const { queryTableRows, headers, entities } = this.state;
|
||||
const queryTableRowsClone = [...queryTableRows];
|
||||
// queryTableRowsClone[0].fieldOptions = getformattedOptions(headers);
|
||||
this.setState({
|
||||
operators: this.state.queryViewModel.queryBuilderViewModel().operators(),
|
||||
queryTableRows: queryTableRowsClone,
|
||||
@ -291,48 +290,16 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
||||
let headers: string[] = [];
|
||||
//eslint-disable-next-line
|
||||
let documents: any = {};
|
||||
// const data = await tableEntityListViewModel.a();
|
||||
// console.log(
|
||||
// "🚀 ~ file: QueryTablesTabComponent.tsx ~ line 311 ~ QueryTablesTabComponent ~ loadEntities ~ data",
|
||||
// data
|
||||
// );
|
||||
|
||||
// setTimeout(() => {
|
||||
// console.log("Items > ", this.state.tableEntityListViewModel.items());
|
||||
// }, 10000);
|
||||
// await tableEntityListViewModel.renderNextPageAndupdateCache(selectedQueryText);
|
||||
// setTimeout(() => {
|
||||
// // console.log("Processing...");
|
||||
// this.isEntitiesAvailable(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 = documents.Results?.length
|
||||
? this.getFormattedHeaders(documents.Results)
|
||||
: ["userid", "name", "email"];
|
||||
this.setupIntialEntities(headers, documents.Results, isInitialLoad);
|
||||
headers = documents?.length ? this.getFormattedHeaders(documents) : ["userid", "name", "email"];
|
||||
this.setupIntialEntities(headers, documents, isInitialLoad);
|
||||
} else {
|
||||
// console.log(
|
||||
// "🚀 ~ file: QueryTablesTabComponent.tsx ~ line 311 ~ QueryTablesTabComponent ~ loadEntities ~ data",
|
||||
// documents
|
||||
// );
|
||||
headers = documents.Results?.length
|
||||
? this.getFormattedHeaders(documents.Results)
|
||||
: ["RowKey", "PartitionKey", "Timestamp"];
|
||||
headers = documents?.length ? this.getFormattedHeaders(documents) : ["RowKey", "PartitionKey", "Timestamp"];
|
||||
this.setupIntialEntities(headers, documents, isInitialLoad);
|
||||
}
|
||||
// this.isEntitiesAvailable(isInitialLoad, data);
|
||||
} catch (error) {
|
||||
this.setState({
|
||||
queryErrorMessage: error.responseText,
|
||||
@ -415,9 +382,6 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
||||
sortAscendingAriaLabel: "Sorted A to Z",
|
||||
sortDescendingAriaLabel: "Sorted Z to A",
|
||||
onColumnClick: this.onColumnClick,
|
||||
// onRender: (item: Entities.ITableEntity) => {
|
||||
// return <div className={!item[header] ? "noData" : ""}>{item[header] ? item[header] : " "}</div>;
|
||||
// },
|
||||
});
|
||||
});
|
||||
|
||||
@ -455,36 +419,6 @@ 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 => {
|
||||
const { columns, items } = this.state;
|
||||
const newColumns: IColumn[] = columns.slice();
|
||||
@ -640,10 +574,6 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
||||
selectedQueryText: this.state.queryViewModel.runQuery(queryTableRows),
|
||||
});
|
||||
setTimeout(() => {
|
||||
// console.log(
|
||||
// "🚀 ~ file: QueryTablesTabComponent.tsx ~ line 651 ~ QueryTablesTabComponent ~ runQuery ~ selectedQueryText",
|
||||
// this.state.selectedQueryText
|
||||
// );
|
||||
this.loadEntities(false, queryTableRows.length > 0 ? true : false);
|
||||
}, 2000);
|
||||
this.setState({
|
||||
@ -1147,53 +1077,55 @@ class QueryTablesTabComponent extends Component<IQueryTablesTabComponentProps, I
|
||||
<div className="query-tab-document-pagination">
|
||||
{this.state.items.length > 0 && !this.state.isLoading && (
|
||||
<>
|
||||
<ul className="pagination ">
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination("FIRST", this.state.originalItems, this.state.currentStartIndex, PAGESIZE)
|
||||
}
|
||||
>
|
||||
First
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination(
|
||||
"PREVIOUS",
|
||||
this.state.originalItems,
|
||||
this.state.currentStartIndex,
|
||||
PAGESIZE
|
||||
)
|
||||
}
|
||||
>
|
||||
Previous
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination("NEXT", this.state.originalItems, this.state.currentStartIndex, PAGESIZE)
|
||||
}
|
||||
>
|
||||
Next
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination("LAST", this.state.originalItems, this.state.currentStartIndex, PAGESIZE)
|
||||
}
|
||||
>
|
||||
Last
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{this.state.originalItems.length > PAGESIZE && (
|
||||
<ul className="pagination ">
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination("FIRST", this.state.originalItems, this.state.currentStartIndex, PAGESIZE)
|
||||
}
|
||||
>
|
||||
First
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination(
|
||||
"PREVIOUS",
|
||||
this.state.originalItems,
|
||||
this.state.currentStartIndex,
|
||||
PAGESIZE
|
||||
)
|
||||
}
|
||||
>
|
||||
Previous
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination("NEXT", this.state.originalItems, this.state.currentStartIndex, PAGESIZE)
|
||||
}
|
||||
>
|
||||
Next
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className="item-link"
|
||||
onClick={() =>
|
||||
this.handlePagination("LAST", this.state.originalItems, this.state.currentStartIndex, PAGESIZE)
|
||||
}
|
||||
>
|
||||
Last
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
)}
|
||||
<Text variant="medium">
|
||||
Results {this.state.fromDocument + 1} -{" "}
|
||||
{this.state.originalItems.length >= this.state.toDocument
|
||||
|
Loading…
x
Reference in New Issue
Block a user