UNPKG

@hashicorp/design-system-components

Version:
210 lines (207 loc) 8.19 kB
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