a ticket must be assigned to someone when creating
This commit is contained in:
parent
b8d67f7926
commit
52c9a42e42
|
|
@ -19,7 +19,7 @@ import {
|
||||||
Typography
|
Typography
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import AttachFileIcon from '@mui/icons-material/AttachFile';
|
import AttachFileIcon from '@mui/icons-material/AttachFile';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage, useIntl } from 'react-intl';
|
||||||
import axiosConfig from 'src/Resources/axiosConfig';
|
import axiosConfig from 'src/Resources/axiosConfig';
|
||||||
import {
|
import {
|
||||||
TicketPriority,
|
TicketPriority,
|
||||||
|
|
@ -28,7 +28,8 @@ import {
|
||||||
subCategoryLabels,
|
subCategoryLabels,
|
||||||
subCategoriesByCategory,
|
subCategoriesByCategory,
|
||||||
categoryLabels,
|
categoryLabels,
|
||||||
otherSubCategoryValues
|
otherSubCategoryValues,
|
||||||
|
AdminUser
|
||||||
} from 'src/interfaces/TicketTypes';
|
} from 'src/interfaces/TicketTypes';
|
||||||
|
|
||||||
type Installation = {
|
type Installation = {
|
||||||
|
|
@ -65,6 +66,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }: Props) {
|
function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }: Props) {
|
||||||
|
const intl = useIntl();
|
||||||
const [subject, setSubject] = useState('');
|
const [subject, setSubject] = useState('');
|
||||||
const [selectedProduct, setSelectedProduct] = useState<number | ''>('');
|
const [selectedProduct, setSelectedProduct] = useState<number | ''>('');
|
||||||
const [selectedDevice, setSelectedDevice] = useState<number | ''>('');
|
const [selectedDevice, setSelectedDevice] = useState<number | ''>('');
|
||||||
|
|
@ -73,6 +75,8 @@ function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }:
|
||||||
useState<Installation | null>(null);
|
useState<Installation | null>(null);
|
||||||
const [loadingInstallations, setLoadingInstallations] = useState(false);
|
const [loadingInstallations, setLoadingInstallations] = useState(false);
|
||||||
const [priority, setPriority] = useState<number>(TicketPriority.Medium);
|
const [priority, setPriority] = useState<number>(TicketPriority.Medium);
|
||||||
|
const [assigneeId, setAssigneeId] = useState<number | ''>('');
|
||||||
|
const [adminUsers, setAdminUsers] = useState<AdminUser[]>([]);
|
||||||
const [category, setCategory] = useState<number>(TicketCategory.Hardware);
|
const [category, setCategory] = useState<number>(TicketCategory.Hardware);
|
||||||
const [subCategory, setSubCategory] = useState<number>(
|
const [subCategory, setSubCategory] = useState<number>(
|
||||||
TicketSubCategory.Battery
|
TicketSubCategory.Battery
|
||||||
|
|
@ -189,6 +193,16 @@ function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }:
|
||||||
.finally(() => setLoadingInstallations(false));
|
.finally(() => setLoadingInstallations(false));
|
||||||
}, [selectedProduct]);
|
}, [selectedProduct]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!open) return;
|
||||||
|
axiosConfig
|
||||||
|
.get('/GetAdminUsers')
|
||||||
|
.then((res) => {
|
||||||
|
if (Array.isArray(res.data)) setAdminUsers(res.data);
|
||||||
|
})
|
||||||
|
.catch(() => setAdminUsers([]));
|
||||||
|
}, [open]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (defaultInstallationId == null || !open) return;
|
if (defaultInstallationId == null || !open) return;
|
||||||
axiosConfig
|
axiosConfig
|
||||||
|
|
@ -233,6 +247,7 @@ function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }:
|
||||||
setAllInstallations([]);
|
setAllInstallations([]);
|
||||||
setSelectedInstallation(null);
|
setSelectedInstallation(null);
|
||||||
setPriority(TicketPriority.Medium);
|
setPriority(TicketPriority.Medium);
|
||||||
|
setAssigneeId('');
|
||||||
setCategory(TicketCategory.Hardware);
|
setCategory(TicketCategory.Hardware);
|
||||||
setSubCategory(TicketSubCategory.Battery);
|
setSubCategory(TicketSubCategory.Battery);
|
||||||
setDescription('');
|
setDescription('');
|
||||||
|
|
@ -244,6 +259,15 @@ function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }:
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!subject.trim()) return;
|
if (!subject.trim()) return;
|
||||||
|
if (assigneeId === '') {
|
||||||
|
setError(
|
||||||
|
intl.formatMessage({
|
||||||
|
id: 'assigneeRequired',
|
||||||
|
defaultMessage: 'Please assign this ticket to someone before creating it.'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
setError('');
|
setError('');
|
||||||
|
|
||||||
|
|
@ -253,6 +277,7 @@ function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }:
|
||||||
description,
|
description,
|
||||||
installationId: selectedInstallation?.id ?? null,
|
installationId: selectedInstallation?.id ?? null,
|
||||||
priority,
|
priority,
|
||||||
|
assigneeId,
|
||||||
category,
|
category,
|
||||||
subCategory: isOtherCategory ? 0 : subCategory,
|
subCategory: isOtherCategory ? 0 : subCategory,
|
||||||
customSubCategory: (isOtherSubCategory || isOtherCategory) ? customSubCategory || null : null,
|
customSubCategory: (isOtherSubCategory || isOtherCategory) ? customSubCategory || null : null,
|
||||||
|
|
@ -390,6 +415,33 @@ function CreateTicketModal({ open, onClose, onCreated, defaultInstallationId }:
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FormControl fullWidth margin="dense" required error={assigneeId === ''}>
|
||||||
|
<InputLabel>
|
||||||
|
<FormattedMessage id="assignee" defaultMessage="Assignee" />
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={assigneeId}
|
||||||
|
label="Assignee"
|
||||||
|
onChange={(e) =>
|
||||||
|
setAssigneeId(e.target.value === '' ? '' : Number(e.target.value))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{adminUsers
|
||||||
|
.filter((u) => {
|
||||||
|
const name = (u.name ?? '').toLowerCase();
|
||||||
|
return (
|
||||||
|
!name.includes('inesco energy master admin') &&
|
||||||
|
!name.includes('paal myhre')
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map((u) => (
|
||||||
|
<MenuItem key={u.id} value={u.id}>
|
||||||
|
{u.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
<FormControl fullWidth margin="dense">
|
<FormControl fullWidth margin="dense">
|
||||||
<InputLabel>
|
<InputLabel>
|
||||||
<FormattedMessage id="priority" defaultMessage="Priority" />
|
<FormattedMessage id="priority" defaultMessage="Priority" />
|
||||||
|
|
|
||||||
|
|
@ -591,11 +591,19 @@ function TicketDetailPage() {
|
||||||
/>
|
/>
|
||||||
</em>
|
</em>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{adminUsers.map((u) => (
|
{adminUsers
|
||||||
<MenuItem key={u.id} value={u.id}>
|
.filter((u) => {
|
||||||
{u.name}
|
const name = (u.name ?? '').toLowerCase();
|
||||||
</MenuItem>
|
return (
|
||||||
))}
|
!name.includes('inesco energy master admin') &&
|
||||||
|
!name.includes('paal myhre')
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map((u) => (
|
||||||
|
<MenuItem key={u.id} value={u.id}>
|
||||||
|
{u.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -574,6 +574,7 @@
|
||||||
"resolvedAt": "Gelöst",
|
"resolvedAt": "Gelöst",
|
||||||
"noDescription": "Keine Beschreibung vorhanden.",
|
"noDescription": "Keine Beschreibung vorhanden.",
|
||||||
"assignee": "Zuständig",
|
"assignee": "Zuständig",
|
||||||
|
"assigneeRequired": "Bitte weisen Sie dieses Ticket jemandem zu, bevor Sie es erstellen.",
|
||||||
"unassigned": "Nicht zugewiesen",
|
"unassigned": "Nicht zugewiesen",
|
||||||
"deleteTicket": "Löschen",
|
"deleteTicket": "Löschen",
|
||||||
"confirmDeleteTicket": "Ticket löschen?",
|
"confirmDeleteTicket": "Ticket löschen?",
|
||||||
|
|
|
||||||
|
|
@ -322,6 +322,7 @@
|
||||||
"resolvedAt": "Resolved",
|
"resolvedAt": "Resolved",
|
||||||
"noDescription": "No description provided.",
|
"noDescription": "No description provided.",
|
||||||
"assignee": "Assignee",
|
"assignee": "Assignee",
|
||||||
|
"assigneeRequired": "Please assign this ticket to someone before creating it.",
|
||||||
"unassigned": "Unassigned",
|
"unassigned": "Unassigned",
|
||||||
"deleteTicket": "Delete",
|
"deleteTicket": "Delete",
|
||||||
"confirmDeleteTicket": "Delete Ticket?",
|
"confirmDeleteTicket": "Delete Ticket?",
|
||||||
|
|
|
||||||
|
|
@ -574,6 +574,7 @@
|
||||||
"resolvedAt": "Résolu",
|
"resolvedAt": "Résolu",
|
||||||
"noDescription": "Aucune description fournie.",
|
"noDescription": "Aucune description fournie.",
|
||||||
"assignee": "Responsable",
|
"assignee": "Responsable",
|
||||||
|
"assigneeRequired": "Veuillez assigner ce ticket à quelqu'un avant de le créer.",
|
||||||
"unassigned": "Non assigné",
|
"unassigned": "Non assigné",
|
||||||
"deleteTicket": "Supprimer",
|
"deleteTicket": "Supprimer",
|
||||||
"confirmDeleteTicket": "Supprimer le ticket ?",
|
"confirmDeleteTicket": "Supprimer le ticket ?",
|
||||||
|
|
|
||||||
|
|
@ -574,6 +574,7 @@
|
||||||
"resolvedAt": "Risolto",
|
"resolvedAt": "Risolto",
|
||||||
"noDescription": "Nessuna descrizione fornita.",
|
"noDescription": "Nessuna descrizione fornita.",
|
||||||
"assignee": "Assegnatario",
|
"assignee": "Assegnatario",
|
||||||
|
"assigneeRequired": "Assegna questo ticket a qualcuno prima di crearlo.",
|
||||||
"unassigned": "Non assegnato",
|
"unassigned": "Non assegnato",
|
||||||
"deleteTicket": "Elimina",
|
"deleteTicket": "Elimina",
|
||||||
"confirmDeleteTicket": "Eliminare il ticket?",
|
"confirmDeleteTicket": "Eliminare il ticket?",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue