* Migrations, models, commands * ui * Move starred hint to location state * lint * tsc * refactor * Add collection empty state in expanded sidebar * Add empty placeholder within starred collections * Drag and drop improves, Relative refactor * fix: Starring untitled draft leaves empty space * fix: Creating draft in starred collection shouldnt open main * fix: Dupe drop cursor * Final fixes * fix: Canonical redirect replaces starred location state * fix: Don't show reorder cursor at the top of collection with no permission to edit when dragging
83 lines
2.1 KiB
TypeScript
83 lines
2.1 KiB
TypeScript
import fractionalIndex from "fractional-index";
|
|
import naturalSort from "@shared/utils/naturalSort";
|
|
import { Collection, Document, Star } from "@server/models";
|
|
|
|
export async function collectionIndexing(
|
|
teamId: string
|
|
): Promise<{ [id: string]: string }> {
|
|
const collections = await Collection.findAll({
|
|
where: {
|
|
teamId,
|
|
// no point in maintaining index of deleted collections.
|
|
deletedAt: null,
|
|
},
|
|
attributes: ["id", "index", "name"],
|
|
});
|
|
|
|
const sortable = naturalSort(collections, (collection) => collection.name);
|
|
|
|
// for each collection with null index, use previous collection index to create new index
|
|
let previousIndex = null;
|
|
const promises = [];
|
|
|
|
for (const collection of sortable) {
|
|
if (collection.index === null) {
|
|
collection.index = fractionalIndex(previousIndex, null);
|
|
promises.push(collection.save());
|
|
}
|
|
|
|
previousIndex = collection.index;
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
const indexedCollections = {};
|
|
sortable.forEach((collection) => {
|
|
indexedCollections[collection.id] = collection.index;
|
|
});
|
|
return indexedCollections;
|
|
}
|
|
|
|
export async function starIndexing(
|
|
userId: string
|
|
): Promise<{ [id: string]: string }> {
|
|
const stars = await Star.findAll({
|
|
where: { userId },
|
|
});
|
|
|
|
const documents = await Document.findAll({
|
|
attributes: ["id", "updatedAt"],
|
|
where: {
|
|
id: stars.map((star) => star.documentId).filter(Boolean) as string[],
|
|
},
|
|
order: [["updatedAt", "DESC"]],
|
|
});
|
|
|
|
const sortable = stars.sort(function (a, b) {
|
|
return (
|
|
documents.findIndex((d) => d.id === a.documentId) -
|
|
documents.findIndex((d) => d.id === b.documentId)
|
|
);
|
|
});
|
|
|
|
let previousIndex = null;
|
|
const promises = [];
|
|
|
|
for (const star of sortable) {
|
|
if (star.index === null) {
|
|
star.index = fractionalIndex(previousIndex, null);
|
|
promises.push(star.save());
|
|
}
|
|
|
|
previousIndex = star.index;
|
|
}
|
|
|
|
await Promise.all(promises);
|
|
|
|
const indexedStars = {};
|
|
sortable.forEach((star) => {
|
|
indexedStars[star.id] = star.index;
|
|
});
|
|
return indexedStars;
|
|
}
|