Skip to content

Commit 2ac1b44

Browse files
committed
feat: right click context
1 parent 773da61 commit 2ac1b44

File tree

7 files changed

+489
-63
lines changed

7 files changed

+489
-63
lines changed

apps/api/src/controllers/ticket.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -443,20 +443,29 @@ export function ticketRoutes(fastify: FastifyInstance) {
443443
const { user, id }: any = request.body;
444444

445445
if (token) {
446-
const assigned = await prisma.user.update({
447-
where: { id: user },
448-
data: {
449-
tickets: {
450-
connect: {
451-
id: id,
446+
if (user) {
447+
const assigned = await prisma.user.update({
448+
where: { id: user },
449+
data: {
450+
tickets: {
451+
connect: {
452+
id: id,
453+
},
452454
},
453455
},
454-
},
455-
});
456+
});
456457

457-
const { email } = assigned;
458+
const { email } = assigned;
458459

459-
await sendAssignedEmail(email);
460+
await sendAssignedEmail(email);
461+
} else {
462+
await prisma.ticket.update({
463+
where: { id: id },
464+
data: {
465+
userId: null,
466+
},
467+
});
468+
}
460469

461470
reply.send({
462471
success: true,

apps/api/src/routes.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ import { emailQueueRoutes } from "./controllers/queue";
88
import { objectStoreRoutes } from "./controllers/storage";
99
import { ticketRoutes } from "./controllers/ticket";
1010
import { timeTrackingRoutes } from "./controllers/time";
11-
import { todoRoutes } from "./controllers/todos";
1211
import { userRoutes } from "./controllers/users";
1312
import { webhookRoutes } from "./controllers/webhooks";
1413

1514
export function registerRoutes(fastify: FastifyInstance) {
1615
authRoutes(fastify);
1716
emailQueueRoutes(fastify);
18-
todoRoutes(fastify);
1917
dataRoutes(fastify);
2018
ticketRoutes(fastify);
2119
userRoutes(fastify);
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import * as React from "react"
2+
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu"
3+
import { Check, ChevronRight, Circle } from "lucide-react"
4+
5+
import { cn } from "@/shadcn/lib/utils"
6+
7+
const ContextMenu = ContextMenuPrimitive.Root
8+
9+
const ContextMenuTrigger = ContextMenuPrimitive.Trigger
10+
11+
const ContextMenuGroup = ContextMenuPrimitive.Group
12+
13+
const ContextMenuPortal = ContextMenuPrimitive.Portal
14+
15+
const ContextMenuSub = ContextMenuPrimitive.Sub
16+
17+
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup
18+
19+
const ContextMenuSubTrigger = React.forwardRef<
20+
React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
21+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
22+
inset?: boolean
23+
}
24+
>(({ className, inset, children, ...props }, ref) => (
25+
<ContextMenuPrimitive.SubTrigger
26+
ref={ref}
27+
className={cn(
28+
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
29+
inset && "pl-8",
30+
className
31+
)}
32+
{...props}
33+
>
34+
{children}
35+
<ChevronRight className="ml-auto h-4 w-4" />
36+
</ContextMenuPrimitive.SubTrigger>
37+
))
38+
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName
39+
40+
const ContextMenuSubContent = React.forwardRef<
41+
React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
42+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
43+
>(({ className, ...props }, ref) => (
44+
<ContextMenuPrimitive.SubContent
45+
ref={ref}
46+
className={cn(
47+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
48+
className
49+
)}
50+
{...props}
51+
/>
52+
))
53+
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName
54+
55+
const ContextMenuContent = React.forwardRef<
56+
React.ElementRef<typeof ContextMenuPrimitive.Content>,
57+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
58+
>(({ className, ...props }, ref) => (
59+
<ContextMenuPrimitive.Portal>
60+
<ContextMenuPrimitive.Content
61+
ref={ref}
62+
className={cn(
63+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
64+
className
65+
)}
66+
{...props}
67+
/>
68+
</ContextMenuPrimitive.Portal>
69+
))
70+
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName
71+
72+
const ContextMenuItem = React.forwardRef<
73+
React.ElementRef<typeof ContextMenuPrimitive.Item>,
74+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
75+
inset?: boolean
76+
}
77+
>(({ className, inset, ...props }, ref) => (
78+
<ContextMenuPrimitive.Item
79+
ref={ref}
80+
className={cn(
81+
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
82+
inset && "pl-8",
83+
className
84+
)}
85+
{...props}
86+
/>
87+
))
88+
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName
89+
90+
const ContextMenuCheckboxItem = React.forwardRef<
91+
React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
92+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
93+
>(({ className, children, checked, ...props }, ref) => (
94+
<ContextMenuPrimitive.CheckboxItem
95+
ref={ref}
96+
className={cn(
97+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
98+
className
99+
)}
100+
checked={checked}
101+
{...props}
102+
>
103+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
104+
<ContextMenuPrimitive.ItemIndicator>
105+
<Check className="h-4 w-4" />
106+
</ContextMenuPrimitive.ItemIndicator>
107+
</span>
108+
{children}
109+
</ContextMenuPrimitive.CheckboxItem>
110+
))
111+
ContextMenuCheckboxItem.displayName =
112+
ContextMenuPrimitive.CheckboxItem.displayName
113+
114+
const ContextMenuRadioItem = React.forwardRef<
115+
React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
116+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
117+
>(({ className, children, ...props }, ref) => (
118+
<ContextMenuPrimitive.RadioItem
119+
ref={ref}
120+
className={cn(
121+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
122+
className
123+
)}
124+
{...props}
125+
>
126+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
127+
<ContextMenuPrimitive.ItemIndicator>
128+
<Circle className="h-2 w-2 fill-current" />
129+
</ContextMenuPrimitive.ItemIndicator>
130+
</span>
131+
{children}
132+
</ContextMenuPrimitive.RadioItem>
133+
))
134+
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName
135+
136+
const ContextMenuLabel = React.forwardRef<
137+
React.ElementRef<typeof ContextMenuPrimitive.Label>,
138+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
139+
inset?: boolean
140+
}
141+
>(({ className, inset, ...props }, ref) => (
142+
<ContextMenuPrimitive.Label
143+
ref={ref}
144+
className={cn(
145+
"px-2 py-1.5 text-sm font-semibold text-foreground",
146+
inset && "pl-8",
147+
className
148+
)}
149+
{...props}
150+
/>
151+
))
152+
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName
153+
154+
const ContextMenuSeparator = React.forwardRef<
155+
React.ElementRef<typeof ContextMenuPrimitive.Separator>,
156+
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
157+
>(({ className, ...props }, ref) => (
158+
<ContextMenuPrimitive.Separator
159+
ref={ref}
160+
className={cn("-mx-1 my-1 h-px bg-border", className)}
161+
{...props}
162+
/>
163+
))
164+
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName
165+
166+
const ContextMenuShortcut = ({
167+
className,
168+
...props
169+
}: React.HTMLAttributes<HTMLSpanElement>) => {
170+
return (
171+
<span
172+
className={cn(
173+
"ml-auto text-xs tracking-widest text-muted-foreground",
174+
className
175+
)}
176+
{...props}
177+
/>
178+
)
179+
}
180+
ContextMenuShortcut.displayName = "ContextMenuShortcut"
181+
182+
export {
183+
ContextMenu,
184+
ContextMenuTrigger,
185+
ContextMenuContent,
186+
ContextMenuItem,
187+
ContextMenuCheckboxItem,
188+
ContextMenuRadioItem,
189+
ContextMenuLabel,
190+
ContextMenuSeparator,
191+
ContextMenuShortcut,
192+
ContextMenuGroup,
193+
ContextMenuPortal,
194+
ContextMenuSub,
195+
ContextMenuSubContent,
196+
ContextMenuSubTrigger,
197+
ContextMenuRadioGroup,
198+
}

apps/client/components/TicketDetails/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ export default function Ticket() {
154154
.then((res) => res.json())
155155
.then(() => {
156156
setEdit(false);
157-
// refetch();
158157
});
159158
}
160159

apps/client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@radix-ui/react-alert-dialog": "^1.1.2",
1818
"@radix-ui/react-avatar": "^1.1.1",
1919
"@radix-ui/react-collapsible": "^1.1.1",
20+
"@radix-ui/react-context-menu": "^2.2.2",
2021
"@radix-ui/react-dialog": "^1.1.2",
2122
"@radix-ui/react-dropdown-menu": "^2.1.2",
2223
"@radix-ui/react-label": "^2.1.0",

0 commit comments

Comments
 (0)