Files
outline/server/utils/removeIndexCollisions.js
T
2021-03-15 18:59:00 -07:00

65 lines
1.8 KiB
JavaScript

// @flow
import fractionalIndex from "fractional-index";
import { Collection } from "../models";
import { sequelize } from "../sequelize";
/**
*
* @param teamId The team id whose collections has to be fetched
* @returns An array or undefined. If array, each array element is an array of collided collection id and its new index [id,newIndex]
*/
export default async function removeIndexCollisions(teamId: string) {
let collections = await Collection.findAll({
where: { teamId, deletedAt: null },
attributes: ["id", "index", "updatedAt"],
order: [
sequelize.literal('"collection"."index" collate "C"'),
["updatedAt", "DESC"],
],
});
collections = collections.map((collection) => {
return [collection, collection.index];
});
// a set to store the index value of collections.
const indexSet = new Set();
let collision = false;
// make the index null, if there is index collision
collections = collections.map((collection) => {
if (indexSet.has(collection[1])) {
collision = true;
collection[1] = null;
return collection;
}
indexSet.add(collection[1]);
return collection;
});
if (!collision) {
return;
}
let indexArray = Array.from(indexSet);
indexArray.sort();
const collectionIdsWithIndex = [];
for (const [i, collection] of collections.entries()) {
if (collection[1] === null) {
const previousCollectionIndex = i - 1 < 0 ? null : indexArray[i - 1];
const nextCollectionIndex =
i === indexArray.length ? null : indexArray[i];
const newIndex = fractionalIndex(
previousCollectionIndex,
nextCollectionIndex
);
indexArray.splice(i, 0, newIndex);
await collection[0].update({ index: newIndex });
collectionIdsWithIndex.push([collection[0].id, newIndex]);
}
}
return collectionIdsWithIndex;
}