fix(dashboard): duplicate members

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-10-15 21:38:39 +02:00
parent b2687a2289
commit b693d0ba2b
5 changed files with 43 additions and 19 deletions

View File

@@ -67,11 +67,13 @@ export default function CreateInvite({ projects }: Props) {
</SheetTrigger> </SheetTrigger>
<SheetContent> <SheetContent>
<SheetHeader> <SheetHeader>
<div>
<SheetTitle>Invite a user</SheetTitle> <SheetTitle>Invite a user</SheetTitle>
<SheetDescription> <SheetDescription>
Invite users to your organization. They will recieve an email will Invite users to your organization. They will recieve an email will
instructions. instructions.
</SheetDescription> </SheetDescription>
</div>
</SheetHeader> </SheetHeader>
<form <form
onSubmit={handleSubmit((values) => mutation.mutate(values))} onSubmit={handleSubmit((values) => mutation.mutate(values))}

View File

@@ -104,7 +104,7 @@ const Tracking = ({
render={({ field, formState }) => { render={({ field, formState }) => {
return ( return (
<div> <div>
<Label>Workspace name</Label> <Label>Workspace</Label>
<Combobox <Combobox
className="w-full" className="w-full"
placeholder="Select workspace" placeholder="Select workspace"

View File

@@ -11,7 +11,7 @@ import { api } from '@/trpc/client';
import type { ColumnDef, Row } from '@tanstack/react-table'; import type { ColumnDef, Row } from '@tanstack/react-table';
import { MoreHorizontalIcon } from 'lucide-react'; import { MoreHorizontalIcon } from 'lucide-react';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useState } from 'react'; import { useRef, useState } from 'react';
import { toast } from 'sonner'; import { toast } from 'sonner';
import type { IServiceMember, IServiceProject } from '@openpanel/db'; import type { IServiceMember, IServiceProject } from '@openpanel/db';
@@ -76,10 +76,16 @@ function AccessCell({
row: Row<IServiceMember>; row: Row<IServiceMember>;
projects: IServiceProject[]; projects: IServiceProject[];
}) { }) {
const initial = useRef(row.original.access.map((item) => item.projectId));
const [access, setAccess] = useState<string[]>( const [access, setAccess] = useState<string[]>(
row.original.access.map((item) => item.projectId), row.original.access.map((item) => item.projectId),
); );
const mutation = api.organization.updateMemberAccess.useMutation(); const mutation = api.organization.updateMemberAccess.useMutation({
onError(error) {
toast.error(error.message);
setAccess(initial.current);
},
});
return ( return (
<ComboboxAdvanced <ComboboxAdvanced
@@ -128,7 +134,8 @@ function ActionsCell({ row }: { row: Row<IServiceMember> }) {
onClick={() => { onClick={() => {
revoke.mutate({ revoke.mutate({
organizationId: row.original.organizationId, organizationId: row.original.organizationId,
userId: row.original.id, userId: row.original.userId!,
id: row.original.id,
}); });
}} }}
> >

View File

@@ -77,6 +77,7 @@ export const onboardingRouter = createTRPCRouter({
throw new Error('Organization slug is missing'); throw new Error('Organization slug is missing');
} }
if (input.organization) {
await db.member.create({ await db.member.create({
data: { data: {
email: user.email, email: user.email,
@@ -85,6 +86,7 @@ export const onboardingRouter = createTRPCRouter({
userId: user.id, userId: user.id,
}, },
}); });
}
const project = await db.project.create({ const project = await db.project.create({
data: { data: {

View File

@@ -130,10 +130,18 @@ export const organizationRouter = createTRPCRouter({
z.object({ z.object({
organizationId: z.string(), organizationId: z.string(),
userId: z.string(), userId: z.string(),
id: z.string(),
}), }),
) )
.mutation(async ({ input, ctx }) => { .mutation(async ({ input, ctx }) => {
if (ctx.session.userId === input.userId) { const exists = await db.member.count({
where: {
userId: input.userId,
organizationId: input.organizationId,
},
});
if (ctx.session.userId === input.userId && exists === 1) {
throw new Error('You cannot remove yourself from the organization'); throw new Error('You cannot remove yourself from the organization');
} }
@@ -147,8 +155,9 @@ export const organizationRouter = createTRPCRouter({
} }
await db.$transaction([ await db.$transaction([
db.member.deleteMany({ db.member.delete({
where: { where: {
id: input.id,
userId: input.userId, userId: input.userId,
organizationId: input.organizationId, organizationId: input.organizationId,
}, },
@@ -171,6 +180,10 @@ export const organizationRouter = createTRPCRouter({
}), }),
) )
.mutation(async ({ input, ctx }) => { .mutation(async ({ input, ctx }) => {
if (input.userId === ctx.session.userId) {
throw TRPCAccessError('You cannot update your own access');
}
const access = await getOrganizationAccess({ const access = await getOrganizationAccess({
userId: ctx.session.userId, userId: ctx.session.userId,
organizationId: input.organizationSlug, organizationId: input.organizationSlug,