mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-30 06:40:58 +02:00
Merge pull request #14421 from dback2/entityListReorderColumns
Entity list - reorder columns
This commit is contained in:
commit
d7e3935d57
3 changed files with 117 additions and 40 deletions
|
@ -1390,6 +1390,10 @@ input[type=button]#export {
|
||||||
cursor: col-resize;
|
cursor: col-resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#entity-table .dragging {
|
||||||
|
background-color: #b3ecff;
|
||||||
|
}
|
||||||
|
|
||||||
#entity-table td {
|
#entity-table td {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ const MAX_LENGTH_RADIUS = 9;
|
||||||
const MINIMUM_COLUMN_WIDTH = 24;
|
const MINIMUM_COLUMN_WIDTH = 24;
|
||||||
const SCROLLBAR_WIDTH = 20;
|
const SCROLLBAR_WIDTH = 20;
|
||||||
const RESIZER_WIDTH = 10;
|
const RESIZER_WIDTH = 10;
|
||||||
|
const DELTA_X_MOVE_COLUMNS_THRESHOLD = 2;
|
||||||
|
const DELTA_X_COLUMN_SWAP_POSITION = 5;
|
||||||
|
|
||||||
const COLUMNS = {
|
const COLUMNS = {
|
||||||
type: {
|
type: {
|
||||||
|
@ -108,8 +110,8 @@ const COLUMNS = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const COMPARE_ASCENDING = function(a, b) {
|
const COMPARE_ASCENDING = function(a, b) {
|
||||||
let va = a[currentSortColumn];
|
let va = a[currentSortColumnID];
|
||||||
let vb = b[currentSortColumn];
|
let vb = b[currentSortColumnID];
|
||||||
|
|
||||||
if (va < vb) {
|
if (va < vb) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -172,7 +174,7 @@ let entityList = null; // The ListView
|
||||||
*/
|
*/
|
||||||
let entityListContextMenu = null;
|
let entityListContextMenu = null;
|
||||||
|
|
||||||
let currentSortColumn = 'type';
|
let currentSortColumnID = 'type';
|
||||||
let currentSortOrder = ASCENDING_SORT;
|
let currentSortOrder = ASCENDING_SORT;
|
||||||
let elSortOrders = {};
|
let elSortOrders = {};
|
||||||
let typeFilters = [];
|
let typeFilters = [];
|
||||||
|
@ -180,10 +182,13 @@ let isFilterInView = false;
|
||||||
|
|
||||||
let columns = [];
|
let columns = [];
|
||||||
let columnsByID = {};
|
let columnsByID = {};
|
||||||
let currentResizeEl = null;
|
let lastResizeEvent = null;
|
||||||
let startResizeEvent = null;
|
|
||||||
let resizeColumnIndex = 0;
|
let resizeColumnIndex = 0;
|
||||||
let startThClick = null;
|
let elTargetTh = null;
|
||||||
|
let elTargetSpan = null;
|
||||||
|
let targetColumnIndex = 0;
|
||||||
|
let lastColumnSwapPosition = -1;
|
||||||
|
let initialThEvent = null;
|
||||||
let renameTimeout = null;
|
let renameTimeout = null;
|
||||||
let renameLastBlur = null;
|
let renameLastBlur = null;
|
||||||
let renameLastEntityID = null;
|
let renameLastEntityID = null;
|
||||||
|
@ -230,10 +235,6 @@ const PROFILE = !ENABLE_PROFILING ? PROFILE_NOOP : function(name, fn, args) {
|
||||||
console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms");
|
console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms");
|
||||||
};
|
};
|
||||||
|
|
||||||
debugPrint = function (message) {
|
|
||||||
console.log(message);
|
|
||||||
};
|
|
||||||
|
|
||||||
function loaded() {
|
function loaded() {
|
||||||
openEventBridge(function() {
|
openEventBridge(function() {
|
||||||
elEntityTable = document.getElementById("entity-table");
|
elEntityTable = document.getElementById("entity-table");
|
||||||
|
@ -324,10 +325,11 @@ function loaded() {
|
||||||
for (let columnID in COLUMNS) {
|
for (let columnID in COLUMNS) {
|
||||||
let columnData = COLUMNS[columnID];
|
let columnData = COLUMNS[columnID];
|
||||||
|
|
||||||
let thID = "entity-" + columnID;
|
|
||||||
let elTh = document.createElement("th");
|
let elTh = document.createElement("th");
|
||||||
|
let thID = "entity-" + columnID;
|
||||||
elTh.setAttribute("id", thID);
|
elTh.setAttribute("id", thID);
|
||||||
elTh.setAttribute("data-resizable-column-id", thID);
|
elTh.setAttribute("columnIndex", columnIndex);
|
||||||
|
elTh.setAttribute("columnID", columnID);
|
||||||
if (columnData.glyph) {
|
if (columnData.glyph) {
|
||||||
let elGlyph = document.createElement("span");
|
let elGlyph = document.createElement("span");
|
||||||
elGlyph.className = "glyph";
|
elGlyph.className = "glyph";
|
||||||
|
@ -336,20 +338,20 @@ function loaded() {
|
||||||
} else {
|
} else {
|
||||||
elTh.innerText = columnData.columnHeader;
|
elTh.innerText = columnData.columnHeader;
|
||||||
}
|
}
|
||||||
elTh.onmousedown = function() {
|
elTh.onmousedown = function(event) {
|
||||||
startThClick = this;
|
if (event.target.nodeName === 'TH') {
|
||||||
};
|
elTargetTh = event.target;
|
||||||
elTh.onmouseup = function() {
|
targetColumnIndex = parseInt(elTargetTh.getAttribute("columnIndex"));
|
||||||
if (startThClick === this) {
|
lastColumnSwapPosition = event.clientX;
|
||||||
setSortColumn(columnID);
|
} else if (event.target.nodeName === 'SPAN') {
|
||||||
|
elTargetSpan = event.target;
|
||||||
}
|
}
|
||||||
startThClick = null;
|
initialThEvent = event;
|
||||||
};
|
};
|
||||||
|
|
||||||
let elResizer = document.createElement("span");
|
let elResizer = document.createElement("span");
|
||||||
elResizer.className = "resizer";
|
elResizer.className = "resizer";
|
||||||
elResizer.innerHTML = " ";
|
elResizer.innerHTML = " ";
|
||||||
elResizer.setAttribute("columnIndex", columnIndex);
|
|
||||||
elResizer.onmousedown = onStartResize;
|
elResizer.onmousedown = onStartResize;
|
||||||
elTh.appendChild(elResizer);
|
elTh.appendChild(elResizer);
|
||||||
|
|
||||||
|
@ -762,13 +764,13 @@ function loaded() {
|
||||||
refreshNoEntitiesMessage();
|
refreshNoEntitiesMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSortColumn(column) {
|
function setSortColumn(columnID) {
|
||||||
PROFILE("set-sort-column", function() {
|
PROFILE("set-sort-column", function() {
|
||||||
if (currentSortColumn === column) {
|
if (currentSortColumnID === columnID) {
|
||||||
currentSortOrder *= -1;
|
currentSortOrder *= -1;
|
||||||
} else {
|
} else {
|
||||||
elSortOrders[currentSortColumn].innerHTML = "";
|
elSortOrders[currentSortColumnID].innerHTML = "";
|
||||||
currentSortColumn = column;
|
currentSortColumnID = columnID;
|
||||||
currentSortOrder = ASCENDING_SORT;
|
currentSortOrder = ASCENDING_SORT;
|
||||||
}
|
}
|
||||||
refreshSortOrder();
|
refreshSortOrder();
|
||||||
|
@ -777,7 +779,7 @@ function loaded() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshSortOrder() {
|
function refreshSortOrder() {
|
||||||
elSortOrders[currentSortColumn].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING;
|
elSortOrders[currentSortColumnID].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshEntities() {
|
function refreshEntities() {
|
||||||
|
@ -1093,8 +1095,8 @@ function loaded() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStartResize(event) {
|
function onStartResize(event) {
|
||||||
startResizeEvent = event;
|
lastResizeEvent = event;
|
||||||
resizeColumnIndex = parseInt(this.getAttribute("columnIndex"));
|
resizeColumnIndex = parseInt(this.parentNode.getAttribute("columnIndex"));
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,8 +1139,37 @@ function loaded() {
|
||||||
entityList.refresh();
|
entityList.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
document.onmousemove = function(ev) {
|
function swapColumns(columnAIndex, columnBIndex) {
|
||||||
if (startResizeEvent) {
|
let columnA = columns[columnAIndex];
|
||||||
|
let columnB = columns[columnBIndex];
|
||||||
|
let columnATh = columns[columnAIndex].elTh;
|
||||||
|
let columnBTh = columns[columnBIndex].elTh;
|
||||||
|
let columnThParent = columnATh.parentNode;
|
||||||
|
columnThParent.removeChild(columnBTh);
|
||||||
|
columnThParent.insertBefore(columnBTh, columnATh);
|
||||||
|
columnATh.setAttribute("columnIndex", columnBIndex);
|
||||||
|
columnBTh.setAttribute("columnIndex", columnAIndex);
|
||||||
|
columnA.elResizer.setAttribute("columnIndex", columnBIndex);
|
||||||
|
columnB.elResizer.setAttribute("columnIndex", columnAIndex);
|
||||||
|
|
||||||
|
for (let i = 0; i < visibleEntities.length; ++i) {
|
||||||
|
let elRow = visibleEntities[i].elRow;
|
||||||
|
if (elRow) {
|
||||||
|
let columnACell = elRow.childNodes[columnAIndex];
|
||||||
|
let columnBCell = elRow.childNodes[columnBIndex];
|
||||||
|
elRow.removeChild(columnBCell);
|
||||||
|
elRow.insertBefore(columnBCell, columnACell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
columns[columnAIndex] = columnB;
|
||||||
|
columns[columnBIndex] = columnA;
|
||||||
|
|
||||||
|
updateColumnWidths();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.onmousemove = function(event) {
|
||||||
|
if (lastResizeEvent) {
|
||||||
startTh = null;
|
startTh = null;
|
||||||
|
|
||||||
let column = columns[resizeColumnIndex];
|
let column = columns[resizeColumnIndex];
|
||||||
|
@ -1150,7 +1181,7 @@ function loaded() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let fullWidth = elEntityTableBody.offsetWidth;
|
let fullWidth = elEntityTableBody.offsetWidth;
|
||||||
let dx = ev.clientX - startResizeEvent.clientX;
|
let dx = event.clientX - lastResizeEvent.clientX;
|
||||||
let dPct = dx / fullWidth;
|
let dPct = dx / fullWidth;
|
||||||
|
|
||||||
let newColWidth = column.width + dPct;
|
let newColWidth = column.width + dPct;
|
||||||
|
@ -1160,14 +1191,60 @@ function loaded() {
|
||||||
column.width += dPct;
|
column.width += dPct;
|
||||||
nextColumn.width -= dPct;
|
nextColumn.width -= dPct;
|
||||||
updateColumnWidths();
|
updateColumnWidths();
|
||||||
startResizeEvent = ev;
|
lastResizeEvent = event;
|
||||||
|
}
|
||||||
|
} else if (elTargetTh) {
|
||||||
|
let dxFromInitial = event.clientX - initialThEvent.clientX;
|
||||||
|
if (Math.abs(dxFromInitial) >= DELTA_X_MOVE_COLUMNS_THRESHOLD) {
|
||||||
|
elTargetTh.className = "dragging";
|
||||||
|
}
|
||||||
|
if (targetColumnIndex < columns.length - 1) {
|
||||||
|
let nextColumnIndex = targetColumnIndex + 1;
|
||||||
|
let nextColumnTh = columns[nextColumnIndex].elTh;
|
||||||
|
let nextColumnStartX = nextColumnTh.getBoundingClientRect().left;
|
||||||
|
if (event.clientX >= nextColumnStartX && event.clientX - lastColumnSwapPosition >= DELTA_X_COLUMN_SWAP_POSITION) {
|
||||||
|
swapColumns(targetColumnIndex, nextColumnIndex);
|
||||||
|
targetColumnIndex = nextColumnIndex;
|
||||||
|
lastColumnSwapPosition = event.clientX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (targetColumnIndex >= 1) {
|
||||||
|
let prevColumnIndex = targetColumnIndex - 1;
|
||||||
|
let prevColumnTh = columns[prevColumnIndex].elTh;
|
||||||
|
let prevColumnEndX = prevColumnTh.getBoundingClientRect().right;
|
||||||
|
if (event.clientX <= prevColumnEndX && lastColumnSwapPosition - event.clientX >= DELTA_X_COLUMN_SWAP_POSITION) {
|
||||||
|
swapColumns(prevColumnIndex, targetColumnIndex);
|
||||||
|
targetColumnIndex = prevColumnIndex;
|
||||||
|
lastColumnSwapPosition = event.clientX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (elTargetSpan) {
|
||||||
|
let dxFromInitial = event.clientX - initialThEvent.clientX;
|
||||||
|
if (Math.abs(dxFromInitial) >= DELTA_X_MOVE_COLUMNS_THRESHOLD) {
|
||||||
|
elTargetTh = elTargetSpan.parentNode;
|
||||||
|
elTargetTh.className = "dragging";
|
||||||
|
targetColumnIndex = parseInt(elTargetTh.getAttribute("columnIndex"));
|
||||||
|
lastColumnSwapPosition = event.clientX;
|
||||||
|
elTargetSpan = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
document.onmouseup = function(ev) {
|
document.onmouseup = function(event) {
|
||||||
startResizeEvent = null;
|
if (elTargetTh) {
|
||||||
ev.stopPropagation();
|
if (elTargetTh.className !== "dragging" && elTargetTh === event.target) {
|
||||||
|
let columnID = elTargetTh.getAttribute("columnID");
|
||||||
|
setSortColumn(columnID);
|
||||||
|
}
|
||||||
|
elTargetTh.className = "";
|
||||||
|
} else if (elTargetSpan) {
|
||||||
|
let columnID = elTargetSpan.parentNode.getAttribute("columnID");
|
||||||
|
setSortColumn(columnID);
|
||||||
|
}
|
||||||
|
lastResizeEvent = null;
|
||||||
|
elTargetTh = null;
|
||||||
|
elTargetSpan = null;
|
||||||
|
initialThEvent = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
function setSpaceMode(spaceMode) {
|
function setSpaceMode(spaceMode) {
|
||||||
|
|
|
@ -9,10 +9,6 @@
|
||||||
const SCROLL_ROWS = 2; // number of rows used as scrolling buffer, each time we pass this number of rows we scroll
|
const SCROLL_ROWS = 2; // number of rows used as scrolling buffer, each time we pass this number of rows we scroll
|
||||||
const FIRST_ROW_INDEX = 2; // the first elRow element's index in the child nodes of the table body
|
const FIRST_ROW_INDEX = 2; // the first elRow element's index in the child nodes of the table body
|
||||||
|
|
||||||
debugPrint = function (message) {
|
|
||||||
console.log(message);
|
|
||||||
};
|
|
||||||
|
|
||||||
function ListView(elTableBody, elTableScroll, elTableHeaderRow, createRowFunction, updateRowFunction, clearRowFunction,
|
function ListView(elTableBody, elTableScroll, elTableHeaderRow, createRowFunction, updateRowFunction, clearRowFunction,
|
||||||
preRefreshFunction, postRefreshFunction, preResizeFunction, WINDOW_NONVARIABLE_HEIGHT) {
|
preRefreshFunction, postRefreshFunction, preResizeFunction, WINDOW_NONVARIABLE_HEIGHT) {
|
||||||
this.elTableBody = elTableBody;
|
this.elTableBody = elTableBody;
|
||||||
|
@ -246,7 +242,7 @@ ListView.prototype = {
|
||||||
|
|
||||||
resize: function() {
|
resize: function() {
|
||||||
if (!this.elTableBody || !this.elTableScroll) {
|
if (!this.elTableBody || !this.elTableScroll) {
|
||||||
debugPrint("ListView.resize - no valid table body or table scroll element");
|
console.log("ListView.resize - no valid table body or table scroll element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.preResizeFunction();
|
this.preResizeFunction();
|
||||||
|
@ -288,7 +284,7 @@ ListView.prototype = {
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
if (!this.elTableBody || !this.elTableScroll) {
|
if (!this.elTableBody || !this.elTableScroll) {
|
||||||
debugPrint("ListView.initialize - no valid table body or table scroll element");
|
console.log("ListView.initialize - no valid table body or table scroll element");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue