Skip to content

Commit

Permalink
chore: Upgrade React (#32288)
Browse files Browse the repository at this point in the history
  • Loading branch information
tassoevan authored Jan 29, 2025
1 parent d222467 commit 8e2c989
Show file tree
Hide file tree
Showing 192 changed files with 746 additions and 1,704 deletions.
830 changes: 0 additions & 830 deletions .yarn/patches/@tanstack-react-query-npm-5.60.5-04c500b172.patch

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Keys as IconName } from '@rocket.chat/icons';
import type { TranslationKey } from '@rocket.chat/ui-contexts';
import { flushSync } from 'react-dom';

import AddLinkComposerActionModal from './AddLinkComposerActionModal';
import type { ComposerAPI } from '../../../../client/lib/chats/ChatAPI';
Expand Down Expand Up @@ -72,9 +73,14 @@ export const formattingButtons: ReadonlyArray<FormattingButton> = [
};

const onConfirm = (url: string, text: string) => {
onClose();
composerApi.replaceText(`[${text}](${url})`, selection);
composerApi.setCursorToEnd();
// Composer API can't handle the selection of the text while the modal is open
flushSync(() => {
onClose();
});
flushSync(() => {
composerApi.replaceText(`[${text}](${url})`, selection);
composerApi.setCursorToEnd();
});
};

imperativeModal.open({ component: AddLinkComposerActionModal, props: { onConfirm, selectedText, onClose } });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useAuditMenu } from './useAuditMenu';

