Skip to content

Commit

Permalink
add feature flag to enable setting a group as global, and a list of g…
Browse files Browse the repository at this point in the history
…lobal groups display in the groups page
  • Loading branch information
ChristopherJohnston committed Oct 20, 2024
1 parent 39c1a2f commit 6eea3ef
Show file tree
Hide file tree
Showing 25 changed files with 126 additions and 16 deletions.
1 change: 1 addition & 0 deletions messages/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Letzte Gruppen",
"starred": "Favorisierte Gruppen",
"archived": "Archivierte Gruppen",
"global": "Global Groups",
"archive": "Gruppe archivieren",
"unarchive": "Gruppe wiederherstellen",
"removeRecent": "Aus letzten Gruppen entfernen",
Expand Down
1 change: 1 addition & 0 deletions messages/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Recent groups",
"starred": "Starred groups",
"archived": "Archived groups",
"global": "Global Groups",
"archive": "Archive group",
"unarchive": "Unarchive group",
"removeRecent": "Remove from recent groups",
Expand Down
1 change: 1 addition & 0 deletions messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Grupos recientes",
"starred": "Grupos favoritos",
"archived": "Grupos archivados",
"global": "Global Groups",
"archive": "Archivar grupo",
"unarchive": "Desarchivar groupo",
"removeRecent": "Remove from recent groups",
Expand Down
1 change: 1 addition & 0 deletions messages/fi.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Äskettäiset",
"starred": "Suosikit",
"archived": "Arkistoidut",
"global": "Global Groups",
"archive": "Arkistoi ryhmä",
"unarchive": "Palauta ryhmä arkistosta",
"removeRecent": "Poista äskettäisistä",
Expand Down
1 change: 1 addition & 0 deletions messages/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Groupes récents",
"starred": "Groupes favoris",
"archived": "Groupes archivés",
"global": "Global Groups",
"archive": "Archiver le groupe",
"unarchive": "Désarchiver le groupe",
"removeRecent": "Supprimer des groupes récents",
Expand Down
1 change: 1 addition & 0 deletions messages/it-IT.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Gruppi recenti",
"starred": "Gruppi speciali",
"archived": "Gruppi archiviati",
"global": "Global Groups",
"archive": "Archivia gruppo",
"unarchive": "Rimuovi il gruppo dall'archivio",
"removeRecent": "Rimuovi dai gruppi recenti",
Expand Down
1 change: 1 addition & 0 deletions messages/pl-PL.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Ostatnie grupy",
"starred": "Ogwiazdkowane grupy",
"archived": "Zarchiwizowane grupy",
"global": "Global Groups",
"archive": "Zarchiwizuj grupę",
"unarchive": "Odarchwiruj grupę",
"removeRecent": "Usuń z ostatnich grup",
Expand Down
1 change: 1 addition & 0 deletions messages/ro.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Ultimele grupuri",
"starred": "Grupuri favorite",
"archived": "Grupuri arhivate",
"global": "Global Groups",
"archive": "Arhivează grupul",
"unarchive": "Dezarhivează grupul",
"removeRecent": "Șterge din ultimele grupuri",
Expand Down
1 change: 1 addition & 0 deletions messages/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Недавние группы",
"starred": "Избранные",
"archived": "Архивированные группы",
"global": "Global Groups",
"archive": "Архивировать группу",
"unarchive": "Восстановить группу",
"removeRecent": "Убрать группу из недавних",
Expand Down
1 change: 1 addition & 0 deletions messages/ua-UA.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "Нещодавні групи",
"starred": "Обрані групи",
"archived": "Архівовані групи",
"global": "Global Groups",
"archive": "Архівувати групу",
"unarchive": "Розархівувати групу",
"removeRecent": "Видалити з останніх груп",
Expand Down
1 change: 1 addition & 0 deletions messages/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"recent": "最近的群组",
"starred": "已收藏的群组",
"archived": "已归档的群组",
"global": "Global Groups",
"archive": "归档群组",
"unarchive": "取消归档群组",
"removeRecent": "从最近的群组中删除",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Group" ADD COLUMN "isGlobal" BOOLEAN NOT NULL DEFAULT false;
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ model Group {
expenses Expense[]
activities Activity[]
createdAt DateTime @default(now())
isGlobal Boolean @default(false)
}

