Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Upgrade React #32288

Draft
wants to merge 10 commits into
base: develop
Choose a base branch
from
Draft
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

Large diffs are not rendered by default.

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
20 changes: 14 additions & 6 deletions apps/meteor/client/components/GenericModal/GenericModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useTranslation } from 'react-i18next';

import type { RequiredModalProps } from './withDoNotAskAgain';
import { withDoNotAskAgain } from './withDoNotAskAgain';
import { modalStore } from '../../providers/ModalProvider/ModalStore';

type VariantType = 'danger' | 'warning' | 'info' | 'success';

Expand Down Expand Up @@ -97,13 +98,20 @@ const GenericModal = ({
onClose?.();
});

useEffect(
() => () => {
const handleDismiss = useEffectEvent(() => {
dismissedRef.current = true;
onDismiss?.();
});

useEffect(() => {
const thisModal = modalStore.current;

return () => {
if (thisModal === modalStore.current) return;
if (!dismissedRef.current) return;
onDismiss?.();
},
[onDismiss],
);
handleDismiss();
};
}, [handleDismiss]);

return (
<Modal aria-labelledby={`${genericModalId}-title`} wrapperFunction={wrapperFunction} {...props}>
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
Loading