it('should return an empty array of items if doesn`t have license', async () => {
const { result } = renderHook(() => useAuditMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/licenses.info', () => ({
// @ts-expect-error: just for testing
Expand All @@ -24,7 +23,6 @@ it('should return an empty array of items if doesn`t have license', async () =>

it('should return an empty array of items if have license and not have permissions', async () => {
const { result } = renderHook(() => useAuditMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/licenses.info', () => ({
license: {
Expand All @@ -46,7 +44,6 @@ it('should return an empty array of items if have license and not have permissio

it('should return auditItems if have license and permissions', async () => {
const { result } = renderHook(() => useAuditMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/licenses.info', () => ({
license: {
Expand Down Expand Up @@ -81,7 +78,6 @@ it('should return auditItems if have license and permissions', async () => {

it('should return auditMessages item if have license and can-audit permission', async () => {
const { result } = renderHook(() => useAuditMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/licenses.info', () => ({
license: {
Expand Down Expand Up @@ -109,7 +105,6 @@ it('should return auditMessages item if have license and can-audit permission',

it('should return audiLogs item if have license and can-audit-log permission', async () => {
const { result } = renderHook(() => useAuditMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/licenses.info', () => ({
license: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useMarketPlaceMenu } from './useMarketPlaceMenu';

it('should return and empty array if the user does not have `manage-apps` and `access-marketplace` permission', () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [])
.build(),
Expand All @@ -17,7 +16,6 @@ it('should return and empty array if the user does not have `manage-apps` and `a

it('should return `explore` and `installed` items if the user has `access-marketplace` permission', () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [])
.withPermission('access-marketplace')
Expand All @@ -39,7 +37,6 @@ it('should return `explore` and `installed` items if the user has `access-market

it('should return `explore`, `installed` and `requested` items if the user has `manage-apps` permission', () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [])
.withEndpoint('GET', '/apps/app-request/stats', () => ({
Expand Down Expand Up @@ -73,7 +70,6 @@ it('should return `explore`, `installed` and `requested` items if the user has `

it('should return one action from the server with no conditions', async () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [
{
Expand Down Expand Up @@ -117,7 +113,6 @@ it('should return one action from the server with no conditions', async () => {
describe('Marketplace menu with role conditions', () => {
it('should return the action if the user has admin role', async () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [
{
Expand Down Expand Up @@ -165,7 +160,6 @@ describe('Marketplace menu with role conditions', () => {

it('should return filter the action if the user doesn`t have admin role', async () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [
{
Expand Down Expand Up @@ -213,7 +207,6 @@ describe('Marketplace menu with role conditions', () => {
describe('Marketplace menu with permission conditions', () => {
it('should return the action if the user has manage-apps permission', async () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [
{
Expand Down Expand Up @@ -259,7 +252,6 @@ describe('Marketplace menu with permission conditions', () => {

it('should return filter the action if the user doesn`t have `any` permission', async () => {
const { result } = renderHook(() => useMarketPlaceMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/apps/actionButtons', () => [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useAdministrationMenu } from './useAdministrationMenu';

it('should return omnichannel item if has `view-livechat-manager` permission ', async () => {
const { result } = renderHook(() => useAdministrationMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/licenses.info', () => ({
// @ts-expect-error this is a mock
Expand All @@ -31,7 +30,6 @@ it('should return omnichannel item if has `view-livechat-manager` permission ',

it('should show administration item if has at least one admin permission', async () => {
const { result } = renderHook(() => useAdministrationMenu(), {
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/licenses.info', () => ({
// @ts-expect-error this is a mock
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Palette } from '@rocket.chat/fuselage';
import type { ScrollValues } from 'rc-scrollbars';
import { Scrollbars } from 'rc-scrollbars';
import type { MutableRefObject, CSSProperties, ReactNode } from 'react';
import type { MutableRefObject, CSSProperties, ReactNode, HTMLAttributes } from 'react';
import { memo, forwardRef, useCallback, useMemo } from 'react';

export type CustomScrollbarsProps = {
overflowX?: boolean;
style?: CSSProperties;
children?: ReactNode;
children?: HTMLAttributes<HTMLElement>['children'];
onScroll?: (values: ScrollValues) => void;
renderView?: typeof Scrollbars.defaultProps.renderView;
renderTrackHorizontal?: typeof Scrollbars.defaultProps.renderTrackHorizontal;
Expand All @@ -26,7 +26,7 @@ const CustomScrollbars = forwardRef<HTMLElement, CustomScrollbarsProps>(function
const scrollbarsStyle = useMemo(() => ({ ...style, ...styleDefault }), [style]);

const refSetter = useCallback(
(scrollbarRef: Scrollbars) => {
(scrollbarRef: Scrollbars | null) => {
if (ref && scrollbarRef) {
if (typeof ref === 'function') {
ref(scrollbarRef.view ?? null);
Expand All @@ -52,7 +52,7 @@ const CustomScrollbars = forwardRef<HTMLElement, CustomScrollbarsProps>(function
renderThumbVertical={({ style, ...props }) => (
<div {...props} style={{ ...style, backgroundColor: Palette.stroke['stroke-dark'].toString(), borderRadius: '4px' }} />
)}
children={children}
children={children as ReactNode} // workaround for incompatible types between react-virtuoso and react-i18next
ref={refSetter}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { ComponentProps, Ref } from 'react';
import type { ComponentPropsWithoutRef } from 'react';
import { forwardRef } from 'react';

import CustomScrollbars from './CustomScrollbars';

type VirtuosoScrollbarsProps = ComponentProps<typeof CustomScrollbars>;
type VirtuosoScrollbarsProps = ComponentPropsWithoutRef<typeof CustomScrollbars>;

const VirtuosoScrollbars = forwardRef(function VirtuosoScrollbars(
{ style, children, ...props }: VirtuosoScrollbarsProps,
ref: Ref<HTMLDivElement>,
const VirtuosoScrollbars = forwardRef<HTMLDivElement, VirtuosoScrollbarsProps>(function VirtuosoScrollbars(
{ style, children, ...props },
ref,
) {
return (
<CustomScrollbars style={style} ref={ref} renderView={(viewProps) => <div {...viewProps} {...props} tabIndex={-1} />}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const renderModal = (modalElement: ReactElement) => {
const {
result: { current: setModal },
} = renderHook(() => useSetModal(), {
legacyRoot: true,
wrapper: ({ children }) => (
<Suspense fallback={null}>
<ModalProviderWithRegion>{children}</ModalProviderWithRegion>
Expand Down
12 changes: 6 additions & 6 deletions apps/meteor/client/components/InfoPanel/InfoPanel.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ export default {
component: InfoPanel,
subcomponents: {
InfoPanelAction: InfoPanelAction as ComponentType<any>,
InfoPanelActionGroup,
InfoPanelAvatar,
InfoPanelField,
InfoPanelLabel,
InfoPanelSection,
InfoPanelText,
InfoPanelActionGroup: InfoPanelActionGroup as ComponentType<any>,
InfoPanelAvatar: InfoPanelAvatar as ComponentType<any>,
InfoPanelField: InfoPanelField as ComponentType<any>,
InfoPanelLabel: InfoPanelLabel as ComponentType<any>,
InfoPanelSection: InfoPanelSection as ComponentType<any>,
InfoPanelText: InfoPanelText as ComponentType<any>,
InfoPanelTitle: InfoPanelTitle as ComponentType<any>,
RetentionPolicyCallout: RetentionPolicyCallout as ComponentType<any>,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ describe('RetentionPolicyCallout', () => {
it('Should render callout if settings are valid', () => {
const fakeRoom = createFakeRoom({ t: 'c' });
render(<RetentionPolicyCallout room={fakeRoom} />, {
legacyRoot: true,
wrapper: createMock({ appliesToChannels: true, TTLChannels: 60000 }),
});
expect(screen.getByRole('alert')).toHaveTextContent('a minute June 1, 2024 at 12:30 AM');
Expand All @@ -23,7 +22,6 @@ describe('RetentionPolicyCallout', () => {
it('Should not render callout if settings are invalid', () => {
const fakeRoom = createFakeRoom({ t: 'c' });
render(<RetentionPolicyCallout room={fakeRoom} />, {
legacyRoot: true,
wrapper: createMock({ appliesToChannels: true, TTLChannels: 60000, advancedPrecisionCron: '* * * 12 *', advancedPrecision: true }),
});
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
Expand Down
2 changes: 0 additions & 2 deletions apps/meteor/client/components/MarkdownText.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const markdownText = `
it('should render html elements as expected using default parser', async () => {
const { container } = render(<MarkdownText content={markdownText} variant='document' />, {
wrapper: mockAppRoot().build(),
legacyRoot: true,
});

const normalizedHtml = normalizeHtml(container.innerHTML);
Expand Down Expand Up @@ -73,7 +72,6 @@ it('should render html elements as expected using default parser', async () => {
it('should render html elements as expected using inline parser', async () => {
const { container } = render(<MarkdownText content={markdownText} variant='inline' />, {
wrapper: mockAppRoot().build(),
legacyRoot: true,
});

const normalizedHtml = normalizeHtml(container.innerHTML);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ it('should not fetch and add selected department if it is already in the departm
selectedDepartment: '5',
}),
{
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/livechat/department', () => ({
count: 25,
Expand Down Expand Up @@ -90,7 +89,6 @@ it('should fetch and add selected department if it is not part of departments li
selectedDepartment: '56f5be8bcf8cd67f9e9bcfdc',
}),
{
legacyRoot: true,
wrapper: mockAppRoot()
.withEndpoint('GET', '/v1/livechat/department', () => ({
count: 25,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const CloseChatModal = ({ department, visitorEmail, onCancel, onConfirm }: Close
};

const onSubmit = useCallback(
({ comment, tags, transcriptPDF, transcriptEmail, subject }: CloseChatModalFormData): void => {
({ comment, tags, transcriptPDF, transcriptEmail, subject }: CloseChatModalFormData) => {
const preferences = {
omnichannelTranscriptPDF: !!transcriptPDF,
omnichannelTranscriptEmail: alwaysSendTranscript ? true : !!transcriptEmail,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const defaultProps = {

it('should show Undo request button when roomOpen is true and transcriptRequest exist', async () => {
const onDiscardMock = jest.fn();
render(<TranscriptModal {...defaultProps} onDiscard={onDiscardMock} />, { legacyRoot: true });
render(<TranscriptModal {...defaultProps} onDiscard={onDiscardMock} />);

const undoRequestButton = await screen.findByText('Undo_request');
await userEvent.click(undoRequestButton);
Expand All @@ -33,14 +33,14 @@ it('should show Undo request button when roomOpen is true and transcriptRequest
});

it('should show Request button when roomOpen is true and transcriptRequest not exist', async () => {
render(<TranscriptModal {...{ ...defaultProps, room: { ...room, transcriptRequest: undefined } }} />, { legacyRoot: true });
render(<TranscriptModal {...{ ...defaultProps, room: { ...room, transcriptRequest: undefined } }} />);

const requestBtn = await screen.findByRole('button', { name: 'request-button' });
expect(requestBtn).toBeInTheDocument();
});

it('should show Send button when roomOpen is false', async () => {
render(<TranscriptModal {...{ ...defaultProps, room: { ...room, open: false } }} />, { legacyRoot: true });
render(<TranscriptModal {...{ ...defaultProps, room: { ...room, open: false } }} />);

const sendBtn = await screen.findByRole('button', { name: 'send-button' });
expect(sendBtn).toBeInTheDocument();
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/client/components/Page/Page.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export default {
title: 'Components/Page',
component: Page,
subcomponents: {
PageContent,
PageContent: PageContent as ComponentType<any>,
PageHeader: PageHeader as ComponentType<any>,
PageScrollableContent,
PageScrollableContentWithShadow,
PageScrollableContent: PageScrollableContent as ComponentType<any>,
PageScrollableContentWithShadow: PageScrollableContentWithShadow as ComponentType<any>,
},
parameters: {
layout: 'fullscreen',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const SidebarTogglerBadge = ({ children }: SidebarTogglerBadgeProps) => (
right: 3px;
`}
>
<Badge variant='danger' children={children} />
<Badge variant='danger'>{children}</Badge>
</Box>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { OptionType } from '@rocket.chat/fuselage';
import { MultiSelectFiltered, Icon, Box, Chip } from '@rocket.chat/fuselage';
import { useDebouncedValue } from '@rocket.chat/fuselage-hooks';
import { UserAvatar } from '@rocket.chat/ui-avatar';
Expand Down Expand Up @@ -93,7 +94,7 @@ const UserAutoCompleteMultipleFederated = ({
);

return (
<OptionsContext.Provider value={{ options }}>
<OptionsContext.Provider value={{ options: options as unknown as OptionType[] }}>
<MultiSelectFiltered
{...props}
data-qa-type='user-auto-complete-input'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { OptionType } from '@rocket.chat/fuselage';
import { Options } from '@rocket.chat/fuselage';
import type { ComponentProps, ReactElement, Ref } from 'react';
import { forwardRef, createContext, useContext } from 'react';
Expand All @@ -9,7 +10,7 @@ import UserAutoCompleteMultipleOption from './UserAutoCompleteMultipleOption';
// but we also need to pass internal state to this renderer, as well as the props that also come from the Select.

type OptionsContextValue = {
options: ComponentProps<typeof Options>['options'];
options: OptionType[];
};

export const OptionsContext = createContext<OptionsContextValue>({
Expand Down
4 changes: 3 additions & 1 deletion apps/meteor/client/components/UserStatusMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ const UserStatusMenu = ({
[hide, reset],
);

useEffect(() => onChange(status), [status, onChange]);
useEffect(() => {
onChange(status);
}, [status, onChange]);

return (
<>
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/client/components/WarningModal.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import WarningModal from './WarningModal';

it('should look good', async () => {
render(<WarningModal text='text' confirmText='confirm' cancelText='cancel' confirm={() => undefined} close={() => undefined} />, {
legacyRoot: true,
wrapper: mockAppRoot().build(),
});

Expand Down
Loading

0 comments on commit 8e2c989

Please sign in to comment.