From d56087d2bc5f40cd7c66beb002e549d0c95caa53 Mon Sep 17 00:00:00 2001 From: Tasso Date: Tue, 7 Jan 2025 03:03:38 -0300 Subject: [PATCH] refactor: Invalid values as React nodes --- .../SidebarToggler/SidebarToggler.tsx | 2 +- .../SidebarToggler/SidebarTogglerBadge.tsx | 7 +++- .../SidebarToggler/SidebarTogglerButton.tsx | 3 +- .../content/attachments/QuoteAttachment.tsx | 2 +- apps/meteor/client/lib/utils/timeAgo.ts | 2 +- .../additionalForms/BusinessHoursMultiple.tsx | 3 +- .../CustomFieldsAdditionalForm.tsx | 3 +- .../cannedResponses/CannedResponseEdit.tsx | 4 +-- ...esponseForm.tsx => CannedResponseForm.tsx} | 3 +- .../CreateCannedResponseModal.tsx | 2 +- .../RoomList/SideBarItemTemplateWithData.tsx | 33 +++++++++---------- .../AirGappedRestrictionWarning.tsx | 4 +-- .../RoomList/SidebarItemTemplateWithData.tsx | 33 +++++++++---------- .../AirGappedRestrictionWarning.tsx | 2 +- .../incoming/EditIncomingWebhook.tsx | 2 +- .../incoming/IncomingWebhookForm.tsx | 3 +- .../views/admin/permissions/EditRolePage.tsx | 10 +++++- .../views/admin/permissions/RoleForm.tsx | 13 ++++---- .../SubscriptionCalloutLimits.tsx | 32 +++++++++++++----- .../views/admin/users/AdminUserForm.tsx | 4 +-- .../admin/users/AdminUserFormWithData.tsx | 2 +- .../views/admin/users/AdminUsersPage.tsx | 8 +++-- .../client/views/directory/RoomTags.tsx | 4 +-- .../channels/ChannelsTable/ChannelsTable.tsx | 4 +-- .../ChannelsTable/ChannelsTableRow.tsx | 4 +-- .../tabs/teams/TeamsTable/TeamsTable.tsx | 4 +-- .../tabs/teams/TeamsTable/TeamsTableRow.tsx | 4 +-- .../components/AuthorizationFormPage.tsx | 4 +-- .../customFields/EditCustomFields.tsx | 16 ++++++++- .../views/room/Header/DirectRoomHeader.tsx | 18 +++++----- .../Omnichannel/OmnichannelRoomHeader.tsx | 17 +++++----- .../client/views/room/Header/RoomHeader.tsx | 17 +++++----- .../Omnichannel/OmnichannelRoomHeader.tsx | 17 +++++----- .../client/views/room/HeaderV2/RoomHeader.tsx | 17 +++++----- .../views/root/MainLayout/LoginPage.tsx | 2 +- apps/meteor/definition/IRoomTypeConfig.ts | 2 +- packages/i18n/src/locales/en.i18n.json | 4 +-- .../livechat/src/routes/Register/index.tsx | 4 +-- .../src/routes/SwitchDepartment/index.tsx | 21 +++++++----- packages/livechat/tsconfig.json | 8 ++--- .../components/LoginSwitchLanguageFooter.tsx | 4 +-- yarn.lock | 13 +------- 42 files changed, 203 insertions(+), 158 deletions(-) rename apps/meteor/client/omnichannel/cannedResponses/components/{cannedResponseForm.tsx => CannedResponseForm.tsx} (98%) diff --git a/apps/meteor/client/components/SidebarToggler/SidebarToggler.tsx b/apps/meteor/client/components/SidebarToggler/SidebarToggler.tsx index fa30bba3f6b2..02d22fb86804 100644 --- a/apps/meteor/client/components/SidebarToggler/SidebarToggler.tsx +++ b/apps/meteor/client/components/SidebarToggler/SidebarToggler.tsx @@ -9,7 +9,7 @@ import { useEmbeddedLayout } from '../../hooks/useEmbeddedLayout'; const SideBarToggler = (): ReactElement => { const { sidebar } = useLayout(); const isLayoutEmbedded = useEmbeddedLayout(); - const unreadMessagesBadge = useSession('unread'); + const unreadMessagesBadge = useSession('unread') as number | string | undefined; const toggleSidebar = useEffectEvent(() => sidebar.toggle()); diff --git a/apps/meteor/client/components/SidebarToggler/SidebarTogglerBadge.tsx b/apps/meteor/client/components/SidebarToggler/SidebarTogglerBadge.tsx index c2671e686f17..5472d24a0a97 100644 --- a/apps/meteor/client/components/SidebarToggler/SidebarTogglerBadge.tsx +++ b/apps/meteor/client/components/SidebarToggler/SidebarTogglerBadge.tsx @@ -1,7 +1,12 @@ import { css } from '@rocket.chat/css-in-js'; import { Box, Badge } from '@rocket.chat/fuselage'; +import type { ReactNode } from 'react'; -const SidebarTogglerBadge = ({ children }: { children?: unknown }) => ( +type SidebarTogglerBadgeProps = { + children?: ReactNode; +}; + +const SidebarTogglerBadge = ({ children }: SidebarTogglerBadgeProps) => ( void; }; diff --git a/apps/meteor/client/components/message/content/attachments/QuoteAttachment.tsx b/apps/meteor/client/components/message/content/attachments/QuoteAttachment.tsx index 5bb9346229c6..4f44f1d810c6 100644 --- a/apps/meteor/client/components/message/content/attachments/QuoteAttachment.tsx +++ b/apps/meteor/client/components/message/content/attachments/QuoteAttachment.tsx @@ -37,7 +37,7 @@ type QuoteAttachmentProps = { export const QuoteAttachment = ({ attachment }: QuoteAttachmentProps): ReactElement => { const formatTime = useTimeAgo(); - const displayAvatarPreference = useUserPreference('displayAvatars'); + const displayAvatarPreference = useUserPreference('displayAvatars'); return ( <> diff --git a/apps/meteor/client/lib/utils/timeAgo.ts b/apps/meteor/client/lib/utils/timeAgo.ts index 5a322096a258..d31a787a6062 100644 --- a/apps/meteor/client/lib/utils/timeAgo.ts +++ b/apps/meteor/client/lib/utils/timeAgo.ts @@ -9,7 +9,7 @@ import { t } from '../../../app/utils/lib/i18n'; const dayFormat = ['h:mm A', 'H:mm']; -export const timeAgo = async (date: MomentInput): Promise => { +export const timeAgo = (date: MomentInput) => { const clockMode = Tracker.nonreactive(() => getUserPreference(Meteor.userId(), 'clockMode', false) as number | boolean); const messageTimeFormat = Tracker.nonreactive(() => settings.get('Message_TimeFormat')); const sameDay = (typeof clockMode === 'number' ? dayFormat[clockMode - 1] : undefined) || messageTimeFormat; diff --git a/apps/meteor/client/omnichannel/additionalForms/BusinessHoursMultiple.tsx b/apps/meteor/client/omnichannel/additionalForms/BusinessHoursMultiple.tsx index 69912a1c3881..59f10af0c46b 100644 --- a/apps/meteor/client/omnichannel/additionalForms/BusinessHoursMultiple.tsx +++ b/apps/meteor/client/omnichannel/additionalForms/BusinessHoursMultiple.tsx @@ -6,13 +6,14 @@ import { useTranslation } from 'react-i18next'; import AutoCompleteDepartmentMultiple from '../../components/AutoCompleteDepartmentMultiple'; import { useHasLicenseModule } from '../../hooks/useHasLicenseModule'; +import type { BusinessHoursFormData } from '../../views/omnichannel/businessHours/BusinessHoursForm'; const BusinessHoursMultiple = ({ className }: { className?: ComponentProps['className'] }) => { const { t } = useTranslation(); const { control, formState: { errors }, - } = useFormContext(); + } = useFormContext(); const hasLicense = useHasLicenseModule('livechat-enterprise'); const enabledField = useUniqueId(); diff --git a/apps/meteor/client/omnichannel/additionalForms/CustomFieldsAdditionalForm.tsx b/apps/meteor/client/omnichannel/additionalForms/CustomFieldsAdditionalForm.tsx index 3e94693bd037..4fa821b7a75c 100644 --- a/apps/meteor/client/omnichannel/additionalForms/CustomFieldsAdditionalForm.tsx +++ b/apps/meteor/client/omnichannel/additionalForms/CustomFieldsAdditionalForm.tsx @@ -7,6 +7,7 @@ import { useFormContext, Controller } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { useHasLicenseModule } from '../../hooks/useHasLicenseModule'; +import type { EditCustomFieldsFormData } from '../../views/omnichannel/customFields/EditCustomFields'; const checkIsOptionsValid = (value: string) => { if (!value || value.trim() === '') { @@ -22,7 +23,7 @@ const CustomFieldsAdditionalForm = ({ className }: { className?: ComponentProps< control, watch, formState: { errors }, - } = useFormContext(); + } = useFormContext(); const hasLicense = useHasLicenseModule('livechat-enterprise'); const { visibility, type } = watch(); diff --git a/apps/meteor/client/omnichannel/cannedResponses/CannedResponseEdit.tsx b/apps/meteor/client/omnichannel/cannedResponses/CannedResponseEdit.tsx index b4b0ef40ba99..be7d1c3d8054 100644 --- a/apps/meteor/client/omnichannel/cannedResponses/CannedResponseEdit.tsx +++ b/apps/meteor/client/omnichannel/cannedResponses/CannedResponseEdit.tsx @@ -6,11 +6,11 @@ import { useQueryClient } from '@tanstack/react-query'; import { memo, useCallback } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; -import CannedResponseForm from './components/cannedResponseForm'; +import CannedResponseForm from './components/CannedResponseForm'; import { useRemoveCannedResponse } from './useRemoveCannedResponse'; import { Page, PageHeader, PageScrollableContentWithShadow, PageFooter } from '../../components/Page'; -type CannedResponseEditFormData = { +export type CannedResponseEditFormData = { _id: string; shortcut: string; text: string; diff --git a/apps/meteor/client/omnichannel/cannedResponses/components/cannedResponseForm.tsx b/apps/meteor/client/omnichannel/cannedResponses/components/CannedResponseForm.tsx similarity index 98% rename from apps/meteor/client/omnichannel/cannedResponses/components/cannedResponseForm.tsx rename to apps/meteor/client/omnichannel/cannedResponses/components/CannedResponseForm.tsx index c4b02bb36721..507d4a95ce55 100644 --- a/apps/meteor/client/omnichannel/cannedResponses/components/cannedResponseForm.tsx +++ b/apps/meteor/client/omnichannel/cannedResponses/components/CannedResponseForm.tsx @@ -10,6 +10,7 @@ import CannedResponsesComposer from './CannedResponsesComposer/CannedResponsesCo import CannedResponsesComposerPreview from './CannedResponsesComposer/CannedResponsesComposerPreview'; import AutoCompleteDepartment from '../../../components/AutoCompleteDepartment'; import Tags from '../../../components/Omnichannel/Tags'; +import type { CannedResponseEditFormData } from '../CannedResponseEdit'; // TODO: refactor Tags field to get proper validation const CannedResponseForm = () => { @@ -21,7 +22,7 @@ const CannedResponseForm = () => { control, formState: { errors }, watch, - } = useFormContext(); + } = useFormContext(); const clickable = css` cursor: pointer; diff --git a/apps/meteor/client/omnichannel/cannedResponses/modals/CreateCannedResponse/CreateCannedResponseModal.tsx b/apps/meteor/client/omnichannel/cannedResponses/modals/CreateCannedResponse/CreateCannedResponseModal.tsx index 59fcfb4547b8..6bd2bb79f701 100644 --- a/apps/meteor/client/omnichannel/cannedResponses/modals/CreateCannedResponse/CreateCannedResponseModal.tsx +++ b/apps/meteor/client/omnichannel/cannedResponses/modals/CreateCannedResponse/CreateCannedResponseModal.tsx @@ -6,7 +6,7 @@ import { FormProvider, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import GenericModal from '../../../../components/GenericModal'; -import CannedResponseForm from '../../components/cannedResponseForm'; +import CannedResponseForm from '../../components/CannedResponseForm'; type CreateCannedResponseModalFormData = { _id: string; diff --git a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx index 4add7090a6db..741d0740d633 100644 --- a/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx +++ b/apps/meteor/client/sidebar/RoomList/SideBarItemTemplateWithData.tsx @@ -63,7 +63,7 @@ type RoomListRowProps = { actions: unknown; href: string; time?: Date; - menu?: ReactNode; + menu?: () => ReactNode; menuOptions?: unknown; subtitle?: ReactNode; titleIcon?: string; @@ -191,22 +191,21 @@ function SideBarItemTemplateWithData({ avatar={AvatarTemplate && } actions={actions} menu={ - !isIOsDevice && - !isAnonymous && - (!isQueued || (isQueued && isPriorityEnabled)) && - ((): ReactElement => ( - - )) + !isIOsDevice && !isAnonymous && (!isQueued || (isQueued && isPriorityEnabled)) + ? (): ReactElement => ( + + ) + : undefined } /> ); diff --git a/apps/meteor/client/sidebar/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx b/apps/meteor/client/sidebar/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx index ceda9d769336..9296f79392dd 100644 --- a/apps/meteor/client/sidebar/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx +++ b/apps/meteor/client/sidebar/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx @@ -14,8 +14,8 @@ const AirGappedRestrictionWarning = ({ isRestricted, remainingDays }: { isRestri } return ( - - This air-gapped workspace will enter read-only mode in <>{{ remainingDays }} days.{' '} + + This air-gapped workspace will enter read-only mode in {remainingDays} days.{' '} Connect it to the internet or upgrade to a premium plan to prevent this. diff --git a/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx b/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx index 673f5357b187..17c75984177b 100644 --- a/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx +++ b/apps/meteor/client/sidebarv2/RoomList/SidebarItemTemplateWithData.tsx @@ -47,7 +47,7 @@ type RoomListRowProps = { actions: unknown; href: string; time?: Date; - menu?: ReactNode; + menu?: () => ReactNode; menuOptions?: unknown; subtitle?: ReactNode; titleIcon?: string; @@ -154,22 +154,21 @@ const SidebarItemTemplateWithData = ({ avatar={AvatarTemplate && } actions={actions} menu={ - !isIOsDevice && - !isAnonymous && - (!isQueued || (isQueued && isPriorityEnabled)) && - ((): ReactElement => ( - 0} - rid={rid} - unread={!!unread} - roomOpen={selected} - type={type} - cl={cl} - name={title} - hideDefaultOptions={isQueued} - /> - )) + !isIOsDevice && !isAnonymous && (!isQueued || (isQueued && isPriorityEnabled)) + ? (): ReactElement => ( + 0} + rid={rid} + unread={!!unread} + roomOpen={selected} + type={type} + cl={cl} + name={title} + hideDefaultOptions={isQueued} + /> + ) + : undefined } /> ); diff --git a/apps/meteor/client/sidebarv2/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx b/apps/meteor/client/sidebarv2/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx index 2ab97312a73e..b1def40e812c 100644 --- a/apps/meteor/client/sidebarv2/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx +++ b/apps/meteor/client/sidebarv2/sections/AirGappedRestrictionBanner/AirGappedRestrictionWarning.tsx @@ -15,7 +15,7 @@ const AirGappedRestrictionWarning = ({ isRestricted, remainingDays }: { isRestri return ( - This air-gapped workspace will enter read-only mode in <>{{ remainingDays }} days.{' '} + This air-gapped workspace will enter read-only mode in {remainingDays} days.{' '} Connect it to internet or upgrade to a premium plan to prevent this. diff --git a/apps/meteor/client/views/admin/integrations/incoming/EditIncomingWebhook.tsx b/apps/meteor/client/views/admin/integrations/incoming/EditIncomingWebhook.tsx index c23c61d892e2..50a698797b3b 100644 --- a/apps/meteor/client/views/admin/integrations/incoming/EditIncomingWebhook.tsx +++ b/apps/meteor/client/views/admin/integrations/incoming/EditIncomingWebhook.tsx @@ -12,7 +12,7 @@ import { useCreateIntegration } from '../hooks/useCreateIntegration'; import { useDeleteIntegration } from '../hooks/useDeleteIntegration'; import { useUpdateIntegration } from '../hooks/useUpdateIntegration'; -type EditIncomingWebhookFormData = { +export type EditIncomingWebhookFormData = { enabled: boolean; channel: string; username: string; diff --git a/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx b/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx index 9470ec8ca70c..f1f641fccfeb 100644 --- a/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx +++ b/apps/meteor/client/views/admin/integrations/incoming/IncomingWebhookForm.tsx @@ -23,6 +23,7 @@ import { useMemo } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; +import type { EditIncomingWebhookFormData } from './EditIncomingWebhook'; import useClipboardWithToast from '../../../../hooks/useClipboardWithToast'; import { useHighlightedCode } from '../../../../hooks/useHighlightedCode'; import { useExampleData } from '../hooks/useExampleIncomingData'; @@ -35,7 +36,7 @@ const IncomingWebhookForm = ({ webhookData }: { webhookData?: Serialized(); const { alias, emoji, avatar } = watch(); const url = absoluteUrl(`hooks/${webhookData?._id}/${webhookData?.token}`); diff --git a/apps/meteor/client/views/admin/permissions/EditRolePage.tsx b/apps/meteor/client/views/admin/permissions/EditRolePage.tsx index 9778f4f4093d..018750e878a1 100644 --- a/apps/meteor/client/views/admin/permissions/EditRolePage.tsx +++ b/apps/meteor/client/views/admin/permissions/EditRolePage.tsx @@ -10,6 +10,14 @@ import RoleForm from './RoleForm'; import { ContextualbarFooter, ContextualbarScrollableContent } from '../../../components/Contextualbar'; import GenericModal from '../../../components/GenericModal'; +export type EditRolePageFormData = { + roleId?: string; + name: string; + description: string; + scope: 'Users' | 'Subscriptions'; + mandatory2fa: boolean; +}; + const EditRolePage = ({ role, isEnterprise }: { role?: IRole; isEnterprise: boolean }): ReactElement => { const { t } = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); @@ -21,7 +29,7 @@ const EditRolePage = ({ role, isEnterprise }: { role?: IRole; isEnterprise: bool const updateRole = useEndpoint('POST', '/v1/roles.update'); const deleteRole = useEndpoint('POST', '/v1/roles.delete'); - const methods = useForm({ + const methods = useForm({ defaultValues: { roleId: role?._id, name: role?.name, diff --git a/apps/meteor/client/views/admin/permissions/RoleForm.tsx b/apps/meteor/client/views/admin/permissions/RoleForm.tsx index a3b0eccbb407..5c725b042d23 100644 --- a/apps/meteor/client/views/admin/permissions/RoleForm.tsx +++ b/apps/meteor/client/views/admin/permissions/RoleForm.tsx @@ -1,10 +1,11 @@ import type { SelectOption } from '@rocket.chat/fuselage'; import { Field, FieldLabel, FieldRow, FieldError, FieldHint, TextInput, Select, ToggleSwitch } from '@rocket.chat/fuselage'; -import type { ReactElement } from 'react'; import { useMemo } from 'react'; import { useFormContext, Controller } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; +import type { EditRolePageFormData } from './EditRolePage'; + type RoleFormProps = { className?: string; editing?: boolean; @@ -12,13 +13,13 @@ type RoleFormProps = { isDisabled?: boolean; }; -const RoleForm = ({ className, editing = false, isProtected = false, isDisabled = false }: RoleFormProps): ReactElement => { +const RoleForm = ({ className, editing = false, isProtected = false, isDisabled = false }: RoleFormProps) => { const { t } = useTranslation(); const { register, control, formState: { errors }, - } = useFormContext(); + } = useFormContext(); const options: SelectOption[] = useMemo( () => [ @@ -54,9 +55,7 @@ const RoleForm = ({ className, editing = false, isProtected = false, isDisabled ( - } /> @@ -66,7 +65,7 @@ const RoleForm = ({ className, editing = false, isProtected = false, isDisabled } + render={({ field: { value, ...field } }) => } /> diff --git a/apps/meteor/client/views/admin/subscription/SubscriptionCalloutLimits.tsx b/apps/meteor/client/views/admin/subscription/SubscriptionCalloutLimits.tsx index bd252acb3c49..a4e2ef55f0d6 100644 --- a/apps/meteor/client/views/admin/subscription/SubscriptionCalloutLimits.tsx +++ b/apps/meteor/client/views/admin/subscription/SubscriptionCalloutLimits.tsx @@ -25,8 +25,12 @@ export const SubscriptionCalloutLimits = () => { <> {start_fair_policy && ( - - Your workspace reached the <>{{ val: start_fair_policy.map(toTranslationKey) }} limit. + + Your workspace reached the <>{start_fair_policy.map(toTranslationKey)} limit. { {prevent_action && ( - - Your workspace exceeded the <>{{ val: prevent_action.map(toTranslationKey) }} license limit. + + Your workspace exceeded the <>{prevent_action.map(toTranslationKey)} license limit. { {disable_modules && ( - - Your workspace exceeded the <>{{ val: disable_modules.map(toTranslationKey) }} license limit. + + Your workspace exceeded the <>{disable_modules.map(toTranslationKey)} license limit. { {invalidate_license && ( - - Your workspace exceeded the <>{{ val: invalidate_license.map(toTranslationKey) }} license limit. + + Your workspace exceeded the <>{invalidate_license.map(toTranslationKey)} license limit. void; roleData: { roles: IRole[] } | undefined; - roleError: unknown; + roleError: Error | null; }; export type UserFormProps = Omit; @@ -363,7 +363,7 @@ const AdminUserForm = ({ userData, onReload, context, refetchUserFormData, roleD {t('Roles')} - {roleError && {roleError}} + {roleError && {roleError.message}} {!roleError && ( void; context: string; roleData: { roles: IRole[] } | undefined; - roleError: unknown; + roleError: Error | null; }; const AdminUserFormWithData = ({ uid, onReload, context, roleData, roleError }: AdminUserFormWithDataProps): ReactElement => { diff --git a/apps/meteor/client/views/admin/users/AdminUsersPage.tsx b/apps/meteor/client/views/admin/users/AdminUsersPage.tsx index 0a792ef75dde..534e591be932 100644 --- a/apps/meteor/client/views/admin/users/AdminUsersPage.tsx +++ b/apps/meteor/client/views/admin/users/AdminUsersPage.tsx @@ -115,8 +115,12 @@ const AdminUsersPage = (): ReactElement => { {preventAction?.includes('activeUsers') && ( - - Your workspace exceeded the <>{{ val: preventAction.map(toTranslationKey) }} license limit. + + Your workspace exceeded the <>{preventAction.map(toTranslationKey)} license limit. { +const RoomTags = ({ room }: { room: Serialized }): ReactElement => { const { t } = useTranslation(); return ( diff --git a/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTable.tsx b/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTable.tsx index 91a55952bca3..bceb9f248e94 100644 --- a/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTable.tsx +++ b/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTable.tsx @@ -1,4 +1,4 @@ -import type { IRoom } from '@rocket.chat/core-typings'; +import type { IRoom, Serialized } from '@rocket.chat/core-typings'; import { Pagination, States, StatesIcon, StatesTitle, StatesActions, StatesAction } from '@rocket.chat/fuselage'; import { useMediaQuery } from '@rocket.chat/fuselage-hooks'; import { useRoute, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; @@ -113,7 +113,7 @@ const ChannelsTable = () => { {headers} {data.result.map((room) => ( - + } onClick={onClick} mediaQuery={mediaQuery} /> ))} diff --git a/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTableRow.tsx b/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTableRow.tsx index f2a894a5df6c..e149531988f3 100644 --- a/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTableRow.tsx +++ b/apps/meteor/client/views/directory/tabs/channels/ChannelsTable/ChannelsTableRow.tsx @@ -1,4 +1,4 @@ -import type { IRoom, ITeam } from '@rocket.chat/core-typings'; +import type { IRoom, Serialized } from '@rocket.chat/core-typings'; import { Box, Avatar } from '@rocket.chat/fuselage'; import type { KeyboardEvent, MouseEvent } from 'react'; @@ -11,7 +11,7 @@ import RoomTags from '../../../RoomTags'; type ChannelsTableRowProps = { onClick: (name: IRoom['name'], type: IRoom['t']) => (e: KeyboardEvent | MouseEvent) => void; - room: IRoom & { belongsTo?: ITeam }; + room: Serialized; mediaQuery: boolean; }; diff --git a/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTable.tsx b/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTable.tsx index e4788d9e5b3e..131319991db3 100644 --- a/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTable.tsx +++ b/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTable.tsx @@ -1,4 +1,4 @@ -import type { IRoom } from '@rocket.chat/core-typings'; +import type { IRoom, Serialized } from '@rocket.chat/core-typings'; import { Pagination, States, StatesIcon, StatesTitle, StatesActions, StatesAction } from '@rocket.chat/fuselage'; import { useMediaQuery } from '@rocket.chat/fuselage-hooks'; import { useRoute, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; @@ -91,7 +91,7 @@ const TeamsTable = () => { {data.result.map((team) => ( & { roomsCount: number }} onClick={onClick} mediaQuery={mediaQuery} /> diff --git a/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTableRow.tsx b/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTableRow.tsx index 50e7a2d1cc7b..86f8ab99b0a6 100644 --- a/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTableRow.tsx +++ b/apps/meteor/client/views/directory/tabs/teams/TeamsTable/TeamsTableRow.tsx @@ -1,4 +1,4 @@ -import type { IRoom } from '@rocket.chat/core-typings'; +import type { IRoom, Serialized } from '@rocket.chat/core-typings'; import { Box, Avatar } from '@rocket.chat/fuselage'; import type { KeyboardEvent, MouseEvent } from 'react'; @@ -11,7 +11,7 @@ import RoomTags from '../../../RoomTags'; type TeamsTableRowProps = { onClick: (name: IRoom['name'], type: IRoom['t']) => (e: KeyboardEvent | MouseEvent) => void; - team: IRoom & { roomsCount: number }; + team: Serialized; mediaQuery: boolean; }; diff --git a/apps/meteor/client/views/oauth/components/AuthorizationFormPage.tsx b/apps/meteor/client/views/oauth/components/AuthorizationFormPage.tsx index 390795ce45fd..d4e9713e055a 100644 --- a/apps/meteor/client/views/oauth/components/AuthorizationFormPage.tsx +++ b/apps/meteor/client/views/oauth/components/AuthorizationFormPage.tsx @@ -60,8 +60,8 @@ const AuthorizationFormPage = ({ oauthApp, redirectUri, user }: AuthorizationFor

- - {{ appName: oauthApp.name }} + + {oauthApp.name}

diff --git a/apps/meteor/client/views/omnichannel/customFields/EditCustomFields.tsx b/apps/meteor/client/views/omnichannel/customFields/EditCustomFields.tsx index 42c62ec616bd..e8bd17e2576f 100644 --- a/apps/meteor/client/views/omnichannel/customFields/EditCustomFields.tsx +++ b/apps/meteor/client/views/omnichannel/customFields/EditCustomFields.tsx @@ -30,6 +30,20 @@ import { import { CustomFieldsAdditionalForm } from '../additionalForms'; import { useRemoveCustomField } from './useRemoveCustomField'; +export type EditCustomFieldsFormData = { + field: string; + label: string; + scope: 'visitor' | 'room'; + visibility: boolean; + searchable: boolean; + regexp: string; + type: string; + required: boolean; + defaultValue: string; + options: string; + public: boolean; +}; + const getInitialValues = (customFieldData: Serialized | undefined) => ({ field: customFieldData?._id || '', label: customFieldData?.label || '', @@ -53,7 +67,7 @@ const EditCustomFields = ({ customFieldData }: { customFieldData?: Serialized({ mode: 'onBlur', values: getInitialValues(customFieldData) }); const { control, handleSubmit, diff --git a/apps/meteor/client/views/room/Header/DirectRoomHeader.tsx b/apps/meteor/client/views/room/Header/DirectRoomHeader.tsx index ad2706b67e70..457626a7f91c 100644 --- a/apps/meteor/client/views/room/Header/DirectRoomHeader.tsx +++ b/apps/meteor/client/views/room/Header/DirectRoomHeader.tsx @@ -1,6 +1,6 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { useUserId } from '@rocket.chat/ui-contexts'; -import type { ReactElement } from 'react'; +import type { ReactElement, ReactNode } from 'react'; import RoomHeader from './RoomHeader'; import { usePresence } from '../../../hooks/usePresence'; @@ -8,15 +8,15 @@ import { usePresence } from '../../../hooks/usePresence'; type DirectRoomHeaderProps = { room: IRoom; slots: { - start?: unknown; - preContent?: unknown; - insideContent?: unknown; - posContent?: unknown; - end?: unknown; + start?: ReactNode; + preContent?: ReactNode; + insideContent?: ReactNode; + posContent?: ReactNode; + end?: ReactNode; toolbox?: { - pre?: unknown; - content?: unknown; - pos?: unknown; + pre?: ReactNode; + content?: ReactNode; + pos?: ReactNode; }; }; }; diff --git a/apps/meteor/client/views/room/Header/Omnichannel/OmnichannelRoomHeader.tsx b/apps/meteor/client/views/room/Header/Omnichannel/OmnichannelRoomHeader.tsx index df47b1e2d686..cbe31d3b7957 100644 --- a/apps/meteor/client/views/room/Header/Omnichannel/OmnichannelRoomHeader.tsx +++ b/apps/meteor/client/views/room/Header/Omnichannel/OmnichannelRoomHeader.tsx @@ -1,4 +1,5 @@ import { useLayout, useRouter } from '@rocket.chat/ui-contexts'; +import type { ReactNode } from 'react'; import { useCallback, useMemo } from 'react'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; @@ -12,15 +13,15 @@ import QuickActions from './QuickActions'; type OmnichannelRoomHeaderProps = { slots: { - start?: unknown; - preContent?: unknown; - insideContent?: unknown; - posContent?: unknown; - end?: unknown; + start?: ReactNode; + preContent?: ReactNode; + insideContent?: ReactNode; + posContent?: ReactNode; + end?: ReactNode; toolbox?: { - pre?: unknown; - content?: unknown; - pos?: unknown; + pre?: ReactNode; + content?: ReactNode; + pos?: ReactNode; }; }; }; diff --git a/apps/meteor/client/views/room/Header/RoomHeader.tsx b/apps/meteor/client/views/room/Header/RoomHeader.tsx index a28f5c882341..931aeaac92a4 100644 --- a/apps/meteor/client/views/room/Header/RoomHeader.tsx +++ b/apps/meteor/client/views/room/Header/RoomHeader.tsx @@ -1,6 +1,7 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { isRoomFederated } from '@rocket.chat/core-typings'; import { RoomAvatar } from '@rocket.chat/ui-avatar'; +import type { ReactNode } from 'react'; import { Suspense } from 'react'; import { useTranslation } from 'react-i18next'; @@ -19,15 +20,15 @@ export type RoomHeaderProps = { room: IRoom; topic?: string; slots: { - start?: unknown; - preContent?: unknown; - insideContent?: unknown; - posContent?: unknown; - end?: unknown; + start?: ReactNode; + preContent?: ReactNode; + insideContent?: ReactNode; + posContent?: ReactNode; + end?: ReactNode; toolbox?: { - pre?: unknown; - content?: unknown; - pos?: unknown; + pre?: ReactNode; + content?: ReactNode; + pos?: ReactNode; }; }; roomToolbox?: JSX.Element; diff --git a/apps/meteor/client/views/room/HeaderV2/Omnichannel/OmnichannelRoomHeader.tsx b/apps/meteor/client/views/room/HeaderV2/Omnichannel/OmnichannelRoomHeader.tsx index 2e3f5997b362..1e405c20130b 100644 --- a/apps/meteor/client/views/room/HeaderV2/Omnichannel/OmnichannelRoomHeader.tsx +++ b/apps/meteor/client/views/room/HeaderV2/Omnichannel/OmnichannelRoomHeader.tsx @@ -1,4 +1,5 @@ import { useLayout, useRouter } from '@rocket.chat/ui-contexts'; +import type { ReactNode } from 'react'; import { useCallback, useMemo } from 'react'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; @@ -12,15 +13,15 @@ import QuickActions from './QuickActions'; type OmnichannelRoomHeaderProps = { slots: { - start?: unknown; - preContent?: unknown; - insideContent?: unknown; - posContent?: unknown; - end?: unknown; + start?: ReactNode; + preContent?: ReactNode; + insideContent?: ReactNode; + posContent?: ReactNode; + end?: ReactNode; toolbox?: { - pre?: unknown; - content?: unknown; - pos?: unknown; + pre?: ReactNode; + content?: ReactNode; + pos?: ReactNode; }; }; }; diff --git a/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx b/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx index e7fc1d9d8d3e..1683873a7c5c 100644 --- a/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx +++ b/apps/meteor/client/views/room/HeaderV2/RoomHeader.tsx @@ -1,6 +1,7 @@ import type { IRoom } from '@rocket.chat/core-typings'; import { isRoomFederated } from '@rocket.chat/core-typings'; import { RoomAvatar } from '@rocket.chat/ui-avatar'; +import type { ReactNode } from 'react'; import { Suspense } from 'react'; import { useTranslation } from 'react-i18next'; @@ -17,15 +18,15 @@ import { Header, HeaderAvatar, HeaderContent, HeaderContentRow, HeaderToolbar } export type RoomHeaderProps = { room: IRoom; slots: { - start?: unknown; - preContent?: unknown; - insideContent?: unknown; - posContent?: unknown; - end?: unknown; + start?: ReactNode; + preContent?: ReactNode; + insideContent?: ReactNode; + posContent?: ReactNode; + end?: ReactNode; toolbox?: { - pre?: unknown; - content?: unknown; - pos?: unknown; + pre?: ReactNode; + content?: ReactNode; + pos?: ReactNode; }; }; roomToolbox?: JSX.Element; diff --git a/apps/meteor/client/views/root/MainLayout/LoginPage.tsx b/apps/meteor/client/views/root/MainLayout/LoginPage.tsx index 4d4cdefe079b..d96d9932631d 100644 --- a/apps/meteor/client/views/root/MainLayout/LoginPage.tsx +++ b/apps/meteor/client/views/root/MainLayout/LoginPage.tsx @@ -9,7 +9,7 @@ import LoggedOutBanner from '../../../components/deviceManagement/LoggedOutBanne const LoginPage = ({ defaultRoute, children }: { defaultRoute?: LoginRoutes; children?: ReactNode }): ReactElement => { const { t } = useTranslation(); - const showForcedLogoutBanner = useSession('force_logout'); + const showForcedLogoutBanner = useSession('force_logout') as boolean; const iframeLoginUrl = useIframeLogin(); if (iframeLoginUrl) { diff --git a/apps/meteor/definition/IRoomTypeConfig.ts b/apps/meteor/definition/IRoomTypeConfig.ts index 12a4bea39f05..c1772ad34cf2 100644 --- a/apps/meteor/definition/IRoomTypeConfig.ts +++ b/apps/meteor/definition/IRoomTypeConfig.ts @@ -78,7 +78,7 @@ export interface IRoomTypeClientDirectives { getUiText: (context: ValueOf) => string; condition: () => boolean; getAvatarPath: ( - room: AtLeast & { username?: IRoom['_id'] }, + room: Pick & { username?: IRoom['_id'] }, ) => string; getIcon?: (room: Partial) => IconName; extractOpenRoomParams?: (routeParams: Record) => { type: RoomType; reference: string }; diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index 93ea90a09a3c..a7f3bbfe7a69 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -407,8 +407,8 @@ "Agree": "Agree", "AI_Actions": "AI actions", "AirGapped_Restriction_Warning": "**Your air-gapped workspace will enter read-only mode in {{remainingDays}} days.** \n Users will still be able to access rooms and read existing messages but will be unable to send new messages. \n Reconnect it to the internet or [upgrade to a premium license](https://go.rocket.chat/i/air-gapped) to prevent this.", - "Airgapped_workspace_warning": "This air-gapped workspace will enter read-only mode in {{remainingDays}} days. <2>Connect it to the internet or upgrade to a premium plan to prevent this.", - "Airgapped_workspace_restriction": "This air-gapped workspace is in read-only mode. <2>Connect it to the internet or upgrade to a premium plan to restore full functionality.", + "Airgapped_workspace_warning": "This air-gapped workspace will enter read-only mode in {{remainingDays}} days. <1>Connect it to the internet or upgrade to a premium plan to prevent this.", + "Airgapped_workspace_restriction": "This air-gapped workspace is in read-only mode. <1>Connect it to the internet or upgrade to a premium plan to restore full functionality.", "Alerts": "Alerts", "Alias": "Alias", "Alias_Format": "Alias Format", diff --git a/packages/livechat/src/routes/Register/index.tsx b/packages/livechat/src/routes/Register/index.tsx index dcf2e3f050a6..4ec7be702179 100644 --- a/packages/livechat/src/routes/Register/index.tsx +++ b/packages/livechat/src/routes/Register/index.tsx @@ -1,11 +1,12 @@ import type { FunctionalComponent } from 'preact'; -import { route } from 'preact-router'; import { useContext, useEffect, useMemo, useRef } from 'preact/hooks'; import type { JSXInternal } from 'preact/src/jsx'; +import { route } from 'preact-router'; import type { FieldValues, SubmitHandler } from 'react-hook-form'; import { Controller, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; +import styles from './styles.scss'; import { Livechat } from '../../api'; import { Button } from '../../components/Button'; import { Form, FormField, TextInput, SelectInput, CustomFields as CustomFieldsForm } from '../../components/Form'; @@ -19,7 +20,6 @@ import { parentCall } from '../../lib/parentCall'; import Triggers from '../../lib/triggers'; import { StoreContext } from '../../store'; import type { StoreState } from '../../store'; -import styles from './styles.scss'; // Custom field as in the form payload type FormPayloadCustomField = { [key: string]: string }; diff --git a/packages/livechat/src/routes/SwitchDepartment/index.tsx b/packages/livechat/src/routes/SwitchDepartment/index.tsx index 5c7f79b9ce5a..5fc3d3b44745 100644 --- a/packages/livechat/src/routes/SwitchDepartment/index.tsx +++ b/packages/livechat/src/routes/SwitchDepartment/index.tsx @@ -1,12 +1,10 @@ import type { IOmnichannelRoom, Serialized } from '@rocket.chat/core-typings'; -import type { FunctionalComponent } from 'preact'; -import { route } from 'preact-router'; import { useContext } from 'preact/hooks'; -import type { JSXInternal } from 'preact/src/jsx'; -import type { FieldValues, SubmitHandler } from 'react-hook-form'; +import { route } from 'preact-router'; import { Controller, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; +import styles from './styles.scss'; import { Livechat } from '../../api'; import { Button } from '../../components/Button'; import { ButtonGroup } from '../../components/ButtonGroup'; @@ -18,9 +16,14 @@ import { loadConfig } from '../../lib/main'; import { createToken } from '../../lib/random'; import type { StoreState } from '../../store'; import { StoreContext } from '../../store'; -import styles from './styles.scss'; -const SwitchDepartment: FunctionalComponent<{ path: string }> = () => { +type SwitchDepartmentFormData = { department: string }; + +type SwitchDepartmentProps = { + path: string; +}; + +const SwitchDepartment = (_: SwitchDepartmentProps) => { const { t } = useTranslation(); const { @@ -41,7 +44,7 @@ const SwitchDepartment: FunctionalComponent<{ path: string }> = () => { handleSubmit, formState: { errors, isDirty, isValid, isSubmitting }, control, - } = useForm({ mode: 'onChange' }); + } = useForm({ mode: 'onChange' }); const departments = deps.filter((dept) => dept.showOnRegistration && dept._id !== guest?.department); @@ -53,7 +56,7 @@ const SwitchDepartment: FunctionalComponent<{ path: string }> = () => { return typeof result.success === 'boolean' && result.success; }; - const onSubmit = async ({ department }: { department: string }) => { + const onSubmit = async ({ department }: SwitchDepartmentFormData) => { const confirm = await confirmChangeDepartment(); if (!confirm) { return; @@ -121,7 +124,7 @@ const SwitchDepartment: FunctionalComponent<{ path: string }> = () => {
) as unknown as JSXInternal.GenericEventHandler} + onSubmit={handleSubmit(onSubmit)} > {suggestions.map((suggestion) => ( diff --git a/yarn.lock b/yarn.lock index 03336ea31696..0b6b8888903d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12336,18 +12336,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*": - version: 17.0.80 - resolution: "@types/react@npm:17.0.80" - dependencies: - "@types/prop-types": "npm:*" - "@types/scheduler": "npm:^0.16" - csstype: "npm:^3.0.2" - checksum: 10/f5dce5825e693313bb7f8db0199299a25be21d58a7f6eedea9dacd593d2b4013d664ed3d54e5fb241a43c7ebbdfeee41d5a500ed2979cc772a89d460aa40d8f4 - languageName: node - linkType: hard - -"@types/react@npm:~17.0.83": +"@types/react@npm:*, @types/react@npm:~17.0.83": version: 17.0.83 resolution: "@types/react@npm:17.0.83" dependencies: