import type { ILivechatDepartment, ILivechatDepartmentAgents, Serialized } from '@rocket.chat/core-typings'; import { FieldGroup, Field, FieldLabel, FieldRow, FieldError, TextInput, Box, Icon, Divider, ToggleSwitch, TextAreaInput, ButtonGroup, Button, PaginatedSelectFiltered, FieldHint, Option, } from '@rocket.chat/fuselage'; import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; import { validateEmail } from '@rocket.chat/tools'; import { Page, PageHeader, PageScrollableContentWithShadow } from '@rocket.chat/ui-client'; import { useToastMessageDispatch, useEndpoint, useRouter, usePermission } from '@rocket.chat/ui-contexts'; import { useQueryClient } from '@tanstack/react-query'; import { useId, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import DepartmentsAgentsTable from './DepartmentAgentsTable/DepartmentAgentsTable'; import DepartmentTags from './DepartmentTags'; import type { EditDepartmentFormData } from './definitions'; import { formatAgentListPayload } from './utils/formatAgentListPayload'; import { formatEditDepartmentPayload } from './utils/formatEditDepartmentPayload'; import { getFormInitialValues } from './utils/getFormInititalValues'; import { useFormSubmitWithDirtyCheck } from '../../../hooks/useFormSubmitWithDirtyCheck'; import { useHasLicenseModule } from '../../../hooks/useHasLicenseModule'; import { useRoomsList } from '../../../hooks/useRoomsList'; import { EeTextInput, EeTextAreaInput, EeNumberInput, DepartmentBusinessHours } from '../additionalForms'; import AutoCompleteUnit from '../additionalForms/AutoCompleteUnit'; import AutoCompleteDepartment from '../components/AutoCompleteDepartment'; import AutoCompleteDepartmentMultiple from '../components/AutoCompleteDepartmentMultiple'; export type EditDepartmentProps = { id?: string; title: string; data?: Serialized<{ department: ILivechatDepartment | null; agents?: ILivechatDepartmentAgents[]; }>; allowedToForwardData?: Serialized<{ departments: ILivechatDepartment[]; }>; }; function EditDepartment({ data, id, title, allowedToForwardData }: EditDepartmentProps) { const dispatchToastMessage = useToastMessageDispatch(); const { t } = useTranslation(); const router = useRouter(); const queryClient = useQueryClient(); const { department, agents = [] } = data || {}; const { data: hasLicense = false } = useHasLicenseModule('livechat-enterprise'); const canManageUnits = usePermission('manage-livechat-units'); const initialValues = getFormInitialValues({ department, agents, allowedToForwardData }); const { register, control, handleSubmit, formState: { errors, isDirty, isSubmitting }, } = useForm({ defaultValues: initialValues }); const [fallbackFilter, setFallbackFilter] = useState(''); const [isUnitRequired, setUnitRequired] = useState(false); const debouncedFallbackFilter = useDebouncedValue(fallbackFilter, 500); const { data: roomItems = [], fetchNextPage } = useRoomsList({ text: debouncedFallbackFilter }); const createDepartment = useEndpoint('POST', '/v1/livechat/department'); const updateDepartmentInfo = useEndpoint('PUT', '/v1/livechat/department/:_id', { _id: id || '' }); const saveDepartmentAgentsInfoOnEdit = useEndpoint('POST', `/v1/livechat/department/:_id/agents`, { _id: id || '' }); const handleSave = useFormSubmitWithDirtyCheck( async (data: EditDepartmentFormData) => { try { const { agentList } = data; const payload = formatEditDepartmentPayload(data); const departmentUnit = data.unit ? { _id: data.unit } : undefined; if (id) { await updateDepartmentInfo({ department: payload, agents: [], departmentUnit, }); const { agentList: initialAgentList } = initialValues; const agentListPayload = formatAgentListPayload(initialAgentList, agentList); if (agentListPayload.upsert.length > 0 || agentListPayload.remove.length > 0) { await saveDepartmentAgentsInfoOnEdit(agentListPayload); } } else { await createDepartment({ department: payload, agents: agentList.map(({ agentId, count, order }) => ({ agentId, count, order })), departmentUnit, }); } queryClient.invalidateQueries({ queryKey: ['/v1/livechat/department/:_id', id] }); dispatchToastMessage({ type: 'success', message: t('Saved') }); router.navigate('/omnichannel/departments'); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } }, { isDirty }, ); const formId = useId(); const enabledField = useId(); const nameField = useId(); const descriptionField = useId(); const showOnRegistrationField = useId(); const emailField = useId(); const showOnOfflineFormField = useId(); const offlineMessageChannelNameField = useId(); const fallbackForwardDepartmentField = useId(); const requestTagBeforeClosingChatField = useId(); const chatClosingTagsField = useId(); const allowReceiveForwardOffline = useId(); const unitFieldId = useId(); const agentsLabelId = useId(); const departmentsAllowedToForwardFieldId = useId(); return ( router.navigate('/omnichannel/departments')}> {t('Enabled')} {t('Name')} {errors.name && ( {errors.name?.message} )} {t('Description')} {t('Show_on_registration_page')} {t('Email')} } placeholder={t('Email')} {...register('email', { required: t('Required_field', { field: t('Email') }), validate: (email) => validateEmail(email) || t('error-invalid-email-address'), })} aria-describedby={`${emailField}-error`} /> {errors.email && ( {errors.email?.message} )} {t('Show_on_offline_page')} {t('Livechat_DepartmentOfflineMessageToChannel')} ( void} options={roomItems} placeholder={t('Channel_name')} endReached={() => fetchNextPage()} aria-busy={fallbackFilter !== debouncedFallbackFilter} /> )} /> {hasLicense && ( <> ( )} /> ( )} /> ( )} /> ( )} /> {t('List_of_departments_for_forward')} ( )} /> {t('List_of_departments_for_forward_description')} {t('Fallback_forward_department')} ( ( {t('Unit')} ( { // NOTE: list.itemCount > 1 to account for the "None" option setUnitRequired(!canManageUnits && list.length > 1); }} /> )} /> {errors.unit && ( {errors.unit?.message} )} )} {t('Request_tag_before_closing_chat')} {t('Conversation_closing_tags')} ( )} /> {t('Conversation_closing_tags_description')} {errors.chatClosingTags && ( {errors.chatClosingTags?.message} )} {t('Accept_receive_inquiry_no_online_agents')} {t('Accept_receive_inquiry_no_online_agents_Hint')} {t('Agents')} ); } export default EditDepartment;