Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dougfabris committed Jul 24, 2024
1 parent 9397779 commit 8c4961a
Showing 1 changed file with 79 additions and 37 deletions.
116 changes: 79 additions & 37 deletions apps/meteor/client/views/omnichannel/contactInfo/EditContactInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { ILivechatVisitor, Serialized } from '@rocket.chat/core-typings';
import { Field, FieldLabel, FieldRow, FieldError, TextInput, ButtonGroup, Button } from '@rocket.chat/fuselage';
import { Field, FieldLabel, FieldRow, FieldError, TextInput, ButtonGroup, Button, IconButton } from '@rocket.chat/fuselage';
import { useUniqueId } from '@rocket.chat/fuselage-hooks';
import { CustomFieldsForm } from '@rocket.chat/ui-client';
import { useToastMessageDispatch, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts';
import { useQueryClient } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React, { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import React, { useState, useEffect, Fragment } from 'react';
import { Controller, useFieldArray, useForm } from 'react-hook-form';

import { hasAtLeastOnePermission } from '../../../../app/authorization/client';
import { validateEmail } from '../../../../lib/emailValidator';
Expand Down Expand Up @@ -34,17 +35,17 @@ type ContactNewEditProps = {
type ContactFormData = {
token: string;
name: string;
email: string;
phone: string;
emails: string[];
phones: string[];
username: string;
customFields: Record<any, any>;
};

const DEFAULT_VALUES = {
token: '',
name: '',
email: '',
phone: '',
emails: [],
phones: [],
username: '',
customFields: {},
};
Expand All @@ -59,21 +60,21 @@ const getInitialValues = (data: ContactNewEditProps['contactData']): ContactForm
return {
token: token ?? '',
name: name ?? '',
email: visitorEmails ? visitorEmails[0].address : '',
phone: phone ? phone[0].phoneNumber : '',
emails: visitorEmails?.map(({ address }) => address) ?? [],
phones: phone?.map(({ phoneNumber }) => phoneNumber) ?? [],
customFields: livechatData ?? {},
username: contactManager?.username ?? '',
};
};

// TODO: Add group select input
const EditContactInfo = ({ id, contactData, onClose, onCancel }: ContactNewEditProps): ReactElement => {
const t = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();
const queryClient = useQueryClient();
const handleNavigate = useContactRoute();

const canViewCustomFields = (): boolean =>
hasAtLeastOnePermission(['view-livechat-room-customfields', 'edit-livechat-room-customfields']);
const canViewCustomFields = hasAtLeastOnePermission(['view-livechat-room-customfields', 'edit-livechat-room-customfields']);

const [userId, setUserId] = useState('no-agent-selected');
const saveContact = useEndpoint('POST', '/v1/omnichannel/contact');
Expand All @@ -82,15 +83,14 @@ const EditContactInfo = ({ id, contactData, onClose, onCancel }: ContactNewEditP

const { data: customFieldsMetadata = [], isInitialLoading: isLoadingCustomFields } = useCustomFieldsMetadata({
scope: 'visitor',
enabled: canViewCustomFields(),
enabled: canViewCustomFields,
});

const initialValue = getInitialValues(contactData);
const { username: initialUsername } = initialValue;

const {
register,
formState: { errors, isValid, isDirty, isSubmitting },
formState: { errors, isSubmitting },
control,
setValue,
handleSubmit,
Expand All @@ -101,6 +101,24 @@ const EditContactInfo = ({ id, contactData, onClose, onCancel }: ContactNewEditP
defaultValues: initialValue,
});

const {
fields: emailFields,
append: appendEmail,
remove: removeEmail,
} = useFieldArray({
control,
name: 'emails',
});

const {
fields: phoneFields,
append: appendPhone,
remove: removePhone,
} = useFieldArray({
control,
name: 'phones',
});

useEffect(() => {
if (!initialUsername) {
return;
Expand Down Expand Up @@ -158,6 +176,8 @@ const EditContactInfo = ({ id, contactData, onClose, onCancel }: ContactNewEditP
};

const handleSave = async (data: ContactFormData): Promise<void> => {
console.log(data);
return;
if (!(await validateAsync(data))) {
return;
}
Expand All @@ -184,6 +204,9 @@ const EditContactInfo = ({ id, contactData, onClose, onCancel }: ContactNewEditP
}
};

const nameField = useUniqueId();
const phoneField = useUniqueId();

if (isLoadingCustomFields) {
return (
<ContextualbarContent>
Expand All @@ -201,43 +224,62 @@ const EditContactInfo = ({ id, contactData, onClose, onCancel }: ContactNewEditP
</ContextualbarHeader>
<ContextualbarScrollableContent is='form' onSubmit={handleSubmit(handleSave)}>
<Field>
<FieldLabel>{t('Name')}*</FieldLabel>
<FieldLabel htmlFor={nameField} required>
{t('Name')}
</FieldLabel>
<FieldRow>
<TextInput {...register('name', { validate: validateName })} error={errors.name?.message} flexGrow={1} />
<Controller
name='name'
control={control}
rules={{ validate: validateName }}
render={({ field }) => <TextInput id={nameField} {...field} error={errors.name?.message} />}
/>
</FieldRow>
<FieldError>{errors.name?.message}</FieldError>
</Field>
<Field>
<FieldLabel>{t('Email')}</FieldLabel>
<FieldRow>
<TextInput {...register('email', { validate: validateEmailFormat })} error={errors.email?.message} flexGrow={1} />
</FieldRow>
<FieldError>{errors.email?.message}</FieldError>
{emailFields.map((field, index) => (
<Fragment key={field.id}>
<FieldRow>
<Controller
name={`emails.${index}`}
control={control}
rules={{ validate: validateEmailFormat }}
render={({ field }) => <TextInput {...field} error={errors.emails?.[index]?.message} />}
/>
<IconButton disabled={index === 0} onClick={() => removeEmail(index)} mis={8} secondary icon='trash' />
</FieldRow>
<FieldError>{errors.emails?.[index]?.message}</FieldError>
</Fragment>
))}
<Button onClick={() => appendEmail('')}>{t('Add_email')}</Button>
</Field>
<Field>
<FieldLabel>{t('Phone')}</FieldLabel>
<FieldRow>
<TextInput {...register('phone')} error={errors.phone?.message} flexGrow={1} />
</FieldRow>
<FieldError>{errors.phone?.message}</FieldError>
{phoneFields.map((field, index) => (
<Fragment key={field.id}>
<FieldRow>
<Controller
name={`phones.${index}`}
control={control}
render={({ field }) => <TextInput {...field} error={errors.phones?.[index]?.message} />}
/>
<Button mis={8} square icon='trash' />
<IconButton disabled={index === 0} onClick={() => removePhone(index)} mis={8} secondary icon='trash' />
</FieldRow>
<FieldError>{errors.phones?.[index]?.message}</FieldError>
</Fragment>
))}
<Button onClick={() => appendPhone('')}>{t('Add_phone')}</Button>
</Field>
{canViewCustomFields() && <CustomFieldsForm formName='customFields' formControl={control} metadata={customFieldsMetadata} />}
<ContactManagerForm value={userId} handler={handleContactManagerChange} />
{canViewCustomFields && <CustomFieldsForm formName='customFields' formControl={control} metadata={customFieldsMetadata} />}
</ContextualbarScrollableContent>
<ContextualbarFooter>
<ButtonGroup stretch>
<Button flexGrow={1} onClick={onCancel}>
{t('Cancel')}
</Button>
<Button
mie='none'
type='submit'
onClick={handleSubmit(handleSave)}
flexGrow={1}
loading={isSubmitting}
disabled={!isValid || !isDirty}
primary
>
<Button onClick={onCancel}>{t('Cancel')}</Button>
<Button onClick={handleSubmit(handleSave)} loading={isSubmitting} primary>
{t('Save')}
</Button>
</ButtonGroup>
Expand Down

0 comments on commit 8c4961a

Please sign in to comment.