Skip to content

Commit

Permalink
feat: issue actions
Browse files Browse the repository at this point in the history
  • Loading branch information
potts99 committed Nov 6, 2024
1 parent bb67cd4 commit 55d7368
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 30 deletions.
63 changes: 53 additions & 10 deletions apps/api/src/controllers/ticket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,16 +638,59 @@ export function ticketRoutes(fastify: FastifyInstance) {
if (token) {
const { hidden, id }: any = request.body;

await prisma.ticket
.update({
where: { id: id },
data: {
hidden: hidden,
},
})
.then(async (ticket) => {
// await sendTicketStatus(ticket);
});
await prisma.ticket.update({
where: { id: id },
data: {
hidden: hidden,
},
});

reply.send({
success: true,
});
}
}
);

// Lock a ticket
fastify.put(
"/api/v1/ticket/status/lock",

async (request: FastifyRequest, reply: FastifyReply) => {
const bearer = request.headers.authorization!.split(" ")[1];
const token = checkToken(bearer);

if (token) {
const { locked, id }: any = request.body;

await prisma.ticket.update({
where: { id: id },
data: {
locked: locked,
},
});

reply.send({
success: true,
});
}
}
);

// Delete a ticket
fastify.post(
"/api/v1/ticket/delete",

async (request: FastifyRequest, reply: FastifyReply) => {
const bearer = request.headers.authorization!.split(" ")[1];
const token = checkToken(bearer);

if (token) {
const { id }: any = request.body;

await prisma.ticket.delete({
where: { id: id },
});

reply.send({
success: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Ticket" ADD COLUMN "locked" BOOLEAN NOT NULL DEFAULT false;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "Comment" DROP CONSTRAINT "Comment_ticketId_fkey";

-- AddForeignKey
ALTER TABLE "Comment" ADD CONSTRAINT "Comment_ticketId_fkey" FOREIGN KEY ("ticketId") REFERENCES "Ticket"("id") ON DELETE CASCADE ON UPDATE CASCADE;
3 changes: 2 additions & 1 deletion apps/api/src/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ model Ticket {
type TicketType @default(support)
hidden Boolean @default(false)
createdBy Json?
locked Boolean @default(false)
TicketFile TicketFile[]
Comment Comment[]
Expand Down Expand Up @@ -164,7 +165,7 @@ model Comment {
userId String?
user User? @relation(fields: [userId], references: [id])
ticketId String
ticket Ticket @relation(fields: [ticketId], references: [id])
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
}

model Client {
Expand Down
167 changes: 148 additions & 19 deletions apps/client/components/TicketDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,31 @@ import { IconCombo, UserCombo } from "../Combo";
import {
CircleCheck,
CircleDotDashed,
Ellipsis,
Eye,
EyeClosed,
EyeOff,
LifeBuoy,
Loader,
LoaderCircle,
Lock,
SignalHigh,
SignalLow,
SignalMedium,
Trash,
Trash2,
Unlock,
} from "lucide-react";
import { toast } from "@/shadcn/hooks/use-toast";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/shadcn/ui/dropdown-menu";
import { IconKeyboardHide } from "@tabler/icons-react";

const ticketStatusMap = [
{ id: 1, value: "needs_support", name: "Needs Support", icon: LifeBuoy },
Expand Down Expand Up @@ -171,6 +188,46 @@ export default function Ticket() {
.then(() => refetch());
}

async function lock(locked) {
await fetch(`/api/v1/ticket/status/lock`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
locked,
id,
}),
})
.then((res) => res.json())
.then(() => refetch());
}

async function deleteIssue(locked) {
await fetch(`/api/v1/ticket/delete`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
id,
}),
})
.then((res) => res.json())
.then((res) => {
if (res.success) {
toast({
variant: "default",
title: "Issue Deleted",
description: "The issue has been deleted",
});
router.push("/issues");
}
});
}

async function addComment() {
await fetch(`/api/v1/ticket/comment`, {
method: "POST",
Expand Down Expand Up @@ -410,34 +467,106 @@ export default function Ticket() {
key={data.ticket.id}
/>
</div>
<div className="mt-2 text-xs flex flex-row items-center space-x-1 text-gray-500 dark:text-white">
<div>
{!data.ticket.isComplete ? (
<div className="flex items-center space-x-2">
<span className="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">
{t("open_issue")}
<div className="mt-2 text-xs flex flex-row justify-between items-center space-x-1 text-gray-500 dark:text-white">
<div className="flex flex-row space-x-1 items-center">
<div>
{!data.ticket.isComplete ? (
<div className="flex items-center space-x-2">
<span className="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">
{t("open_issue")}
</span>
</div>
) : (
<div className="flex items-center space-x-2">
<span className="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-600/10">
{t("closed_issue")}
</span>
</div>
)}
</div>
<div>
<span className="inline-flex items-center rounded-md bg-orange-50 px-2 py-1 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-600/20">
{data.ticket.type}
</span>
</div>
{data.ticket.hidden && (
<div>
<span className="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-600/20">
Hidden
</span>
</div>
) : (
<div className="flex items-center space-x-2">
<span className="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-600/10">
{t("closed_issue")}
)}
{data.ticket.locked && (
<div>
<span className="inline-flex items-center rounded-md bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-600/20">
Locked
</span>
</div>
)}
</div>
<div>
<span className="inline-flex items-center rounded-md bg-orange-50 px-2 py-1 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-600/20">
{data.ticket.type}
</span>
</div>
{data.ticket.client && (
<div>
{user.isAdmin && (
<DropdownMenu>
<DropdownMenuTrigger className="inline-flex items-center px-2 py-1 text-xs font-medium text-foreground ring-none outline-none ">
<Ellipsis className="h-4 w-4" />
</DropdownMenuTrigger>
<DropdownMenuContent
align="end"
className="min-w-[160px]"
>
<DropdownMenuLabel>
<span>Issue Actions</span>
</DropdownMenuLabel>
<DropdownMenuSeparator />
{data.ticket.hidden ? (
<DropdownMenuItem
className="flex flex-row space-x-3 items-center"
onClick={() => hide(false)}
>
<Eye className="h-4 w-4" />
<span>Show Issue</span>
</DropdownMenuItem>
) : (
<DropdownMenuItem
className="flex flex-row space-x-3 items-center"
onClick={() => hide(true)}
>
<EyeOff className="h-4 w-4" />
<span>Hide Issue</span>
</DropdownMenuItem>
)}
{data.ticket.locked ? (
<DropdownMenuItem
className="flex flex-row space-x-3 items-center"
onClick={() => lock(false)}
>
<Unlock className="h-4 w-4" />
<span>Unlock Issue</span>
</DropdownMenuItem>
) : (
<DropdownMenuItem
className="flex flex-row space-x-3 items-center"
onClick={() => lock(true)}
>
<Lock className="h-4 w-4" />
<span>Lock Issue</span>
</DropdownMenuItem>
)}
<DropdownMenuSeparator />
<DropdownMenuItem
className="flex flex-row space-x-3 items-center transition-colors duration-200 focus:bg-red-500 focus:text-white"
onClick={() => deleteIssue()}
>
<Trash2 className="h-4 w-4" />
<span className="">Delete Issue</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
{/* <div>
<span className="inline-flex items-center rounded-md bg-orange-50 px-2 py-1 text-xs font-medium text-orange-700 ring-1 ring-inset ring-orange-600/20">
{data.ticket.client.name}
</span>
</div>
)}
</div> */}
</div>
</div>
</div>
Expand Down

0 comments on commit 55d7368

Please sign in to comment.