mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 17:30:16 +01:00
🗂️ fix: Optimize Conversation Grouping and Sorting (#4173)
* chore: remove double import of TrashIcon * fix(convos): eslint warnings * ci(convos): add test for month sorting * fix(convos): grouping by month in chronological order instead of alphabetical, optimize sort * ci: additional tests for conversation sorting * chore: fix eslint disable rule * chore: imports, use constant enum for 'new' value * fix: test dependent on current date
This commit is contained in:
parent
44458d3832
commit
c1c13a69dc
3 changed files with 243 additions and 39 deletions
|
|
@ -60,6 +60,32 @@ const getGroupName = (date: Date) => {
|
|||
return ' ' + getYear(date).toString();
|
||||
};
|
||||
|
||||
const monthOrderMap = new Map([
|
||||
['december', 11],
|
||||
['november', 10],
|
||||
['october', 9],
|
||||
['september', 8],
|
||||
['august', 7],
|
||||
['july', 6],
|
||||
['june', 5],
|
||||
['may', 4],
|
||||
['april', 3],
|
||||
['march', 2],
|
||||
['february', 1],
|
||||
['january', 0],
|
||||
]);
|
||||
|
||||
const dateKeysReverse = Object.fromEntries(
|
||||
Object.entries(dateKeys).map(([key, value]) => [value, key]),
|
||||
);
|
||||
|
||||
const dateGroupsSet = new Set([
|
||||
dateKeys.today,
|
||||
dateKeys.yesterday,
|
||||
dateKeys.previous7Days,
|
||||
dateKeys.previous30Days,
|
||||
]);
|
||||
|
||||
export const groupConversationsByDate = (
|
||||
conversations: Array<TConversation | null>,
|
||||
): GroupedConversations => {
|
||||
|
|
@ -68,47 +94,60 @@ export const groupConversationsByDate = (
|
|||
}
|
||||
|
||||
const seenConversationIds = new Set();
|
||||
const groups = conversations.reduce((acc, conversation) => {
|
||||
if (!conversation) {
|
||||
return acc;
|
||||
}
|
||||
const groups = new Map();
|
||||
const today = startOfToday();
|
||||
|
||||
if (seenConversationIds.has(conversation.conversationId)) {
|
||||
return acc;
|
||||
conversations.forEach((conversation) => {
|
||||
if (!conversation || seenConversationIds.has(conversation.conversationId)) {
|
||||
return;
|
||||
}
|
||||
seenConversationIds.add(conversation.conversationId);
|
||||
|
||||
const date = conversation.updatedAt ? parseISO(conversation.updatedAt) : startOfToday();
|
||||
const date = conversation.updatedAt ? parseISO(conversation.updatedAt) : today;
|
||||
const groupName = getGroupName(date);
|
||||
if (!acc[groupName]) {
|
||||
acc[groupName] = [];
|
||||
if (!groups.has(groupName)) {
|
||||
groups.set(groupName, []);
|
||||
}
|
||||
acc[groupName].push(conversation);
|
||||
return acc;
|
||||
}, {});
|
||||
groups.get(groupName).push(conversation);
|
||||
});
|
||||
|
||||
const sortedGroups = {};
|
||||
const dateGroups = [
|
||||
dateKeys.today,
|
||||
dateKeys.yesterday,
|
||||
dateKeys.previous7Days,
|
||||
dateKeys.previous30Days,
|
||||
];
|
||||
dateGroups.forEach((group) => {
|
||||
if (groups[group]) {
|
||||
sortedGroups[group] = groups[group];
|
||||
const sortedGroups = new Map();
|
||||
|
||||
// Add date groups first
|
||||
dateGroupsSet.forEach((group) => {
|
||||
if (groups.has(group)) {
|
||||
sortedGroups.set(group, groups.get(group));
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(groups)
|
||||
.filter((group) => !dateGroups.includes(group))
|
||||
.sort()
|
||||
.reverse()
|
||||
.forEach((year) => {
|
||||
sortedGroups[year] = groups[year];
|
||||
// Sort and add year/month groups
|
||||
const yearMonthGroups = Array.from(groups.keys())
|
||||
.filter((group) => !dateGroupsSet.has(group))
|
||||
.sort((a, b) => {
|
||||
const [yearA, yearB] = [parseInt(a.trim()), parseInt(b.trim())];
|
||||
if (yearA !== yearB) {
|
||||
return yearB - yearA;
|
||||
}
|
||||
|
||||
const [monthA, monthB] = [dateKeysReverse[a], dateKeysReverse[b]];
|
||||
const bOrder = monthOrderMap.get(monthB) ?? -1;
|
||||
const aOrder = monthOrderMap.get(monthA) ?? -1;
|
||||
return bOrder - aOrder;
|
||||
});
|
||||
|
||||
return Object.entries(sortedGroups);
|
||||
yearMonthGroups.forEach((group) => {
|
||||
sortedGroups.set(group, groups.get(group));
|
||||
});
|
||||
|
||||
// Sort conversations within each group
|
||||
sortedGroups.forEach((conversations) => {
|
||||
conversations.sort(
|
||||
(a: TConversation, b: TConversation) =>
|
||||
new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),
|
||||
);
|
||||
});
|
||||
|
||||
return Array.from(sortedGroups, ([key, value]) => [key, value]);
|
||||
};
|
||||
|
||||
export const addConversation = (
|
||||
|
|
@ -195,7 +234,7 @@ export const getConversationById = (
|
|||
data: ConversationData | undefined,
|
||||
conversationId: string | null,
|
||||
): TConversation | undefined => {
|
||||
if (!data || !conversationId) {
|
||||
if (!data || !(conversationId ?? '')) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
|
@ -224,11 +263,11 @@ export function storeEndpointSettings(conversation: TConversation | null) {
|
|||
return;
|
||||
}
|
||||
|
||||
const lastModel = JSON.parse(localStorage.getItem(LocalStorageKeys.LAST_MODEL) || '{}');
|
||||
const lastModel = JSON.parse(localStorage.getItem(LocalStorageKeys.LAST_MODEL) ?? '{}');
|
||||
lastModel[endpoint] = model;
|
||||
|
||||
if (endpoint === EModelEndpoint.gptPlugins) {
|
||||
lastModel.secondaryModel = agentOptions?.model || model || '';
|
||||
lastModel.secondaryModel = agentOptions?.model ?? model ?? '';
|
||||
}
|
||||
|
||||
localStorage.setItem(LocalStorageKeys.LAST_MODEL, JSON.stringify(lastModel));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue