WIP: fix reactivity on row updates

This commit is contained in:
David Tsay 2024-12-02 15:44:17 -08:00
parent 057a5f997c
commit 6d2bf8b8a3
4 changed files with 54 additions and 15 deletions

View File

@ -91,15 +91,20 @@ export default class TelemetryTableRow {
return [VIEW_DATUM_ACTION_KEY, VIEW_HISTORICAL_DATA_ACTION_KEY];
}
updateWithDatum(updatesToDatum) {
const normalizedUpdatesToDatum = createNormalizedDatum(updatesToDatum, this.columns);
/**
* Merges the row datum with the given row datum. This is used to merge rows
* when the user has selected multiple rows.
* @param {TelemetryTableRow} row
*/
updateWithDatum(row) {
this.datum = {
...this.datum,
...normalizedUpdatesToDatum
...row.datum
};
this.fullDatum = {
...this.fullDatum,
...updatesToDatum
...row.fullDatum
};
}
}

View File

@ -23,6 +23,10 @@ import { EventEmitter } from 'eventemitter3';
import _ from 'lodash';
import { ORDER } from '../constants.js';
/**
* @typedef {import('.TelemetryTableRow.js').default} TelemetryTableRow
*/
/**
* @constructor
*/
@ -59,12 +63,6 @@ export default class TableRowCollection extends EventEmitter {
let rowsToAdd = this.filterRows(rows);
this.sortAndMergeRows(rowsToAdd);
// we emit filter no matter what to trigger
// an update of visible rows
if (rowsToAdd.length > 0) {
this.emit('add', rowsToAdd);
}
}
clearRowsFromTableAndFilter(rows) {
@ -92,6 +90,8 @@ export default class TableRowCollection extends EventEmitter {
if (this.rows.length === 0) {
this.rows = sortedRows;
this.emit('add', sortedRows);
return;
}
@ -124,10 +124,22 @@ export default class TableRowCollection extends EventEmitter {
return foundIndex;
}
updateRowInPlace(row, index) {
const foundRow = this.rows[index];
foundRow.updateWithDatum(row.datum);
this.rows[index] = foundRow;
/**
* Incoming row exists in the collection,
* so merge existing and incoming row properties
*
* Do to reactivity of Vue, we want to emit the new row object
* @param {TelemetryTableRow} incomingRow to update rather than add to the collection
* @param {number} index of the existing row in the collection
*/
updateRowInPlace(incomingRow, index) {
// Merge the existing row with the incoming row
const existingRow = this.rows[index];
incomingRow.updateWithDatum(existingRow);
// Emit the updated incoming row to trigger reactivity
this.rows.splice(index, 1, incomingRow);
this.emit('update', incomingRow);
}
setLimit(rowLimit) {
@ -150,6 +162,8 @@ export default class TableRowCollection extends EventEmitter {
}
insertOrUpdateRows(rowsToAdd, addToBeginning) {
const rowsAdded = [];
rowsToAdd.forEach((row, addRowsIndex) => {
const index = this.getInPlaceUpdateIndex(row);
if (index > -1) {
@ -157,15 +171,22 @@ export default class TableRowCollection extends EventEmitter {
} else {
if (addToBeginning) {
this.rows.splice(addRowsIndex, 0, row);
rowsAdded.push(row);
} else {
this.rows.push(row);
rowsAdded.push(row);
}
}
});
if (rowsAdded.length > 0) {
this.emit('add', rowsAdded);
}
}
mergeSortedRows(incomingRows) {
const mergedRows = [];
const addedRows = [];
let existingRowIndex = 0;
let incomingRowIndex = 0;
@ -184,6 +205,7 @@ export default class TableRowCollection extends EventEmitter {
} else {
mergedRows.push(incomingRow);
incomingRowIndex++;
addedRows.push(existingRow);
}
}
}
@ -199,10 +221,15 @@ export default class TableRowCollection extends EventEmitter {
if (incomingRowIndex < incomingRows.length) {
for (incomingRowIndex; incomingRowIndex < incomingRows.length; incomingRowIndex++) {
mergedRows.push(incomingRows[incomingRowIndex]);
addedRows.push(incomingRows[incomingRowIndex]);
}
}
this.rows = mergedRows;
if (addedRows.length > 0) {
this.emit('add', addedRows);
}
}
firstRowInSortOrder(row1, row2) {

View File

@ -543,6 +543,7 @@ export default {
this.table.configuration.on('change', this.handleConfigurationChanges);
this.table.tableRows.on('add', this.rowsAdded);
this.table.tableRows.on('update', this.throttledUpdateVisibleRows);
this.table.tableRows.on('remove', this.rowsRemoved);
this.table.tableRows.on('sort', this.throttledUpdateVisibleRows);
this.table.tableRows.on('filter', this.throttledUpdateVisibleRows);
@ -577,6 +578,7 @@ export default {
this.table.configuration.off('change', this.handleConfigurationChanges);
this.table.tableRows.off('add', this.rowsAdded);
this.table.tableRows.off('update', this.throttledUpdateVisibleRows);
this.table.tableRows.off('remove', this.rowsRemoved);
this.table.tableRows.off('sort', this.throttledUpdateVisibleRows);
this.table.tableRows.off('filter', this.throttledUpdateVisibleRows);

View File

@ -99,6 +99,9 @@ export default {
}, {})
};
},
beforeUnmount() {
console.log('destroyed row');
},
computed: {
ariaLabel() {
return this.marked ? 'Selected Table Row' : 'Table Row';
@ -126,7 +129,9 @@ export default {
watch: {
rowOffset: 'calculateRowTop',
row: {
handler: 'formatRow',
handler() {
this.formatRow(this.row);
},
deep: true
}
},