Skip to content

Commit f2c2972

Browse files
leilabbtoniorioleriklindgrendependabot[bot]
authored
110 add hideshow function to chat groupings (#130)
* add key perk to landing page (#107) * add key perk to landing page * fix spelling * 98-clarify-copy-when-creating-a-team * modify copy when creating a new team * add missing env to gh action/workflow --------- Co-authored-by: Toni Oriol <[email protected]> * add grouping to chats * add last 30 days group * 104-change-the-word-fork-it-to-clone-including-icon * Change 'fork' to 'clone' and change icon * Change copy of modal after clicking 'Clone' * replace fork with clone * add last year group * refactor time functions * change function name * change func name * add missing env vars to example * Create dependabot.yml * Bump vite from 4.3.9 to 4.5.2 (#112) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.3.9 to 4.5.2. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v4.5.2/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v4.5.2/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Update dependabot.yml Include GitHub Actions version updates. * Bump actions/checkout from 2 to 4 (#123) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v2...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump actions/setup-node from 2 to 4 (#122) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 2 to 4. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v2...v4) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Upgrade to node 20 * Run tests on push to dev * add tests + new grouping function * Bump axios, openai and postmark (#113) * Bump axios, openai and postmark Bumps [axios](https://github.com/axios/axios) to 1.6.5 and updates ancestor dependencies [axios](https://github.com/axios/axios), [openai](https://github.com/openai/openai-node) and [postmark](https://github.com/ActiveCampaign/postmark.js). These dependencies need to be updated together. Updates `axios` from 0.25.0 to 1.6.5 - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v0.25.0...v1.6.5) Updates `openai` from 3.3.0 to 4.25.0 - [Release notes](https://github.com/openai/openai-node/releases) - [Changelog](https://github.com/openai/openai-node/blob/master/CHANGELOG.md) - [Commits](openai/openai-node@v3.3.0...v4.25.0) Updates `postmark` from 3.0.19 to 4.0.2 - [Release notes](https://github.com/ActiveCampaign/postmark.js/releases) - [Changelog](https://github.com/ActiveCampaign/postmark.js/blob/main/CHANGELOG.md) - [Commits](ActiveCampaign/postmark.js@3.0.19...4.0.2) --- updated-dependencies: - dependency-name: axios dependency-type: indirect - dependency-name: openai dependency-type: direct:production - dependency-name: postmark dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> * update to openai@4 fixes --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Toni Oriol <[email protected]> * refactoring * add grouping to all chats ever made * add code fix * change function name * change type name * refactor * style code * add tests * catch future dates¨ * add hide show functionality * rename functions * 99 group chat history by monthyear (#111) * add grouping to chats * add last 30 days group * add last year group * refactor time functions * change function name * change func name * add tests + new grouping function * refactoring * add grouping to all chats ever made * add code fix * change function name * change type name * refactor * style code * add tests * catch future dates¨ * add final fixes * edit test file * refactor groupings wip * refactoring * modify tests --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Toni Oriol <[email protected]> Co-authored-by: Erik Lindgren <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent 9ad5165 commit f2c2972

File tree

5 files changed

+98
-61
lines changed

5 files changed

+98
-61
lines changed

package-lock.json

Lines changed: 7 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
},
2020
"dependencies": {
2121
"@babeard/svelte-heroicons": "^2.0.0-rc.0",
22-
"@faker-js/faker": "^8.1.0",
2322
"@magidoc/plugin-svelte-marked": "^4.1.2",
2423
"@playwright/test": "^1.41.2",
2524
"@prisma/client": "^5.4.2",
@@ -74,6 +73,9 @@
7473
"zod": "^3.21.4"
7574
},
7675
"prisma": {
77-
"seed": "tsx prisma/seed.ts"
76+
"seed": "ts-node prisma/seed.ts"
77+
},
78+
"devDependencies": {
79+
"@faker-js/faker": "^8.4.0"
7880
}
7981
}

