Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
682dec7
testFuselagForms
sandranymark Jul 4, 2025
dd1dfb4
revert some changes
gabriellsh Jul 15, 2025
3774675
review
gabriellsh Jul 15, 2025
73325f2
remove id
gabriellsh Jul 30, 2025
9b8575c
update import
gabriellsh Jul 30, 2025
a81e433
feat: use `NumberInput` from fuselage-forms in `PreferencesUserPresen…
juliajforesti Mar 18, 2026
6b8c030
chore: use `Slider` from `fuselage-forms`
juliajforesti Mar 19, 2026
6af5b95
chore: use `MultiSelect` from `fuselage-forms`
juliajforesti Mar 19, 2026
e145a99
chore: add type definitions to form fields in `PreferencesSoundSection`
juliajforesti Mar 24, 2026
b14967f
chore: only add `required` field prop when `requireName` is truthy
juliajforesti Mar 26, 2026
9a3c913
chore: apply fuselage-forms in `omnichannel` account preferences
juliajforesti Mar 27, 2026
492ad98
chore: add id associations for accessibility in `PreferencesMessagesS…
juliajforesti Mar 27, 2026
f966cbc
chore: apply `Select` from `fuselage-forms` in `AccountIntegrationsPage`
juliajforesti Mar 27, 2026
84c761d
fix: add back removed config
dougfabris Mar 31, 2026
ea5654a
fix: unnecessary changes
dougfabris Mar 31, 2026
9fcf94b
chore: restore positions
dougfabris Mar 31, 2026
ae1e0c6
chore: remove unused id associations in PreferencesMessagesSection
dougfabris Mar 31, 2026
5df674a
fix: update form handling in PreferencesHighlightsSection to use Cont…
dougfabris Apr 1, 2026
6534533
chore: remove unused id association and simplify error handling in Ac…
dougfabris Apr 1, 2026
1a2c851
fix: update form handling in PreferencesConversationTranscript to use…
dougfabris Apr 1, 2026
ad1cedf
fix: update form handling in PreferencesGeneral to use Controller
dougfabris Apr 1, 2026
d9b449c
fix: simplify Controller usage in PreferencesLocalizationSection
dougfabris Apr 1, 2026
7e9de68
fix: streamline Controller rendering in PreferencesMessagesSection
dougfabris Apr 1, 2026
9ce8d34
fix: refactor Controller rendering in AccessibilityPage for improved …
dougfabris Apr 1, 2026
130ea23
fix: simplify Controller rendering in PreferencesNotificationsSection…
dougfabris Apr 1, 2026
c227a01
fix: streamline Controller rendering in PreferencesSoundSection for i…
dougfabris Apr 1, 2026
41822ee
fix: streamline Controller rendering in PreferencesUserPresenceSectio…
dougfabris Apr 1, 2026
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
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { css } from '@rocket.chat/css-in-js';
import type { SelectOption } from '@rocket.chat/fuselage';
import { Accordion, AccordionItem, Box, Button, ButtonGroup } from '@rocket.chat/fuselage';
import {
FieldDescription,
Accordion,
AccordionItem,
Box,
Button,
ButtonGroup,
Field,
FieldGroup,
FieldHint,
Expand All @@ -15,7 +11,7 @@ import {
RadioButton,
Select,
ToggleSwitch,
} from '@rocket.chat/fuselage';
} from '@rocket.chat/fuselage-forms';
import { ExternalLink, Page, PageHeader, PageScrollableContentWithShadow, PageFooter } from '@rocket.chat/ui-client';
import { useTranslation, useToastMessageDispatch, useEndpoint, useSetting } from '@rocket.chat/ui-contexts';
import { useMutation } from '@tanstack/react-query';
Expand Down Expand Up @@ -49,11 +45,6 @@ const AccessibilityPage = () => {
);

const pageFormId = useId();
const fontSizeId = useId();
const mentionsWithSymbolId = useId();
const clockModeId = useId();
const hideUsernamesId = useId();
const hideRolesId = useId();
const linkListId = useId();

