Skip to content

Commit

Permalink
Merge branch 'develop' into fix-slack-bridge-version-incompatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Jan 15, 2025
2 parents a815b86 + 62660fc commit 327f924
Show file tree
Hide file tree
Showing 165 changed files with 1,096 additions and 663 deletions.
5 changes: 5 additions & 0 deletions .changeset/eleven-pugs-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixes an issue where losing connection could break app's action buttons
6 changes: 6 additions & 0 deletions .changeset/friendly-kings-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": patch
"@rocket.chat/rest-typings": patch
---

Allows users to fetch the `packageValue` of settings when calling `/settings` endpoint via `includeDefaults` query param.
5 changes: 5 additions & 0 deletions .changeset/gentle-moons-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes an issue where room scroll position wasn't being restored when moving between rooms.
5 changes: 5 additions & 0 deletions .changeset/good-clouds-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixes an issue that prevented room history from loading under certain conditions.
9 changes: 8 additions & 1 deletion apps/meteor/app/api/server/v1/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
isSettingsUpdatePropsActions,
isSettingsUpdatePropsColor,
isSettingsPublicWithPaginationProps,
isSettingsGetParams,
} from '@rocket.chat/rest-typings';
import { Meteor } from 'meteor/meteor';
import type { FindOptions } from 'mongodb';
Expand Down Expand Up @@ -131,9 +132,10 @@ API.v1.addRoute(

API.v1.addRoute(
'settings',
{ authRequired: true },
{ authRequired: true, validateParams: isSettingsGetParams },
{
async get() {
const { includeDefaults } = this.queryParams;
const { offset, count } = await getPaginationItems(this.queryParams);
const { sort, fields, query } = await this.parseJsonQuery();

Expand All @@ -147,6 +149,11 @@ API.v1.addRoute(

ourQuery = Object.assign({}, query, ourQuery);

// Note: change this when `fields` gets removed
if (includeDefaults) {
fields.packageValue = 1;
}

const { settings, totalCount: total } = await fetchSettings(ourQuery, sort, offset, count, fields);

return API.v1.success({
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/client/apps/gameCenter/GameCenter.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { IExternalComponent } from '@rocket.chat/apps-engine/definition/externalComponent';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useState } from 'react';
import type { ReactElement } from 'react';
import type { MouseEvent, ReactElement } from 'react';

import GameCenterContainer from './GameCenterContainer';
import GameCenterList from './GameCenterList';
Expand All @@ -18,12 +18,12 @@ const GameCenter = (): ReactElement => {

const result = useExternalComponentsQuery();

const handleClose = useEffectEvent((e) => {
const handleClose = useEffectEvent((e: MouseEvent) => {
preventSyntheticEvent(e);
closeTab();
});

const handleBack = useEffectEvent((e) => {
const handleBack = useEffectEvent((e: MouseEvent) => {
setOpenedGame(undefined);
preventSyntheticEvent(e);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useEmbeddedLayout } from '../../hooks/useEmbeddedLayout';
const SideBarToggler = (): ReactElement => {
const { sidebar } = useLayout();
const isLayoutEmbedded = useEmbeddedLayout();
const unreadMessagesBadge = useSession('unread');
const unreadMessagesBadge = useSession('unread') as number | string | undefined;

const toggleSidebar = useEffectEvent(() => sidebar.toggle());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { css } from '@rocket.chat/css-in-js';
import { Box, Badge } from '@rocket.chat/fuselage';
import type { ReactNode } from 'react';

const SidebarTogglerBadge = ({ children }: { children?: unknown }) => (
type SidebarTogglerBadgeProps = {
children?: ReactNode;
};

const SidebarTogglerBadge = ({ children }: SidebarTogglerBadgeProps) => (
<Box
className={css`
position: absolute;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Box, IconButton } from '@rocket.chat/fuselage';
import type { ReactNode } from 'react';
import { useTranslation } from 'react-i18next';

import SidebarTogglerBadge from './SidebarTogglerBadge';

type SideBarTogglerButtonProps = {
badge?: number | unknown;
badge?: ReactNode;
onClick: () => void;
};

Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/components/avatar/RoomAvatarEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const RoomAvatarEditor = ({ disabled = false, room, roomAvatar, onChangeAvatar }
const { t } = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();

const handleChangeAvatar = useEffectEvent(async (file) => {
const handleChangeAvatar = useEffectEvent(async (file: File) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = async (): Promise<void> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type QuoteAttachmentProps = {

export const QuoteAttachment = ({ attachment }: QuoteAttachmentProps): ReactElement => {
const formatTime = useTimeAgo();
const displayAvatarPreference = useUserPreference('displayAvatars');
const displayAvatarPreference = useUserPreference<boolean>('displayAvatars');

return (
<>
Expand Down
7 changes: 4 additions & 3 deletions apps/meteor/client/hooks/useAppActionButtons.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { type IUIActionButton, type UIActionButtonContext } from '@rocket.chat/apps-engine/definition/ui';
import { useDebouncedCallback } from '@rocket.chat/fuselage-hooks';
import { useEndpoint, useStream, useUserId } from '@rocket.chat/ui-contexts';
import { useConnectionStatus, useEndpoint, useStream, useUserId } from '@rocket.chat/ui-contexts';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useEffect } from 'react';

export const getIdForActionButton = ({ appId, actionId }: IUIActionButton): string => `${appId}/${actionId}`;

export const useAppActionButtons = <TContext extends `${UIActionButtonContext}`>(context?: TContext) => {
const queryClient = useQueryClient();

const apps = useStream('apps');
const uid = useUserId();
const { status } = useConnectionStatus();

const getActionButtons = useEndpoint('GET', '/apps/actionButtons');

const result = useQuery({
queryKey: ['apps', 'actionButtons'],
queryKey: ['apps', 'actionButtons', status],
enabled: status === 'connected',
queryFn: () => getActionButtons(),

...(context && {
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/hooks/useClipboardWithToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export default function useClipboardWithToast(text: string): UseClipboardReturn

return useClipboard(text, {
onCopySuccess: useEffectEvent(() => dispatchToastMessage({ type: 'success', message: t('Copied') })),
onCopyError: useEffectEvent((e) => dispatchToastMessage({ type: 'error', message: e })),
onCopyError: useEffectEvent((e?: Error) => dispatchToastMessage({ type: 'error', message: e })),
});
}
2 changes: 1 addition & 1 deletion apps/meteor/client/hooks/usePreventPropagation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import type { UIEvent } from 'react';

export const usePreventPropagation = (fn?: (e: UIEvent) => void): ((e: UIEvent) => void) => {
const preventClickPropagation = useEffectEvent((e): void => {
const preventClickPropagation = useEffectEvent((e: UIEvent): void => {
e.stopPropagation();
fn?.(e);
});
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/lib/utils/timeAgo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { t } from '../../../app/utils/lib/i18n';

const dayFormat = ['h:mm A', 'H:mm'];

export const timeAgo = async (date: MomentInput): Promise<string> => {
export const timeAgo = (date: MomentInput) => {
const clockMode = Tracker.nonreactive(() => getUserPreference(Meteor.userId(), 'clockMode', false) as number | boolean);
const messageTimeFormat = Tracker.nonreactive(() => settings.get('Message_TimeFormat'));
const sameDay = (typeof clockMode === 'number' ? dayFormat[clockMode - 1] : undefined) || messageTimeFormat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import { useTranslation } from 'react-i18next';

import AutoCompleteDepartmentMultiple from '../../components/AutoCompleteDepartmentMultiple';
import { useHasLicenseModule } from '../../hooks/useHasLicenseModule';
import type { BusinessHoursFormData } from '../../views/omnichannel/businessHours/BusinessHoursForm';

const BusinessHoursMultiple = ({ className }: { className?: ComponentProps<typeof Field>['className'] }) => {
const { t } = useTranslation();
const {
control,
formState: { errors },
} = useFormContext();
} = useFormContext<BusinessHoursFormData>();
const hasLicense = useHasLicenseModule('livechat-enterprise');

const enabledField = useUniqueId();
Expand Down
16 changes: 14 additions & 2 deletions apps/meteor/client/omnichannel/additionalForms/CurrentChatTags.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { useHasLicenseModule } from '../../hooks/useHasLicenseModule';
import AutoCompleteTagsMultiple from '../tags/AutoCompleteTagsMultiple';

type CurrentChatTagsProps = { value: Array<{ value: string; label: string }>; handler: any; department?: string; viewAll?: boolean };
type CurrentChatTagsProps = {
value: Array<{ value: string; label: string }>;
handler: (value: { label: string; value: string }[]) => void;
department?: string;
viewAll?: boolean;
};

const CurrentChatTags = ({ value, handler, department, viewAll }: CurrentChatTagsProps) => {
const hasLicense = useHasLicenseModule('livechat-enterprise');
Expand All @@ -10,7 +15,14 @@ const CurrentChatTags = ({ value, handler, department, viewAll }: CurrentChatTag
return null;
}

return <AutoCompleteTagsMultiple onChange={handler} value={value} department={department} viewAll={viewAll} />;
return (
<AutoCompleteTagsMultiple
onChange={handler as any} // FIXME: any
value={value}
department={department}
viewAll={viewAll}
/>
);
};

export default CurrentChatTags;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useFormContext, Controller } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

import { useHasLicenseModule } from '../../hooks/useHasLicenseModule';
import type { EditCustomFieldsFormData } from '../../views/omnichannel/customFields/EditCustomFields';

const checkIsOptionsValid = (value: string) => {
if (!value || value.trim() === '') {
Expand All @@ -22,7 +23,7 @@ const CustomFieldsAdditionalForm = ({ className }: { className?: ComponentProps<
control,
watch,
formState: { errors },
} = useFormContext();
} = useFormContext<EditCustomFieldsFormData>();
const hasLicense = useHasLicenseModule('livechat-enterprise');

const { visibility, type } = watch();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const useRemoveBusinessHour = () => {
const removeBusinessHour = useMethod('livechat:removeBusinessHour');
const queryClient = useQueryClient();

const handleRemove = useEffectEvent((_id, type) => {
const handleRemove = useEffectEvent((_id: string, type: string) => {
const onDeleteBusinessHour = async () => {
try {
await removeBusinessHour(_id, type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { useQueryClient } from '@tanstack/react-query';
import { memo, useCallback } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import CannedResponseForm from './components/cannedResponseForm';
import CannedResponseForm from './components/CannedResponseForm';
import { useRemoveCannedResponse } from './useRemoveCannedResponse';
import { Page, PageHeader, PageScrollableContentWithShadow, PageFooter } from '../../components/Page';

type CannedResponseEditFormData = {
export type CannedResponseEditFormData = {
_id: string;
shortcut: string;
text: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const CannedResponsesTable = () => {

const handleAddNew = useEffectEvent(() => router.navigate('/omnichannel/canned-responses/new'));

const onRowClick = useEffectEvent((id, scope) => (): void => {
const onRowClick = useEffectEvent((id: string, scope: string) => (): void => {
if (scope === 'global' && isMonitor && !isManager) {
return dispatchToastMessage({
type: 'error',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import CannedResponsesComposer from './CannedResponsesComposer/CannedResponsesCo
import CannedResponsesComposerPreview from './CannedResponsesComposer/CannedResponsesComposerPreview';
import AutoCompleteDepartment from '../../../components/AutoCompleteDepartment';
import Tags from '../../../components/Omnichannel/Tags';
import type { CannedResponseEditFormData } from '../CannedResponseEdit';

// TODO: refactor Tags field to get proper validation
const CannedResponseForm = () => {
Expand All @@ -21,7 +22,7 @@ const CannedResponseForm = () => {
control,
formState: { errors },
watch,
} = useFormContext();
} = useFormContext<CannedResponseEditFormData>();

const clickable = css`
cursor: pointer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type CannedResponseListProps = {
type: string;
setType: Dispatch<SetStateAction<string>>;
isRoomOverMacLimit: boolean;
onClickItem: (data: any) => void;
onClickItem: (data: any) => void; // FIXME: fix typings
onClickCreate: (e: MouseEvent<HTMLOrSVGElement>) => void;
onClickUse: (e: MouseEvent<HTMLOrSVGElement>, text: string) => void;
reload: () => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { IOmnichannelCannedResponse, ILivechatDepartment } from '@rocket.chat/core-typings';
import { useDebouncedValue, useLocalStorage, useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useSetModal, useRouter } from '@rocket.chat/ui-contexts';
import type { ChangeEvent, MouseEvent } from 'react';
Expand Down Expand Up @@ -38,18 +39,24 @@ export const WrapCannedResponseList = () => {
);
const { phase, items, itemCount } = useRecordList(cannedList);

const onClickItem = useEffectEvent((data) => {
const { _id: context } = data;

router.navigate({
name: router.getRouteName() ?? 'live',
params: {
id: room._id,
tab: 'canned-responses',
context,
const onClickItem = useEffectEvent(
(
data: IOmnichannelCannedResponse & {
departmentName: ILivechatDepartment['name'];
},
});
});
) => {
const { _id: context } = data;

router.navigate({
name: router.getRouteName() ?? 'live',
params: {
id: room._id,
tab: 'canned-responses',
context,
},
});
},
);

const composer = useChat()?.composer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { FormProvider, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

import GenericModal from '../../../../components/GenericModal';
import CannedResponseForm from '../../components/cannedResponseForm';
import CannedResponseForm from '../../components/CannedResponseForm';

type CreateCannedResponseModalFormData = {
_id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const useRemoveCannedResponse = () => {
const dispatchToastMessage = useToastMessageDispatch();
const removeCannedResponse = useMethod('removeCannedResponse');

const handleDelete = useEffectEvent((id) => {
const handleDelete = useEffectEvent((id: string) => {
const onDeleteCannedResponse: () => Promise<void> = async () => {
try {
await removeCannedResponse(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type AgentsTableProps = {
export const AgentsTable = memo(({ data, sortBy, sortDirection, setSort }: AgentsTableProps) => {
const { t } = useTranslation();

const onHeaderClick = useEffectEvent((id) => {
const onHeaderClick = useEffectEvent((id: 'name' | 'total') => {
setSort(id, sortDirection === 'asc' ? 'desc' : 'asc');
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IconButton } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useRoute, useEndpoint, useSetModal, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import type { MouseEvent } from 'react';
import { useTranslation } from 'react-i18next';

import GenericModal from '../../components/GenericModal';
Expand All @@ -14,7 +15,7 @@ const RemoveSlaButton = ({ _id, reload }: { _id: string; reload: () => void }) =

const removeSLA = useEndpoint('DELETE', `/v1/livechat/sla/:slaId`, { slaId: _id });

const handleDelete = useEffectEvent((e) => {
const handleDelete = useEffectEvent((e: MouseEvent) => {
e.stopPropagation();
const onDeleteAgent = async (): Promise<void> => {
try {
Expand Down
Loading

0 comments on commit 327f924

Please sign in to comment.