snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-16 01:21:02 +05:00
commit 30810eecd7
10161 changed files with 987110 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
import type { IOmnichannelRoom } from '@rocket.chat/core-typings';
import { UserAvatar } from '@rocket.chat/ui-avatar';
import { useEndpoint } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { FormSkeleton } from './FormSkeleton';
import { UserStatus } from '../../../../components/UserStatus';
import AgentInfoDetails from '../../components/AgentInfoDetails';
import Field from '../../components/Field';
import Info from '../../components/Info';
import Label from '../../components/Label';
export type AgentFieldProps = {
agent: IOmnichannelRoom['servedBy'];
isSmall?: boolean;
};
const AgentField = ({ agent, isSmall = false }: AgentFieldProps) => {
const { t } = useTranslation();
const { username = '' } = agent ?? {};
const getUserInfo = useEndpoint('GET', '/v1/users.info');
const { data, isLoading } = useQuery({
queryKey: ['/v1/users.info', username],
queryFn: () => getUserInfo({ username }),
});
if (isLoading) {
return <FormSkeleton />;
}
const {
user: { name, status },
} = data ?? { user: {} };
const displayName = name || username;
return (
<Field>
<Label>{t('Agent')}</Label>
<Info style={{ display: 'flex' }}>
<UserAvatar size={isSmall ? 'x28' : 'x40'} title={username} username={username || ''} />
<AgentInfoDetails
marginInlineStart={isSmall ? 'x8' : 'x10'}
name={displayName}
shortName={username}
status={<UserStatus status={status} />}
/>
</Info>
</Field>
);
};
export default AgentField;

View File

@@ -0,0 +1,59 @@
import type { IOmnichannelGenericRoom, IVisitor } from '@rocket.chat/core-typings';
import { Avatar, Box } from '@rocket.chat/fuselage';
import { useEndpoint } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import { FormSkeleton } from './FormSkeleton';
import { UserStatus } from '../../../../components/UserStatus';
import { roomCoordinator } from '../../../../lib/rooms/roomCoordinator';
import AgentInfoDetails from '../../components/AgentInfoDetails';
import Field from '../../components/Field';
import Info from '../../components/Info';
import Label from '../../components/Label';
export type ContactFieldProps = {
contact: IVisitor;
room: IOmnichannelGenericRoom;
};
const ContactField = ({ contact, room }: ContactFieldProps) => {
const { t } = useTranslation();
const { status } = contact;
const { fname, t: type } = room;
const avatarUrl = roomCoordinator.getRoomDirectives(type).getAvatarPath(room) || '';
const getVisitorInfo = useEndpoint('GET', '/v1/livechat/visitors.info');
const { data, isPending, isError } = useQuery({
queryKey: ['/v1/livechat/visitors.info', contact._id],
queryFn: () => getVisitorInfo({ visitorId: contact._id }),
});
if (isPending) {
return <FormSkeleton />;
}
if (isError || !data?.visitor) {
return <Box marginBlockStart={16}>{t('Contact_not_found')}</Box>;
}
const {
visitor: { username, name, phone },
} = data;
const displayName = name || username;
const phoneNumber = phone?.[0]?.phoneNumber;
const contactIdentifier = [...new Set([username, phoneNumber])].filter(Boolean).join(' · ');
return (
<Field>
<Label>{t('Contact')}</Label>
<Info style={{ display: 'flex' }}>
<Avatar size='x40' title={fname} url={avatarUrl} />
<AgentInfoDetails marginInlineStart={10} name={displayName} shortName={contactIdentifier} status={<UserStatus status={status} />} />
</Info>
</Field>
);
};
export default ContactField;

View File

@@ -0,0 +1,15 @@
import { Box, Skeleton } from '@rocket.chat/fuselage';
import type { ComponentPropsWithoutRef } from 'react';
export type FormSkeletonProps = ComponentPropsWithoutRef<typeof Box>;
export const FormSkeleton = (props: FormSkeletonProps) => (
<Box width='full' paddingBlock={24} {...props}>
<Skeleton marginBlockEnd={8} />
<Skeleton marginBlockEnd={4} />
<Skeleton marginBlockEnd={4} />
<Skeleton marginBlockEnd={8} />
<Skeleton marginBlockEnd={4} />
<Skeleton marginBlockEnd={8} />
</Box>
);

