From 549e38a1c57c91e6a0cbfd02d7d3206916fb598e Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Wed, 6 Jul 2022 10:40:00 -0300 Subject: [PATCH 01/15] remove method calls for room menu component --- apps/meteor/app/e2e/client/tabbar.ts | 6 ++-- apps/meteor/client/sidebar/RoomMenu.tsx | 36 ++++++++++++++----- packages/rest-typings/src/v1/rooms.ts | 13 +++++++ .../src/v1/subscriptionsEndpoints.ts | 8 ++--- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/apps/meteor/app/e2e/client/tabbar.ts b/apps/meteor/app/e2e/client/tabbar.ts index 0d9b5e435c55..22eff563ae98 100644 --- a/apps/meteor/app/e2e/client/tabbar.ts +++ b/apps/meteor/app/e2e/client/tabbar.ts @@ -1,6 +1,6 @@ import { useMemo, useCallback } from 'react'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import { useSetting, usePermission, useMethod } from '@rocket.chat/ui-contexts'; +import { useSetting, usePermission, useEndpoint } from '@rocket.chat/ui-contexts'; import { addAction } from '../../../client/views/room/lib/Toolbox'; import { useReactiveValue } from '../../../client/hooks/useReactiveValue'; @@ -13,10 +13,10 @@ addAction('e2e', ({ room }) => { const canEditRoom = usePermission('edit-room', room._id); const hasPermission = (room.t === 'd' || (canEditRoom && canToggleE2e)) && e2eReady; - const toggleE2E = useMethod('saveRoomSettings'); + const toggleE2E = useEndpoint('POST', '/v1/rooms.saveRoomSettings'); const action = useMutableCallback(() => { - toggleE2E(room._id, 'encrypted', !room.encrypted); + toggleE2E({ rid: room._id, encrypted: !room.encrypted }); }); const enabledOnRoom = !!room.encrypted; diff --git a/apps/meteor/client/sidebar/RoomMenu.tsx b/apps/meteor/client/sidebar/RoomMenu.tsx index 01a334cff29f..7241862f29dc 100644 --- a/apps/meteor/client/sidebar/RoomMenu.tsx +++ b/apps/meteor/client/sidebar/RoomMenu.tsx @@ -12,6 +12,7 @@ import { useTranslation, TranslationKey, Fields, + useEndpoint, } from '@rocket.chat/ui-contexts'; import React, { memo, ReactElement, useMemo } from 'react'; @@ -39,6 +40,24 @@ type RoomMenuProps = { name?: string; }; +const closeEndpoints = { + p: '/v1/groups.close', + c: '/v1/channels.close', + d: '/v1/im.close', + + v: '/v1/channels.close', + l: '/v1/groups.close', +} as const; + +const leaveEndpoints = { + p: '/v1/groups.leave', + c: '/v1/channels.leave', + d: '/v1/im.leave', + + v: '/v1/channels.leave', + l: '/v1/groups.leave', +} as const; + const RoomMenu = ({ rid, unread, threadUnread, alert, roomOpen, type, cl, name = '' }: RoomMenuProps): ReactElement => { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); @@ -54,11 +73,12 @@ const RoomMenu = ({ rid, unread, threadUnread, alert, roomOpen, type, cl, name = const dontAskHideRoom = useDontAskAgain('hideRoom'); - const hideRoom = useMethod('hideRoom'); - const readMessages = useMethod('readMessages'); + const hideRoom = useEndpoint('POST', closeEndpoints[type]); + const readMessages = useEndpoint('POST', '/v1/subscriptions.read'); + const toggleFavorite = useEndpoint('POST', '/v1/rooms.favorite'); + const leaveRoom = useEndpoint('POST', leaveEndpoints[type]); + const unreadMessages = useMethod('unreadMessages'); - const toggleFavorite = useMethod('toggleFavorite'); - const leaveRoom = useMethod('leaveRoom'); const isUnread = alert || unread || threadUnread; @@ -78,7 +98,7 @@ const RoomMenu = ({ rid, unread, threadUnread, alert, roomOpen, type, cl, name = const handleLeave = useMutableCallback(() => { const leave = async (): Promise => { try { - await leaveRoom(rid); + await leaveRoom({ roomId: rid }); if (roomOpen) { router.push({}); } @@ -106,7 +126,7 @@ const RoomMenu = ({ rid, unread, threadUnread, alert, roomOpen, type, cl, name = const handleHide = useMutableCallback(async () => { const hide = async (): Promise => { try { - await hideRoom(rid); + await hideRoom({ roomId: rid }); } catch (error) { dispatchToastMessage({ type: 'error', message: String(error) }); } @@ -140,7 +160,7 @@ const RoomMenu = ({ rid, unread, threadUnread, alert, roomOpen, type, cl, name = const handleToggleRead = useMutableCallback(async () => { try { if (isUnread) { - await readMessages(rid); + await readMessages({ rid }); return; } await unreadMessages(null, rid); @@ -157,7 +177,7 @@ const RoomMenu = ({ rid, unread, threadUnread, alert, roomOpen, type, cl, name = const handleToggleFavorite = useMutableCallback(async () => { try { - await toggleFavorite(rid, !isFavorite); + await toggleFavorite({ roomId: rid, favorite: !isFavorite }); } catch (error) { dispatchToastMessage({ type: 'error', message: String(error) }); } diff --git a/packages/rest-typings/src/v1/rooms.ts b/packages/rest-typings/src/v1/rooms.ts index 0f5ef83c5655..806e5511ef69 100644 --- a/packages/rest-typings/src/v1/rooms.ts +++ b/packages/rest-typings/src/v1/rooms.ts @@ -479,4 +479,17 @@ export type RoomsEndpoints = { success: boolean; }; }; + '/v1/rooms.favorite': { + POST: ( + params: + | { + roomId: string; + favorite: boolean; + } + | { + roomName: string; + favorite: boolean; + }, + ) => void; + }; }; diff --git a/packages/rest-typings/src/v1/subscriptionsEndpoints.ts b/packages/rest-typings/src/v1/subscriptionsEndpoints.ts index d913fb8ebc1d..43746f2a8eac 100644 --- a/packages/rest-typings/src/v1/subscriptionsEndpoints.ts +++ b/packages/rest-typings/src/v1/subscriptionsEndpoints.ts @@ -88,24 +88,24 @@ const SubscriptionsUnreadSchema = { export const isSubscriptionsUnreadProps = ajv.compile(SubscriptionsUnreadSchema); export type SubscriptionsEndpoints = { - 'subscriptions.get': { + '/v1/subscriptions.get': { GET: (params: SubscriptionsGet) => { update: ISubscription[]; remove: (Pick & { _deletedAt: Date })[]; }; }; - 'subscriptions.getOne': { + '/v1/subscriptions.getOne': { GET: (params: SubscriptionsGetOne) => { subscription: ISubscription | null; }; }; - 'subscriptions.read': { + '/v1/subscriptions.read': { POST: (params: SubscriptionsRead) => void; }; - 'subscriptions.unread': { + '/v1/subscriptions.unread': { POST: (params: SubscriptionsUnread) => void; }; }; From 4200410aed00733ed74183daa287b86e8a4fe543 Mon Sep 17 00:00:00 2001 From: Yash Rajpal <58601732+yash-rajpal@users.noreply.github.com> Date: Fri, 8 Jul 2022 22:32:51 +0530 Subject: [PATCH 02/15] Chore: Remove setUserStatus method call (#26186) --- apps/meteor/client/sidebar/header/EditStatusModal.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/meteor/client/sidebar/header/EditStatusModal.tsx b/apps/meteor/client/sidebar/header/EditStatusModal.tsx index 93b04600fb83..7371bbdd608e 100644 --- a/apps/meteor/client/sidebar/header/EditStatusModal.tsx +++ b/apps/meteor/client/sidebar/header/EditStatusModal.tsx @@ -1,7 +1,7 @@ import type { IUser } from '@rocket.chat/core-typings'; import { Field, TextInput, FieldGroup, Modal, Icon, ButtonGroup, Button } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import { useToastMessageDispatch, useSetting, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import { useToastMessageDispatch, useSetting, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; import React, { ReactElement, useState, ChangeEvent, useCallback } from 'react'; import { USER_STATUS_TEXT_MAX_LENGTH } from '../../components/UserStatus'; @@ -15,7 +15,6 @@ type EditStatusModalProps = { const EditStatusModal = ({ onClose, userStatus, userStatusText }: EditStatusModalProps): ReactElement => { const allowUserStatusMessageChange = useSetting('Accounts_AllowUserStatusMessageChange'); - const setUserStatus = useMethod('setUserStatus'); const dispatchToastMessage = useToastMessageDispatch(); const t = useTranslation(); @@ -23,6 +22,8 @@ const EditStatusModal = ({ onClose, userStatus, userStatusText }: EditStatusModa const [statusType, setStatusType] = useState(userStatus); const [statusTextError, setStatusTextError] = useState(); + const setUserStatus = useEndpoint('POST', '/v1/users.setStatus'); + const handleStatusText = useMutableCallback((e: ChangeEvent): void => { setStatusText(e.currentTarget.value); @@ -37,14 +38,14 @@ const EditStatusModal = ({ onClose, userStatus, userStatusText }: EditStatusModa const handleSaveStatus = useCallback(async () => { try { - await setUserStatus(statusType, statusText); + await setUserStatus({ message: statusText, status: statusType }); dispatchToastMessage({ type: 'success', message: t('StatusMessage_Changed_Successfully') }); } catch (error) { dispatchToastMessage({ type: 'error', message: String(error) }); } onClose(); - }, [dispatchToastMessage, statusType, statusText, setUserStatus, onClose, t]); + }, [dispatchToastMessage, setUserStatus, statusText, statusType, onClose, t]); return ( From 60ab310f4bfb999099e032c099f14a501ef67bb6 Mon Sep 17 00:00:00 2001 From: Yash Rajpal <58601732+yash-rajpal@users.noreply.github.com> Date: Fri, 8 Jul 2022 22:33:25 +0530 Subject: [PATCH 03/15] Chore: Remove custom user status method calls (#26191) --- .../admin/customUserStatus/CustomUserStatusForm.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusForm.tsx b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusForm.tsx index 8df628c9041b..36e9207c4c62 100644 --- a/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusForm.tsx +++ b/apps/meteor/client/views/admin/customUserStatus/CustomUserStatusForm.tsx @@ -1,6 +1,6 @@ import { IUserStatus } from '@rocket.chat/core-typings'; import { Button, ButtonGroup, TextInput, Field, Select, Icon, SelectOption } from '@rocket.chat/fuselage'; -import { useSetModal, useRoute, useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import { useSetModal, useRoute, useToastMessageDispatch, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; import React, { useCallback, ReactElement } from 'react'; import { useForm, Controller } from 'react-hook-form'; @@ -29,13 +29,13 @@ const CustomUserStatusForm = ({ onClose, onReload, status }: CustomUserStatusFor defaultValues: { name: status?.name ?? '', statusType: status?.statusType ?? '' }, }); - const saveStatus = useMethod('insertOrUpdateUserStatus'); - const deleteStatus = useMethod('deleteCustomUserStatus'); + const saveStatus = useEndpoint('POST', _id ? '/v1/custom-user-status.update' : '/v1/custom-user-status.create'); + const deleteStatus = useEndpoint('POST', '/v1/custom-user-status.delete'); const handleSave = useCallback( async (data) => { try { - await saveStatus({ _id, previousName: name, previousStatusType: statusType, ...data }); + await saveStatus({ _id, name, statusType, ...data }); dispatchToastMessage({ type: 'success', @@ -58,7 +58,7 @@ const CustomUserStatusForm = ({ onClose, onReload, status }: CustomUserStatusFor const handleDelete = async (): Promise => { try { - await deleteStatus(_id); + await deleteStatus({ customUserStatusId: _id || '' }); dispatchToastMessage({ type: 'success', message: t('Custom_User_Status_Has_Been_Deleted') }); onReload(); route.push({}); From 8b993666fa088126f137c343aca7f2025140b325 Mon Sep 17 00:00:00 2001 From: Filipe Marins Date: Fri, 8 Jul 2022 17:50:40 -0300 Subject: [PATCH 04/15] Chore: Remove meteor call on AccountBox (#26202) --- apps/meteor/app/ui-utils/client/lib/AccountBox.ts | 7 ++++--- apps/meteor/client/sidebar/header/UserDropdown.tsx | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/meteor/app/ui-utils/client/lib/AccountBox.ts b/apps/meteor/app/ui-utils/client/lib/AccountBox.ts index a3f42a8645bc..d7829a93ffbd 100644 --- a/apps/meteor/app/ui-utils/client/lib/AccountBox.ts +++ b/apps/meteor/app/ui-utils/client/lib/AccountBox.ts @@ -1,10 +1,11 @@ import { IUIActionButton, IUActionButtonWhen } from '@rocket.chat/apps-engine/definition/ui/IUIActionButtonDescriptor'; +import { UserStatus } from '@rocket.chat/core-typings'; import { ReactiveVar } from 'meteor/reactive-var'; import { Tracker } from 'meteor/tracker'; -import { Meteor } from 'meteor/meteor'; import { SideNav } from './SideNav'; import { applyDropdownActionButtonFilters } from '../../../ui-message/client/actionButtons/lib/applyButtonFilters'; +import { APIClient } from '../../../utils/client'; export interface IAppAccountBoxItem extends IUIActionButton { name: string; @@ -31,8 +32,8 @@ export class AccountBoxBase { private status = 0; - public setStatus(status: number, statusText: string): any { - return Meteor.call('setUserStatus', status, statusText); + public setStatus(status: UserStatus, statusText: string): any { + return APIClient.post('/v1/users.setStatus', { status, message: statusText }); } public open(): void { diff --git a/apps/meteor/client/sidebar/header/UserDropdown.tsx b/apps/meteor/client/sidebar/header/UserDropdown.tsx index 56e4862594e8..b2632f515f53 100644 --- a/apps/meteor/client/sidebar/header/UserDropdown.tsx +++ b/apps/meteor/client/sidebar/header/UserDropdown.tsx @@ -42,7 +42,7 @@ const isDefaultStatus = (id: string): boolean => (Object.values(UserStatusEnum) const isDefaultStatusName = (_name: string, id: string): _name is UserStatusEnum => isDefaultStatus(id); const setStatus = (status: typeof userStatus.list['']): void => { - AccountBox.setStatus(status.statusType as unknown as number, !isDefaultStatus(status.id) ? status.name : ''); + AccountBox.setStatus(status.statusType, !isDefaultStatus(status.id) ? status.name : ''); callbacks.run('userStatusManuallySet', status); }; From 72f0c7335522423e41d7ae37ddad36c0a6180fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Jaeger=20Foresti?= <60678893+juliajforesti@users.noreply.github.com> Date: Mon, 11 Jul 2022 09:51:44 -0300 Subject: [PATCH 05/15] Chore: useMethod remove - AssetSettingInput (#26198) Co-authored-by: Guilherme Gazzo --- apps/meteor/app/api/server/v1/assets.ts | 20 +++++++------- .../settings/inputs/AssetSettingInput.tsx | 26 ++++++++----------- apps/meteor/tests/end-to-end/api/14-assets.js | 6 ++++- packages/rest-typings/src/v1/assets.ts | 21 ++++++++++++--- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/apps/meteor/app/api/server/v1/assets.ts b/apps/meteor/app/api/server/v1/assets.ts index 655d4fa49e23..db3d63827535 100644 --- a/apps/meteor/app/api/server/v1/assets.ts +++ b/apps/meteor/app/api/server/v1/assets.ts @@ -10,10 +10,14 @@ API.v1.addRoute( { authRequired: true }, { async post() { - const [asset, { refreshAllClients }, assetName] = await getUploadFormData({ - request: this.request, - }); + const [asset, { refreshAllClients, assetName: customName }, fileName] = await getUploadFormData( + { + request: this.request, + }, + { field: 'asset' }, + ); + const assetName = customName || fileName; const assetsKeys = Object.keys(RocketChatAssets.assets); const isValidAsset = assetsKeys.includes(assetName); @@ -21,12 +25,10 @@ API.v1.addRoute( throw new Meteor.Error('error-invalid-asset', 'Invalid asset'); } - Meteor.runAsUser(this.userId, () => { - Meteor.call('setAsset', asset.fileBuffer, asset.mimetype, assetName); - if (refreshAllClients) { - Meteor.call('refreshClients'); - } - }); + Meteor.call('setAsset', asset.fileBuffer, asset.mimetype, assetName); + if (refreshAllClients) { + Meteor.call('refreshClients'); + } return API.v1.success(); }, diff --git a/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.tsx b/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.tsx index 7ca04c117659..2cf364899549 100644 --- a/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.tsx +++ b/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.tsx @@ -1,5 +1,5 @@ import { Button, Field, Icon } from '@rocket.chat/fuselage'; -import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import { useToastMessageDispatch, useEndpoint, useTranslation, useUpload } from '@rocket.chat/ui-contexts'; import { Random } from 'meteor/random'; import React, { ChangeEventHandler, DragEvent, ReactElement } from 'react'; @@ -17,8 +17,8 @@ function AssetSettingInput({ _id, label, value, asset, fileConstraints }: AssetS const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); - const setAsset = useMethod('setAsset'); - const unsetAsset = useMethod('unsetAsset'); + const setAsset = useUpload('/v1/assets.setAsset'); + const unsetAsset = useEndpoint('POST', '/v1/assets.unsetAsset'); const isDataTransferEvent = (event: T): event is T & DragEvent => Boolean('dataTransfer' in event && (event as any).dataTransfer.files); @@ -32,24 +32,20 @@ function AssetSettingInput({ _id, label, value, asset, fileConstraints }: AssetS } } - Object.values(files ?? []).forEach((blob) => { + Object.values(files ?? []).forEach(async (blob) => { dispatchToastMessage({ type: 'info', message: t('Uploading_file') }); - const reader = new FileReader(); - reader.readAsBinaryString(blob); - reader.onloadend = async (): Promise => { - try { - await setAsset(reader.result, blob.type, asset); - dispatchToastMessage({ type: 'success', message: t('File_uploaded') }); - } catch (error) { - dispatchToastMessage({ type: 'error', message: String(error) }); - } - }; + + const fileData = new FormData(); + fileData.append('asset', blob, asset); + fileData.append('assetName', asset); + + await setAsset(fileData); }); }; const handleDeleteButtonClick = async (): Promise => { try { - await unsetAsset(asset); + await unsetAsset({ assetName: asset }); } catch (error) { dispatchToastMessage({ type: 'error', message: String(error) }); } diff --git a/apps/meteor/tests/end-to-end/api/14-assets.js b/apps/meteor/tests/end-to-end/api/14-assets.js index 6dcf99652043..1a01bb092409 100644 --- a/apps/meteor/tests/end-to-end/api/14-assets.js +++ b/apps/meteor/tests/end-to-end/api/14-assets.js @@ -26,7 +26,11 @@ describe('[Assets]', function () { request .post(api('assets.setAsset')) .set(credentials) - .attach('logo', imgURL) + .attach('asset', imgURL) + + .field({ + assetName: 'logo', + }) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { diff --git a/packages/rest-typings/src/v1/assets.ts b/packages/rest-typings/src/v1/assets.ts index fc318f63ba49..3e867d41eab8 100644 --- a/packages/rest-typings/src/v1/assets.ts +++ b/packages/rest-typings/src/v1/assets.ts @@ -3,12 +3,14 @@ import type { IRocketChatAssets } from '@rocket.chat/core-typings'; export type AssetsUnsetAssetProps = { assetName: keyof IRocketChatAssets; refreshAllClients?: boolean }; +export type AssetsSetAssetProps = { asset: string | ArrayBuffer; assetName: keyof IRocketChatAssets; refreshAllClients?: boolean }; + export type AssetsEndpoints = { - 'assets.setAsset': { - POST: (params: AssetsUnsetAssetProps) => void; + '/v1/assets.setAsset': { + POST: (params: AssetsSetAssetProps) => void; }; - 'assets.unsetAsset': { + '/v1/assets.unsetAsset': { POST: (params: AssetsUnsetAssetProps) => void; }; }; @@ -25,4 +27,17 @@ const assetsUnsetAssetPropsSchema: JSONSchemaType = { additionalProperties: false, }; +const assetsSetAssetPropsSchema: JSONSchemaType = { + type: 'object', + properties: { + assetName: { type: 'string' }, + asset: { type: 'string' }, + refreshAllClients: { type: 'boolean', nullable: true }, + }, + required: ['assetName'], + additionalProperties: false, +}; + export const isAssetsUnsetAssetProps = ajv.compile(assetsUnsetAssetPropsSchema); + +export const isAssetsSetAssetProps = ajv.compile(assetsSetAssetPropsSchema); From 9531e08b77654c8bd7594cb3b1ad829946c7796a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlia=20Jaeger=20Foresti?= <60678893+juliajforesti@users.noreply.github.com> Date: Mon, 11 Jul 2022 10:04:48 -0300 Subject: [PATCH 06/15] Chore: useMethod remove - InformationRoute (#26189) Co-authored-by: Guilherme Gazzo --- .../client/views/admin/info/InformationRoute.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/meteor/client/views/admin/info/InformationRoute.tsx b/apps/meteor/client/views/admin/info/InformationRoute.tsx index 0f3e68e5a35a..b98140675e57 100644 --- a/apps/meteor/client/views/admin/info/InformationRoute.tsx +++ b/apps/meteor/client/views/admin/info/InformationRoute.tsx @@ -1,6 +1,6 @@ -import type { IStats } from '@rocket.chat/core-typings'; +import type { IInstanceStatus, IStats } from '@rocket.chat/core-typings'; import { Callout, ButtonGroup, Button, Icon } from '@rocket.chat/fuselage'; -import { usePermission, useMethod, useServerInformation, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; +import { usePermission, useServerInformation, useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; import React, { useState, useEffect, memo, ReactElement } from 'react'; import Page from '../../../components/Page'; @@ -18,10 +18,10 @@ const InformationRoute = (): ReactElement => { const [isLoading, setLoading] = useState(true); const [error, setError] = useState(false); const [statistics, setStatistics] = useState(); - const [instances, setInstances] = useState([]); + const [instances, setInstances] = useState(); const [fetchStatistics, setFetchStatistics] = useState(() => (): void => undefined); const getStatistics = useEndpoint('GET', '/v1/statistics'); - const getInstances = useMethod('instances/get'); + const getInstances = useEndpoint('GET', '/v1/instances.get'); useEffect(() => { let didCancel = false; @@ -31,13 +31,13 @@ const InformationRoute = (): ReactElement => { setError(false); try { - const [statistics, instances] = await Promise.all([getStatistics({ refresh: refresh ? 'true' : 'false' }), getInstances()]); + const [statistics, { instances }] = await Promise.all([getStatistics({ refresh: refresh ? 'true' : 'false' }), getInstances()]); if (didCancel) { return; } setStatistics(statistics); - setInstances(instances); + setInstances(instances as IInstanceStatus[]); } catch (error) { setError(!!error); } finally { @@ -98,7 +98,7 @@ const InformationRoute = (): ReactElement => { canViewStatistics={canViewStatistics} info={info} statistics={statistics} - instances={instances} + instances={instances || []} onClickRefreshButton={handleClickRefreshButton} onClickDownloadInfo={handleClickDownloadInfo} /> From c2721ed904ef58b1a3366fbdb91ef1d9d0882cb5 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Mon, 25 Jul 2022 23:09:19 -0300 Subject: [PATCH 07/15] rooms.saveRoomSettings' --- apps/meteor/client/providers/SettingsProvider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/providers/SettingsProvider.tsx b/apps/meteor/client/providers/SettingsProvider.tsx index 0ed442dabc11..2d90c64c5faf 100644 --- a/apps/meteor/client/providers/SettingsProvider.tsx +++ b/apps/meteor/client/providers/SettingsProvider.tsx @@ -1,4 +1,4 @@ -import { SettingsContext, SettingsContextValue, useAtLeastOnePermission, useMethod } from '@rocket.chat/ui-contexts'; +import { SettingsContext, SettingsContextValue, useAtLeastOnePermission, useEndpoint, useMethod } from '@rocket.chat/ui-contexts'; import { Tracker } from 'meteor/tracker'; import React, { useCallback, useEffect, useMemo, useState, FunctionComponent } from 'react'; @@ -80,7 +80,7 @@ const SettingsProvider: FunctionComponent = ({ children, [cachedCollection], ); - const saveSettings = useMethod('saveSettings'); + const saveSettings = useEndpoint('POST', '/v1/rooms.saveRoomSettings'); const dispatch = useCallback( async (changes) => { await saveSettings(changes); From 056c9b7e4387745450468b840c8bc7ec1bdb0f9c Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Mon, 25 Jul 2022 23:09:27 -0300 Subject: [PATCH 08/15] spotlight --- apps/meteor/client/sidebar/search/SearchList.tsx | 8 ++++---- packages/rest-typings/src/v1/misc.ts | 10 +--------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/apps/meteor/client/sidebar/search/SearchList.tsx b/apps/meteor/client/sidebar/search/SearchList.tsx index d73620d8a5ef..94e2c0d2c479 100644 --- a/apps/meteor/client/sidebar/search/SearchList.tsx +++ b/apps/meteor/client/sidebar/search/SearchList.tsx @@ -10,7 +10,7 @@ import { useMergedRefs, } from '@rocket.chat/fuselage-hooks'; import { escapeRegExp } from '@rocket.chat/string-helpers'; -import { useUserPreference, useUserSubscriptions, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; +import { useUserPreference, useUserSubscriptions, useSetting, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { forwardRef, @@ -29,7 +29,7 @@ import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; import tinykeys from 'tinykeys'; import { AsyncStatePhase } from '../../hooks/useAsyncState'; -import { useMethodData } from '../../hooks/useMethodData'; +import { useEndpointData } from '../../hooks/useEndpointData'; import { useAvatarTemplate } from '../hooks/useAvatarTemplate'; import { useTemplateByViewMode } from '../hooks/useTemplateByViewMode'; import Row from './Row'; @@ -63,9 +63,9 @@ const useSpotlight = (filterText: string, usernames: string[]) => { return { users: true, rooms: true }; }, [searchForChannels, searchForDMs]); - const args = useMemo(() => [name, usernames, type], [type, name, usernames]); + const query = useMemo(() => ({ query: JSON.stringify([name, usernames, type]) }), [type, name, usernames]); - const { value: data, phase: status } = useMethodData('spotlight', args); + const { value: data, phase: status } = useEndpointData('/v1/spotlight', query); return useMemo(() => { if (!data) { diff --git a/packages/rest-typings/src/v1/misc.ts b/packages/rest-typings/src/v1/misc.ts index 5271af72212b..dd44d494a65f 100644 --- a/packages/rest-typings/src/v1/misc.ts +++ b/packages/rest-typings/src/v1/misc.ts @@ -40,7 +40,7 @@ const ShieldSvgSchema = { export const isShieldSvgProps = ajv.compile(ShieldSvgSchema); -type Spotlight = { query: string; limit: number; offset: number }; +type Spotlight = { query: string }; const SpotlightSchema = { type: 'object', @@ -48,14 +48,6 @@ const SpotlightSchema = { query: { type: 'string', }, - limit: { - type: 'number', - nullable: true, - }, - offset: { - type: 'number', - nullable: true, - }, }, required: ['query'], additionalProperties: false, From 40cd2a5cb0c5214ff72f555c8bcb7fde086fe6ff Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Tue, 26 Jul 2022 09:15:17 -0300 Subject: [PATCH 09/15] ci --- apps/meteor/client/providers/SettingsProvider.tsx | 2 +- apps/meteor/client/sidebar/search/SearchList.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/providers/SettingsProvider.tsx b/apps/meteor/client/providers/SettingsProvider.tsx index 2d90c64c5faf..ebd4f51c8f8b 100644 --- a/apps/meteor/client/providers/SettingsProvider.tsx +++ b/apps/meteor/client/providers/SettingsProvider.tsx @@ -1,4 +1,4 @@ -import { SettingsContext, SettingsContextValue, useAtLeastOnePermission, useEndpoint, useMethod } from '@rocket.chat/ui-contexts'; +import { SettingsContext, SettingsContextValue, useAtLeastOnePermission, useEndpoint } from '@rocket.chat/ui-contexts'; import { Tracker } from 'meteor/tracker'; import React, { useCallback, useEffect, useMemo, useState, FunctionComponent } from 'react'; diff --git a/apps/meteor/client/sidebar/search/SearchList.tsx b/apps/meteor/client/sidebar/search/SearchList.tsx index 94e2c0d2c479..a3ab8dc6c197 100644 --- a/apps/meteor/client/sidebar/search/SearchList.tsx +++ b/apps/meteor/client/sidebar/search/SearchList.tsx @@ -10,7 +10,7 @@ import { useMergedRefs, } from '@rocket.chat/fuselage-hooks'; import { escapeRegExp } from '@rocket.chat/string-helpers'; -import { useUserPreference, useUserSubscriptions, useSetting, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; +import { useUserPreference, useUserSubscriptions, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { forwardRef, From 7282ca3c31bd2753acae1b926211b9138d661aff Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 29 Jul 2022 11:23:59 -0300 Subject: [PATCH 10/15] misc --- packages/rest-typings/src/v1/misc.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rest-typings/src/v1/misc.ts b/packages/rest-typings/src/v1/misc.ts index dd44d494a65f..1e7ce6e95fba 100644 --- a/packages/rest-typings/src/v1/misc.ts +++ b/packages/rest-typings/src/v1/misc.ts @@ -181,8 +181,8 @@ export type MiscEndpoints = { '/v1/spotlight': { GET: (params: Spotlight) => { - users: Pick[]; - rooms: IRoom[]; + users: Pick, 'name' | 'status' | 'statusText' | 'avatarETag' | '_id' | 'username'>[]; + rooms: Pick, 't' | 'name' | 'lastMessage' | '_id'>[]; }; }; From cb4261cf51bc04e1f9c3a7243f4a5be3b40e58fa Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Fri, 29 Jul 2022 18:10:59 -0300 Subject: [PATCH 11/15] Chore: Replace `useMethodData` (#26208) Co-authored-by: Guilherme Gazzo --- apps/meteor/client/hooks/useMethodData.ts | 38 ---- .../client/hooks/usePolledMethodData.ts | 29 --- .../client/sidebar/search/SearchList.tsx | 175 +++++++++--------- .../client/views/admin/cloud/CloudPage.tsx | 37 ++-- .../federationDashboard/OverviewSection.tsx | 45 ++--- .../federationDashboard/ServersSection.tsx | 28 ++- .../{ResetPassword.js => ResetPassword.tsx} | 50 +++-- .../facebook/FacebookPageContainer.tsx | 66 +++---- .../ReadReceiptsModal/ReadReceiptsModal.tsx | 30 +-- apps/meteor/definition/methods/federation.ts | 4 +- .../{AuditLogPage.js => AuditLogPage.tsx} | 22 +-- ...DateRangePicker.js => DateRangePicker.tsx} | 32 ++-- apps/meteor/ee/definition/methods.ts | 1 + .../ui-contexts/src/ServerContext/methods.ts | 5 + 14 files changed, 246 insertions(+), 316 deletions(-) delete mode 100644 apps/meteor/client/hooks/useMethodData.ts delete mode 100644 apps/meteor/client/hooks/usePolledMethodData.ts rename apps/meteor/client/views/login/ResetPassword/{ResetPassword.js => ResetPassword.tsx} (69%) rename apps/meteor/ee/client/audit/{AuditLogPage.js => AuditLogPage.tsx} (61%) rename apps/meteor/ee/client/audit/{DateRangePicker.js => DateRangePicker.tsx} (75%) diff --git a/apps/meteor/client/hooks/useMethodData.ts b/apps/meteor/client/hooks/useMethodData.ts deleted file mode 100644 index 3c7388cc17a6..000000000000 --- a/apps/meteor/client/hooks/useMethodData.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { Awaited } from '@rocket.chat/core-typings'; -import { useToastMessageDispatch, ServerMethodFunction, ServerMethodParameters, ServerMethods, useMethod } from '@rocket.chat/ui-contexts'; -import { useCallback, useEffect } from 'react'; - -import { AsyncState, useAsyncState } from './useAsyncState'; - -export const useMethodData = >>>( - methodName: MethodName, - args: ServerMethodParameters, - initialValue?: Result | (() => Result), -): AsyncState & { reload: () => void } => { - const { resolve, reject, reset, ...state } = useAsyncState(initialValue); - const dispatchToastMessage = useToastMessageDispatch(); - const getData: ServerMethodFunction = useMethod(methodName); - - const fetchData = useCallback(() => { - reset(); - getData(...args) - .then(resolve) - .catch((error) => { - console.error(error); - dispatchToastMessage({ - type: 'error', - message: error, - }); - reject(error); - }); - }, [reset, getData, args, resolve, dispatchToastMessage, reject]); - - useEffect(() => { - fetchData(); - }, [fetchData]); - - return { - ...state, - reload: fetchData, - }; -}; diff --git a/apps/meteor/client/hooks/usePolledMethodData.ts b/apps/meteor/client/hooks/usePolledMethodData.ts deleted file mode 100644 index dce09ebba935..000000000000 --- a/apps/meteor/client/hooks/usePolledMethodData.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Awaited } from '@rocket.chat/core-typings'; -import { ServerMethodFunction, ServerMethodParameters, ServerMethods } from '@rocket.chat/ui-contexts'; -import { useEffect } from 'react'; - -import { AsyncState } from './useAsyncState'; -import { useMethodData } from './useMethodData'; - -export const usePolledMethodData = >>>( - methodName: keyof ServerMethods, - args: ServerMethodParameters, - intervalMs: number, -): AsyncState & { reload: () => void } => { - const { reload, ...state } = useMethodData(methodName, args); - - useEffect(() => { - const timer = setInterval(() => { - reload(); - }, intervalMs); - - return (): void => { - clearInterval(timer); - }; - }, [reload, intervalMs]); - - return { - ...state, - reload, - }; -}; diff --git a/apps/meteor/client/sidebar/search/SearchList.tsx b/apps/meteor/client/sidebar/search/SearchList.tsx index a3ab8dc6c197..8817f9aa683f 100644 --- a/apps/meteor/client/sidebar/search/SearchList.tsx +++ b/apps/meteor/client/sidebar/search/SearchList.tsx @@ -1,4 +1,4 @@ -import { RoomType } from '@rocket.chat/core-typings'; +import { IRoom, ISubscription, RoomType } from '@rocket.chat/core-typings'; import { css } from '@rocket.chat/css-in-js'; import { Sidebar, TextInput, Box, Icon } from '@rocket.chat/fuselage'; import { @@ -10,7 +10,7 @@ import { useMergedRefs, } from '@rocket.chat/fuselage-hooks'; import { escapeRegExp } from '@rocket.chat/string-helpers'; -import { useUserPreference, useUserSubscriptions, useSetting, useTranslation } from '@rocket.chat/ui-contexts'; +import { useUserPreference, useUserSubscriptions, useSetting, useTranslation, useMethod } from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; import React, { forwardRef, @@ -25,11 +25,10 @@ import React, { FormEventHandler, Ref, } from 'react'; +import { useQuery, UseQueryResult } from 'react-query'; import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; import tinykeys from 'tinykeys'; -import { AsyncStatePhase } from '../../hooks/useAsyncState'; -import { useEndpointData } from '../../hooks/useEndpointData'; import { useAvatarTemplate } from '../hooks/useAvatarTemplate'; import { useTemplateByViewMode } from '../hooks/useTemplateByViewMode'; import Row from './Row'; @@ -45,36 +44,6 @@ const shortcut = ((): string => { return '(\u2303+K)'; })(); -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -const useSpotlight = (filterText: string, usernames: string[]) => { - const expression = /(@|#)?(.*)/i; - const [, mention, name] = filterText.match(expression) || []; - - const searchForChannels = mention === '#'; - const searchForDMs = mention === '@'; - - const type = useMemo(() => { - if (searchForChannels) { - return { users: false, rooms: true }; - } - if (searchForDMs) { - return { users: true, rooms: false }; - } - return { users: true, rooms: true }; - }, [searchForChannels, searchForDMs]); - - const query = useMemo(() => ({ query: JSON.stringify([name, usernames, type]) }), [type, name, usernames]); - - const { value: data, phase: status } = useEndpointData('/v1/spotlight', query); - - return useMemo(() => { - if (!data) { - return { data: { users: [], rooms: [] }, status: 'loading' }; - } - return { data, status }; - }, [data, status]); -}; - const options = { sort: { lm: -1, @@ -82,76 +51,97 @@ const options = { }, }; -const useSearchItems = (filterText: string): any => { +const useSearchItems = (filterText: string): UseQueryResult<(ISubscription & IRoom)[] | undefined, Error> => { const expression = /(@|#)?(.*)/i; - const [, type, name] = filterText.match(expression) || []; + const [, mention, name] = filterText.match(expression) || []; const query = useMemo(() => { const filterRegex = new RegExp(escapeRegExp(name), 'i'); return { $or: [{ name: filterRegex }, { fname: filterRegex }], - ...(type && { - t: type === '@' ? 'd' : { $ne: 'd' }, + ...(mention && { + t: mention === '@' ? 'd' : { $ne: 'd' }, }), }; - }, [name, type]); + }, [name, mention]); const localRooms: { rid: string; t: RoomType; _id: string; name: string; uids?: string }[] = useUserSubscriptions(query, options); const usernamesFromClient = useStableArray([...localRooms?.map(({ t, name }) => (t === 'd' ? name : null))].filter(Boolean)) as string[]; - const { data: spotlight, status } = useSpotlight(filterText, usernamesFromClient); - - return useMemo(() => { - const filterUsersUnique = ({ _id }: { _id: string }, index: number, arr: { _id: string }[]): boolean => - index === arr.findIndex((user) => _id === user._id); - - const roomFilter = (room: { t: string; uids?: string[]; _id: string; name?: string }): boolean => - !localRooms.find( - (item) => - (room.t === 'd' && room.uids && room.uids.length > 1 && room.uids?.includes(item._id)) || [item.rid, item._id].includes(room._id), - ); - const usersfilter = (user: { _id: string }): boolean => - !localRooms.find((room) => room.t === 'd' && room.uids && room.uids?.length === 2 && room.uids.includes(user._id)); - - const userMap = (user: { - _id: string; - name: string; - username: string; - avatarETag?: string; - }): { - _id: string; - t: string; - name: string; - fname: string; - avatarETag?: string; - } => ({ - _id: user._id, - t: 'd', - name: user.username, - fname: user.name, - avatarETag: user.avatarETag, - }); - - type resultsFromServerType = { - _id: string; - t: string; - name: string; - fname?: string; - avatarETag?: string | undefined; - uids?: string[] | undefined; - }[]; - - const resultsFromServer: resultsFromServerType = []; - resultsFromServer.push(...spotlight.users.filter(filterUsersUnique).filter(usersfilter).map(userMap)); - resultsFromServer.push(...spotlight.rooms.filter(roomFilter)); + const searchForChannels = mention === '#'; + const searchForDMs = mention === '@'; - const exact = resultsFromServer?.filter((item) => [item.name, item.fname].includes(name)); + const type = useMemo(() => { + if (searchForChannels) { + return { users: false, rooms: true }; + } + if (searchForDMs) { + return { users: true, rooms: false }; + } + return { users: true, rooms: true }; + }, [searchForChannels, searchForDMs]); - return { data: Array.from(new Set([...exact, ...localRooms, ...resultsFromServer])), status }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [localRooms, name, spotlight]); + const getSpotlight = useMethod('spotlight'); + + return useQuery( + ['sidebar/search/spotlight', name, usernamesFromClient, type, localRooms], + async () => { + const spotlight = await getSpotlight(name, usernamesFromClient, type); + + const filterUsersUnique = ({ _id }: { _id: string }, index: number, arr: { _id: string }[]): boolean => + index === arr.findIndex((user) => _id === user._id); + + const roomFilter = (room: { t: string; uids?: string[]; _id: string; name?: string }): boolean => + !localRooms.find( + (item) => + (room.t === 'd' && room.uids && room.uids.length > 1 && room.uids?.includes(item._id)) || + [item.rid, item._id].includes(room._id), + ); + const usersfilter = (user: { _id: string }): boolean => + !localRooms.find((room) => room.t === 'd' && room.uids && room.uids?.length === 2 && room.uids.includes(user._id)); + + const userMap = (user: { + _id: string; + name: string; + username: string; + avatarETag?: string; + }): { + _id: string; + t: string; + name: string; + fname: string; + avatarETag?: string; + } => ({ + _id: user._id, + t: 'd', + name: user.username, + fname: user.name, + avatarETag: user.avatarETag, + }); + + type resultsFromServerType = { + _id: string; + t: string; + name: string; + fname?: string; + avatarETag?: string | undefined; + uids?: string[] | undefined; + }[]; + + const resultsFromServer: resultsFromServerType = []; + resultsFromServer.push(...spotlight.users.filter(filterUsersUnique).filter(usersfilter).map(userMap)); + resultsFromServer.push(...spotlight.rooms.filter(roomFilter)); + + const exact = resultsFromServer?.filter((item) => [item.name, item.fname].includes(name)); + return Array.from(new Set([...exact, ...localRooms, ...resultsFromServer])); + }, + { + staleTime: 60_000, + keepPreviousData: true, + }, + ); }; const useInput = (initial: string): { value: string; onChange: FormEventHandler; setValue: Dispatch> } => { @@ -206,7 +196,8 @@ const SearchList = forwardRef(function SearchList({ onClose }: SearchListProps, const placeholder = [t('Search'), shortcut].filter(Boolean).join(' '); - const { data: items, status } = useSearchItems(filterText); + const { data: items = [], isLoading } = useSearchItems(filterText); + console.log({ items, isLoading }); const itemData = useMemo( () => ({ @@ -280,7 +271,7 @@ const SearchList = forwardRef(function SearchList({ onClose }: SearchListProps, }, ArrowDown: () => { const currentElement = changeSelection('down'); - itemIndexRef.current = Math.min(itemIndexRef.current + 1, items?.length + 1); + itemIndexRef.current = Math.min(itemIndexRef.current + 1, items.length + 1); listRef.current?.scrollToIndex({ index: itemIndexRef.current }); selectedElement.current = currentElement; }, @@ -331,11 +322,11 @@ const SearchList = forwardRef(function SearchList({ onClose }: SearchListProps, w='full' data-qa='sidebar-search-result' onClick={onClose} - aria-busy={status !== AsyncStatePhase.RESOLVED} + aria-busy={isLoading} > } diff --git a/apps/meteor/client/views/admin/cloud/CloudPage.tsx b/apps/meteor/client/views/admin/cloud/CloudPage.tsx index b729676119a0..ae839ea5203b 100644 --- a/apps/meteor/client/views/admin/cloud/CloudPage.tsx +++ b/apps/meteor/client/views/admin/cloud/CloudPage.tsx @@ -1,4 +1,5 @@ import { Box, Button, ButtonGroup, Margins } from '@rocket.chat/fuselage'; +import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useSetModal, useToastMessageDispatch, @@ -9,9 +10,9 @@ import { useTranslation, } from '@rocket.chat/ui-contexts'; import React, { useEffect, ReactNode } from 'react'; +import { useQuery } from 'react-query'; import Page from '../../../components/Page'; -import { useMethodData } from '../../../hooks/useMethodData'; import ConnectToCloudSection from './ConnectToCloudSection'; import ManualWorkspaceRegistrationModal from './ManualWorkspaceRegistrationModal'; import TroubleshootingSection from './TroubleshootingSection'; @@ -20,8 +21,6 @@ import WorkspaceLoginSection from './WorkspaceLoginSection'; import WorkspaceRegistrationSection from './WorkspaceRegistrationSection'; import { cloudConsoleUrl } from './constants'; -const args: [] = []; - const CloudPage = function CloudPage(): ReactNode { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); @@ -37,11 +36,9 @@ const CloudPage = function CloudPage(): ReactNode { const finishOAuthAuthorization = useMethod('cloud:finishOAuthAuthorization'); - const { reload, ...checkRegisterStatus } = useMethodData('cloud:checkRegisterStatus', args); - - useEffect(() => { - console.log('checkRegisterStatus', checkRegisterStatus); - }, [checkRegisterStatus]); + const checkCloudRegisterStatus = useMethod('cloud:checkRegisterStatus'); + const result = useQuery(['admin/cloud/register-status'], async () => checkCloudRegisterStatus()); + const reload = useMutableCallback(() => result.refetch()); const connectWorkspace = useMethod('cloud:connectWorkspace'); @@ -105,16 +102,18 @@ const CloudPage = function CloudPage(): ReactNode { setModal(); }; - if (checkRegisterStatus.phase === 'loading') { - return null; - } - - if (checkRegisterStatus.phase === 'rejected') { + if (result.isLoading || result.isIdle || result.isError) { return null; } - const isConnectToCloudDesired = checkRegisterStatus.value.connectToCloud; - const isWorkspaceRegistered = checkRegisterStatus.value.workspaceRegistered; + const { + connectToCloud: isConnectToCloudDesired, + workspaceRegistered: isWorkspaceRegistered, + email, + token: resultToken, + workspaceId, + uniqueId, + } = result.data; return ( @@ -140,10 +139,10 @@ const CloudPage = function CloudPage(): ReactNode { ) : ( )} diff --git a/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx b/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx index 618ad33f18e1..b0ba52579b14 100644 --- a/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx +++ b/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx @@ -1,31 +1,34 @@ import { Box, Skeleton } from '@rocket.chat/fuselage'; -import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { ReactElement, useMemo } from 'react'; +import { useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, ReactNode } from 'react'; +import { useQuery } from 'react-query'; import CounterSet from '../../../components/dataView/CounterSet'; -import { AsyncStatePhase } from '../../../hooks/useAsyncState'; -import { usePolledMethodData } from '../../../hooks/usePolledMethodData'; + +const useOverviewData = (): [eventCount: ReactNode, userCount: ReactNode, serverCount: ReactNode] => { + const getFederationOverviewData = useMethod('federation:getOverviewData'); + + const result = useQuery(['admin/federation-dashboard/overview'], async () => getFederationOverviewData(), { + refetchInterval: 10_000, + }); + + if (result.isLoading || result.isIdle) { + return [, , ]; + } + + if (result.isError) { + return [Error, Error, Error]; + } + + const { data } = result.data; + + return [data[0].value, data[1].value, data[2].value]; +}; function OverviewSection(): ReactElement { const t = useTranslation(); - const { value: overviewData, phase: overviewStatus } = usePolledMethodData( - 'federation:getOverviewData', - useMemo(() => [], []), - 10000, - ); - const eventCount = - (overviewStatus === AsyncStatePhase.LOADING && ) || - (overviewStatus === AsyncStatePhase.REJECTED && Error) || - overviewData?.data[0]?.value; - const userCount = - (overviewStatus === AsyncStatePhase.LOADING && ) || - (overviewStatus === AsyncStatePhase.REJECTED && Error) || - overviewData?.data[1]?.value; - const serverCount = - (overviewStatus === AsyncStatePhase.LOADING && ) || - (overviewStatus === AsyncStatePhase.REJECTED && Error) || - overviewData?.data[2]?.value; + const [eventCount, userCount, serverCount] = useOverviewData(); return ( [], []), - 10000, - ); + const getFederationServers = useMethod('federation:getServers'); - if (serversStatus === AsyncStatePhase.LOADING) { + const result = useQuery(['admin/federation-dashboard/servers'], async () => getFederationServers(), { + refetchInterval: 10_000, + }); + + if (result.isLoading || result.isIdle) { return ; } - if (serversData?.data?.length === 0) { + if (result.isError || result.data.data.length === 0) { return null; } + const servers = result.data.data; + return (
    - {serversData?.data?.map(({ domain }) => ( + {servers.map(({ domain }) => (
  • {domain}
  • ))}
diff --git a/apps/meteor/client/views/login/ResetPassword/ResetPassword.js b/apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx similarity index 69% rename from apps/meteor/client/views/login/ResetPassword/ResetPassword.js rename to apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx index 8a08127cb0c5..d4e373c0ca7d 100644 --- a/apps/meteor/client/views/login/ResetPassword/ResetPassword.js +++ b/apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx @@ -1,41 +1,53 @@ -import { Button, TextInput, Field, Modal, Box, Throbber } from '@rocket.chat/fuselage'; +import { Button, Field, Modal, Box, Throbber, PasswordInput } from '@rocket.chat/fuselage'; import { useSafely } from '@rocket.chat/fuselage-hooks'; -import { useRouteParameter, useRoute, useUser, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import { + useRouteParameter, + useRoute, + useUser, + useMethod, + useTranslation, + TranslationKey, + useToastMessageDispatch, +} from '@rocket.chat/ui-contexts'; import { Meteor } from 'meteor/meteor'; -import React, { useState, useCallback, useMemo } from 'react'; +import React, { useState, useCallback, ReactElement } from 'react'; +import { useQuery } from 'react-query'; -import { useMethodData } from '../../../hooks/useMethodData'; import LoginLayout from '../LoginLayout'; const getChangePasswordReason = ({ requirePasswordChange, requirePasswordChangeReason = requirePasswordChange ? 'You_need_to_change_your_password' : 'Please_enter_your_new_password_below', -} = {}) => requirePasswordChangeReason; +}: { requirePasswordChange?: boolean; requirePasswordChangeReason?: TranslationKey } = {}): TranslationKey => requirePasswordChangeReason; -const ResetPassword = () => { +const ResetPassword = (): ReactElement => { const user = useUser(); const t = useTranslation(); const setUserPassword = useMethod('setUserPassword'); const resetPassword = useMethod('resetPassword'); const token = useRouteParameter('token'); - const params = useMemo( - () => [ - { - token, + + const getPasswordPolicy = useMethod('getPasswordPolicy'); + + const dispatchToastMessage = useToastMessageDispatch(); + + const { data: { enabled: policyEnabled, policy: policies } = {} } = useQuery( + ['login/password-policy', token], + async () => getPasswordPolicy(token ? { token } : undefined), + { + onError: (error: any) => { + dispatchToastMessage({ type: 'error', message: error }); }, - ], - [token], + }, ); - const { value: { enabled: policyEnabled, policy: policies } = {} } = useMethodData('getPasswordPolicy', params); - const router = useRoute('home'); const changePasswordReason = getChangePasswordReason(user || {}); const [newPassword, setNewPassword] = useState(''); const [isLoading, setIsLoading] = useSafely(useState(false)); - const [error, setError] = useSafely(useState()); + const [error, setError] = useSafely(useState()); const handleOnChange = useCallback((event) => setNewPassword(event.currentTarget.value), [setNewPassword]); @@ -57,7 +69,8 @@ const ResetPassword = () => { await setUserPassword(newPassword); } } catch ({ error, reason }) { - setError(reason ?? error); + const _error = reason ?? error; + setError(_error ? String(_error) : undefined); } finally { setIsLoading(false); } @@ -75,9 +88,8 @@ const ResetPassword = () => { {t(changePasswordReason)} - { {error && {error}} {policyEnabled && ( - {policies.map((policy, index) => ( + {policies?.map((policy, index) => ( {t(...policy)} diff --git a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx index db0331e7872e..2c052514d3c7 100644 --- a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx +++ b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx @@ -1,12 +1,11 @@ import { Callout } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; -import React, { FC } from 'react'; +import React, { ReactElement } from 'react'; +import { useQuery } from 'react-query'; import Page from '../../../components/Page'; import PageSkeleton from '../../../components/PageSkeleton'; -import { AsyncStatePhase } from '../../../hooks/useAsyncState'; -import { useMethodData } from '../../../hooks/useMethodData'; import FacebookPage from './FacebookPage'; type PageItem = { @@ -24,37 +23,30 @@ type InitialStateData = { hasToken: boolean; }; -const initialStateArgs: [ - { - action: 'initialState'; - }, -] = [ - { - action: 'initialState', - }, -]; - -const listPageArgs: [ - { - action: 'list-pages'; - }, -] = [ - { - action: 'list-pages', - }, -]; - -const FacebookPageContainer: FC = () => { +const FacebookPageContainer = (): ReactElement => { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); - const { value: initialStateData, phase: state, reload: reloadInitial } = useMethodData('livechat:facebook', initialStateArgs); - const { value: pagesData, phase: listState, reload: reloadData } = useMethodData('livechat:facebook', listPageArgs); + const livechatFacebook = useMethod('livechat:facebook'); - const { enabled, hasToken } = (initialStateData as InitialStateData) || { enabled: false, hasToken: false }; - const { pages } = (pagesData as unknown as PageData) || { pages: [] }; + const initialStateResult = useQuery( + ['omnichannel/facebook/initial-state'], + async () => livechatFacebook({ action: 'initialState' }) as Promise, + { + initialData: { enabled: false, hasToken: false }, + }, + ); - const livechatFacebook = useMethod('livechat:facebook'); + const listPagesResult = useQuery( + ['omnichannel/facebook/list-pages'], + async () => livechatFacebook({ action: 'list-pages' }) as Promise, + { + initialData: { pages: [] }, + }, + ); + + const { enabled, hasToken } = initialStateResult.data ?? { enabled: false, hasToken: false }; + const { pages } = listPagesResult.data ?? { pages: [] }; const onToggle = useMutableCallback(async (id, isSubscribed, setSubscribed) => { setSubscribed(!isSubscribed); @@ -74,8 +66,8 @@ const FacebookPageContainer: FC = () => { try { await livechatFacebook({ action: 'disable' }); dispatchToastMessage({ type: 'success', message: t('Integration_disabled') }); - reloadInitial(); - reloadData(); + initialStateResult.refetch(); + listPagesResult.refetch(); } catch (error) { dispatchToastMessage({ type: 'error', message: error instanceof Error ? error : String(error) }); } @@ -99,19 +91,19 @@ const FacebookPageContainer: FC = () => { onEnable(); }); } else { - reloadInitial(); - reloadData(); + initialStateResult.refetch(); + listPagesResult.refetch(); } } catch (error) { dispatchToastMessage({ type: 'error', message: error instanceof Error ? error : String(error) }); } }); - if (state === AsyncStatePhase.LOADING || listState === AsyncStatePhase.LOADING) { + if (initialStateResult.isLoading || initialStateResult.isIdle || listPagesResult.isLoading || listPagesResult.isIdle) { return ; } - if (state === AsyncStatePhase.REJECTED) { + if (initialStateResult.isError) { return ( @@ -122,7 +114,7 @@ const FacebookPageContainer: FC = () => { ); } - if (enabled && hasToken && listState === AsyncStatePhase.REJECTED) { + if (enabled && hasToken && listPagesResult.isError) { onEnable(); } @@ -132,7 +124,7 @@ const FacebookPageContainer: FC = () => { enabled={enabled} hasToken={hasToken} onToggle={onToggle} - onRefresh={reloadData} + onRefresh={listPagesResult.refetch} onDisable={onDisable} onEnable={onEnable} /> diff --git a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx index 47bc67c49147..7a23c59e70ca 100644 --- a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx +++ b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx @@ -1,11 +1,10 @@ -import type { IMessage } from '@rocket.chat/core-typings'; +import { IMessage, ReadReceipt } from '@rocket.chat/core-typings'; import { Skeleton } from '@rocket.chat/fuselage'; -import { useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; -import React, { ReactElement, useMemo, useEffect } from 'react'; +import { useMethod, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, useEffect } from 'react'; +import { useQuery } from 'react-query'; import GenericModal from '../../../../components/GenericModal'; -import { useMethodData } from '../../../../hooks/useMethodData'; -import { AsyncStatePhase } from '../../../../lib/asyncState'; import ReadReceiptRow from './ReadReceiptRow'; type ReadReceiptsModalProps = { @@ -17,19 +16,18 @@ const ReadReceiptsModal = ({ messageId, onClose }: ReadReceiptsModalProps): Reac const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); - const { phase, value, error } = useMethodData( - 'getReadReceipts', - useMemo(() => [{ messageId }], [messageId]), - ); + const getReadReceipts = useMethod('getReadReceipts'); + + const readReceiptsResult = useQuery(['read-receipts', messageId], () => getReadReceipts({ messageId })); useEffect(() => { - if (error) { - dispatchToastMessage({ type: 'error', message: error }); + if (readReceiptsResult.isError) { + dispatchToastMessage({ type: 'error', message: readReceiptsResult.error }); onClose(); } - }, [error, dispatchToastMessage, t, onClose]); + }, [dispatchToastMessage, t, onClose, readReceiptsResult.isError, readReceiptsResult.error]); - if (phase === AsyncStatePhase.LOADING || !value || error) { + if (readReceiptsResult.isLoading || readReceiptsResult.isIdle || readReceiptsResult.isError) { return ( @@ -37,10 +35,12 @@ const ReadReceiptsModal = ({ messageId, onClose }: ReadReceiptsModalProps): Reac ); } + const readReceipts = readReceiptsResult.data; + return ( - {value.length < 1 && t('No_results_found')} - {value.map((receipt) => ( + {readReceipts.length < 1 && t('No_results_found')} + {readReceipts.map((receipt) => ( ))} diff --git a/apps/meteor/definition/methods/federation.ts b/apps/meteor/definition/methods/federation.ts index 5782c81f1510..807ceecf5f44 100644 --- a/apps/meteor/definition/methods/federation.ts +++ b/apps/meteor/definition/methods/federation.ts @@ -4,7 +4,7 @@ import '@rocket.chat/ui-contexts'; declare module '@rocket.chat/ui-contexts' { // eslint-disable-next-line @typescript-eslint/naming-convention interface ServerMethods { - 'federation:getServers': (...args: any[]) => { value: { data: IFederationServer[] } }; - 'federation:getOverviewData': (...args: any[]) => (...args: any[]) => { value: { data: IFederationServer[] } }; + 'federation:getServers': () => { data: IFederationServer[] }; + 'federation:getOverviewData': () => { data: { title: string; value: number }[] }; } } diff --git a/apps/meteor/ee/client/audit/AuditLogPage.js b/apps/meteor/ee/client/audit/AuditLogPage.tsx similarity index 61% rename from apps/meteor/ee/client/audit/AuditLogPage.js rename to apps/meteor/ee/client/audit/AuditLogPage.tsx index 6cd810503bcb..2db66a401850 100644 --- a/apps/meteor/ee/client/audit/AuditLogPage.js +++ b/apps/meteor/ee/client/audit/AuditLogPage.tsx @@ -1,13 +1,13 @@ import { Field } from '@rocket.chat/fuselage'; -import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useMemo, useState } from 'react'; +import { useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import React, { ReactElement, useState } from 'react'; +import { useQuery } from 'react-query'; import Page from '../../../client/components/Page'; -import { useMethodData } from '../../../client/hooks/useMethodData'; import AuditLogTable from './AuditLogTable'; import DateRangePicker from './DateRangePicker'; -const AuditLogPage = () => { +const AuditLogPage = (): ReactElement => { const t = useTranslation(); const [dateRange, setDateRange] = useState({ @@ -17,17 +17,9 @@ const AuditLogPage = () => { const { start, end } = dateRange; - const params = useMemo( - () => [ - { - startDate: new Date(start), - endDate: new Date(end), - }, - ], - [end, start], - ); + const getAudits = useMethod('auditGetAuditions'); - const { value: data } = useMethodData('auditGetAuditions', params); + const result = useQuery(['audits', { start, end }], async () => getAudits({ startDate: new Date(start), endDate: new Date(end) })); return ( @@ -39,7 +31,7 @@ const AuditLogPage = () => { - +
); diff --git a/apps/meteor/ee/client/audit/DateRangePicker.js b/apps/meteor/ee/client/audit/DateRangePicker.tsx similarity index 75% rename from apps/meteor/ee/client/audit/DateRangePicker.js rename to apps/meteor/ee/client/audit/DateRangePicker.tsx index a2e0b871fec3..eaf12f47272a 100644 --- a/apps/meteor/ee/client/audit/DateRangePicker.js +++ b/apps/meteor/ee/client/audit/DateRangePicker.tsx @@ -1,15 +1,15 @@ import { Box, InputBox, Menu, Margins } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useState, useMemo, useEffect } from 'react'; +import React, { useState, useMemo, useEffect, ReactElement, ComponentProps } from 'react'; const date = new Date(); -const formatToDateInput = (date) => date.toISOString().slice(0, 10); +const formatToDateInput = (date: Date): string => date.toISOString().slice(0, 10); const todayDate = formatToDateInput(date); -const getMonthRange = (monthsToSubtractFromToday) => { +const getMonthRange = (monthsToSubtractFromToday: number): { start: string; end: string } => { const date = new Date(); return { start: formatToDateInput(new Date(date.getFullYear(), date.getMonth() - monthsToSubtractFromToday, 1)), @@ -17,7 +17,7 @@ const getMonthRange = (monthsToSubtractFromToday) => { }; }; -const getWeekRange = (daysToSubtractFromStart, daysToSubtractFromEnd) => { +const getWeekRange = (daysToSubtractFromStart: number, daysToSubtractFromEnd: number): { start: string; end: string } => { const date = new Date(); return { start: formatToDateInput(new Date(date.getFullYear(), date.getMonth(), date.getDate() - daysToSubtractFromStart)), @@ -25,7 +25,11 @@ const getWeekRange = (daysToSubtractFromStart, daysToSubtractFromEnd) => { }; }; -const DateRangePicker = ({ onChange = () => {}, ...props }) => { +type DateRangePickerProps = Omit, 'onChange'> & { + onChange?: (dateRange: { start: string; end: string }) => void; +}; + +const DateRangePicker = ({ onChange, ...props }: DateRangePickerProps): ReactElement => { const t = useTranslation(); const [range, setRange] = useState({ start: '', end: '' }); @@ -37,7 +41,7 @@ const DateRangePicker = ({ onChange = () => {}, ...props }) => { end: range.end, }; setRange(rangeObj); - onChange(rangeObj); + onChange?.(rangeObj); }); const handleEnd = useMutableCallback(({ currentTarget }) => { @@ -46,12 +50,12 @@ const DateRangePicker = ({ onChange = () => {}, ...props }) => { start: range.start, }; setRange(rangeObj); - onChange(rangeObj); + onChange?.(rangeObj); }); const handleRange = useMutableCallback((range) => { setRange(range); - onChange(range); + onChange?.(range); }); useEffect(() => { @@ -66,42 +70,42 @@ const DateRangePicker = ({ onChange = () => {}, ...props }) => { today: { icon: 'history', label: t('Today'), - action: () => { + action: (): void => { handleRange(getWeekRange(0, 0)); }, }, yesterday: { icon: 'history', label: t('Yesterday'), - action: () => { + action: (): void => { handleRange(getWeekRange(1, 1)); }, }, thisWeek: { icon: 'history', label: t('This_week'), - action: () => { + action: (): void => { handleRange(getWeekRange(7, 0)); }, }, previousWeek: { icon: 'history', label: t('Previous_week'), - action: () => { + action: (): void => { handleRange(getWeekRange(14, 7)); }, }, thisMonth: { icon: 'history', label: t('This_month'), - action: () => { + action: (): void => { handleRange(getMonthRange(0)); }, }, lastMonth: { icon: 'history', label: t('Previous_month'), - action: () => { + action: (): void => { handleRange(getMonthRange(1)); }, }, diff --git a/apps/meteor/ee/definition/methods.ts b/apps/meteor/ee/definition/methods.ts index 4dcc9b27c72a..956bf3c18a6d 100644 --- a/apps/meteor/ee/definition/methods.ts +++ b/apps/meteor/ee/definition/methods.ts @@ -5,5 +5,6 @@ declare module '@rocket.chat/ui-contexts' { export interface ServerMethods { 'license:getModules': () => string[]; 'license:getTags': () => ILicenseTag[]; + 'auditGetAuditions': (params: { startDate: Date; endDate: Date }) => unknown[]; } } diff --git a/packages/ui-contexts/src/ServerContext/methods.ts b/packages/ui-contexts/src/ServerContext/methods.ts index 9ae0a253adb3..490e4372b59d 100644 --- a/packages/ui-contexts/src/ServerContext/methods.ts +++ b/packages/ui-contexts/src/ServerContext/methods.ts @@ -1,6 +1,7 @@ import type { IRoom, ISetting, ISupportedLanguage, IUser } from '@rocket.chat/core-typings'; import type { DeleteResult } from 'mongodb'; +import type { TranslationKey } from '../TranslationContext'; import type { AddWebdavAccountMethod } from './methods/addWebdavAccount'; import type { FollowMessageMethod } from './methods/followMessage'; import type { GetReadReceiptsMethod } from './methods/getReadReceipts'; @@ -145,6 +146,10 @@ export interface ServerMethods { avatarETag?: string; }[]; }; + 'getPasswordPolicy': (params?: { token: string }) => { + enabled: boolean; + policy: [name: TranslationKey, options?: Record][]; + }; } export type ServerMethodName = keyof ServerMethods; From 2178f7132116bc0345472b0643751f31a6d18f06 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 5 Aug 2022 13:24:18 -0300 Subject: [PATCH 12/15] lint --- apps/meteor/client/sidebar/search/SearchList.tsx | 2 +- apps/meteor/client/views/admin/cloud/CloudPage.tsx | 2 +- .../client/views/admin/federationDashboard/OverviewSection.tsx | 2 +- .../client/views/admin/federationDashboard/ServersSection.tsx | 2 +- apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx | 2 +- .../client/views/omnichannel/facebook/FacebookPageContainer.tsx | 2 +- .../views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx | 2 +- apps/meteor/ee/client/audit/AuditLogPage.tsx | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/meteor/client/sidebar/search/SearchList.tsx b/apps/meteor/client/sidebar/search/SearchList.tsx index 8817f9aa683f..cc1f61a46571 100644 --- a/apps/meteor/client/sidebar/search/SearchList.tsx +++ b/apps/meteor/client/sidebar/search/SearchList.tsx @@ -11,6 +11,7 @@ import { } from '@rocket.chat/fuselage-hooks'; import { escapeRegExp } from '@rocket.chat/string-helpers'; import { useUserPreference, useUserSubscriptions, useSetting, useTranslation, useMethod } from '@rocket.chat/ui-contexts'; +import { useQuery, UseQueryResult } from '@tanstack/react-query'; import { Meteor } from 'meteor/meteor'; import React, { forwardRef, @@ -25,7 +26,6 @@ import React, { FormEventHandler, Ref, } from 'react'; -import { useQuery, UseQueryResult } from 'react-query'; import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'; import tinykeys from 'tinykeys'; diff --git a/apps/meteor/client/views/admin/cloud/CloudPage.tsx b/apps/meteor/client/views/admin/cloud/CloudPage.tsx index ae839ea5203b..b47f399883b9 100644 --- a/apps/meteor/client/views/admin/cloud/CloudPage.tsx +++ b/apps/meteor/client/views/admin/cloud/CloudPage.tsx @@ -9,8 +9,8 @@ import { useMethod, useTranslation, } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; import React, { useEffect, ReactNode } from 'react'; -import { useQuery } from 'react-query'; import Page from '../../../components/Page'; import ConnectToCloudSection from './ConnectToCloudSection'; diff --git a/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx b/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx index b0ba52579b14..bb32446c5d0a 100644 --- a/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx +++ b/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx @@ -1,7 +1,7 @@ import { Box, Skeleton } from '@rocket.chat/fuselage'; import { useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; import React, { ReactElement, ReactNode } from 'react'; -import { useQuery } from 'react-query'; import CounterSet from '../../../components/dataView/CounterSet'; diff --git a/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx b/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx index 5426a8a9709b..0268411d8e89 100644 --- a/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx +++ b/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx @@ -1,7 +1,7 @@ import { Box, Throbber } from '@rocket.chat/fuselage'; import { useMethod } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; import React, { ReactElement } from 'react'; -import { useQuery } from 'react-query'; function ServersSection(): ReactElement | null { const getFederationServers = useMethod('federation:getServers'); diff --git a/apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx b/apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx index d4e373c0ca7d..7ce0425ca044 100644 --- a/apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx +++ b/apps/meteor/client/views/login/ResetPassword/ResetPassword.tsx @@ -9,9 +9,9 @@ import { TranslationKey, useToastMessageDispatch, } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; import { Meteor } from 'meteor/meteor'; import React, { useState, useCallback, ReactElement } from 'react'; -import { useQuery } from 'react-query'; import LoginLayout from '../LoginLayout'; diff --git a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx index 2c052514d3c7..48b3c70222d7 100644 --- a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx +++ b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx @@ -1,8 +1,8 @@ import { Callout } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; import React, { ReactElement } from 'react'; -import { useQuery } from 'react-query'; import Page from '../../../components/Page'; import PageSkeleton from '../../../components/PageSkeleton'; diff --git a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx index 7a23c59e70ca..09897f459a08 100644 --- a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx +++ b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx @@ -1,8 +1,8 @@ import { IMessage, ReadReceipt } from '@rocket.chat/core-typings'; import { Skeleton } from '@rocket.chat/fuselage'; import { useMethod, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; import React, { ReactElement, useEffect } from 'react'; -import { useQuery } from 'react-query'; import GenericModal from '../../../../components/GenericModal'; import ReadReceiptRow from './ReadReceiptRow'; diff --git a/apps/meteor/ee/client/audit/AuditLogPage.tsx b/apps/meteor/ee/client/audit/AuditLogPage.tsx index 2db66a401850..6f802aab41b8 100644 --- a/apps/meteor/ee/client/audit/AuditLogPage.tsx +++ b/apps/meteor/ee/client/audit/AuditLogPage.tsx @@ -1,7 +1,7 @@ import { Field } from '@rocket.chat/fuselage'; import { useMethod, useTranslation } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; import React, { ReactElement, useState } from 'react'; -import { useQuery } from 'react-query'; import Page from '../../../client/components/Page'; import AuditLogTable from './AuditLogTable'; From a83205ebfdd0ea7d46cf907cba0dc4d54d98ed52 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Sat, 6 Aug 2022 02:10:44 -0300 Subject: [PATCH 13/15] remove is idle react query --- apps/meteor/client/views/admin/cloud/CloudPage.tsx | 2 +- .../client/views/admin/federationDashboard/OverviewSection.tsx | 2 +- .../client/views/admin/federationDashboard/ServersSection.tsx | 2 +- .../client/views/omnichannel/facebook/FacebookPageContainer.tsx | 2 +- .../views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/meteor/client/views/admin/cloud/CloudPage.tsx b/apps/meteor/client/views/admin/cloud/CloudPage.tsx index b47f399883b9..b73c9c08c34c 100644 --- a/apps/meteor/client/views/admin/cloud/CloudPage.tsx +++ b/apps/meteor/client/views/admin/cloud/CloudPage.tsx @@ -102,7 +102,7 @@ const CloudPage = function CloudPage(): ReactNode { setModal(); }; - if (result.isLoading || result.isIdle || result.isError) { + if (result.isLoading || result.isError) { return null; } diff --git a/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx b/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx index bb32446c5d0a..cb84f0cd8110 100644 --- a/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx +++ b/apps/meteor/client/views/admin/federationDashboard/OverviewSection.tsx @@ -12,7 +12,7 @@ const useOverviewData = (): [eventCount: ReactNode, userCount: ReactNode, server refetchInterval: 10_000, }); - if (result.isLoading || result.isIdle) { + if (result.isLoading) { return [, , ]; } diff --git a/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx b/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx index 0268411d8e89..d591008c91ab 100644 --- a/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx +++ b/apps/meteor/client/views/admin/federationDashboard/ServersSection.tsx @@ -10,7 +10,7 @@ function ServersSection(): ReactElement | null { refetchInterval: 10_000, }); - if (result.isLoading || result.isIdle) { + if (result.isLoading) { return ; } diff --git a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx index 48b3c70222d7..80b8fef9db4f 100644 --- a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx +++ b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx @@ -99,7 +99,7 @@ const FacebookPageContainer = (): ReactElement => { } }); - if (initialStateResult.isLoading || initialStateResult.isIdle || listPagesResult.isLoading || listPagesResult.isIdle) { + if (initialStateResult.isLoading || listPagesResult.isLoading) { return ; } diff --git a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx index 09897f459a08..d25a95131f44 100644 --- a/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx +++ b/apps/meteor/client/views/room/modals/ReadReceiptsModal/ReadReceiptsModal.tsx @@ -27,7 +27,7 @@ const ReadReceiptsModal = ({ messageId, onClose }: ReadReceiptsModalProps): Reac } }, [dispatchToastMessage, t, onClose, readReceiptsResult.isError, readReceiptsResult.error]); - if (readReceiptsResult.isLoading || readReceiptsResult.isIdle || readReceiptsResult.isError) { + if (readReceiptsResult.isLoading || readReceiptsResult.isError) { return ( From fce2d9c72b4f4215548dddd6a981498b3fbf9bc0 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Mon, 8 Aug 2022 12:58:36 -0300 Subject: [PATCH 14/15] FacebookPageContainer --- .../views/omnichannel/facebook/FacebookPageContainer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx index 80b8fef9db4f..6fc77927ce82 100644 --- a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx +++ b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx @@ -31,7 +31,7 @@ const FacebookPageContainer = (): ReactElement => { const initialStateResult = useQuery( ['omnichannel/facebook/initial-state'], - async () => livechatFacebook({ action: 'initialState' }) as Promise, + async () => livechatFacebook({ action: 'initialState' }) as unknown as Promise, { initialData: { enabled: false, hasToken: false }, }, @@ -39,7 +39,7 @@ const FacebookPageContainer = (): ReactElement => { const listPagesResult = useQuery( ['omnichannel/facebook/list-pages'], - async () => livechatFacebook({ action: 'list-pages' }) as Promise, + async () => livechatFacebook({ action: 'list-pages' }) as unknown as Promise, { initialData: { pages: [] }, }, From 1192548743e15906599a1ae06e95155742377c55 Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Tue, 9 Aug 2022 10:32:30 -0300 Subject: [PATCH 15/15] undo SettingsProvider --- apps/meteor/client/providers/SettingsProvider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/providers/SettingsProvider.tsx b/apps/meteor/client/providers/SettingsProvider.tsx index ebd4f51c8f8b..0ed442dabc11 100644 --- a/apps/meteor/client/providers/SettingsProvider.tsx +++ b/apps/meteor/client/providers/SettingsProvider.tsx @@ -1,4 +1,4 @@ -import { SettingsContext, SettingsContextValue, useAtLeastOnePermission, useEndpoint } from '@rocket.chat/ui-contexts'; +import { SettingsContext, SettingsContextValue, useAtLeastOnePermission, useMethod } from '@rocket.chat/ui-contexts'; import { Tracker } from 'meteor/tracker'; import React, { useCallback, useEffect, useMemo, useState, FunctionComponent } from 'react'; @@ -80,7 +80,7 @@ const SettingsProvider: FunctionComponent = ({ children, [cachedCollection], ); - const saveSettings = useEndpoint('POST', '/v1/rooms.saveRoomSettings'); + const saveSettings = useMethod('saveSettings'); const dispatch = useCallback( async (changes) => { await saveSettings(changes);