Fix datatables issue and indicator not loading for Table API > Entities. Upgrade jquery. Fix right panel resize issue. (#1713)

* Fix datatables issue and indicator not loading for Table API > Entities

* Fix jquery and datatables compile issues. Add patch for datatables.net-colreorder error in types

* Fix side panel size. Fix bug resizing side panel.

* Update PanelContainerComponent unit test snapshot

* Fix commented code
This commit is contained in:
Laurent Nguyen 2024-01-03 13:52:34 +00:00 committed by GitHub
parent c91ac39248
commit e9181f19d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 506 additions and 4950 deletions

1406
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -55,8 +55,8 @@
"crossroads": "0.12.2", "crossroads": "0.12.2",
"css-element-queries": "1.1.1", "css-element-queries": "1.1.1",
"d3": "6.1.1", "d3": "6.1.1",
"datatables.net-colreorder-dt": "1.5.1", "datatables.net-colreorder-dt": "1.7.0",
"datatables.net-dt": "1.10.19", "datatables.net-dt": "1.13.8",
"date-fns": "1.29.0", "date-fns": "1.29.0",
"dayjs": "1.8.19", "dayjs": "1.8.19",
"dom-to-image": "2.6.0", "dom-to-image": "2.6.0",
@ -71,13 +71,14 @@
"iframe-resizer-react": "1.1.0", "iframe-resizer-react": "1.1.0",
"immutable": "4.0.0-rc.12", "immutable": "4.0.0-rc.12",
"is-ci": "2.0.0", "is-ci": "2.0.0",
"jquery": "3.5.1", "jquery": "3.7.1",
"jquery-typeahead": "2.10.6", "jquery-typeahead": "2.11.1",
"jquery-ui-dist": "1.12.1", "jquery-ui-dist": "1.13.2",
"knockout": "3.5.1", "knockout": "3.5.1",
"mkdirp": "1.0.4", "mkdirp": "1.0.4",
"monaco-editor": "0.44.0", "monaco-editor": "0.44.0",
"ms": "2.1.3", "ms": "2.1.3",
"patch-package": "8.0.0",
"p-retry": "4.6.2", "p-retry": "4.6.2",
"plotly.js-cartesian-dist-min": "1.52.3", "plotly.js-cartesian-dist-min": "1.52.3",
"post-robot": "10.0.42", "post-robot": "10.0.42",
@ -114,11 +115,14 @@
"@types/codemirror": "0.0.56", "@types/codemirror": "0.0.56",
"@types/crossroads": "0.0.30", "@types/crossroads": "0.0.30",
"@types/d3": "5.9.2", "@types/d3": "5.9.2",
"@types/datatables.net": "1.10.28",
"@types/datatables.net-colreorder": "1.4.5",
"@types/dom-to-image": "2.6.2", "@types/dom-to-image": "2.6.2",
"@types/enzyme": "3.10.7", "@types/enzyme": "3.10.7",
"@types/enzyme-adapter-react-16": "1.0.6", "@types/enzyme-adapter-react-16": "1.0.6",
"@types/hasher": "0.0.31", "@types/hasher": "0.0.31",
"@types/jest": "26.0.20", "@types/jest": "26.0.20",
"@types/jquery": "3.5.29",
"@types/node": "12.11.1", "@types/node": "12.11.1",
"@types/post-robot": "10.0.1", "@types/post-robot": "10.0.1",
"@types/q": "1.5.1", "@types/q": "1.5.1",
@ -187,6 +191,7 @@
"webpack-dev-server": "4.15.1" "webpack-dev-server": "4.15.1"
}, },
"scripts": { "scripts": {
"postinstall": "patch-package",
"start": "webpack serve --mode development", "start": "webpack serve --mode development",
"dev": "echo \"WARNING: npm run dev has been deprecated\" && npm run build", "dev": "echo \"WARNING: npm run dev has been deprecated\" && npm run build",
"build:dataExplorer:ci": "npm run build:ci", "build:dataExplorer:ci": "npm run build:ci",
@ -233,4 +238,4 @@
"printWidth": 120, "printWidth": 120,
"endOfLine": "auto" "endOfLine": "auto"
} }
} }

View File

