fix(dashboard): duplicate members
This commit is contained in:
@@ -67,11 +67,13 @@ export default function CreateInvite({ projects }: Props) {
|
|||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
<SheetContent>
|
<SheetContent>
|
||||||
<SheetHeader>
|
<SheetHeader>
|
||||||
<SheetTitle>Invite a user</SheetTitle>
|
<div>
|
||||||
<SheetDescription>
|
<SheetTitle>Invite a user</SheetTitle>
|
||||||
Invite users to your organization. They will recieve an email will
|
<SheetDescription>
|
||||||
instructions.
|
Invite users to your organization. They will recieve an email will
|
||||||
</SheetDescription>
|
instructions.
|
||||||
|
</SheetDescription>
|
||||||
|
</div>
|
||||||
</SheetHeader>
|
</SheetHeader>
|
||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit((values) => mutation.mutate(values))}
|
onSubmit={handleSubmit((values) => mutation.mutate(values))}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -77,14 +77,16 @@ export const onboardingRouter = createTRPCRouter({
|
|||||||
throw new Error('Organization slug is missing');
|
throw new Error('Organization slug is missing');
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.member.create({
|
if (input.organization) {
|
||||||
data: {
|
await db.member.create({
|
||||||
email: user.email,
|
data: {
|
||||||
organizationId: organization.id,
|
email: user.email,
|
||||||
role: 'org:admin',
|
organizationId: organization.id,
|
||||||
userId: user.id,
|
role: 'org:admin',
|
||||||
},
|
userId: user.id,
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const project = await db.project.create({
|
const project = await db.project.create({
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user