mirror of
https://github.com/outline/outline.git
synced 2026-06-26 09:44:24 +03:00
70 lines
1.8 KiB
JavaScript
70 lines
1.8 KiB
JavaScript
// @flow
|
|
import fractionalIndex from "fractional-index";
|
|
import { Collection } from "../models";
|
|
|
|
export default async function removeIndexCollisions(
|
|
teamId: string,
|
|
index?: string,
|
|
collections?: Collection[]
|
|
) {
|
|
collections = collections
|
|
? collections
|
|
: await Collection.findAll({
|
|
where: { teamId, deletedAt: null }, //no point in maintaining index of deleted collections.
|
|
attributes: ["id", "index", "updatedAt"],
|
|
});
|
|
|
|
// use updatedAt because in case of index collision we need to have a predictable order
|
|
collections.sort((a, b) => {
|
|
if (a.index === b.index) {
|
|
return a.updatedAt > b.updatedAt ? -1 : 1;
|
|
}
|
|
return a.index < b.index ? -1 : 1;
|
|
});
|
|
|
|
collections = collections.map((collection) => {
|
|
return [collection, collection.index];
|
|
});
|
|
|
|
// a set to store the index value of collections.
|
|
const indexSet = new Set();
|
|
|
|
if (index) {
|
|
indexSet.add(index);
|
|
}
|
|
|
|
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;
|
|
});
|
|
|
|
let indexArray = Array.from(indexSet);
|
|
indexArray.sort();
|
|
|
|
if (!collision) {
|
|
return;
|
|
}
|
|
|
|
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 });
|
|
}
|
|
}
|
|
}
|