Bridge integration

This commit is contained in:
Darren Clarke 2024-05-09 07:42:44 +02:00
parent 42a5e09c94
commit 162390008b
56 changed files with 776 additions and 591 deletions

View file

@ -1,18 +1,12 @@
"use client";
import { FC, useEffect, useState } from "react";
import { FC, useState } from "react";
import useSWR from "swr";
import { getTicketQuery } from "app/_graphql/getTicketQuery";
import { getTicketArticlesQuery } from "app/_graphql/getTicketArticlesQuery";
import {
Grid,
Box,
Typography,
Button,
// Dialog,
// DialogActions,
// DialogContent,
} from "@mui/material";
import { Grid, Box, Typography } from "@mui/material";
import { Button, fonts, colors } from "ui";
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import {
MainContainer,
@ -28,6 +22,8 @@ interface TicketDetailProps {
}
export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
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(
@ -52,7 +48,6 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
});
const closeDialog = () => setDialogOpen(false);
console.log({ recentViewData, recentViewError });
const ticket = ticketData?.ticket;
const ticketArticles = ticketArticlesData?.ticketArticles;
@ -79,13 +74,19 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
>
<Typography
variant="h5"
sx={{ fontFamily: "Poppins", fontWeight: 700 }}
sx={{
fontFamily: poppins.style.fontFamily,
fontWeight: 700,
}}
>
{ticket.title}
</Typography>
<Typography
variant="h6"
sx={{ fontFamily: "Roboto", fontWeight: 400 }}
sx={{
fontFamily: roboto.style.fontFamily,
fontWeight: 400,
}}
>{`Ticket #${ticket.number} (created ${new Date(
ticket.createdAt,
).toLocaleDateString()})`}</Typography>
@ -118,8 +119,8 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
<Box
sx={{
height: 80,
background: "#eeeeee",
borderTop: "1px solid #ddd",
background: veryLightGray,
borderTop: `1px solid ${lightGray}`,
position: "absolute",
bottom: 0,
width: "100%",
@ -128,59 +129,31 @@ export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
>
<Grid
container
spacing={4}
spacing={6}
justifyContent="center"
alignItems="center"
alignContent="center"
sx={{ height: "100%", pt: 6 }}
>
<Grid item>
<Button
variant="contained"
disableElevation
sx={{
fontFamily: "Poppins, sans-serif",
fontWeight: 700,
borderRadius: 2,
textTransform: "none",
backgroundColor: "#1982FC",
padding: "6px 30px",
margin: "20px 0px",
whiteSpace: "nowrap",
py: "10px",
mt: 2,
}}
onClick={() => {
setArticleKind(firstArticleKind);
setDialogOpen(true);
}}
>
Reply to ticket
</Button>
</Grid>
<Grid item>
<Button
variant="contained"
disableElevation
sx={{
fontFamily: "Poppins, sans-serif",
fontWeight: 700,
borderRadius: 2,
textTransform: "none",
color: "black",
backgroundColor: "#FFB620",
padding: "6px 30px",
margin: "20px 0px",
whiteSpace: "nowrap",
py: "10px",
mt: 2,
}}
text="Write note to agent"
color="#FFB620"
onClick={() => {
setArticleKind("note");
setDialogOpen(true);
}}
>
Write note to agent
</Button>
/>
</Grid>
<Grid item>
<Button
text="Reply to ticket"
kind="primary"
onClick={() => {
setArticleKind(firstArticleKind);
setDialogOpen(true);
}}
/>
</Grid>
</Grid>
</Box>

View file

@ -1,35 +1,23 @@
"use client";
import { FC, useEffect, useState } from "react";
import {
Grid,
Box,
// Typography,
// TextField,
// Stack,
Select,
MenuItem,
} from "@mui/material";
import { Grid, Box, MenuItem } from "@mui/material";
import { useFormState } from "react-dom";
import { Select, Button } from "ui";
import { MuiChipsInput } from "mui-chips-input";
import useSWR, { useSWRConfig } from "swr";
import { getTicketQuery } from "app/_graphql/getTicketQuery";
import { updateTicketMutation } from "app/_graphql/updateTicketMutation";
import { updateTagsMutation } from "app/_graphql/updateTagsMutation";
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import { updateTicketAction } from "app/_actions/tickets";
interface TicketEditProps {
id: string;
}
export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
const [selectedGroup, setSelectedGroup] = useState("");
const [selectedOwner, setSelectedOwner] = useState("");
const [selectedPriority, setSelectedPriority] = useState("");
const [selectedState, setSelectedState] = useState("");
const [pendingDate, setPendingDate] = useState(new Date());
const [pendingVisible, setPendingVisible] = useState(false);
const [selectedTags, setSelectedTags] = useState([]);
const selectedTags = [];
const pendingVisible = false;
const pendingDate = new Date();
const handleDelete = () => {
console.info("You clicked the delete icon.");
};
@ -58,24 +46,28 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
const ticket = ticketData?.ticket;
if (ticket) {
const groupID = ticket.group.id?.split("/").pop();
setSelectedGroup(groupID);
// setSelectedGroup(groupID);
const ownerID = ticket.owner.id?.split("/").pop();
setSelectedOwner(ownerID);
// setSelectedOwner(ownerID);
const priorityID = ticket.priority.id?.split("/").pop();
setSelectedPriority(priorityID);
// setSelectedPriority(priorityID);
const stateID = ticket.state.id?.split("/").pop();
setSelectedState(stateID);
setSelectedTags(ticket.tags);
// setSelectedState(stateID);
// setSelectedTags(ticket.tags);
}
}, [ticketData, ticketError]);
/*
useEffect(() => {
const stateName = filteredStates?.find(
(state: any) => state.id === selectedState,
)?.name;
setPendingVisible(stateName?.includes("pending") ?? false);
}, [selectedState]);
*/
const updateTicket = async (input: any) => {
/*
console.log({ input });
const res = await fetcher({
document: updateTicketMutation,
@ -85,8 +77,10 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
},
});
console.log({ res });
*/
};
const updateTags = async (tags: string[]) => {
/*
console.log({ tags });
const res = await fetcher({
document: updateTagsMutation,
@ -96,144 +90,175 @@ export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
},
});
console.log({ res });
*/
};
const initialState = {
messages: [],
errors: [],
values: {
customer: "",
group: "",
owner: "",
priority: "",
state: "",
tags: [],
title: "",
article: {
body: "",
type: "note",
internal: true,
},
},
};
const [formState, formAction] = useFormState(
updateTicketAction,
initialState,
);
const shouldRender = ticketData && !ticketError;
return (
shouldRender && (
<Box sx={{ height: "100vh", background: "#ddd", p: 2 }}>
<Grid container direction="column" spacing={3}>
<Grid item>
<Box sx={{ m: 1 }}>Group</Box>
<Select
defaultValue={selectedGroup}
value={selectedGroup}
onChange={(e: any) => {
const newGroup = e.target.value;
setSelectedGroup(newGroup);
updateTicket({
groupId: `gid://zammad/Group/${newGroup}`,
});
}}
size="small"
sx={{
width: "100%",
backgroundColor: "white",
}}
<form action={formAction}>
<Grid container direction="column" spacing={3}>
<Grid item>
<Box sx={{ m: 1 }}>Group</Box>
<Select
name="group"
label="Group"
formState={formState}
getOptions={() =>
groups?.map((group: any) => ({
value: group.id,
label: group.name,
})) ?? []
}
/*
onChange={(e: any) => {
const newGroup = e.target.value;
setSelectedGroup(newGroup);
updateTicket({
groupId: `gid://zammad/Group/${newGroup}`,
});
}}
*/
/>
</Grid>
<Grid item>
<Box sx={{ m: 1, mt: 0 }}>Owner</Box>
<Select
name="owner"
label="Owner"
formState={formState}
getOptions={() =>
agents?.map((user: any) => ({
value: user.id,
label: `${user.firstname} ${user.lastname}`,
})) ?? []
}
/*
onChange={(e: any) => {
const newOwner = e.target.value;
setSelectedOwner(newOwner);
updateTicket({ ownerId: `gid://zammad/User/${newOwner}` });
}}
*/
/>
</Grid>
<Grid item xs={12}>
<Box sx={{ m: 1, mt: 0 }}>State</Box>
<Select
name="state"
label="State"
formState={formState}
getOptions={() =>
filteredStates?.map((state: any) => ({
value: state.id,
label: state.name,
})) ?? []
}
/*
onChange={(e: any) => {
const newState = e.target.value;
setSelectedState(newState);
updateTicket({
stateId: `gid://zammad/Ticket::State/${newState}`,
pendingTime: pendingDate.toISOString(),
});
}}
*/
/>
</Grid>
<Grid
item
xs={12}
sx={{ display: pendingVisible ? "inherit" : "none" }}
>
{groups?.map((group: any) => (
<MenuItem key={group.id} value={`${group.id}`}>
{group.name}
</MenuItem>
))}
</Select>
</Grid>
<Grid item>
<Box sx={{ m: 1, mt: 0 }}>Owner</Box>
<Select
value={selectedOwner}
onChange={(e: any) => {
const newOwner = e.target.value;
setSelectedOwner(newOwner);
updateTicket({ ownerId: `gid://zammad/User/${newOwner}` });
}}
size="small"
sx={{
width: "100%",
backgroundColor: "white",
}}
>
{agents?.map((user: any) => (
<MenuItem key={user.id} value={`${user.id}`}>
{user.firstname} {user.lastname}
</MenuItem>
))}
</Select>
</Grid>
<Grid item xs={12}>
<Box sx={{ m: 1, mt: 0 }}>State</Box>
<Select
value={selectedState}
onChange={(e: any) => {
const newState = e.target.value;
setSelectedState(newState);
updateTicket({
stateId: `gid://zammad/Ticket::State/${newState}`,
pendingTime: pendingDate.toISOString(),
});
}}
size="small"
sx={{
width: "100%",
backgroundColor: "white",
}}
>
{filteredStates?.map((state: any) => (
<MenuItem key={state.id} value={state.id}>
{state.name}
</MenuItem>
))}
</Select>
</Grid>
<Grid
item
xs={12}
sx={{ display: pendingVisible ? "inherit" : "none" }}
>
<DatePicker
label="Pending Date"
value={pendingDate}
onChange={(newValue: any) => {
console.log(newValue);
setPendingDate(newValue);
updateTicket({
pendingTime: newValue.toISOString(),
});
}}
slotProps={{ textField: { size: "small" } }}
sx={{
width: "100%",
backgroundColor: "white",
}}
/>
</Grid>
<Grid item>
<Box sx={{ m: 1, mt: 0 }}>Priority</Box>
<Select
value={selectedPriority}
onChange={(e: any) => {
const newPriority = e.target.value;
setSelectedPriority(newPriority);
updateTicket({
priorityId: `gid://zammad/Ticket::Priority/${newPriority}`,
});
}}
size="small"
sx={{
width: "100%",
backgroundColor: "white",
}}
>
{priorities?.map((priority: any) => (
<MenuItem key={priority.id} value={priority.id}>
{priority.name}
</MenuItem>
))}
</Select>
</Grid>
{/* <DatePicker
label="Pending Date"
value={pendingDate}
onChange={(newValue: any) => {
<Grid item>
<Box sx={{ mb: 1 }}>Tags</Box>
<MuiChipsInput
sx={{ backgroundColor: "white", width: "100%" }}
value={selectedTags}
onChange={(tags: any) => {
setSelectedTags(tags);
updateTags(tags);
}}
/>
console.log(newValue);
setPendingDate(newValue);
updateTicket({
pendingTime: newValue.toISOString(),
})
}}
slotProps={{ textField: { size: "small" } }}
sx={{
width: "100%",
backgroundColor: "white",
}}
/> */}
</Grid>
<Grid item>
<Box sx={{ m: 1, mt: 0 }}>Priority</Box>
<Select
name="priority"
label="Priority"
formState={formState}
getOptions={() =>
priorities?.map((priority: any) => ({
value: priority.id,
label: priority.name,
})) ?? []
}
/*
onChange={(e: any) => {
const newPriority = e.target.value;
setSelectedPriority(newPriority);
updateTicket({
priorityId: `gid://zammad/Ticket::Priority/${newPriority}`,
});
}}
*/
/>
</Grid>
<Grid item>
<Box sx={{ mb: 1 }}>Tags</Box>
<MuiChipsInput
sx={{ backgroundColor: "white", width: "100%" }}
value={selectedTags}
onChange={(tags: any) => {
/*
setSelectedTags(tags);
updateTags(tags);
*/
}}
/>
</Grid>
<Grid item container direction="row-reverse">
<Grid item>
<Button text="Save" kind="primary" type="submit" />
</Grid>
</Grid>
</Grid>
</Grid>
</form>
</Box>
)
);