@hashicorp/design-system-components
Version:
Helios Design System Components
210 lines (207 loc) • 8.19 kB
JavaScript
import Component from '@glimmer/component';
import { fn, hash } from '@ember/helper';
import { assert } from '@ember/debug';
import { guidFor } from '@ember/object/internals';
import { scheduleOnce } from '@ember/runloop';
import { tracked } from '@glimmer/tracking';
import { modifier } from 'ember-modifier';
import 'tracked-built-ins';
import { HdsAdvancedTableColumnReorderSideValues } from '../types.js';
import { precompileTemplate } from '@ember/template-compilation';
import { setComponentTemplate } from '@ember/component';
import { g, i } from 'decorator-transforms/runtime';
class HdsAdvancedTableColumnManagerOrder extends Component {
static {
g(this.prototype, "draggedColumnKey", [tracked], function () {
return null;
});
}
#draggedColumnKey = (i(this, "draggedColumnKey"), void 0);
static {
g(this.prototype, "reorderHoveredColumnKey", [tracked], function () {
return null;
});
}
#reorderHoveredColumnKey = (i(this, "reorderHoveredColumnKey"), void 0);
static {
g(this.prototype, "_columnOrder", [tracked], function () {
return [];
});
}
#_columnOrder = (i(this, "_columnOrder"), void 0);
syncColumnOrder = modifier((_element, [columns, columnOrder]) => {
const columnKeys = columns.map(column => this._getColumnKey(column));
let nextOrder = this._columnOrder;
if (columnOrder !== undefined) {
const visibleSet = new Set(columnOrder);
const hiddenKeys = nextOrder.filter(key => !visibleSet.has(key));
const reordered = [];
let visibleIdx = 0;
let hiddenIdx = 0;
for (let i = 0; i < nextOrder.length; i++) {
if (hiddenKeys.includes(nextOrder[i])) {
reordered.push(hiddenKeys[hiddenIdx++]);
} else {
reordered.push(columnOrder[visibleIdx++]);
}
}
nextOrder = reordered;
}
const missingKeys = columnKeys.filter(key => !nextOrder.includes(key));
if (missingKeys.length > 0) {
nextOrder = [...nextOrder, ...missingKeys];
}
const isSame = nextOrder.length === this._columnOrder.length && nextOrder.every((value, index) => value === this._columnOrder[index]);
const setColumnOrder = () => this.columnOrder = nextOrder;
if (!isSame) {
// eslint-disable-next-line ember/no-runloop
scheduleOnce('afterRender', this, setColumnOrder);
}
});
get columnOrder() {
return this._columnOrder.length > 0 ? this._columnOrder : this.args.columns.map(column => this._getColumnKey(column));
}
set columnOrder(value) {
this._columnOrder = value;
}
get visibleColumnOrder() {
const visibleKeys = new Set(this.args.columns.map(column => this._getColumnKey(column)));
return this._columnOrder.filter(key => visibleKeys.has(key));
}
get orderedColumns() {
const {
hasReorderableColumns,
columns
} = this.args;
if (hasReorderableColumns && this.columnOrder !== undefined) {
const columnMap = new Map(columns.map(column => [column.key, column]));
return this.columnOrder.reduce((acc, key) => {
const column = columnMap.get(key);
if (column !== undefined) {
acc.push(column);
}
return acc;
}, []);
} else {
return columns;
}
}
get firstColumnKey() {
const firstColumn = this.orderedColumns[0];
return firstColumn?.key;
}
get firstNonStickyColumnIndex() {
return this.args.hasStickyFirstColumn ? 1 : 0;
}
get firstNonStickyColumnKey() {
const firstNonStickyColumn = this.orderedColumns[this.firstNonStickyColumnIndex];
return firstNonStickyColumn?.key;
}
get lastColumnKey() {
const lastColumn = this.orderedColumns[this.orderedColumns.length - 1];
return lastColumn?.key;
}
moveColumnToTerminalPosition = (columnKey, position) => {
let targetColumnKey;
let side;
const lastColumn = this.orderedColumns[this.orderedColumns.length - 1];
if (this.firstNonStickyColumnKey === undefined || lastColumn === undefined) {
return;
}
if (position === 'start') {
targetColumnKey = this.firstNonStickyColumnKey;
side = HdsAdvancedTableColumnReorderSideValues.Left;
} else {
targetColumnKey = lastColumn.key;
side = HdsAdvancedTableColumnReorderSideValues.Right;
}
// Move the column to the target position
this.moveColumnToTarget(columnKey, targetColumnKey, side);
};
stepColumn = (columnKey, step) => {
const oldIndex = this.columnOrder.indexOf(columnKey);
const newIndex = oldIndex + step;
// Check if the new position is within the array bounds.
if (newIndex < this.firstNonStickyColumnIndex || newIndex >= this.columnOrder.length) {
return;
}
const targetColumnKey = this.columnOrder[newIndex];
if (targetColumnKey === undefined) {
return;
}
// Determine the side based on the step direction.
const side = step > 0 ? HdsAdvancedTableColumnReorderSideValues.Right : HdsAdvancedTableColumnReorderSideValues.Left;
this.moveColumnToTarget(columnKey, targetColumnKey, side);
};
moveColumnToDropTarget = (targetColumnKey, side) => {
const sourceColumnKey = this.draggedColumnKey;
if (sourceColumnKey === null || sourceColumnKey === targetColumnKey) {
return;
}
this.moveColumnToTarget(sourceColumnKey, targetColumnKey, side);
};
moveColumnToTarget = (sourceColumnKey, targetColumnKey, side) => {
const oldIndex = this.columnOrder.indexOf(sourceColumnKey);
const newIndex = this.columnOrder.indexOf(targetColumnKey);
if (oldIndex !== -1 && newIndex !== -1) {
const updated = [...this.columnOrder];
updated.splice(oldIndex, 1); // Remove from old position
// Calculate the insertion index based on the side
// If dropping to the right of the target, insert after the target
// If dropping to the left of the target, insert before the target
// Adjust for the shift in indices caused by removing the source column
const adjustedIndex = side === HdsAdvancedTableColumnReorderSideValues.Right ? newIndex > oldIndex ? newIndex : newIndex + 1 : newIndex > oldIndex ? newIndex - 1 : newIndex;
updated.splice(adjustedIndex, 0, sourceColumnKey); // Insert at new position
this.columnOrder = updated;
// we need to wait until the reposition has finished
requestAnimationFrame(() => {
const thElement = this.args.thElements.get(sourceColumnKey);
if (thElement === undefined) {
return;
}
thElement.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'center'
});
this.draggedColumnKey = null;
const column = this.args.getColumnByKey(sourceColumnKey);
assert('No column found with that key', column !== undefined);
this.setColumnOrder({
column,
newOrder: updated,
insertedAt: updated.indexOf(sourceColumnKey)
});
});
}
};
setColumnOrder = ({
column,
newOrder,
insertedAt
}) => {
const {
onColumnReorder
} = this.args;
this.columnOrder = newOrder;
onColumnReorder?.({
column,
newOrder,
insertedAt
});
};
_getColumnKey(column) {
return column.key ?? guidFor(column);
}
static {
setComponentTemplate(precompileTemplate("{{yield (hash orderedColumns=this.orderedColumns columnOrder=this.visibleColumnOrder draggedColumnKey=this.draggedColumnKey reorderHoveredColumnKey=this.reorderHoveredColumnKey firstColumnKey=this.firstColumnKey firstNonStickyColumnKey=this.firstNonStickyColumnKey lastColumnKey=this.lastColumnKey syncColumnOrder=this.syncColumnOrder moveColumnToDropTarget=this.moveColumnToDropTarget moveColumnToTarget=this.moveColumnToTarget moveColumnToTerminalPosition=this.moveColumnToTerminalPosition stepColumn=this.stepColumn setDraggedColumnKey=(fn (mut this.draggedColumnKey)) setReorderHoveredColumnKey=(fn (mut this.reorderHoveredColumnKey)))}}", {
strictMode: true,
scope: () => ({
hash,
fn
})
}), this);
}
}
export { HdsAdvancedTableColumnManagerOrder as default };
//# sourceMappingURL=order.js.map