Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/polite-cars-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": patch
"@rocket.chat/livechat": patch
---

Fixes issue where the livechat offline form would render even when disabled
28 changes: 28 additions & 0 deletions apps/meteor/tests/e2e/omnichannel/omnichannel-livechat.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,31 @@ test.describe.serial('OC - Livechat - Resub after close room', () => {
});
});
});

test.describe('OC - Livechat - Livechat_Display_Offline_Form', () => {
let poLiveChat: OmnichannelLiveChat;
const message = 'This form is not available';

test.beforeAll(async ({ api }) => {
await api.post('/settings/Livechat_display_offline_form', { value: false });
await api.post('/settings/Livechat_offline_form_unavailable', { value: message });
});

test.beforeEach(async ({ page, api }) => {
poLiveChat = new OmnichannelLiveChat(page, api);
await poLiveChat.page.goto('/livechat');
});

test.afterAll(async ({ api }) => {
await api.post('/settings/Livechat_display_offline_form', { value: true });
await api.post('/settings/Livechat_offline_form_unavailable', { value: '' });
});

test('OC - Livechat - Livechat_Display_Offline_Form false', async () => {
await test.step('expect offline form to not be visible', async () => {
await poLiveChat.openAnyLiveChat();
await expect (poLiveChat.page.locator(`div >> text=${message}`)).toBeVisible();
await expect(poLiveChat.textAreaMessage).not.toBeVisible();
});
});
});
1 change: 1 addition & 0 deletions packages/livechat/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"new_chat": "New Chat",
"no": "No",
"no_available_agents_to_transfer": "No available agents to transfer",
"offline_form_not_available": "Offline form not available",
"ok": "OK",
"options": "Options",
"please_tell_us_some_information_to_start_the_chat": "Please, tell us some information to start the chat",
Expand Down
1 change: 1 addition & 0 deletions packages/livechat/src/i18n/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"new_chat": "Novo Chat",
"no": "Não",
"no_available_agents_to_transfer": "Não há agentes disponíveis para transferência",
"offline_form_not_available": "Formulário offline não disponível",
"options": "Opções",
"please_tell_us_some_information_to_start_the_chat": "Por favor, nos passe algumas informações antes de iniciar o chat",
"please_wait_for_the_next_available_agent": "Por favor, aguarde o próximo agente disponível..",
Expand Down
146 changes: 78 additions & 68 deletions packages/livechat/src/routes/LeaveMessage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,87 +82,97 @@ const LeaveMessage: FunctionalComponent<{ path: string }> = () => {

const defaultTitle = t('leave_a_message');
const defaultMessage = t('we_are_not_online_right_now_please_leave_a_message');
const defaultUnavailableMessage = ''; // TODO
const defaultUnavailableMessage = t('offline_form_not_available');

return (
<Screen title={customOfflineTitle || title || defaultTitle} color={offlineColor} className={createClassName(styles, 'leave-message')}>
<FormScrollShadow topRef={topRef} bottomRef={bottomRef}>
<Screen.Content full>
<div id='top' ref={topRef} style={{ height: '1px', width: '100%' }} />
{displayOfflineForm ? (
<FormScrollShadow topRef={topRef} bottomRef={bottomRef}>
<Screen.Content full>
<div id='top' ref={topRef} style={{ height: '1px', width: '100%' }} />

<div className={createClassName(styles, 'leave-message__main-message')}>
<MarkdownBlock text={offlineMessage || defaultMessage} />
</div>

<Form
// The price of using react-hook-form on a preact project ¯\_(ツ)_/¯
onSubmit={handleSubmit(onSubmit as SubmitHandler<FieldValues>) as unknown as JSXInternal.GenericEventHandler<HTMLFormElement>}
id='leaveMessage'
>
<FormField required label={t('name')} error={errors.name?.message?.toString()}>
<Controller
name='name'
control={control}
// defaultValue={guestName}
rules={{ required: true }}
render={({ field }) => (
<TextInput placeholder={t('insert_your_field_here', { field: t('name') })} disabled={loading} {...field} />
)}
/>
</FormField>

<div className={createClassName(styles, 'leave-message__main-message')}>
<MarkdownBlock
text={displayOfflineForm ? offlineMessage || defaultMessage : offlineUnavailableMessage || defaultUnavailableMessage}
/>
</div>
<FormField required label={t('email')} error={errors.email?.message?.toString()}>
<Controller
name='email'
control={control}
// defaultValue={guestEmail}
rules={{
required: true,
validate: { checkEmail: (value) => validateEmail(value, { style: 'rfc' }) || t('invalid_email') },
}}
render={({ field }) => (
<TextInput placeholder={t('insert_your_field_here', { field: t('email') })} disabled={loading} {...field} />
)}
/>
</FormField>

<Form
// The price of using react-hook-form on a preact project ¯\_(ツ)_/¯
onSubmit={handleSubmit(onSubmit as SubmitHandler<FieldValues>) as unknown as JSXInternal.GenericEventHandler<HTMLFormElement>}
id='leaveMessage'
>
<FormField required label={t('name')} error={errors.name?.message?.toString()}>
<Controller
name='name'
control={control}
// defaultValue={guestName}
rules={{ required: true }}
render={({ field }) => (
<TextInput placeholder={t('insert_your_field_here', { field: t('name') })} disabled={loading} {...field} />
)}
/>
</FormField>

<FormField required label={t('email')} error={errors.email?.message?.toString()}>
<Controller
name='email'
control={control}
// defaultValue={guestEmail}
rules={{
required: true,
validate: { checkEmail: (value) => validateEmail(value, { style: 'rfc' }) || t('invalid_email') },
}}
render={({ field }) => (
<TextInput placeholder={t('insert_your_field_here', { field: t('email') })} disabled={loading} {...field} />
)}
/>
</FormField>

{departments?.some((dept) => dept.showOnOfflineForm) ? (
<FormField label={t('i_need_help_with')} error={errors.department?.message?.toString()}>
{departments?.some((dept) => dept.showOnOfflineForm) ? (
<FormField label={t('i_need_help_with')} error={errors.department?.message?.toString()}>
<Controller
name='department'
control={control}
render={({ field }) => (
<SelectInput
options={sortArrayByColumn(departments, 'name').map(({ _id, name }: { _id: string; name: string }) => ({
value: _id,
label: name,
}))}
placeholder={t('choose_an_option')}
disabled={loading}
{...field}
/>
)}
/>
</FormField>
) : null}
<FormField required label={t('message')} error={errors.message?.message?.toString()}>
<Controller
name='department'
name='message'
control={control}
rules={{ required: true }}
render={({ field }) => (
<SelectInput
options={sortArrayByColumn(departments, 'name').map(({ _id, name }: { _id: string; name: string }) => ({
value: _id,
label: name,
}))}
placeholder={t('choose_an_option')}
disabled={loading}
{...field}
/>
<MultilineTextInput rows={4} placeholder={t('write_your_message')} disabled={loading} {...field} />
)}
/>
</FormField>
) : null}
<FormField required label={t('message')} error={errors.message?.message?.toString()}>
<Controller
name='message'
control={control}
rules={{ required: true }}
render={({ field }) => <MultilineTextInput rows={4} placeholder={t('write_your_message')} disabled={loading} {...field} />}
/>
</FormField>
</Form>
<div ref={bottomRef} id='bottom' style={{ height: '1px', width: '100%' }} />
</Form>
<div ref={bottomRef} id='bottom' style={{ height: '1px', width: '100%' }} />
</Screen.Content>
</FormScrollShadow>
) : (
<Screen.Content full>
<div className={createClassName(styles, 'leave-message__main-message')}>
<MarkdownBlock text={offlineUnavailableMessage || defaultUnavailableMessage} />
</div>
</Screen.Content>
</FormScrollShadow>
)}
<Screen.Footer>
<Button loading={loading} form='leaveMessage' submit full disabled={!isDirty || !isValid || loading || isSubmitting}>
{t('send')}
</Button>
{displayOfflineForm ? (
<Button loading={loading} form='leaveMessage' submit full disabled={!isDirty || !isValid || loading || isSubmitting}>
{t('send')}
</Button>
) : null}
</Screen.Footer>
</Screen>
);
Expand Down