Files
notesnook/packages/core/utils/grouping.js

81 lines
2.0 KiB
JavaScript
Raw Normal View History

2021-07-12 13:48:19 +05:00
import "../types";
import fastsort from "fast-sort";
import dayjs from "dayjs";
import { getWeekGroupFromTimestamp, months } from "./date";
2021-07-12 13:48:19 +05:00
/**
*
* @param {GroupOptions} options
* @returns sort selectors
*/
const getSortSelectors = (options) => [
{ desc: (t) => t.conflicted },
{ desc: (t) => t.pinned },
{
[options.sortDirection]: (item) => {
if (options.sortBy === "title") return getFirstCharacter(item);
return item[options.sortBy];
},
},
2021-07-12 13:48:19 +05:00
];
const KEY_SELECTORS = {
abc: (item) => getFirstCharacter(item),
month: (item, groupBy) => dayjs(item[groupBy]).format("MMMM"),
2021-07-12 13:48:19 +05:00
week: (item, groupBy) => getWeekGroupFromTimestamp(item[groupBy]),
year: (item, groupBy) => dayjs(item[groupBy]).year(),
default: (item, groupBy) => {
const date = dayjs(item[groupBy]);
return date.isAfter(dayjs().subtract(1, "week"))
2021-07-12 13:48:19 +05:00
? "Recent"
: date.isAfter(dayjs().subtract(2, "weeks"))
2021-07-12 13:48:19 +05:00
? "Last week"
: "Older";
},
2021-07-12 13:48:19 +05:00
};
/**
* @param {any[]} array
* @param {GroupOptions} options
* @returns Grouped array
*/
2021-07-12 14:09:48 +05:00
export function groupArray(
array,
options = {
groupBy: "default",
2021-07-12 14:09:48 +05:00
sortBy: "dateEdited",
sortDirection: "desc",
}
) {
const keySelector = KEY_SELECTORS[options.groupBy || "default"];
2021-07-12 14:00:22 +05:00
if (options.sortBy && options.sortDirection)
fastsort(array).by(getSortSelectors(options));
2021-07-12 13:48:19 +05:00
let groups = new Map();
array.forEach((item) => {
let groupTitle = item.pinned
? "Pinned"
: item.conflicted
? "Conflicted"
: keySelector(item, options.sortBy);
2021-07-12 13:48:19 +05:00
let group = groups.get(groupTitle) || [];
group.push(item);
groups.set(groupTitle, group);
});
let items = [];
groups.forEach((groupItems, groupTitle) => {
let group = { title: groupTitle, type: "header" };
items.push(group);
groupItems.forEach((item) => items.push(item));
});
return items;
}
function getFirstCharacter(item) {
const title = item.title && item.title.trim();
if (!title || title.length <= 0) return "-";
return title[0].toUpperCase();
}