model Participant {
Expand Down
3 changes: 3 additions & 0 deletions scripts/build.env
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ S3_UPLOAD_ENDPOINT=s3://minio.example.com
NEXT_PUBLIC_ENABLE_RECEIPT_EXTRACT=false
OPENAI_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXX
NEXT_PUBLIC_ENABLE_CATEGORY_EXTRACT=false

# self-hosted features
GLOBAL_GROUPS_ENABLE=false
10 changes: 9 additions & 1 deletion src/app/groups/[groupId]/edit/edit-group.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
'use client'

import { GroupForm } from '@/components/group-form'
import { RuntimeFeatureFlags } from '@/lib/featureFlags'
import { trpc } from '@/trpc/client'

export const EditGroup = ({ groupId }: { groupId: string }) => {
export const EditGroup = ({
groupId,
runtimeFeatureFlags,
}: {
groupId: string
runtimeFeatureFlags: RuntimeFeatureFlags
}) => {
const { data, isLoading } = trpc.groups.get.useQuery({ groupId })
const { mutateAsync } = trpc.groups.update.useMutation()
const utils = trpc.useUtils()
Expand All @@ -18,6 +25,7 @@ export const EditGroup = ({ groupId }: { groupId: string }) => {
await utils.groups.invalidate()
}}
protectedParticipantIds={data?.participantsWithExpenses}
runtimeFeatureFlags={runtimeFeatureFlags}
/>
)
}
8 changes: 7 additions & 1 deletion src/app/groups/[groupId]/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EditGroup } from '@/app/groups/[groupId]/edit/edit-group'
import { getRuntimeFeatureFlags } from '@/lib/featureFlags'
import { Metadata } from 'next'

export const metadata: Metadata = {
Expand All @@ -10,5 +11,10 @@ export default async function EditGroupPage({
}: {
params: { groupId: string }
}) {
return <EditGroup groupId={groupId} />
return (
<EditGroup
groupId={groupId}
runtimeFeatureFlags={await getRuntimeFeatureFlags()}
/>
)
}
9 changes: 7 additions & 2 deletions src/app/groups/create/create-group.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
'use client'

import { GroupForm } from '@/components/group-form'
import { RuntimeFeatureFlags } from '@/lib/featureFlags'
import { trpc } from '@/trpc/client'
import { useRouter } from 'next/navigation'

export const CreateGroup = () => {
export const CreateGroup = ({
runtimeFeatureFlags,
}: {
runtimeFeatureFlags: RuntimeFeatureFlags
}) => {
const { mutateAsync } = trpc.groups.create.useMutation()
const utils = trpc.useUtils()
const router = useRouter()
Expand All @@ -16,6 +20,7 @@ export const CreateGroup = () => {
await utils.groups.invalidate()
router.push(`/groups/${groupId}`)
}}
runtimeFeatureFlags={runtimeFeatureFlags}
/>
)
}
5 changes: 3 additions & 2 deletions src/app/groups/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { CreateGroup } from '@/app/groups/create/create-group'
import { getRuntimeFeatureFlags } from '@/lib/featureFlags'
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Create Group',
}

export default function CreateGroupPage() {
return <CreateGroup />
export default async function CreateGroupPage() {
return <CreateGroup runtimeFeatureFlags={await getRuntimeFeatureFlags()} />
}
3 changes: 2 additions & 1 deletion src/app/groups/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { RecentGroupList } from '@/app/groups/recent-group-list'
import { getGlobalGroups } from '@/lib/api'
import { Metadata } from 'next'

export const metadata: Metadata = {
title: 'Recently visited groups',
}

export default async function GroupsPage() {
return <RecentGroupList />
return <RecentGroupList globalGroups={await getGlobalGroups()} />
}
44 changes: 35 additions & 9 deletions src/app/groups/recent-group-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
getStarredGroups,
} from '@/app/groups/recent-groups-helpers'
import { Button } from '@/components/ui/button'
import { getGroups } from '@/lib/api'
import { getGlobalGroups, getGroups } from '@/lib/api'
import { Loader2 } from 'lucide-react'
import { useTranslations } from 'next-intl'
import Link from 'next/link'
Expand All @@ -22,13 +22,15 @@ export type RecentGroupsState =
groups: RecentGroups
starredGroups: string[]
archivedGroups: string[]
globalGroups: NonNullable<Awaited<ReturnType<typeof getGlobalGroups>>>
}
| {
status: 'complete'
groups: RecentGroups
groupsDetails: Awaited<ReturnType<typeof getGroups>>
starredGroups: string[]
archivedGroups: string[]
globalGroups: NonNullable<Awaited<ReturnType<typeof getGlobalGroups>>>
}

