mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-29 19:58:13 +00:00
114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { Modal, Select, Stack, Text, Textarea } from '@mantine/core';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useGetAssignableOfficersQuery } from '@ema-platform/api';
|
|
import { ModalFooter } from '@ema-platform/ui';
|
|
import { Button } from '@mantine/core';
|
|
|
|
export type AssignKind = 'review' | 'inspection';
|
|
|
|
interface AssignDialogProps {
|
|
opened: boolean;
|
|
onClose: () => void;
|
|
/** Which stage is being handed out — changes the wording, not the mechanics. */
|
|
kind: AssignKind;
|
|
/** Reference of the application being dispatched, shown for confirmation. */
|
|
applicationNumber?: string;
|
|
loading?: boolean;
|
|
onConfirm: (officerId: string, remark?: string) => void;
|
|
}
|
|
|
|
/**
|
|
* The team leader handing work to an employee.
|
|
*
|
|
* One dialog for both stages because the decision is identical — pick a person,
|
|
* optionally say why — and two near-identical modals would drift apart. The
|
|
* `kind` only selects wording.
|
|
*
|
|
* Confirm stays disabled until someone is picked: an assignment with no
|
|
* assignee is the one mistake this dialog exists to prevent.
|
|
*/
|
|
export function AssignDialog({
|
|
opened,
|
|
onClose,
|
|
kind,
|
|
applicationNumber,
|
|
loading,
|
|
onConfirm,
|
|
}: AssignDialogProps) {
|
|
const { t } = useTranslation();
|
|
const { data: officers = [], isLoading } = useGetAssignableOfficersQuery();
|
|
const [officerId, setOfficerId] = useState<string | null>(null);
|
|
const [remark, setRemark] = useState('');
|
|
|
|
// Reopening for a different application must not offer the previous
|
|
// dialog's answers as if they had been chosen for this one.
|
|
useEffect(() => {
|
|
if (opened) {
|
|
setOfficerId(null);
|
|
setRemark('');
|
|
}
|
|
}, [opened]);
|
|
|
|
const title =
|
|
kind === 'review'
|
|
? t('queue.assignReview', 'Assign document review')
|
|
: t('queue.assignInspection', 'Assign inspection');
|
|
|
|
return (
|
|
<Modal opened={opened} onClose={onClose} title={title} size="md">
|
|
<Stack gap="md">
|
|
{applicationNumber && (
|
|
<Text size="sm" c="dimmed">
|
|
{applicationNumber}
|
|
</Text>
|
|
)}
|
|
|
|
<Select
|
|
label={
|
|
kind === 'review'
|
|
? t('queue.assignReviewTo', 'Employee to review the documents')
|
|
: t('queue.assignInspectionTo', 'Employee to conduct the inspection')
|
|
}
|
|
placeholder={t('queue.selectEmployee', 'Select an employee')}
|
|
data={officers.map((o) => ({
|
|
value: o.id,
|
|
label: o.name ?? o.id,
|
|
}))}
|
|
value={officerId}
|
|
onChange={setOfficerId}
|
|
disabled={isLoading}
|
|
searchable
|
|
withAsterisk
|
|
/>
|
|
|
|
<Textarea
|
|
label={t('queue.assignRemark', 'Instructions')}
|
|
description={t(
|
|
'queue.assignRemarkHint',
|
|
'Optional. Sent with the assignment notification.',
|
|
)}
|
|
value={remark}
|
|
onChange={(e) => setRemark(e.currentTarget.value)}
|
|
autosize
|
|
minRows={2}
|
|
/>
|
|
|
|
<ModalFooter>
|
|
<Button variant="default" onClick={onClose} size="sm">
|
|
{t('common.cancel', 'Cancel')}
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
loading={loading}
|
|
disabled={!officerId}
|
|
onClick={() => officerId && onConfirm(officerId, remark || undefined)}
|
|
>
|
|
{t('queue.assignConfirm', 'Assign')}
|
|
</Button>
|
|
</ModalFooter>
|
|
</Stack>
|
|
</Modal>
|
|
);
|
|
}
|