Fixed issue with Tables API when selecting a row with the same row key in different partition keys (#1969)

This commit is contained in:
vchske 2024-09-12 16:36:22 -07:00 committed by GitHub
parent 2c7e788358
commit d7647b2ecf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 17 deletions

View File

@ -155,6 +155,7 @@ export const htmlAttributeNames = {
dataTableContentTypeAttr: "contentType_attr", dataTableContentTypeAttr: "contentType_attr",
dataTableSnapshotAttr: "snapshot_attr", dataTableSnapshotAttr: "snapshot_attr",
dataTableRowKeyAttr: "rowKey_attr", dataTableRowKeyAttr: "rowKey_attr",
dataTablePartitionKeyAttr: "partKey_attr",
dataTableMessageIdAttr: "messageId_attr", dataTableMessageIdAttr: "messageId_attr",
dataTableHeaderIndex: "data-column-index", dataTableHeaderIndex: "data-column-index",
}; };

View File

@ -193,6 +193,9 @@ function getServerData(sSource: any, aoData: any, fnCallback: any, oSettings: an
* from UI elements. * from UI elements.
*/ */
function bindClientId(nRow: Node, aData: Entities.ITableEntity) { function bindClientId(nRow: Node, aData: Entities.ITableEntity) {
if (aData.PartitionKey && aData.PartitionKey._) {
$(nRow).attr(Constants.htmlAttributeNames.dataTablePartitionKeyAttr, aData.PartitionKey._);
}
$(nRow).attr(Constants.htmlAttributeNames.dataTableRowKeyAttr, aData.RowKey._); $(nRow).attr(Constants.htmlAttributeNames.dataTableRowKeyAttr, aData.RowKey._);
return nRow; return nRow;
} }
@ -205,6 +208,10 @@ function selectionChanged(element: any, valueAccessor: any, allBindings: any, vi
selected && selected &&
selected.forEach((b: Entities.ITableEntity) => { selected.forEach((b: Entities.ITableEntity) => {
var sel = DataTableOperations.getRowSelector([ var sel = DataTableOperations.getRowSelector([
{
key: Constants.htmlAttributeNames.dataTablePartitionKeyAttr,
value: b.PartitionKey && b.PartitionKey._ && b.PartitionKey._.toString(),
},
{ {
key: Constants.htmlAttributeNames.dataTableRowKeyAttr, key: Constants.htmlAttributeNames.dataTableRowKeyAttr,
value: b.RowKey && b.RowKey._ && b.RowKey._.toString(), value: b.RowKey && b.RowKey._ && b.RowKey._.toString(),
@ -370,8 +377,9 @@ function updateSelectionStatus(oSettings: any): void {
for (var i = 0; i < $dataTableRows.length; i++) { for (var i = 0; i < $dataTableRows.length; i++) {
var $row: JQuery = $dataTableRows.eq(i); var $row: JQuery = $dataTableRows.eq(i);
var rowKey: string = $row.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr); var rowKey: string = $row.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr);
var partitionKey: string = $row.attr(Constants.htmlAttributeNames.dataTablePartitionKeyAttr);
var table = tableEntityListViewModelMap[oSettings.ajax].tableViewModel; var table = tableEntityListViewModelMap[oSettings.ajax].tableViewModel;
if (table.isItemSelected(table.getTableEntityKeys(rowKey))) { if (table.isItemSelected(table.getTableEntityKeys(rowKey, partitionKey))) {
$row.attr("tabindex", "0"); $row.attr("tabindex", "0");
} }
} }

View File

@ -56,7 +56,10 @@ export default class DataTableOperationManager {
// Simply select the first item in this case. // Simply select the first item in this case.
var lastSelectedItemIndex = lastSelectedItem var lastSelectedItemIndex = lastSelectedItem
? this._tableEntityListViewModel.getItemIndexFromCurrentPage( ? this._tableEntityListViewModel.getItemIndexFromCurrentPage(
this._tableEntityListViewModel.getTableEntityKeys(lastSelectedItem.RowKey._), this._tableEntityListViewModel.getTableEntityKeys(
lastSelectedItem.RowKey._,
lastSelectedItem.PartitionKey && lastSelectedItem.PartitionKey._,
),
) )
: -1; : -1;
var nextIndex: number = isUpArrowKey ? lastSelectedItemIndex - 1 : lastSelectedItemIndex + 1; var nextIndex: number = isUpArrowKey ? lastSelectedItemIndex - 1 : lastSelectedItemIndex + 1;
@ -147,13 +150,14 @@ export default class DataTableOperationManager {
private getEntityIdentity($elem: JQuery<Element>): Entities.ITableEntityIdentity { private getEntityIdentity($elem: JQuery<Element>): Entities.ITableEntityIdentity {
return { return {
RowKey: $elem.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr), RowKey: $elem.attr(Constants.htmlAttributeNames.dataTableRowKeyAttr),
PartitionKey: $elem.attr(Constants.htmlAttributeNames.dataTablePartitionKeyAttr),
}; };
} }
private updateLastSelectedItem($elem: JQuery<Element>, 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.PartitionKey, entityIdentity.RowKey),
); );
this._tableEntityListViewModel.lastSelectedItem = entity; this._tableEntityListViewModel.lastSelectedItem = entity;
@ -168,7 +172,7 @@ export default class DataTableOperationManager {
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem); var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
this._tableEntityListViewModel.clearSelection(); this._tableEntityListViewModel.clearSelection();
this.addToSelection(entityIdentity.RowKey); this.addToSelection(entityIdentity.RowKey, entityIdentity.PartitionKey);
} }
} }
@ -190,11 +194,11 @@ export default class DataTableOperationManager {
if ( if (
!this._tableEntityListViewModel.isItemSelected( !this._tableEntityListViewModel.isItemSelected(
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey), this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.PartitionKey, entityIdentity.RowKey),
) )
) { ) {
// Adding item not previously in selection // Adding item not previously in selection
this.addToSelection(entityIdentity.RowKey); this.addToSelection(entityIdentity.RowKey, entityIdentity.PartitionKey);
} else { } else {
koSelected.remove((item: Entities.ITableEntity) => item.RowKey._ === entityIdentity.RowKey); koSelected.remove((item: Entities.ITableEntity) => item.RowKey._ === entityIdentity.RowKey);
} }
@ -212,10 +216,10 @@ export default class DataTableOperationManager {
if (anchorItem) { if (anchorItem) {
var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem); var entityIdentity: Entities.ITableEntityIdentity = this.getEntityIdentity($elem);
var elementIndex = this._tableEntityListViewModel.getItemIndexFromAllPages( var elementIndex = this._tableEntityListViewModel.getItemIndexFromAllPages(
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey), this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.PartitionKey, entityIdentity.RowKey),
); );
var anchorIndex = this._tableEntityListViewModel.getItemIndexFromAllPages( var anchorIndex = this._tableEntityListViewModel.getItemIndexFromAllPages(
this._tableEntityListViewModel.getTableEntityKeys(anchorItem.RowKey._), this._tableEntityListViewModel.getTableEntityKeys(anchorItem.PartitionKey._, anchorItem.RowKey._),
); );
var startIndex = Math.min(elementIndex, anchorIndex); var startIndex = Math.min(elementIndex, anchorIndex);
@ -234,24 +238,25 @@ export default class DataTableOperationManager {
if ( if (
!this._tableEntityListViewModel.isItemSelected( !this._tableEntityListViewModel.isItemSelected(
this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.RowKey), this._tableEntityListViewModel.getTableEntityKeys(entityIdentity.PartitionKey, entityIdentity.RowKey),
) )
) { ) {
if (this._tableEntityListViewModel.selected().length) { if (this._tableEntityListViewModel.selected().length) {
this._tableEntityListViewModel.clearSelection(); this._tableEntityListViewModel.clearSelection();
} }
this.addToSelection(entityIdentity.RowKey); this.addToSelection(entityIdentity.RowKey, entityIdentity.PartitionKey);
} }
} }
private addToSelection(rowKey: string) { private addToSelection(rowKey: string, partitionKey?: string) {
var selectedEntity: Entities.ITableEntity = this._tableEntityListViewModel.getItemFromCurrentPage( var selectedEntity: Entities.ITableEntity = this._tableEntityListViewModel.getItemFromCurrentPage(
this._tableEntityListViewModel.getTableEntityKeys(rowKey), this._tableEntityListViewModel.getTableEntityKeys(rowKey, partitionKey),
); );
if (selectedEntity != null) { if (selectedEntity != null) {
this._tableEntityListViewModel.selected.push(selectedEntity); this._tableEntityListViewModel.selected.push(selectedEntity);
} }
console.log(this._tableEntityListViewModel.selected().length);
} }
// Selecting first row if the selection is empty. // Selecting first row if the selection is empty.
@ -269,7 +274,7 @@ export default class DataTableOperationManager {
// Clear last selection: lastSelectedItem and lastSelectedAnchorItem // Clear last selection: lastSelectedItem and lastSelectedAnchorItem
this._tableEntityListViewModel.clearLastSelected(); this._tableEntityListViewModel.clearLastSelected();
this.addToSelection(firstEntity.RowKey._); this.addToSelection(firstEntity.RowKey._, firstEntity.PartitionKey && firstEntity.PartitionKey._);
// Update last selection // Update last selection
this._tableEntityListViewModel.lastSelectedItem = firstEntity; this._tableEntityListViewModel.lastSelectedItem = firstEntity;

View File

@ -128,8 +128,14 @@ export default class TableEntityListViewModel extends DataTableViewModel {
this.sqlQuery = ko.observable<string>("SELECT * FROM c"); this.sqlQuery = ko.observable<string>("SELECT * FROM c");
} }
public getTableEntityKeys(rowKey: string): Entities.IProperty[] { public getTableEntityKeys(rowKey: string, partitionKey: string): Entities.IProperty[] {
return [{ key: Constants.EntityKeyNames.RowKey, value: rowKey }]; const properties: Entities.IProperty[] = [{ key: Constants.EntityKeyNames.RowKey, value: rowKey }];
if (partitionKey) {
properties.push({ key: Constants.EntityKeyNames.PartitionKey, value: partitionKey });
}
return properties;
} }
public reloadTable(useSetting: boolean = true, resetHeaders: boolean = true): DataTables.Api<Element> { public reloadTable(useSetting: boolean = true, resetHeaders: boolean = true): DataTables.Api<Element> {
@ -261,7 +267,8 @@ export default class TableEntityListViewModel extends DataTableViewModel {
} }
var oldEntityIndex: number = _.findIndex( var oldEntityIndex: number = _.findIndex(
this.cache.data, this.cache.data,
(data: Entities.ITableEntity) => data.RowKey._ === entity.RowKey._, (data: Entities.ITableEntity) =>
data.RowKey._ === entity.RowKey._ && data.PartitionKey._ === entity.PartitionKey._,
); );
this.cache.data.splice(oldEntityIndex, 1, entity); this.cache.data.splice(oldEntityIndex, 1, entity);
@ -285,7 +292,7 @@ export default class TableEntityListViewModel extends DataTableViewModel {
entities.forEach((entity: Entities.ITableEntity) => { entities.forEach((entity: Entities.ITableEntity) => {
var cachedIndex: number = _.findIndex( var cachedIndex: number = _.findIndex(
this.cache.data, this.cache.data,
(e: Entities.ITableEntity) => e.RowKey._ === entity.RowKey._, (e: Entities.ITableEntity) => e.RowKey._ === entity.RowKey._ && e.PartitionKey._ === entity.PartitionKey._,
); );
if (cachedIndex >= 0) { if (cachedIndex >= 0) {
this.cache.data.splice(cachedIndex, 1); this.cache.data.splice(cachedIndex, 1);
@ -393,6 +400,16 @@ export default class TableEntityListViewModel extends DataTableViewModel {
}); });
} }
// Override as Tables can have the same Row key in different Partition keys
/**
* @override
*/
public getItemFromCurrentPage(itemKeys: Entities.IProperty[]): Entities.ITableEntity {
return _.find(this.items(), (item: Entities.ITableEntity) => {
return this.matchesKeys(item, itemKeys);
});
}
private prefetchAndRender( private prefetchAndRender(
tableQuery: Entities.ITableQuery, tableQuery: Entities.ITableQuery,
tablePageStartIndex: number, tablePageStartIndex: number,

View File

@ -36,4 +36,5 @@ export interface ITableQuery {
export interface ITableEntityIdentity { export interface ITableEntityIdentity {
RowKey: string; RowKey: string;
PartitionKey?: string;
} }