Use server actions instead of client-side API calls
This commit is contained in:
parent
5a3127dcb0
commit
aa453954ed
30 changed files with 703 additions and 462 deletions
|
|
@ -9,8 +9,7 @@ import {
|
|||
DialogContent,
|
||||
TextField,
|
||||
} from "@mui/material";
|
||||
import { useSWRConfig } from "swr";
|
||||
import { updateTicketMutation } from "app/_graphql/updateTicketMutation";
|
||||
import { createTicketArticleAction } from "app/_actions/tickets";
|
||||
|
||||
interface ArticleCreateDialogProps {
|
||||
ticketID: string;
|
||||
|
|
@ -30,7 +29,6 @@ export const ArticleCreateDialog: FC<ArticleCreateDialogProps> = ({
|
|||
const [body, setBody] = useState("");
|
||||
const backgroundColor = kind === "note" ? "#FFB620" : "#1982FC";
|
||||
const color = kind === "note" ? "black" : "white";
|
||||
const { fetcher } = useSWRConfig();
|
||||
const article = {
|
||||
body,
|
||||
type: kind,
|
||||
|
|
@ -42,15 +40,7 @@ export const ArticleCreateDialog: FC<ArticleCreateDialogProps> = ({
|
|||
}
|
||||
|
||||
const createArticle = async () => {
|
||||
await fetcher({
|
||||
document: updateTicketMutation,
|
||||
variables: {
|
||||
ticketId: `gid://zammad/Ticket/${ticketID}`,
|
||||
input: {
|
||||
article,
|
||||
},
|
||||
},
|
||||
});
|
||||
await createTicketArticleAction(ticketID, article);
|
||||
closeDialog();
|
||||
setBody("");
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
"use client";
|
||||
|
||||
import { FC, useState } from "react";
|
||||
import useSWR from "swr";
|
||||
import { getTicketQuery } from "app/_graphql/getTicketQuery";
|
||||
import { getTicketArticlesQuery } from "app/_graphql/getTicketArticlesQuery";
|
||||
import { FC, useState, useEffect } from "react";
|
||||
import { getTicketAction, getTicketArticlesAction } from "app/_actions/tickets";
|
||||
import { Grid, Box, Typography } from "@mui/material";
|
||||
import { Button, fonts, colors } from "@link-stack/ui";
|
||||
|
||||
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
|
||||
import {
|
||||
MainContainer,
|
||||
|
|
@ -22,41 +19,46 @@ interface TicketDetailProps {
|
|||
}
|
||||
|
||||
export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
|
||||
const [ticket, setTicket] = useState<any>(null);
|
||||
const [ticketArticles, setTicketArticles] = useState<any>(null);
|
||||
const { poppins, roboto } = fonts;
|
||||
const { veryLightGray, lightGray } = colors;
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [articleKind, setArticleKind] = useState("note");
|
||||
const { data: ticketData, error: ticketError }: any = useSWR(
|
||||
{
|
||||
document: getTicketQuery,
|
||||
variables: { ticketId: `gid://zammad/Ticket/${id}` },
|
||||
},
|
||||
{ refreshInterval: 10000 },
|
||||
);
|
||||
const { data: ticketArticlesData, error: ticketArticlesError }: any = useSWR(
|
||||
{
|
||||
document: getTicketArticlesQuery,
|
||||
variables: { ticketId: `gid://zammad/Ticket/${id}` },
|
||||
},
|
||||
{ refreshInterval: 2000 },
|
||||
);
|
||||
|
||||
const { data: recentViewData, error: recentViewError }: any = useSWR({
|
||||
url: "/api/v1/recent_view",
|
||||
method: "POST",
|
||||
body: JSON.stringify({ object: "Ticket", o_id: id }),
|
||||
});
|
||||
useEffect(() => {
|
||||
const fetchTicket = async () => {
|
||||
const result = await getTicketAction(id);
|
||||
setTicket(result);
|
||||
};
|
||||
|
||||
fetchTicket();
|
||||
|
||||
const interval = setInterval(fetchTicket, 20000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [id]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTicketArticles = async () => {
|
||||
const result = await getTicketArticlesAction(id);
|
||||
setTicketArticles(result);
|
||||
};
|
||||
|
||||
fetchTicketArticles();
|
||||
|
||||
const interval = setInterval(fetchTicketArticles, 2000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [id]);
|
||||
|
||||
const closeDialog = () => setDialogOpen(false);
|
||||
|
||||
const ticket = ticketData?.ticket;
|
||||
const ticketArticles = ticketArticlesData?.ticketArticles;
|
||||
const firstArticle = ticketArticles?.edges[0]?.node;
|
||||
const firstArticleKind = firstArticle?.type?.name ?? "phone";
|
||||
const firstEmailSender = firstArticle?.from?.parsed?.[0]?.emailAddress ?? "";
|
||||
const recipient = firstEmailSender;
|
||||
const shouldRender =
|
||||
ticketData && !ticketError && ticketArticlesData && !ticketArticlesError;
|
||||
const shouldRender = !!ticket && !!ticketArticles;
|
||||
|
||||
return (
|
||||
shouldRender && (
|
||||
|
|
|
|||
|
|
@ -5,57 +5,87 @@ import { Grid, Box, MenuItem } from "@mui/material";
|
|||
import { useFormState } from "react-dom";
|
||||
import { Select, Button } from "@link-stack/ui";
|
||||
import { MuiChipsInput } from "mui-chips-input";
|
||||
import useSWR, { useSWRConfig } from "swr";
|
||||
import { getTicketQuery } from "app/_graphql/getTicketQuery";
|
||||
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
||||
import { updateTicketAction } from "app/_actions/tickets";
|
||||
import {
|
||||
updateTicketAction,
|
||||
getTicketAction,
|
||||
getTicketStatesAction,
|
||||
getTicketPrioritiesAction,
|
||||
getTicketTagsAction,
|
||||
} from "app/_actions/tickets";
|
||||
import { getAgentsAction } from "app/_actions/users";
|
||||
import { getGroupsAction } from "app/_actions/groups";
|
||||
|
||||
interface TicketEditProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
||||
const [ticket, setTicket] = useState<any>();
|
||||
const [ticketStates, setTicketStates] = useState<any>();
|
||||
const [ticketPriorities, setTicketPriorities] = useState<any>();
|
||||
const [groups, setGroups] = useState<any>();
|
||||
const [tags, setTags] = useState<any>();
|
||||
const [agents, setAgents] = useState<any>();
|
||||
const selectedTags = [];
|
||||
const pendingVisible = false;
|
||||
const pendingDate = new Date();
|
||||
const handleDelete = () => {
|
||||
console.info("You clicked the delete icon.");
|
||||
};
|
||||
const restFetcher = (url: string) => fetch(url).then((r) => r.json());
|
||||
|
||||
const { data: groups } = useSWR("/api/v1/groups", restFetcher);
|
||||
const { data: users } = useSWR("/api/v1/users", restFetcher);
|
||||
const { data: states } = useSWR("/api/v1/ticket_states", restFetcher);
|
||||
const { data: priorities } = useSWR("/api/v1/ticket_priorities", restFetcher);
|
||||
const { data: recent } = useSWR("/api/v1/recent_view", restFetcher);
|
||||
|
||||
// const { data: tags } = useSWR("/api/v1/tags", restFetcher);
|
||||
const filteredStates = states?.filter(
|
||||
const filteredStates = ticketStates?.filter(
|
||||
(state: any) => !["new", "merged", "removed"].includes(state.name),
|
||||
);
|
||||
const agents = users?.filter((user: any) => user.role_ids.includes(2)) ?? [];
|
||||
const { fetcher } = useSWRConfig();
|
||||
const { data: ticketData, error: ticketError }: any = useSWR(
|
||||
{
|
||||
document: getTicketQuery,
|
||||
variables: { ticketId: `gid://zammad/Ticket/${id}` },
|
||||
},
|
||||
{ refreshInterval: 10000 },
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const ticket = ticketData?.ticket;
|
||||
if (ticket) {
|
||||
const groupID = ticket.group.id?.split("/").pop();
|
||||
// setSelectedGroup(groupID);
|
||||
const ownerID = ticket.owner.id?.split("/").pop();
|
||||
// setSelectedOwner(ownerID);
|
||||
const priorityID = ticket.priority.id?.split("/").pop();
|
||||
// setSelectedPriority(priorityID);
|
||||
const stateID = ticket.state.id?.split("/").pop();
|
||||
// setSelectedState(stateID);
|
||||
// setSelectedTags(ticket.tags);
|
||||
}
|
||||
}, [ticketData, ticketError]);
|
||||
const fetchAgents = async () => {
|
||||
const result = await getAgentsAction();
|
||||
console.log({ result });
|
||||
setAgents(result);
|
||||
};
|
||||
|
||||
const fetchGroups = async () => {
|
||||
const result = await getGroupsAction();
|
||||
console.log({ result });
|
||||
setGroups(result);
|
||||
};
|
||||
|
||||
const fetchTicketStates = async () => {
|
||||
const result = await getTicketStatesAction();
|
||||
console.log({ result });
|
||||
setTicketStates(result);
|
||||
};
|
||||
|
||||
const fetchTicketPriorities = async () => {
|
||||
const result = await getTicketPrioritiesAction();
|
||||
console.log({ result });
|
||||
setTicketPriorities(result);
|
||||
};
|
||||
|
||||
const fetchTicketTags = async () => {
|
||||
const result = await getTicketTagsAction();
|
||||
console.log({ result });
|
||||
setTags(result);
|
||||
};
|
||||
|
||||
fetchTicketStates();
|
||||
fetchTicketPriorities();
|
||||
fetchTicketTags();
|
||||
fetchAgents();
|
||||
fetchGroups();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchTicket = async () => {
|
||||
const result = await getTicketAction(id);
|
||||
console.log({ result });
|
||||
setTicket(result);
|
||||
};
|
||||
|
||||
fetchTicket();
|
||||
}, []);
|
||||
|
||||
/*
|
||||
useEffect(() => {
|
||||
|
|
@ -97,10 +127,10 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
|||
errors: [],
|
||||
values: {
|
||||
customer: "",
|
||||
group: "",
|
||||
owner: "",
|
||||
priority: "",
|
||||
state: "",
|
||||
group: ticket.group.id?.split("/").pop(),
|
||||
owner: ticket.owner.id?.split("/").pop(),
|
||||
priority: ticket.priority.id?.split("/").pop(),
|
||||
state: ticket.state.id?.split("/").pop(),
|
||||
tags: [],
|
||||
title: "",
|
||||
article: {
|
||||
|
|
@ -114,7 +144,7 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
|||
updateTicketAction,
|
||||
initialState,
|
||||
);
|
||||
const shouldRender = ticketData && !ticketError;
|
||||
const shouldRender = !!ticket;
|
||||
|
||||
return (
|
||||
shouldRender && (
|
||||
|
|
@ -220,7 +250,7 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
|
|||
label="Priority"
|
||||
formState={formState}
|
||||
getOptions={() =>
|
||||
priorities?.map((priority: any) => ({
|
||||
ticketPriorities?.map((priority: any) => ({
|
||||
value: priority.id,
|
||||
label: priority.name,
|
||||
})) ?? []
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
type PageProps = {
|
||||
params: {
|
||||
id: string;
|
||||
};
|
||||
};
|
||||
|
||||
export default function Page({ params: { id } }: PageProps) {
|
||||
return <div>Page</div>;
|
||||
}
|
||||
|
||||
/*
|
||||
import { GetServerSideProps, GetServerSidePropsContext } from "next";
|
||||
import Head from "next/head";
|
||||
import useSWR from "swr";
|
||||
import { NextPage } from "next";
|
||||
import { Grid } from "@mui/material";
|
||||
import { TicketDetail } from "../_components/TicketDetail";
|
||||
import { TicketEdit } from "../_components/TicketEdit";
|
||||
import { getTicketQuery } from "../_graphql/getTicketQuery";
|
||||
|
||||
type TicketProps = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
const Ticket: NextPage<TicketProps> = ({ id }) => {
|
||||
const { data: ticketData, error: ticketError }: any = useSWR(
|
||||
{
|
||||
document: getTicketQuery,
|
||||
variables: { ticketId: `gid://zammad/Ticket/${id}` },
|
||||
},
|
||||
{ refreshInterval: 100000 }
|
||||
);
|
||||
|
||||
const shouldRender = !ticketError && ticketData;
|
||||
|
||||
return (
|
||||
<>
|
||||
{shouldRender && (
|
||||
<Grid container spacing={0} sx={{ height: "100vh" }} direction="row">
|
||||
<Grid item sx={{ height: "100vh" }} xs={9}>
|
||||
<TicketDetail ticket={ticketData.ticket} />
|
||||
</Grid>
|
||||
<Grid item xs={3} sx={{ height: "100vh" }}>
|
||||
<TicketEdit ticket={ticketData.ticket} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
{ticketError && <div>{ticketError.toString()}</div>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (
|
||||
context: GetServerSidePropsContext
|
||||
) => {
|
||||
const { id } = context.query;
|
||||
return { props: { id } };
|
||||
};
|
||||
|
||||
|
||||
export default Ticket;
|
||||
*/
|
||||
Loading…
Add table
Add a link
Reference in a new issue