const {
Expand Down Expand Up @@ -113,14 +104,14 @@ const AccessibilityPage = () => {
return (
<Field key={id} pbe={themes.length - 1 ? undefined : 'x28'} pbs={index === 0 ? undefined : 'x28'}>
<FieldRow>
<FieldLabel display='flex' alignItems='center' htmlFor={id}>
<FieldLabel display='flex' alignItems='center'>
{t(title)}
</FieldLabel>
<Controller
control={control}
name='themeAppearence'
render={({ field: { onChange, value, ref } }) => (
<RadioButton id={id} ref={ref} onChange={() => onChange(id)} checked={value === id} />
render={({ field: { value, onChange, ...field } }) => (
<RadioButton id={id} {...field} onChange={() => onChange(id)} checked={value === id} />
)}
/>
</FieldRow>
Expand All @@ -137,29 +128,19 @@ const AccessibilityPage = () => {
<legend>{t('Adjustable_layout')}</legend>
</VisuallyHidden>
<Field>
<FieldLabel htmlFor={fontSizeId} mbe={12}>
{t('Font_size')}
</FieldLabel>
<FieldLabel mbe={12}>{t('Font_size')}</FieldLabel>
<FieldRow>
<Controller
control={control}
name='fontSize'
render={({ field: { onChange, value } }) => (
<Select id={fontSizeId} value={value} onChange={onChange} options={fontSizes(t)} />
)}
/>
<Controller control={control} name='fontSize' render={({ field }) => <Select {...field} options={fontSizes(t)} />} />
</FieldRow>
<FieldDescription mb={12}>{t('Adjustable_font_size_description')}</FieldDescription>
</Field>
<Field>
<FieldRow>
<FieldLabel htmlFor={mentionsWithSymbolId}>{t('Mentions_with_@_symbol')}</FieldLabel>
<FieldLabel>{t('Mentions_with_@_symbol')}</FieldLabel>
<Controller
control={control}
name='mentionsWithSymbol'
render={({ field: { onChange, value, ref } }) => (
<ToggleSwitch id={mentionsWithSymbolId} ref={ref} checked={value} onChange={onChange} />
)}
render={({ field: { value, ...field } }) => <ToggleSwitch {...field} checked={value} />}
/>
</FieldRow>
<FieldDescription
Expand All @@ -172,30 +153,23 @@ const AccessibilityPage = () => {
</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor={clockModeId}>{t('Message_TimeFormat')}</FieldLabel>
<FieldLabel>{t('Message_TimeFormat')}</FieldLabel>
<FieldRow>
<Controller
name='clockMode'
control={control}
render={({ field: { value, onChange } }) => (
<Select id={clockModeId} value={`${value}`} onChange={onChange} options={timeFormatOptions} />
)}
render={({ field: { value, ...field } }) => <Select {...field} value={`${value}`} options={timeFormatOptions} />}
/>
</FieldRow>
</Field>
<Field>
<FieldRow>
<FieldLabel htmlFor={hideUsernamesId}>{t('Show_usernames')}</FieldLabel>
<FieldLabel>{t('Show_usernames')}</FieldLabel>
<Controller
name='hideUsernames'
control={control}
render={({ field: { value, onChange, ref } }) => (
<ToggleSwitch
id={hideUsernamesId}
ref={ref}
checked={!value}
onChange={(e) => onChange(!(e.target as HTMLInputElement).checked)}
/>
render={({ field: { value, onChange, ...field } }) => (
<ToggleSwitch {...field} checked={!value} onChange={(e) => onChange(!(e.target as HTMLInputElement).checked)} />
)}
/>
</FieldRow>
Expand All @@ -204,17 +178,12 @@ const AccessibilityPage = () => {
{displayRolesEnabled && (
<Field>
<FieldRow>
<FieldLabel htmlFor={hideRolesId}>{t('Show_roles')}</FieldLabel>
<FieldLabel>{t('Show_roles')}</FieldLabel>
<Controller
name='hideRoles'
control={control}
render={({ field: { value, onChange, ref } }) => (
<ToggleSwitch
id={hideRolesId}
ref={ref}
checked={!value}
onChange={(e) => onChange(!(e.target as HTMLInputElement).checked)}
/>
render={({ field: { value, onChange, ...field } }) => (
<ToggleSwitch {...field} checked={!value} onChange={(e) => onChange(!(e.target as HTMLInputElement).checked)} />
)}
/>
</FieldRow>
Expand Down
Comment thread
dougfabris marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { SelectOption } from '@rocket.chat/fuselage';
import { SelectLegacy, Box, Button, Field, FieldLabel, FieldRow, FieldError } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { Box, Button } from '@rocket.chat/fuselage';
import { Select, Field, FieldLabel, FieldRow, FieldError } from '@rocket.chat/fuselage-forms';
import { Page, PageHeader, PageScrollableContentWithShadow } from '@rocket.chat/ui-client';
import { useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import { useId, useMemo } from 'react';
import { useMemo } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

Expand Down Expand Up @@ -37,11 +37,9 @@ const AccountIntegrationsPage = () => {
},
});

const handleSubmitForm = useEffectEvent(({ accountSelected }: { accountSelected: string }) => {
const handleSubmitForm = ({ accountSelected }: { accountSelected: string }) => {
removeMutation.mutate({ accountSelected });
});

const accountSelectedId = useId();
};

return (
<Page>
Expand All @@ -55,17 +53,13 @@ const AccountIntegrationsPage = () => {
control={control}
name='accountSelected'
rules={{ required: t('Required_field', { field: t('WebDAV_Accounts') }) }}
render={({ field }) => <SelectLegacy {...field} options={options} placeholder={t('Select_an_option')} />}
render={({ field }) => <Select {...field} options={options} placeholder={t('Select_an_option')} />}
/>
<Button type='submit' danger>
{t('Remove')}
</Button>
</FieldRow>
{errors?.accountSelected && (
<FieldError aria-live='assertive' id={`${accountSelectedId}-error`}>
{errors.accountSelected.message}
</FieldError>
)}
{errors?.accountSelected && <FieldError>{errors.accountSelected.message}</FieldError>}
</Field>
</Box>
</PageScrollableContentWithShadow>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { AccordionItem, Box, Field, FieldGroup, FieldLabel, FieldRow, FieldHint, Tag, ToggleSwitch } from '@rocket.chat/fuselage';
import { AccordionItem, Tag } from '@rocket.chat/fuselage';
import { Field, FieldGroup, FieldLabel, FieldRow, FieldHint, ToggleSwitch } from '@rocket.chat/fuselage-forms';
import { useTranslation, usePermission, useSetting } from '@rocket.chat/ui-contexts';
import { useId } from 'react';
import { useFormContext } from 'react-hook-form';
import { Controller, useFormContext } from 'react-hook-form';

import { useHasLicenseModule } from '../../../hooks/useHasLicenseModule';

const PreferencesConversationTranscript = () => {
const t = useTranslation();

const { register } = useFormContext();
const { control } = useFormContext();

const { data: hasLicense = false } = useHasLicenseModule('livechat-enterprise');
const alwaysSendEmailTranscript = useSetting('Livechat_transcript_send_always');
Expand All @@ -17,40 +16,39 @@ const PreferencesConversationTranscript = () => {
const canSendTranscriptEmail = canSendTranscriptEmailPermission && !alwaysSendEmailTranscript;
const cantSendTranscriptPDF = !canSendTranscriptPDF || !hasLicense;

const omnichannelTranscriptPDF = useId();
const omnichannelTranscriptEmail = useId();

return (
<AccordionItem defaultExpanded title={t('Conversational_transcript')}>
<FieldGroup>
<Field>
<FieldRow>
<FieldLabel htmlFor={omnichannelTranscriptPDF}>
<Box display='flex' alignItems='center'>
{t('Omnichannel_transcript_pdf')}
<Box marginInline={4}>
{!hasLicense && <Tag variant='featured'>{t('Premium')}</Tag>}
{!canSendTranscriptPDF && hasLicense && <Tag>{t('No_permission')}</Tag>}
</Box>
</Box>
<FieldLabel>
{t('Omnichannel_transcript_pdf')}
{!hasLicense && (
<Tag mi={4} variant='featured'>
{t('Premium')}
</Tag>
)}
{!canSendTranscriptPDF && hasLicense && <Tag mi={4}>{t('No_permission')}</Tag>}
</FieldLabel>
<ToggleSwitch id={omnichannelTranscriptPDF} disabled={cantSendTranscriptPDF} {...register('omnichannelTranscriptPDF')} />
<Controller
control={control}
name='omnichannelTranscriptPDF'
render={({ field: { value, ...field } }) => <ToggleSwitch disabled={cantSendTranscriptPDF} {...field} checked={value} />}
/>
</FieldRow>
<FieldHint>{t('Accounts_Default_User_Preferences_omnichannelTranscriptPDF_Description')}</FieldHint>
</Field>
<Field>
<FieldRow>
<FieldLabel htmlFor={omnichannelTranscriptEmail}>
<Box display='flex' alignItems='center'>
{t('Omnichannel_transcript_email')}
{!canSendTranscriptEmailPermission && (
<Box marginInline={4}>
<Tag>{t('No_permission')}</Tag>
</Box>
)}
</Box>
<FieldLabel>
{t('Omnichannel_transcript_email')}
{!canSendTranscriptEmailPermission && <Tag mi={4}>{t('No_permission')}</Tag>}
</FieldLabel>
<ToggleSwitch id={omnichannelTranscriptEmail} disabled={!canSendTranscriptEmail} {...register('omnichannelTranscriptEmail')} />
<Controller
control={control}
name='omnichannelTranscriptEmail'
render={({ field: { value, ...field } }) => <ToggleSwitch disabled={!canSendTranscriptEmail} {...field} checked={value} />}
/>
</FieldRow>
<FieldHint>{t('Accounts_Default_User_Preferences_omnichannelTranscriptEmail_Description')}</FieldHint>
</Field>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { Field, FieldGroup, FieldHint, FieldLabel, FieldRow, ToggleSwitch } from '@rocket.chat/fuselage';
import { useId } from 'react';
import { Field, FieldGroup, FieldHint, FieldLabel, FieldRow, ToggleSwitch } from '@rocket.chat/fuselage-forms';
import type { ReactElement } from 'react';
import { useFormContext } from 'react-hook-form';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

export const PreferencesGeneral = (): ReactElement => {
const { t } = useTranslation();
const { register } = useFormContext();
const omnichannelHideAfterClosing = useId();
const { control } = useFormContext();

return (
<FieldGroup marginBlockEnd='1.5rem' paddingInline='0.5rem'>
<Field>
<FieldRow>
<FieldLabel htmlFor={omnichannelHideAfterClosing}>{t('Omnichannel_hide_conversation_after_closing')}</FieldLabel>
<ToggleSwitch id={omnichannelHideAfterClosing} {...register('omnichannelHideConversationAfterClosing')} />
<FieldLabel>{t('Omnichannel_hide_conversation_after_closing')}</FieldLabel>
<Controller
control={control}
name='omnichannelHideConversationAfterClosing'
render={({ field: { value, ...field } }) => <ToggleSwitch {...field} checked={value} />}
/>
</FieldRow>
<FieldHint>{t('Omnichannel_hide_conversation_after_closing_description')}</FieldHint>
</Field>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { SelectOption } from '@rocket.chat/fuselage';
import { AccordionItem, Field, FieldGroup, FieldLabel, FieldRow, MultiSelect } from '@rocket.chat/fuselage';
import { AccordionItem } from '@rocket.chat/fuselage';
import { Field, FieldGroup, FieldLabel, FieldRow, MultiSelect } from '@rocket.chat/fuselage-forms';
import { useUserPreference } from '@rocket.chat/ui-contexts';
import { useId } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

Expand All @@ -12,21 +12,18 @@ const PreferencesGlobalSection = () => {
const options: SelectOption[] = userDontAskAgainList.map(({ action, label }) => [action, label]);

const { control } = useFormContext();
const dontAskAgainListId = useId();

return (
<AccordionItem title={t('Global')}>
<FieldGroup>
<Field>
<FieldLabel is='span' htmlFor={dontAskAgainListId}>
{t('Dont_ask_me_again_list')}
</FieldLabel>
<FieldLabel>{t('Dont_ask_me_again_list')}</FieldLabel>
<FieldRow>
<Controller
name='dontAskAgainList'
control={control}
render={({ field: { value, onChange } }) => (
<MultiSelect id={dontAskAgainListId} placeholder={t('Nothing_found')} value={value} onChange={onChange} options={options} />
<MultiSelect placeholder={t('Nothing_found')} value={value} onChange={onChange} options={options} />
)}
/>
</FieldRow>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import { AccordionItem, Field, FieldGroup, FieldLabel, FieldRow, FieldHint, TextAreaInput } from '@rocket.chat/fuselage';
import { useId } from 'react';
import { useFormContext } from 'react-hook-form';
import { AccordionItem } from '@rocket.chat/fuselage';
import { Field, FieldGroup, FieldLabel, FieldRow, FieldHint, TextAreaInput } from '@rocket.chat/fuselage-forms';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

const PreferencesHighlightsSection = () => {
const { t } = useTranslation();
const { register } = useFormContext();

const highlightsId = useId();
const { control } = useFormContext();

return (
<AccordionItem title={t('Highlights')}>
<FieldGroup>
<Field>
<FieldLabel htmlFor={highlightsId}>{t('Highlights_List')}</FieldLabel>
<FieldLabel>{t('Highlights_List')}</FieldLabel>
Comment thread
juliajforesti marked this conversation as resolved.
<FieldRow>
<TextAreaInput id={highlightsId} {...register('highlights')} rows={4} />
<Controller control={control} name='highlights' render={({ field }) => <TextAreaInput {...field} rows={4} />} />
</FieldRow>
<FieldHint>{t('Highlights_How_To')}</FieldHint>
</Field>
Expand Down
Loading
Loading