function sortGroups(
Expand All @@ -37,6 +39,10 @@ function sortGroups(
const starredGroupInfo = []
const groupInfo = []
const archivedGroupInfo = []
const globalGroupInfo = state.globalGroups.filter(
(group) => state.groups.filter((g) => g.id == group.id).length == 0,
)

for (const group of state.groups) {
if (state.starredGroups.includes(group.id)) {
starredGroupInfo.push(group)
Expand All @@ -50,14 +56,21 @@ function sortGroups(
starredGroupInfo,
groupInfo,
archivedGroupInfo,
globalGroupInfo,
}
}

export function RecentGroupList() {
export type Props = {
globalGroups: NonNullable<Awaited<ReturnType<typeof getGlobalGroups>>>
}

export function RecentGroupList({ globalGroups }: Props) {
const t = useTranslations('Groups')
const [state, setState] = useState<RecentGroupsState>({ status: 'pending' })

function loadGroups() {
function loadGroups(
globalGroups: NonNullable<Awaited<ReturnType<typeof getGlobalGroups>>>,
) {
const groupsInStorage = getRecentGroups()
const starredGroups = getStarredGroups()
const archivedGroups = getArchivedGroups()
Expand All @@ -66,6 +79,7 @@ export function RecentGroupList() {
groups: groupsInStorage,
starredGroups,
archivedGroups,
globalGroups,
})
getGroupsAction(groupsInStorage.map((g) => g.id)).then((groupsDetails) => {
setState({
Expand All @@ -74,17 +88,18 @@ export function RecentGroupList() {
groupsDetails,
starredGroups,
archivedGroups,
globalGroups,
})
})
}

useEffect(() => {
loadGroups()
loadGroups(globalGroups)
}, [])

if (state.status === 'pending') {
return (
<GroupsPage reload={loadGroups}>
<GroupsPage reload={() => loadGroups(globalGroups)}>
<p>
<Loader2 className="w-4 m-4 mr-2 inline animate-spin" />{' '}
{t('loadingRecent')}
Expand All @@ -93,9 +108,9 @@ export function RecentGroupList() {
)
}

if (state.groups.length === 0) {
if (state.groups.length === 0 && state.globalGroups.length === 0) {
return (
<GroupsPage reload={loadGroups}>
<GroupsPage reload={() => loadGroups(globalGroups)}>
<div className="text-sm space-y-2">
<p>{t('NoRecent.description')}</p>
<p>
Expand All @@ -109,10 +124,11 @@ export function RecentGroupList() {
)
}

const { starredGroupInfo, groupInfo, archivedGroupInfo } = sortGroups(state)
const { starredGroupInfo, groupInfo, archivedGroupInfo, globalGroupInfo } =
sortGroups(state)

return (
<GroupsPage reload={loadGroups}>
<GroupsPage reload={() => loadGroups(globalGroups)}>
{starredGroupInfo.length > 0 && (
<>
<h2 className="mb-2">{t('starred')}</h2>
Expand Down Expand Up @@ -143,6 +159,16 @@ export function RecentGroupList() {
</div>
</>
)}
{globalGroupInfo.length > 0 && (
<>
<h2 className="mt-6 mb-2">{t('global')}</h2>
<GroupList
groups={globalGroupInfo}
state={state}
setState={setState}
/>
</>
)}
</GroupsPage>
)
}
Expand Down
Loading

0 comments on commit 6eea3ef

Please sign in to comment.