Skip to content

Commit

Permalink
patch: issue deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
potts99 committed Nov 15, 2024
1 parent a3ef4ec commit 0301576
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 125 deletions.
105 changes: 104 additions & 1 deletion apps/api/src/controllers/ticket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const validateEmail = (email: string) => {
};

export function ticketRoutes(fastify: FastifyInstance) {
// Create a new ticket - public endpoint, no preHandler needed
fastify.post(
"/api/v1/ticket/create",
{
Expand Down Expand Up @@ -133,6 +132,110 @@ export function ticketRoutes(fastify: FastifyInstance) {
}
);

fastify.post(
"/api/v1/ticket/public/create",
async (request: FastifyRequest, reply: FastifyReply) => {
const {
name,
company,
detail,
title,
priority,
email,
engineer,
type,
createdBy,
}: any = request.body;

const ticket: any = await prisma.ticket.create({
data: {
name,
title,
detail: JSON.stringify(detail),
priority: priority ? priority : "low",
email,
type: type ? type.toLowerCase() : "support",
createdBy: createdBy
? {
id: createdBy.id,
name: createdBy.name,
role: createdBy.role,
email: createdBy.email,
}
: undefined,
client:
company !== undefined
? {
connect: { id: company.id || company },
}
: undefined,
fromImap: false,
assignedTo:
engineer && engineer.name !== "Unassigned"
? {
connect: { id: engineer.id },
}
: undefined,
isComplete: Boolean(false),
},
});

if (!email && !validateEmail(email)) {
await sendTicketCreate(ticket);
}

if (engineer && engineer.name !== "Unassigned") {
const assgined = await prisma.user.findUnique({
where: {
id: ticket.userId,
},
});

await sendAssignedEmail(assgined!.email);

await assignedNotification(engineer.id, ticket);
}

const webhook = await prisma.webhooks.findMany({
where: {
type: "ticket_created",
},
});

for (let i = 0; i < webhook.length; i++) {
if (webhook[i].active === true) {
const message = {
event: "ticket_created",
id: ticket.id,
title: ticket.title,
priority: ticket.priority,
email: ticket.email,
name: ticket.name,
type: ticket.type,
createdBy: ticket.createdBy,
assignedTo: ticket.assignedTo,
client: ticket.client,
};

await sendWebhookNotification(webhook[i], message);
}
}

const hog = track();

hog.capture({
event: "ticket_created",
distinctId: ticket.id,
});

reply.status(200).send({
message: "Ticket created correctly",
success: true,
id: ticket.id,
});
}
);

// Get a ticket by id - requires auth
fastify.get(
"/api/v1/ticket/:id",
Expand Down
40 changes: 25 additions & 15 deletions apps/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,39 @@ server.register(multer.contentParser);

registerRoutes(server);

server.get("/", {
schema: {
tags: ['health'], // This groups the endpoint under a category
description: 'Health check endpoint',
response: {
200: {
type: 'object',
properties: {
healthy: { type: 'boolean' }
}
}
}
server.get(
"/",
{
schema: {
tags: ["health"], // This groups the endpoint under a category
description: "Health check endpoint",
response: {
200: {
type: "object",
properties: {
healthy: { type: "boolean" },
},
},
},
},
},
async function (request, response) {
response.send({ healthy: true });
}
}, async function (request, response) {
response.send({ healthy: true });
});
);

// JWT authentication hook
server.addHook("preHandler", async function (request: any, reply: any) {
try {
if (request.url === "/api/v1/auth/login" && request.method === "POST") {
return true;
}
if (
request.url === "/api/v1/ticket/public/create" &&
request.method === "POST"
) {
return true;
}
const bearer = request.headers.authorization!.split(" ")[1];
checkToken(bearer);
} catch (err) {
Expand Down
19 changes: 8 additions & 11 deletions apps/client/components/TicketDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1319,17 +1319,14 @@ export default function Ticket() {

<ContextMenuSeparator />

<ContextMenuItem
className="text-red-600"
onClick={(e) => {
e.preventDefault();
if (confirm("Are you sure you want to delete this ticket?")) {
deleteIssue(data.ticket.id);
}
}}
>
Delete Ticket
</ContextMenuItem>
{user.isAdmin && (
<ContextMenuItem
className="text-red-600"
onClick={(e) => deleteIssue(data.ticket.id)}
>
Delete Ticket
</ContextMenuItem>
)}
</ContextMenuContent>
</ContextMenu>
)}
Expand Down
77 changes: 46 additions & 31 deletions apps/client/pages/issues/closed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +84,38 @@ export default function Tickets() {

const [filterSelected, setFilterSelected] = useState();
const [selectedPriorities, setSelectedPriorities] = useState<string[]>(() => {
const saved = localStorage.getItem('closed_selectedPriorities');
const saved = localStorage.getItem("closed_selectedPriorities");
return saved ? JSON.parse(saved) : [];
});
const [selectedStatuses, setSelectedStatuses] = useState<string[]>(() => {
const saved = localStorage.getItem('closed_selectedStatuses');
const saved = localStorage.getItem("closed_selectedStatuses");
return saved ? JSON.parse(saved) : [];
});
const [selectedAssignees, setSelectedAssignees] = useState<string[]>(() => {
const saved = localStorage.getItem('closed_selectedAssignees');
const saved = localStorage.getItem("closed_selectedAssignees");
return saved ? JSON.parse(saved) : [];
});
const [users, setUsers] = useState<any[]>([]);

useEffect(() => {
localStorage.setItem('closed_selectedPriorities', JSON.stringify(selectedPriorities));
localStorage.setItem(
"closed_selectedPriorities",
JSON.stringify(selectedPriorities)
);
}, [selectedPriorities]);

useEffect(() => {
localStorage.setItem('closed_selectedStatuses', JSON.stringify(selectedStatuses));
localStorage.setItem(
"closed_selectedStatuses",
JSON.stringify(selectedStatuses)
);
}, [selectedStatuses]);

useEffect(() => {
localStorage.setItem('closed_selectedAssignees', JSON.stringify(selectedAssignees));
localStorage.setItem(
"closed_selectedAssignees",
JSON.stringify(selectedAssignees)
);
}, [selectedAssignees]);

const handlePriorityToggle = (priority: string) => {
Expand Down Expand Up @@ -715,30 +724,36 @@ export default function Tickets() {
Share Link
</ContextMenuItem>

<ContextMenuSeparator />

<ContextMenuItem
className="text-red-600"
onClick={(e) => {
e.preventDefault();
if (
confirm(
"Are you sure you want to delete this ticket?"
)
) {
fetch(`/api/v1/ticket/delete`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ id: ticket.id }),
});
}
}}
>
Delete Ticket
</ContextMenuItem>
{user.isAdmin && (
<>
<ContextMenuSeparator />

<ContextMenuItem
className="text-red-600"
onClick={(e) => {
e.preventDefault();
if (
confirm(
"Are you sure you want to delete this ticket?"
)
) {
fetch(`/api/v1/ticket/delete`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ id: ticket.id }),
}).then(() => {
refetch();
});
}
}}
>
Delete Ticket
</ContextMenuItem>
</>
)}
</ContextMenuContent>
</ContextMenu>
);
Expand All @@ -749,7 +764,7 @@ export default function Tickets() {
type="button"
className="relative block w-[400px] rounded-lg border-2 border-dashed border-gray-300 p-12 text-center hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
onClick={() => {
const event = new KeyboardEvent('keydown', { key: 'c' });
const event = new KeyboardEvent("keydown", { key: "c" });
document.dispatchEvent(event);
}}
>
Expand Down
Loading

0 comments on commit 0301576

Please sign in to comment.