View File

@@ -0,0 +1,35 @@
import { Box } from '@rocket.chat/fuselage';
import { useTranslation } from 'react-i18next';
import { FormSkeleton } from './FormSkeleton';
import Field from '../../components/Field';
import Info from '../../components/Info';
import Label from '../../components/Label';
import { usePriorityInfo } from '../hooks/usePriorityInfo';
export type PriorityFieldProps = {
id: string;
};
const PriorityField = ({ id }: PriorityFieldProps) => {
const { t } = useTranslation();
const { data, isLoading, isError } = usePriorityInfo(id);
if (isLoading) {
return <FormSkeleton />;
}
if (isError || !data) {
return <Box marginBlockStart={16}>{t('Custom_Field_Not_Found')}</Box>;
}
const { dirty, name, i18n } = data;
return (
<Field>
<Label>{t('Priority')}</Label>
<Info>{dirty ? name : t(i18n)}</Info>
</Field>
);
};
export default PriorityField;

View File

@@ -0,0 +1,37 @@
import { Box } from '@rocket.chat/fuselage';
import { useId } from 'react';
import { useTranslation } from 'react-i18next';
import { FormSkeleton } from './FormSkeleton';
import Field from '../../components/Field';
import Info from '../../components/Info';
import Label from '../../components/Label';
import { useSlaInfo } from '../hooks/useSlaInfo';
export type SlaFieldProps = {
id: string;
};
const SlaField = ({ id }: SlaFieldProps) => {
const { t } = useTranslation();
const { data, isLoading, isError } = useSlaInfo(id);
const slaFieldId = useId();
if (isLoading) {
return <FormSkeleton />;
}
if (isError || !data) {
return <Box marginBlockStart={16}>{t('Custom_Field_Not_Found')}</Box>;
}
const { name } = data;
return (
<Field>
<Label id={slaFieldId}>{t('SLA_Policy')}</Label>
<Info aria-labelledby={slaFieldId}>{name}</Info>
</Field>
);
};
export default SlaField;

View File

@@ -0,0 +1,51 @@
import type { IOmnichannelRoom } from '@rocket.chat/core-typings';
import { Box } from '@rocket.chat/fuselage';
import { useTranslation } from 'react-i18next';
import { OmnichannelRoomIcon } from '../../../../components/RoomIcon/OmnichannelRoomIcon';
import Field from '../../components/Field';
import Info from '../../components/Info';
import Label from '../../components/Label';
import { useOmnichannelSource } from '../../hooks/useOmnichannelSource';
export type SourceFieldProps = {
room: IOmnichannelRoom;
};
const SourceField = ({ room }: SourceFieldProps) => {
const { t } = useTranslation();
const { getSourceName } = useOmnichannelSource();
const defaultTypesVisitorData: {
widget: string | undefined;
email: string | undefined;
sms: string;
app: string;
api: string;
other: string;
} = {
widget: '',
email: room?.source.id,
sms: t('External'),
app: room.source.label || t('External'),
api: room.source.label || t('External'),
other: t('External'),
};
return (
<Field>
<Label>{t('Channel')}</Label>
<Info>
<Box display='flex' alignItems='center'>
<OmnichannelRoomIcon source={room.source} status={room.v.status} size='x24' />
<Label marginInline={8} marginBlockEnd='0'>
{getSourceName(room.source)}
</Label>
{defaultTypesVisitorData[room.source.type]}
</Box>
</Info>
</Field>
);
};
export default SourceField;

View File

@@ -0,0 +1,5 @@
export { default as AgentField } from './AgentField';
export { default as SlaField } from './SlaField';
export { default as SourceField } from './SourceField';
export { default as ContactField } from './ContactField';
export { FormSkeleton } from './FormSkeleton';