ManageIQ/manageiq-ui-classic

View on GitHub
app/javascript/helpers/move.js

Summary

Maintainability
A
2 hrs
Test Coverage
import { find, findIndex, some, reject } from 'lodash';

// [{id: 123}], [123] => [0]
function idsToElements(arr, ids) {
  return ids.map((id) => find(arr, { id }));
}

function idsToIndexes(arr, ids) {
  return ids.map((id) => findIndex(arr, { id }));
}

function removeElements(arr, elements) {
  return reject(arr, (elem) => some(elements, elem));
}

function filterIndexes(indexes) {
  if (indexes[0] !== 0) {
    return indexes;
  }
  var previous = 0;
  var filteredIndexes = [];
  indexes.forEach(function(index) {
    if (index !== 0 && index - 1 !== previous) {
      filteredIndexes.push(index);
    } else {
      previous = index;
    }
  });
  return filteredIndexes;
}

function filterReverseIndexes(indexes, endIndex) {
  if (indexes[0] !== endIndex) {
    return indexes;
  }
  var previous = endIndex;
  var filteredIndexes = [];
  indexes.forEach(function(index) {
    if (index !== endIndex && index + 1 !== previous) {
      filteredIndexes.push(index);
    } else {
      previous = index;
    }
  });
  return filteredIndexes;
}

function stepUp(array, index) {
  if (index < 1) {
    return;
  }

  [array[index], array[index - 1]] = [array[index - 1], array[index]];
}

function stepDown(array, index) {
  if ((index < 0) || (index >= array.length - 1)) {
    return;
  }

  [array[index], array[index + 1]] = [array[index + 1], array[index]];
}


// move selected elements between two arrays
export function between({from, to, selected}) {
  var moved = idsToElements(from, selected);

  return {
    from: removeElements(from, moved),
    to: to.concat(moved),
  };
}

// move selected elements to the top of the array
export function top({array, selected}) {
  var moved = idsToElements(array, selected);
  array = removeElements(array, moved);

  return moved.concat(array);
}

// move selected elements to the bottom of the array
export function bottom({array, selected}) {
  var moved = idsToElements(array, selected);
  array = removeElements(array, moved);

  return array.concat(moved);
}

// move selected elements one position up
export function up({array, selected}) {
  var indexes = idsToIndexes(array, selected);
  indexes = filterIndexes(indexes);

  indexes.forEach((index) => stepUp(array, index));

  return array;
}

// move selected elements one position up
export function down({array, selected}) {
  var indexes = idsToIndexes(array, selected).reverse();
  indexes = filterReverseIndexes(indexes, array.length - 1);

  indexes.forEach((index) => stepDown(array, index));

  return array;
}