@ -0,0 +1,22 @@
diff --git a/node_modules/datatables.net-colreorder/types/types.d.ts b/node_modules/datatables.net-colreorder/types/types.d.ts
index e5dc283..1930c2b 100644
--- a/node_modules/datatables.net-colreorder/types/types.d.ts
+++ b/node_modules/datatables.net-colreorder/types/types.d.ts
@@ -7,7 +7,7 @@
/// <reference types="jquery" />
-import DataTables, {Api} from 'datatables.net';
+import DataTables, { Api } from 'datatables.net';
export default DataTables;
@@ -40,6 +40,8 @@ declare module 'datatables.net' {
/**
* Create a new ColReorder instance for the target DataTable
*/
+ // Ignore this error: error TS7013: Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.
+ // @ts-ignore
new (dt: Api<any>, settings: boolean | ConfigColReorder);
/**

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
* https://github.com/running-coder/jquery-typeahead/issues/156 * https://github.com/running-coder/jquery-typeahead/issues/156
* TODO: Replace this minimum definition by the official one when it comes out. * TODO: Replace this minimum definition by the official one when it comes out.
*/ */
/// <reference path="jquery.d.ts" /> /// <reference types="jquery" />
interface JQueryTypeaheadParam { interface JQueryTypeaheadParam {
input: string; input: string;

View File

@ -3,7 +3,7 @@
// Definitions by: Boris Yankov <https://github.com/borisyankov/>, John Reilly <https://github.com/johnnyreilly> // Definitions by: Boris Yankov <https://github.com/borisyankov/>, John Reilly <https://github.com/johnnyreilly>
// Definitions: https://github.com/borisyankov/DefinitelyTyped // Definitions: https://github.com/borisyankov/DefinitelyTyped
/// <reference path="jquery.d.ts"/> /// <reference types="jquery"/>
declare namespace JQueryUI { declare namespace JQueryUI {
// Accordion ////////////////////////////////////////////////// // Accordion //////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -1163,15 +1163,12 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
)}"`, )}"`,
).then( ).then(
(documents: DataModels.DocumentId[]) => { (documents: DataModels.DocumentId[]) => {
$.each( $.each(documents, (index: number, doc: any) => {
documents, newIconsMap[doc["_graph_icon_property_value"]] = {
(index: number, doc: { _graph_icon_property_value: string; icon: string; format: string }) => { data: doc["icon"],
newIconsMap[doc["_graph_icon_property_value"]] = { format: doc["format"],
data: doc["icon"], };
format: doc["format"], });
};
},
);
// Update graph configuration // Update graph configuration
this.setState({ this.setState({

View File

@ -29,7 +29,7 @@ export class PanelContainerComponent extends React.Component<PanelContainerProps
}; };
} }
omponentDidMount(): void { componentDidMount(): void {
window.addEventListener("resize", () => this.setState({ height: this.getPanelHeight() })); window.addEventListener("resize", () => this.setState({ height: this.getPanelHeight() }));
} }
@ -62,12 +62,12 @@ export class PanelContainerComponent extends React.Component<PanelContainerProps
customWidth={this.props.panelWidth ? this.props.panelWidth : "440px"} customWidth={this.props.panelWidth ? this.props.panelWidth : "440px"}
headerClassName="panelHeader" headerClassName="panelHeader"
onRenderNavigationContent={this.props.onRenderNavigationContent} onRenderNavigationContent={this.props.onRenderNavigationContent}
isFooterAtBottom={true}
styles={{ styles={{
navigation: { borderBottom: "1px solid #cccccc" }, navigation: { borderBottom: "1px solid #cccccc" },
content: { padding: 0, height: "100%" }, content: { padding: 0 },
scrollableContent: { height: "100%" },
header: { padding: "0 0 8px 34px" }, header: { padding: "0 0 8px 34px" },
commands: { marginTop: 8 }, commands: { marginTop: 8, paddingTop: 0 },
}} }}
style={{ height: this.state.height }} style={{ height: this.state.height }}
> >

View File

@ -6,6 +6,7 @@ exports[`PaneContainerComponent test should be resize if notification console is
customWidth="440px" customWidth="440px"
headerClassName="panelHeader" headerClassName="panelHeader"
headerText="test" headerText="test"
isFooterAtBottom={true}
isLightDismiss={true} isLightDismiss={true}
isOpen={true} isOpen={true}
onDismiss={[Function]} onDismiss={[Function]}
@ -18,9 +19,9 @@ exports[`PaneContainerComponent test should be resize if notification console is
Object { Object {
"commands": Object { "commands": Object {
"marginTop": 8, "marginTop": 8,
"paddingTop": 0,
}, },
"content": Object { "content": Object {
"height": "100%",
"padding": 0, "padding": 0,
}, },
"header": Object { "header": Object {
@ -29,9 +30,6 @@ exports[`PaneContainerComponent test should be resize if notification console is
"navigation": Object { "navigation": Object {
"borderBottom": "1px solid #cccccc", "borderBottom": "1px solid #cccccc",
}, },
"scrollableContent": Object {
"height": "100%",
},
} }
} }
type={7} type={7}
@ -48,6 +46,7 @@ exports[`PaneContainerComponent test should render with panel content and header
customWidth="440px" customWidth="440px"
headerClassName="panelHeader" headerClassName="panelHeader"
headerText="test" headerText="test"
isFooterAtBottom={true}
isLightDismiss={true} isLightDismiss={true}
isOpen={true} isOpen={true}
onDismiss={[Function]} onDismiss={[Function]}
@ -60,9 +59,9 @@ exports[`PaneContainerComponent test should render with panel content and header
Object { Object {
"commands": Object { "commands": Object {
"marginTop": 8, "marginTop": 8,
"paddingTop": 0,
}, },
"content": Object { "content": Object {
"height": "100%",
"padding": 0, "padding": 0,
}, },
"header": Object { "header": Object {
@ -71,9 +70,6 @@ exports[`PaneContainerComponent test should render with panel content and header
"navigation": Object { "navigation": Object {
"borderBottom": "1px solid #cccccc", "borderBottom": "1px solid #cccccc",
}, },
"scrollableContent": Object {
"height": "100%",
},
} }
} }
type={7} type={7}

View File

@ -1,6 +1,8 @@
import * as ko from "knockout"; import * as ko from "knockout";
import * as _ from "underscore"; import * as _ from "underscore";
import * as DataTable from "datatables.net-dt";
import loadingIndicator3Squares from "../../../../images/LoadingIndicator_3Squares.gif";
import QueryTablesTab from "../../Tabs/QueryTablesTab"; import QueryTablesTab from "../../Tabs/QueryTablesTab";
import * as Constants from "../Constants"; import * as Constants from "../Constants";
import * as Entities from "../Entities"; import * as Entities from "../Entities";
@ -94,7 +96,7 @@ function createDataTable(
}); });
} }
tableEntityListViewModel.table = DataTableBuilder.createDataTable($dataTable, <DataTables.Settings>{ tableEntityListViewModel.table = DataTableBuilder.createDataTable($dataTable, <DataTable.Config>{
// WARNING!!! SECURITY: If you add new columns, make sure you encode them if they are user strings from Azure (see encodeText) // WARNING!!! SECURITY: If you add new columns, make sure you encode them if they are user strings from Azure (see encodeText)
// so that they don't get interpreted as HTML in our page. // so that they don't get interpreted as HTML in our page.
colReorder: true, colReorder: true,
@ -116,7 +118,7 @@ function createDataTable(
sPrevious: "<", sPrevious: "<",
sLast: ">>", sLast: ">>",
}, },
sProcessing: '<img style="width: 28px; height: 6px; " src="images/LoadingIndicator_3Squares.gif">', sProcessing: `<img style="width: 28px; height: 6px; " src="${loadingIndicator3Squares}">`,
oAria: { oAria: {
sSortAscending: "", sSortAscending: "",
sSortDescending: "", sSortDescending: "",
@ -345,7 +347,7 @@ function updateSelectionStatus(oSettings: any): void {
// TODO consider centralizing this "post-command" logic into some sort of Command Manager entity. // TODO consider centralizing this "post-command" logic into some sort of Command Manager entity.
// See VSO:166520: "[Storage Explorer] Consider adding a 'command manager' to track command post-effects." // See VSO:166520: "[Storage Explorer] Consider adding a 'command manager' to track command post-effects."
function updateDataTableFocus(queryTablesTabId: string): void { function updateDataTableFocus(queryTablesTabId: string): void {
var $activeElement: JQuery = $(document.activeElement); var $activeElement: JQuery<Element> = $(document.activeElement);
var isFocusLost: boolean = $activeElement.is("body"); // When focus is lost, "body" becomes the active element. var isFocusLost: boolean = $activeElement.is("body"); // When focus is lost, "body" becomes the active element.
var storageExplorerFrameHasFocus: boolean = document.hasFocus(); var storageExplorerFrameHasFocus: boolean = document.hasFocus();
var operationManager = tableEntityListViewModelMap[queryTablesTabId].operationManager; var operationManager = tableEntityListViewModelMap[queryTablesTabId].operationManager;

View File

@ -1,3 +1,4 @@
import * as DataTable from "datatables.net-dt";
import * as Utilities from "../Utilities"; import * as Utilities from "../Utilities";
/** /**
@ -8,7 +9,7 @@ import * as Utilities from "../Utilities";
* @param{$dataTableElem} JQuery data table element * @param{$dataTableElem} JQuery data table element
* @param{$settings} Settings to use when creating the data table * @param{$settings} Settings to use when creating the data table
*/ */
export function createDataTable($dataTableElem: JQuery, settings: any): DataTables.DataTable { export function createDataTable($dataTableElem: JQuery, settings: any): DataTable.Api<HTMLElement> {
return $dataTableElem.DataTable(applyDefaultRendering(settings)); return $dataTableElem.DataTable(applyDefaultRendering(settings));
} }
@ -18,14 +19,14 @@ export function createDataTable($dataTableElem: JQuery, settings: any): DataTabl
* @param{settings} The settings to check * @param{settings} The settings to check
* @return The given settings with all columns having a rendering function * @return The given settings with all columns having a rendering function
*/ */
function applyDefaultRendering(settings: any): DataTables.SettingsLegacy { function applyDefaultRendering(settings: DataTable.Config): any {
var tableColumns: DataTables.ColumnLegacy[] = null; var tableColumns: any[] = null;
if (settings.aoColumns) { if (settings.columns) {
tableColumns = settings.aoColumns; tableColumns = settings.columns;
} else if (settings.aoColumnDefs) { } else if (settings.columnDefs) {
// for tables we use aoColumnDefs instead of aoColumns // for tables we use aoColumnDefs instead of aoColumns
tableColumns = settings.aoColumnDefs; tableColumns = settings.columnDefs;
} }
// either the settings had no columns defined, or they were called // either the settings had no columns defined, or they were called

View File

@ -1,11 +1,11 @@
import ko from "knockout"; import ko from "knockout";
import * as DataTableOperations from "./DataTableOperations";
import * as Constants from "../Constants"; import * as Constants from "../Constants";
import * as Entities from "../Entities";
import * as Utilities from "../Utilities";
import * as DataTableOperations from "./DataTableOperations";
import TableCommands from "./TableCommands"; import TableCommands from "./TableCommands";
import TableEntityListViewModel from "./TableEntityListViewModel"; import TableEntityListViewModel from "./TableEntityListViewModel";
import * as Utilities from "../Utilities";
import * as Entities from "../Entities";
/* /*
* Base class for data table row selection. * Base class for data table row selection.
@ -13,9 +13,9 @@ import * as Entities from "../Entities";
export default class DataTableOperationManager { export default class DataTableOperationManager {
private _tableEntityListViewModel: TableEntityListViewModel; private _tableEntityListViewModel: TableEntityListViewModel;
private _tableCommands: TableCommands; private _tableCommands: TableCommands;
private dataTable: JQuery; private dataTable: JQuery<Element>;
constructor(table: JQuery, viewModel: TableEntityListViewModel, tableCommands: TableCommands) { constructor(table: JQuery<Element>, viewModel: TableEntityListViewModel, tableCommands: TableCommands) {
this.dataTable = table; this.dataTable = table;
this._tableEntityListViewModel = viewModel; this._tableEntityListViewModel = viewModel;
this._tableCommands = tableCommands; this._tableCommands = tableCommands;
@ -25,7 +25,7 @@ export default class DataTableOperationManager {
} }
private click = (event: JQueryEventObject) => { private click = (event: JQueryEventObject) => {
var elem: JQuery = $(event.currentTarget); var elem: JQuery<Element> = $(event.currentTarget);
this.updateLastSelectedItem(elem, event.shiftKey); this.updateLastSelectedItem(elem, event.shiftKey);
if (Utilities.isEnvironmentCtrlPressed(event)) { if (Utilities.isEnvironmentCtrlPressed(event)) {
@ -48,7 +48,7 @@ export default class DataTableOperationManager {
if (isUpArrowKey || isDownArrowKey) { if (isUpArrowKey || isDownArrowKey) {
var lastSelectedItem: Entities.ITableEntity = this._tableEntityListViewModel.lastSelectedItem; var lastSelectedItem: Entities.ITableEntity = this._tableEntityListViewModel.lastSelectedItem;
var dataTableRows: JQuery = $(Constants.htmlSelectors.dataTableAllRowsSelector); var dataTableRows: JQuery<Element> = $(Constants.htmlSelectors.dataTableAllRowsSelector);
var maximumIndex = dataTableRows.length - 1; 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. // If can't find an index for lastSelectedItem, then either no item is previously selected or it goes across page.
@ -60,7 +60,7 @@ export default class DataTableOperationManager {
: -1; : -1;
var nextIndex: number = isUpArrowKey ? lastSelectedItemIndex - 1 : lastSelectedItemIndex + 1; var nextIndex: number = isUpArrowKey ? lastSelectedItemIndex - 1 : lastSelectedItemIndex + 1;
var safeIndex: number = Utilities.ensureBetweenBounds(nextIndex, 0, maximumIndex); var safeIndex: number = Utilities.ensureBetweenBounds(nextIndex, 0, maximumIndex);
var selectedRowElement: JQuery = dataTableRows.eq(safeIndex); var selectedRowElement: JQuery<Element> = dataTableRows.eq(safeIndex);
if (selectedRowElement) { if (selectedRowElement) {
if (event.shiftKey) { if (event.shiftKey) {
@ -143,13 +143,13 @@ export default class DataTableOperationManager {
return handled; return handled;
} }
private getEntityIdentity($elem: JQuery): Entities.ITableEntityIdentity { private getEntityIdentity($elem: JQuery<Element>): Entities.ITableEntityIdentity {
return { return {
RowKey: $elem.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr), RowKey: $elem.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr),
}; };
} }
private updateLastSelectedItem($elem: JQuery, isShiftSelect: boolean) { private updateLastSelectedItem($elem: JQuery<Element>, isShiftSelect: boolean) {
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem); var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
var entity = this._tableEntityListViewModel.getItemFromCurrentPage( var entity = this._tableEntityListViewModel.getItemFromCurrentPage(
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey), this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey),
@ -162,7 +162,7 @@ export default class DataTableOperationManager {
} }
} }
private applySingleSelection($elem: JQuery) { private applySingleSelection($elem: JQuery<Element>) {
if ($elem) { if ($elem) {
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem); var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
@ -179,7 +179,7 @@ export default class DataTableOperationManager {
); );
} }
private applyCtrlSelection($elem: JQuery): void { private applyCtrlSelection($elem: JQuery<Element>): void {
var koSelected: ko.ObservableArray<Entities.ITableEntity> = this._tableEntityListViewModel var koSelected: ko.ObservableArray<Entities.ITableEntity> = this._tableEntityListViewModel
? this._tableEntityListViewModel.selected ? this._tableEntityListViewModel.selected
: null; : null;
@ -200,7 +200,7 @@ export default class DataTableOperationManager {
} }
} }
private applyShiftSelection($elem: JQuery): void { private applyShiftSelection($elem: JQuery<Element>): void {
var anchorItem = this._tableEntityListViewModel.lastSelectedAnchorItem; var anchorItem = this._tableEntityListViewModel.lastSelectedAnchorItem;
// If anchor item doesn't exist, use the first available item of current page instead // If anchor item doesn't exist, use the first available item of current page instead
@ -228,7 +228,7 @@ export default class DataTableOperationManager {
} }
} }
private applyContextMenuSelection($elem: JQuery) { private applyContextMenuSelection($elem: JQuery<Element>) {
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem); var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
if ( if (

View File

@ -1,3 +1,4 @@
import * as DataTables from "datatables.net";
import Q from "q"; import Q from "q";
import _ from "underscore"; import _ from "underscore";
import * as QueryBuilderConstants from "../Constants"; import * as QueryBuilderConstants from "../Constants";
@ -13,7 +14,7 @@ export function getRowSelector(selectorSchema: Entities.IProperty[]): string {
return QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector + selector; return QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector + selector;
} }
export function isRowVisible(dataTableScrollBodyQuery: JQuery, element: HTMLElement): boolean { export function isRowVisible(dataTableScrollBodyQuery: JQuery<Element>, element: Element): boolean {
let isVisible = false; let isVisible = false;
if (dataTableScrollBodyQuery.length && element) { if (dataTableScrollBodyQuery.length && element) {
@ -26,16 +27,18 @@ export function isRowVisible(dataTableScrollBodyQuery: JQuery, element: HTMLElem
return isVisible; return isVisible;
} }
export function scrollToRowIfNeeded(dataTableRows: JQuery, currentIndex: number, isScrollUp: boolean): void { export function scrollToRowIfNeeded(dataTableRows: JQuery<Element>, currentIndex: number, isScrollUp: boolean): void {
if (dataTableRows.length) { if (dataTableRows.length) {
const dataTableScrollBodyQuery: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector), const dataTableScrollBodyQuery: JQuery<Element> = $(
selectedRowElement: HTMLElement = dataTableRows.get(currentIndex); QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector,
),
selectedRowElement: Element = dataTableRows.get(currentIndex);
if (dataTableScrollBodyQuery.length && selectedRowElement) { if (dataTableScrollBodyQuery.length && selectedRowElement) {
const isVisible: boolean = isRowVisible(dataTableScrollBodyQuery, selectedRowElement); const isVisible: boolean = isRowVisible(dataTableScrollBodyQuery, selectedRowElement);
if (!isVisible) { if (!isVisible) {
const selectedRowQuery: JQuery = $(selectedRowElement), const selectedRowQuery: JQuery<Element> = $(selectedRowElement),
scrollPosition: number = dataTableScrollBodyQuery.scrollTop(), scrollPosition: number = dataTableScrollBodyQuery.scrollTop(),
selectedElementPosition: number = selectedRowQuery.position().top; selectedElementPosition: number = selectedRowQuery.position().top;
let newScrollPosition = 0; let newScrollPosition = 0;
@ -54,8 +57,8 @@ export function scrollToRowIfNeeded(dataTableRows: JQuery, currentIndex: number,
} }
export function scrollToTopIfNeeded(): void { export function scrollToTopIfNeeded(): void {
const $dataTableRows: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector), const $dataTableRows: JQuery<Element> = $(QueryBuilderConstants.htmlSelectors.dataTableAllRowsSelector),
$dataTableScrollBody: JQuery = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector); $dataTableScrollBody: JQuery<Element> = $(QueryBuilderConstants.htmlSelectors.dataTableScrollBodySelector);
if ($dataTableRows.length && $dataTableScrollBody.length) { if ($dataTableRows.length && $dataTableScrollBody.length) {
$dataTableScrollBody.scrollTop(0); $dataTableScrollBody.scrollTop(0);
@ -71,7 +74,7 @@ export function setPaginationButtonEventHandlers(): void {
.attr("role", "button"); .attr("role", "button");
} }
export function filterColumns(table: DataTables.DataTable, settings: boolean[]): void { export function filterColumns(table: DataTables.Api<HTMLElement>, settings: boolean[]): void {
settings && settings &&
settings.forEach((value: boolean, index: number) => { settings.forEach((value: boolean, index: number) => {
table.column(index).visible(value, false); table.column(index).visible(value, false);
@ -84,7 +87,7 @@ export function filterColumns(table: DataTables.DataTable, settings: boolean[]):
* If no current order is specified, reorder the columns based on intial order. * If no current order is specified, reorder the columns based on intial order.
*/ */
export function reorderColumns( export function reorderColumns(
table: DataTables.DataTable, table: DataTables.Api<HTMLElement>,
targetOrder: number[], targetOrder: number[],
currentOrder?: number[], currentOrder?: number[],
//eslint-disable-next-line //eslint-disable-next-line
@ -108,7 +111,9 @@ export function reorderColumns(
? calculateTransformationOrder(currentOrder, targetOrder) ? calculateTransformationOrder(currentOrder, targetOrder)
: targetOrder; : targetOrder;
try { try {
$.fn.dataTable.ColReorder(table).fnOrder(transformationOrder); // TODO: This possibly does not work with the new version of datatables.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
($.fn.dataTable as any).ColReorder(table).fnOrder(transformationOrder);
} catch (err) { } catch (err) {
return Q.reject(err); return Q.reject(err);
} }
@ -116,9 +121,9 @@ export function reorderColumns(
return Q.resolve(null); return Q.resolve(null);
} }
export function resetColumns(table: DataTables.DataTable): void { // export function resetColumns(table: DataTables.DataTable): void {
$.fn.dataTable.ColReorder(table).fnReset(); // $.fn.dataTable.ColReorder(table).fnReset();
} // }
/** /**
* A table's initial order is described in the form of a natural ascending order. * A table's initial order is described in the form of a natural ascending order.
@ -133,8 +138,10 @@ export function getInitialOrder(columnsCount: number): number[] {
* Initial order: I = [0, 1, 2, 3, 4, 5, 6, 7, 8] <----> {prop0, prop1, prop2, prop3, prop4, prop5, prop6, prop7, prop8} * 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} * 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[] { export function getCurrentOrder(table: DataTables.Api<HTMLElement>): number[] {
return $.fn.dataTable.ColReorder(table).fnOrder(); // TODO: This possibly does not work with the new version of datatables.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return ($.fn.dataTable as any).ColReorder(table).fnOrder();
} }
/** /**
@ -178,8 +185,8 @@ export function calculateTransformationOrder(currentOrder: number[], targetOrder
return transformationOrder; return transformationOrder;
} }
export function getDataTableHeaders(table: DataTables.DataTable): string[] { export function getDataTableHeaders(table: DataTables.Api<HTMLElement>): string[] {
const columns: DataTables.ColumnsMethods = table.columns(); const columns = table.columns();
let headers: string[] = []; let headers: string[] = [];
if (columns) { if (columns) {
// table.columns() return ColumnsMethods which is an array of arrays // table.columns() return ColumnsMethods which is an array of arrays

View File

@ -1,14 +1,15 @@
import * as ko from "knockout"; import * as ko from "knockout";
import * as _ from "underscore"; import * as _ from "underscore";
import { Action } from "../../../Shared/Telemetry/TelemetryConstants"; import { ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
import CacheBase from "./CacheBase"; import * as DataTables from "datatables.net";
import * as CommonConstants from "../../../Common/Constants"; import * as CommonConstants from "../../../Common/Constants";
import { Action } from "../../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
import QueryTablesTab from "../../Tabs/QueryTablesTab";
import * as Constants from "../Constants"; import * as Constants from "../Constants";
import * as Entities from "../Entities"; import * as Entities from "../Entities";
import QueryTablesTab from "../../Tabs/QueryTablesTab"; import CacheBase from "./CacheBase";
import * as TelemetryProcessor from "../../../Shared/Telemetry/TelemetryProcessor";
import { QueryIterator, ItemDefinition, Resource } from "@azure/cosmos";
// This is the format of the data we will have to pass to Datatable render callback, // This is the format of the data we will have to pass to Datatable render callback,
// and property names are defined by Datatable as well. // and property names are defined by Datatable as well.
@ -27,7 +28,7 @@ abstract class DataTableViewModel {
public items = ko.observableArray<Entities.ITableEntity>(); public items = ko.observableArray<Entities.ITableEntity>();
public selected = ko.observableArray<Entities.ITableEntity>(); public selected = ko.observableArray<Entities.ITableEntity>();
public table: DataTables.DataTable; public table: DataTables.Api<HTMLElement>;
// The anchor item is for shift selection. i.e., select all items between anchor item and a give item. // The anchor item is for shift selection. i.e., select all items between anchor item and a give item.
public lastSelectedAnchorItem: Entities.ITableEntity; public lastSelectedAnchorItem: Entities.ITableEntity;

View File

@ -1,3 +1,4 @@
import * as DataTables from "datatables.net";
import * as ko from "knockout"; import * as ko from "knockout";
import Q from "q"; import Q from "q";
import * as _ from "underscore"; import * as _ from "underscore";
@ -56,7 +57,7 @@ function _parse(err: any): ErrorDataModel[] {
function _getInnerErrors(message: string): any[] { function _getInnerErrors(message: string): any[] {
/* /*
The backend error message has an inner-message which is a stringified object. The backend error message has an inner-message which is a stringified object.
For SQL errors, the "errors" property is an array of SqlErrorDataModel. For SQL errors, the "errors" property is an array of SqlErrorDataModel.
Example: Example:
"Message: {"Errors":["Resource with specified id or name already exists"]}\r\nActivityId: 80005000008d40b6a, Request URI: /apps/19000c000c0a0005/services/mctestdocdbprod-MasterService-0-00066ab9937/partitions/900005f9000e676fb8/replicas/13000000000955p" "Message: {"Errors":["Resource with specified id or name already exists"]}\r\nActivityId: 80005000008d40b6a, Request URI: /apps/19000c000c0a0005/services/mctestdocdbprod-MasterService-0-00066ab9937/partitions/900005f9000e676fb8/replicas/13000000000955p"
@ -131,7 +132,7 @@ export default class TableEntityListViewModel extends DataTableViewModel {
return [{ key: Constants.EntityKeyNames.RowKey, value: rowKey }]; return [{ key: Constants.EntityKeyNames.RowKey, value: rowKey }];
} }
public reloadTable(useSetting: boolean = true, resetHeaders: boolean = true): DataTables.DataTable { public reloadTable(useSetting: boolean = true, resetHeaders: boolean = true): DataTables.Api<Element> {
this.clearCache(); this.clearCache();
this.clearSelection(); this.clearSelection();
this.isCancelled = false; this.isCancelled = false;

View File

@ -1,3 +1,4 @@
import * as DataTable from "datatables.net-dt";
import * as ko from "knockout"; import * as ko from "knockout";
import { KeyCodes } from "../../../Common/Constants"; import { KeyCodes } from "../../../Common/Constants";
import { userContext } from "../../../UserContext"; import { userContext } from "../../../UserContext";
@ -643,7 +644,7 @@ export default class QueryBuilderViewModel {
return groupViewModels; return groupViewModels;
}; };
public runQuery = (): DataTables.DataTable => { public runQuery = (): DataTable.Api<Element> => {
return this._queryViewModel.runQuery(); return this._queryViewModel.runQuery();
}; };

View File

@ -1,9 +1,10 @@
import * as DataTables from "datatables.net";
import * as ko from "knockout"; import * as ko from "knockout";
import React from "react"; import React from "react";
import * as _ from "underscore"; import * as _ from "underscore";
import { KeyCodes } from "../../../Common/Constants"; import { KeyCodes } from "../../../Common/Constants";
import { useSidePanel } from "../../../hooks/useSidePanel";
import { userContext } from "../../../UserContext"; import { userContext } from "../../../UserContext";
import { useSidePanel } from "../../../hooks/useSidePanel";
import { TableQuerySelectPanel } from "../../Panes/Tables/TableQuerySelectPanel/TableQuerySelectPanel"; import { TableQuerySelectPanel } from "../../Panes/Tables/TableQuerySelectPanel/TableQuerySelectPanel";
import QueryTablesTab from "../../Tabs/QueryTablesTab"; import QueryTablesTab from "../../Tabs/QueryTablesTab";
import { getQuotedCqlIdentifier } from "../CqlUtilities"; import { getQuotedCqlIdentifier } from "../CqlUtilities";
@ -158,7 +159,7 @@ export default class QueryViewModel {
notify: "always", notify: "always",
}); });
public runQuery = (): DataTables.DataTable => { public runQuery = (): DataTables.Api<Element> => {
let filter = this.setFilter(); let filter = this.setFilter();
if (filter && userContext.apiType !== "Cassandra") { if (filter && userContext.apiType !== "Cassandra") {
filter = filter.replace(/"/g, "'"); filter = filter.replace(/"/g, "'");
@ -176,7 +177,7 @@ export default class QueryViewModel {
return this._tableEntityListViewModel.reloadTable(/*useSetting*/ false, /*resetHeaders*/ false); return this._tableEntityListViewModel.reloadTable(/*useSetting*/ false, /*resetHeaders*/ false);
}; };
public clearQuery = (): DataTables.DataTable => { public clearQuery = (): DataTables.Api<Element> => {
this.queryText(); this.queryText();
this.topValue(); this.topValue();
this.selectText(); this.selectText();

View File

@ -281,7 +281,7 @@ export class CassandraAPIDataClient extends TableDataClient {
query, query,
paginationToken, paginationToken,
}, },
beforeSend: this.setAuthorizationHeader, beforeSend: this.setAuthorizationHeader as any,
cache: false, cache: false,
}); });
shouldNotify && shouldNotify &&
@ -423,7 +423,7 @@ export class CassandraAPIDataClient extends TableDataClient {
keyspaceId: collection.databaseId, keyspaceId: collection.databaseId,
tableId: collection.id(), tableId: collection.id(),
}, },
beforeSend: this.setAuthorizationHeader, beforeSend: this.setAuthorizationHeader as any,
cache: false, cache: false,
}) })
.then( .then(
@ -463,7 +463,7 @@ export class CassandraAPIDataClient extends TableDataClient {
keyspaceId: collection.databaseId, keyspaceId: collection.databaseId,
tableId: collection.id(), tableId: collection.id(),
}, },
beforeSend: this.setAuthorizationHeader, beforeSend: this.setAuthorizationHeader as any,
cache: false, cache: false,
}) })
.then( .then(
@ -496,7 +496,7 @@ export class CassandraAPIDataClient extends TableDataClient {
resourceId: resourceId, resourceId: resourceId,
query: query, query: query,
}, },
beforeSend: this.setAuthorizationHeader, beforeSend: this.setAuthorizationHeader as any,
cache: false, cache: false,
}).then( }).then(
(data: any) => { (data: any) => {