src/lib/components/Sidebar.svelte

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33
import Gravatar from '$lib/components/Gravatar.svelte'
44
import type { UserWithUserTeamsActiveTeamAndChats } from '$lib/server/entities/user'
55
import { isSidebarOpen } from '$lib/stores/general'
6-
import { ChevronRightIcon, PlusIcon } from '@babeard/svelte-heroicons/solid'
6+
import {
7+
ChevronRightIcon,
8+
PlusIcon,
9+
ChevronDownIcon,
10+
ChevronUpIcon,
11+
} from '@babeard/svelte-heroicons/solid'
12+
713
import { categorizeDate } from '$lib/utils/time'
814
915
export let user: UserWithUserTeamsActiveTeamAndChats
1016
11-
type ChatLists = {
12-
[key: string | number]: any[]
17+
type ChatObject = {
18+
chats: any[]
19+
key: string
20+
label: string
21+
isOpen: boolean
1322
}
1423
1524
$: chats = [
@@ -19,24 +28,21 @@
1928
...(user.activeUserTeam?.chats || []),
2029
].sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())
2130
22-
$: chatsGroupedByTime = chats?.reduce((chatLists: ChatLists, chat) => {
23-
const category = categorizeDate(chat.updatedAt)
24-
if (!chatLists[category]) {
25-
chatLists[category] = []
26-
}
27-
chatLists[category].push(chat)
28-
return chatLists
29-
}, {})
30-
31-
const getTitle = (interval: any) => {
32-
const titleMap: { [key: string]: string } = {
33-
today: 'Today',
34-
yesterday: 'Yesterday',
35-
previousSevenDays: 'Previous 7 Days',
36-
lastMonth: 'Previous 30 Days',
31+
$: chatsGroupedByTime = chats?.reduce((chatObjects: ChatObject[], chat) => {
32+
const { key, label, isOpen } = categorizeDate(chat.updatedAt)
33+
const foundObject = chatObjects.find((obj) => obj.key === key)
34+
if (foundObject) {
35+
foundObject.chats.push(chat)
36+
} else {
37+
chatObjects.push({
38+
key: key,
39+
label: label,
40+
isOpen: isOpen,
41+
chats: [chat],
42+
})
3743
}
38-
return typeof interval === 'number' ? interval : titleMap[interval]
39-
}
44+
return chatObjects
45+
}, [])
4046
</script>
4147

4248
<aside class="flex flex-col grow overflow-hidden h-full">
@@ -62,11 +68,28 @@
6268
</a>
6369
{#if chats.length}
6470
<ul class="overflow-auto grow flex flex-col gap-2 pt-2">
65-
{#each Object.entries(chatsGroupedByTime) as [interval, chats]}
66-
{#if chats.length > 0}
67-
<p class="flex-none text-xs text-gray-600">{getTitle(interval)}</p>
68-
{#each chats as chat}
69-
<ChatLink {chat} {user} />
71+
{#each chatsGroupedByTime as chatGroup}
72+
{#if chatGroup.chats.length > 0}
73+
<div class="flex relative items-center">
74+
<p class="flex-none text-xs text-gray-600">{chatGroup.label}</p>
75+
<div class="right-0 absolute">
76+
{#if chatGroup.isOpen}
77+
<ChevronUpIcon
78+
class="h-3 w-3 text-white"
79+
on:click={() => (chatGroup.isOpen = !chatGroup.isOpen)}
80+
/>
81+
{:else}
82+
<ChevronDownIcon
83+
class="h-3 w-3 text-white"
84+
on:click={() => (chatGroup.isOpen = !chatGroup.isOpen)}
85+
/>
86+
{/if}
87+
</div>
88+
</div>
89+
{#each chatGroup.chats as chat}
90+
<div class={chatGroup.isOpen ? '' : 'hidden'}>
91+
<ChatLink {chat} {user} />
92+
</div>
7093
{/each}
7194
{/if}
7295
{/each}

src/lib/utils/time.test.ts

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,43 @@ const dateFromLastYear = new Date(
88
currentDate.getDate()
99
)
1010
const twoYearsAgo = new Date(currentDate)
11-
const twoYearsAhead = new Date(currentDate)
1211
twoYearsAgo.setFullYear(currentDate.getFullYear() - 2)
12+
13+
const twoYearsAhead = new Date(currentDate)
1314
twoYearsAhead.setFullYear(currentDate.getFullYear() + 2)
1415

16+
const twoYearsAgoYear = twoYearsAgo.getFullYear().toString()
17+
1518
describe(isLastYear, () => {
16-
it('returns true for a date from the previous year'),
17-
() => {
18-
expect(isLastYear(dateFromLastYear)).toBe(true)
19-
}
19+
it('returns true for a date from the previous year', () => {
20+
expect(isLastYear(dateFromLastYear)).toBe(true)
21+
})
2022

21-
it('returns false for a date of the current year'),
22-
() => {
23-
expect(isLastYear(currentDate)).toBe(false)
24-
}
23+
it('returns false for a date of the current year', () => {
24+
expect(isLastYear(currentDate)).toBe(false)
25+
})
2526
})
2627

2728
describe(categorizeDate, () => {
28-
it('returns the year two years ago'),
29-
() => {
30-
expect(categorizeDate(twoYearsAgo)).toBe(2022)
31-
},
32-
it('returns "today" '),
33-
() => {
34-
expect(categorizeDate(currentDate)).toBe('today')
35-
},
36-
it('returns "futureDate" '),
37-
() => {
38-
expect(categorizeDate(twoYearsAhead)).toBe('futureDate')
39-
}
29+
it('returns the year two years ago', () => {
30+
expect(categorizeDate(twoYearsAgo)).toMatchObject({
31+
key: twoYearsAgoYear,
32+
label: twoYearsAgoYear,
33+
isOpen: false,
34+
})
35+
}),
36+
it('returns "today" ', () => {
37+
expect(categorizeDate(currentDate)).toMatchObject({
38+
key: 'today',
39+
label: 'Today',
40+
isOpen: true,
41+
})
42+
}),
43+
it('returns "futureDate" ', () => {
44+
expect(categorizeDate(twoYearsAhead)).toMatchObject({
45+
key: 'futureDate',
46+
label: 'Future Date',
47+
isOpen: false,
48+
})
49+
})
4050
})

src/lib/utils/time.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,26 @@ export const timeSince = (date: Date) => {
3636
}
3737
}
3838

39-
export const categorizeDate = (date: Date): string | number => {
40-
const now = new Date()
39+
export const categorizeDate = (date: Date): { key: string; label: string; isOpen: boolean } => {
4140
if (isToday(date)) {
42-
return 'today'
41+
return { key: 'today', label: 'Today', isOpen: true }
4342
} else if (isYesterday(date)) {
44-
return 'yesterday'
43+
return { key: 'yesterday', label: 'Yesterday', isOpen: true }
4544
} else if (
4645
millisecondsPerDay < millisecondsSince(date) &&
4746
millisecondsSince(date) <= previousSevenDays
4847
) {
49-
return 'previousSevenDays'
48+
return { key: 'previousSevenDays', label: 'Previous 7 Days', isOpen: true }
5049
} else if (
5150
previousSevenDays < millisecondsSince(date) &&
5251
millisecondsSince(date) <= lastThirtyDays
5352
) {
54-
return 'lastMonth'
53+
return { key: 'lastMonth', label: 'Previous 30 Days', isOpen: true }
5554
} else if (date.getFullYear() <= currentYear) {
56-
const year = date.getFullYear()
57-
return year
55+
const year = date.getFullYear().toString()
56+
return { key: year, label: year, isOpen: false }
5857
} else {
59-
return 'futureDate'
58+
return { key: 'futureDate', label: 'Future Date', isOpen: false }
6059
}
6160
}
6261

0 commit comments

Comments
 (0)