Skip to content

Commit

Permalink
feat(ui): dates (#404)
Browse files Browse the repository at this point in the history
* feat: change sidebar date ordering
  • Loading branch information
andrewrisse committed Apr 18, 2024
1 parent 037d157 commit 7efcebf
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 160 deletions.
25 changes: 6 additions & 19 deletions src/leapfrogai_ui/src/lib/components/ChatSidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import { MAX_LABEL_SIZE } from '$lib/constants';
import { conversationsStore, toastStore } from '$stores';
import { page } from '$app/stores';
let deleteModalOpen = false;
let editConversationId: string | null = null;
let editLabelText: string | undefined = undefined;
Expand All @@ -28,18 +27,6 @@
$: organizedConversations = dates.organizeConversationsByDate($conversationsStore.conversations);
$: dateCategories = Array.from(
new Set([
'Today',
'Yesterday',
'This Month',
...dates.sortMonthsReverse(
Object.keys(organizedConversations).filter((item) => item !== 'Old')
),
'Old'
])
);
const resetEditMode = () => {
editConversationId = null;
editLabelText = undefined;
Expand Down Expand Up @@ -121,10 +108,10 @@
</div>

<div class="conversations" data-testid="conversations">
{#each dateCategories as category}
<SideNavMenu text={category} expanded data-testid="side-nav-menu">
{#if organizedConversations[category]}
{#each organizedConversations[category] as conversation (conversation.id)}
{#each organizedConversations as category}
{#if category.conversations.length > 0}
<SideNavMenu text={category.label} expanded data-testid="side-nav-menu">
{#each category.conversations as conversation (conversation.id)}
{@const editMode = editConversationId && editConversationId === conversation.id}
<div class:label-edit-mode={editMode}>
<SideNavMenuItem
Expand Down Expand Up @@ -179,8 +166,8 @@
</SideNavMenuItem>
</div>
{/each}
{/if}
</SideNavMenu>
</SideNavMenu>
{/if}
{/each}
</div>
<Modal
Expand Down
33 changes: 32 additions & 1 deletion src/leapfrogai_ui/src/lib/components/ChatSidebar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {
import { conversationsStore, toastStore } from '$stores';
import { render, screen, within } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import { fakeConversations } from '../../testUtils/fakeData';
import { fakeConversations, getFakeConversation } from '../../testUtils/fakeData';
import { vi } from 'vitest';
import stores from '$app/stores';
import { monthNames } from '$helpers/dates';

const { getStores } = await vi.hoisted(() => import('../../lib/mocks/svelte'));

Expand Down Expand Up @@ -76,6 +77,36 @@ describe('ChatSidebar', () => {
});
});

it('does not render date categories that have no conversations', async () => {
const today = new Date();
const fakeTodayConversation = getFakeConversation();
const fakeYesterdayConversation = getFakeConversation({
insertedAt: new Date(
today.getFullYear(),
today.getMonth(),
today.getDate() - 1
).toDateString()
});

conversationsStore.set({
conversations: [fakeTodayConversation, fakeYesterdayConversation] // uses date override starting in March
});

render(ChatSidebar);
const conversationsSection = screen.getByTestId('conversations');

expect(within(conversationsSection).getByText(fakeTodayConversation.label)).toBeInTheDocument();
expect(
within(conversationsSection).getByText(fakeYesterdayConversation.label)
).toBeInTheDocument();

expect(screen.getByText('Today')).toBeInTheDocument();
expect(screen.getByText('Yesterday')).toBeInTheDocument();

expect(screen.queryByText(monthNames[today.getMonth()])).not.toBeInTheDocument();
expect(screen.queryByText(monthNames[today.getMonth() - 1])).not.toBeInTheDocument();
});

it('deletes conversations', async () => {
mockDeleteConversation();

Expand Down
79 changes: 38 additions & 41 deletions src/leapfrogai_ui/src/lib/helpers/dates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,24 @@ describe('date helpers', () => {

describe('getDateCategory', () => {
it('returns "Old" when the date is more than the default set for numMonthsAgo', () => {
const NUM_MONTHS_TO_DISPLAY = 6;
const currentDate = new Date();
const pastDate = new Date(currentDate.getFullYear(), currentDate.getMonth() - 5);
const pastDate = new Date(
currentDate.getFullYear(),
currentDate.getMonth() - NUM_MONTHS_TO_DISPLAY - 1
);
const expectedCategory = 'Old';

expect(dates.getDateCategory(pastDate)).toBe(expectedCategory);
expect(
dates.getDateCategory({ date: pastDate, numMonthsToDisplay: NUM_MONTHS_TO_DISPLAY })
).toBe(expectedCategory);
});

it('returns "Today" when the date is the same as the current date', () => {
const currentDate = new Date();
const expectedCategory = 'Today';

expect(dates.getDateCategory(currentDate)).toBe(expectedCategory);
expect(dates.getDateCategory({ date: currentDate })).toBe(expectedCategory);
});

it('returns "Yesterday" when the date is one day before the current date', () => {
Expand All @@ -79,45 +85,24 @@ describe('date helpers', () => {
);
const expectedCategory = 'Yesterday';

expect(dates.getDateCategory(yesterday)).toBe(expectedCategory);
expect(dates.getDateCategory({ date: yesterday })).toBe(expectedCategory);
});

it('returns "This Month" when the date is in the same month as the current date', () => {
const currentDate = new Date();
const sameMonthDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), 10);
const expectedCategory = 'This Month';

expect(dates.getDateCategory(sameMonthDate)).toBe(expectedCategory);
});

it('returns the formatted month and year when the date is in a different year', () => {
// Date to compare against needs to be within numMonthsToDisplay months but still
// within previous year in order to see the monthname - year
// we are setting the numMonthsToDisplay to 1200 to make sure it does not put the month in 'Old' category

// The system timezone here is behind UTC so you need to specify T00:00 to make sure it reflects the local
// day properly and doesn't show October when it should be November 1
const date = new Date('2023-11-01T00:00');
const expectedCategory = 'November - 2023';

expect(dates.getDateCategory(date, 1200)).toBe(expectedCategory);
});

it('returns the formatted month when the date is in the current year', () => {
// We can't use actual today because if this test is run in January, the previous month
// will get the year with its category (e.g December - 2023) and the test will fail
const todayOverride = new Date('2024-03-01T00:00');
const date = new Date('2024-02-01T00:00');
const expectedCategory = 'February';

expect(dates.getDateCategory(date, 4, todayOverride)).toBe(expectedCategory);
expect(dates.getDateCategory({ date: sameMonthDate })).toBe(expectedCategory);
});
});

describe('organizeConversationsByDate', () => {
// Overriding to test with months that overlap years
const todayOverride = new Date('2024-03-20T00:00');

it('organizes conversations by date category', () => {
const numMonthsToDisplay = 6;
const conversations = [
// today
getFakeConversation({ insertedAt: todayOverride.toDateString() }),
Expand Down Expand Up @@ -153,25 +138,37 @@ describe('date helpers', () => {
insertedAt: new Date(new Date('2023-12-01T00:00')).toDateString()
}),
// Old
getFakeConversation({
insertedAt: new Date(
todayOverride.getFullYear() - 2,
todayOverride.getMonth()
).toDateString()
}),
getFakeConversation({
insertedAt: new Date(
todayOverride.getFullYear(),
todayOverride.getMonth() - 5
todayOverride.getMonth() - numMonthsToDisplay - 1
).toDateString()
})
];
console.log(conversations.map((c) => c.inserted_at));

const expectedOrganizedConversations = {
Today: [conversations[0]],
Yesterday: [conversations[1], conversations[2]],
'This Month': [conversations[3]],
February: [conversations[4]],
'December - 2023': [conversations[5]],
Old: [conversations[6]]
};

const result = dates.organizeConversationsByDate(conversations, todayOverride);

const expectedOrganizedConversations = [
{ label: 'Today', conversations: [conversations[0]] },
{ label: 'Yesterday', conversations: [conversations[1], conversations[2]] },
{ label: 'This Month', conversations: [conversations[3]] },
{ label: 'February', conversations: [conversations[4]] },
{ label: 'January', conversations: [] },
{ label: 'December', conversations: [conversations[5]] },
{ label: 'November', conversations: [] },
{ label: 'October', conversations: [] },
{ label: 'September', conversations: [] },
{ label: 'Old', conversations: [conversations[7], conversations[6]] } // tests ordering of old dates too
];
const result = dates.organizeConversationsByDate(
conversations,
todayOverride,
numMonthsToDisplay
);
expect(result).toEqual(expectedOrganizedConversations);
});
});
Expand Down
Loading

0 comments on commit 7efcebf

Please sign in to comment.