-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feat/single-contact-id' into feat/contact-blocking
- Loading branch information
Showing
12 changed files
with
435 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 0 additions & 16 deletions
16
apps/meteor/client/views/omnichannel/contactInfo/tabs/ContactInfoChannels.tsx
This file was deleted.
Oops, something went wrong.
34 changes: 34 additions & 0 deletions
34
...eor/client/views/omnichannel/contactInfo/tabs/ContactInfoChannels/ContactInfoChannels.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import type { ILivechatContactChannel, Serialized } from '@rocket.chat/core-typings'; | ||
import { Box } from '@rocket.chat/fuselage'; | ||
import { useTranslation } from '@rocket.chat/ui-contexts'; | ||
import React from 'react'; | ||
|
||
import { ContextualbarEmptyContent, ContextualbarScrollableContent } from '../../../../../components/Contextualbar'; | ||
import ContactInfoChannelsItem from './ContactInfoChannelsItem'; | ||
|
||
type ContactInfoChannelsProps = { | ||
channels: Serialized<ILivechatContactChannel>[]; | ||
}; | ||
|
||
const ContactInfoChannels = ({ channels }: ContactInfoChannelsProps) => { | ||
const t = useTranslation(); | ||
|
||
if (channels.length === 0) { | ||
return <ContextualbarEmptyContent icon='balloon' title={t('No_channels_yet')} subtitle={t('No_channels_yet_description')} />; | ||
} | ||
|
||
return ( | ||
<> | ||
<Box pbs={24} pis={24} mbe={8} fontScale='p2m'> | ||
{t('Last_contacts')} | ||
</Box> | ||
<ContextualbarScrollableContent p={0}> | ||
{channels.map((channel) => ( | ||
<ContactInfoChannelsItem key={channel.visitorId} {...channel} /> | ||
))} | ||
</ContextualbarScrollableContent> | ||
</> | ||
); | ||
}; | ||
|
||
export default ContactInfoChannels; |
69 changes: 69 additions & 0 deletions
69
...client/views/omnichannel/contactInfo/tabs/ContactInfoChannels/ContactInfoChannelsItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import type { ILivechatContactChannel, Serialized } from '@rocket.chat/core-typings'; | ||
import { css } from '@rocket.chat/css-in-js'; | ||
import { Box, Palette, IconButton } from '@rocket.chat/fuselage'; | ||
import { useTranslation, type TranslationKey } from '@rocket.chat/ui-contexts'; | ||
import React, { useState } from 'react'; | ||
|
||
import { OmnichannelRoomIcon } from '../../../../../components/RoomIcon/OmnichannelRoomIcon'; | ||
import { useTimeAgo } from '../../../../../hooks/useTimeAgo'; | ||
|
||
type ContactInfoChannelsItemProps = Serialized<ILivechatContactChannel>; | ||
|
||
const sourceTypeMap: { [key: string]: string } = { | ||
widget: 'Livechat', | ||
email: 'Email', | ||
sms: 'SMS', | ||
app: 'Apps', | ||
api: 'API', | ||
other: 'Other', | ||
}; | ||
|
||
const ContactInfoChannelsItem = ({ details, blocked, lastChat }: ContactInfoChannelsItemProps) => { | ||
const t = useTranslation(); | ||
const timeAgo = useTimeAgo(); | ||
const [showButton, setShowButton] = useState(false); | ||
|
||
const customClass = css` | ||
&:hover, | ||
&:focus { | ||
background: ${Palette.surface['surface-hover']}; | ||
} | ||
`; | ||
|
||
return ( | ||
<Box | ||
tabIndex={0} | ||
borderBlockEndWidth={1} | ||
borderBlockEndColor='stroke-extra-light' | ||
borderBlockEndStyle='solid' | ||
className={['rcx-box--animated', customClass]} | ||
pi={24} | ||
pb={8} | ||
display='flex' | ||
flexDirection='column' | ||
onFocus={() => setShowButton(true)} | ||
onPointerEnter={() => setShowButton(true)} | ||
onPointerLeave={() => setShowButton(false)} | ||
> | ||
<Box display='flex' alignItems='center'> | ||
{details && <OmnichannelRoomIcon source={details} size='x18' placement='default' />} | ||
{details && ( | ||
<Box mi={4} fontScale='p2b'> | ||
{t(sourceTypeMap[details?.type] as TranslationKey)} {blocked && `(${t('Blocked')})`} | ||
</Box> | ||
)} | ||
{lastChat && ( | ||
<Box mis={4} fontScale='c1'> | ||
{timeAgo(lastChat.ts)} | ||
</Box> | ||
)} | ||
</Box> | ||
<Box minHeight='x24' alignItems='center' mbs={4} display='flex' justifyContent='space-between'> | ||
<Box>{details?.destination}</Box> | ||
{showButton && <IconButton icon='menu' tiny />} | ||
</Box> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default ContactInfoChannelsItem; |
1 change: 1 addition & 0 deletions
1
apps/meteor/client/views/omnichannel/contactInfo/tabs/ContactInfoChannels/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './ContactInfoChannels'; |
90 changes: 82 additions & 8 deletions
90
...eteor/client/views/omnichannel/contactInfo/tabs/ContactInfoHistory/ContactInfoHistory.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,90 @@ | ||
import { ContextualbarEmptyContent } from '@rocket.chat/fuselage'; | ||
import { useTranslation } from '@rocket.chat/ui-contexts'; | ||
import { Box, Margins, Throbber, States, StatesIcon, StatesTitle, Select } from '@rocket.chat/fuselage'; | ||
import { useLocalStorage } from '@rocket.chat/fuselage-hooks'; | ||
import { useEndpoint, useTranslation } from '@rocket.chat/ui-contexts'; | ||
import { useQuery } from '@tanstack/react-query'; | ||
import React from 'react'; | ||
import { Virtuoso } from 'react-virtuoso'; | ||
|
||
const ContactInfoHistory = () => { | ||
import { ContextualbarContent, ContextualbarEmptyContent } from '../../../../../components/Contextualbar'; | ||
import { VirtuosoScrollbars } from '../../../../../components/CustomScrollbars'; | ||
import ContactInfoHistoryItem from './ContactInfoHistoryItem'; | ||
|
||
type ContactInfoHistoryProps = { | ||
contactId: string; | ||
setChatId: (chatId: string) => void; | ||
}; | ||
|
||
const ContactInfoHistory = ({ contactId, setChatId }: ContactInfoHistoryProps) => { | ||
const t = useTranslation(); | ||
const isEmpty = true; | ||
|
||
if (!isEmpty) { | ||
return null; | ||
} | ||
const historyFilterOptions: [string, string][] = [ | ||
['all', t('All')], | ||
['widget', t('Livechat')], | ||
['email', t('Email')], | ||
['sms', t('SMS')], | ||
['app', t('Apps')], | ||
['api', t('API')], | ||
['other', t('Other')], | ||
]; | ||
|
||
const [type, setType] = useLocalStorage<string>('contact-history-type', 'all'); | ||
|
||
const getContactHistory = useEndpoint('GET', '/v1/omnichannel/contacts.history'); | ||
const { data, isLoading, isError } = useQuery(['getContactHistory', contactId, type], () => | ||
getContactHistory({ contactId, source: type === 'all' ? undefined : type }), | ||
); | ||
|
||
return <ContextualbarEmptyContent icon='history' title={t('No_history_yet')} subtitle={t('No_history_yet_description')} />; | ||
return ( | ||
<ContextualbarContent paddingInline={0}> | ||
<Box | ||
display='flex' | ||
flexDirection='row' | ||
p={24} | ||
borderBlockEndWidth='default' | ||
borderBlockEndStyle='solid' | ||
borderBlockEndColor='extra-light' | ||
flexShrink={0} | ||
> | ||
<Box display='flex' flexDirection='row' flexGrow={1} mi='neg-x4'> | ||
<Margins inline={4}> | ||
<Select value={type} onChange={(value) => setType(value as string)} placeholder={t('Filter')} options={historyFilterOptions} /> | ||
</Margins> | ||
</Box> | ||
</Box> | ||
{isLoading && ( | ||
<Box pi={24} pb={12}> | ||
<Throbber size='x12' /> | ||
</Box> | ||
)} | ||
{isError && ( | ||
<States> | ||
<StatesIcon name='warning' variation='danger' /> | ||
<StatesTitle>{t('Something_went_wrong')}</StatesTitle> | ||
</States> | ||
)} | ||
{data?.history.length === 0 && ( | ||
<ContextualbarEmptyContent icon='history' title={t('No_history_yet')} subtitle={t('No_history_yet_description')} /> | ||
)} | ||
{!isError && data?.history && data.history.length > 0 && ( | ||
<> | ||
<Box pi={24} pb={12}> | ||
<Box is='span' color='hint' fontScale='p2'> | ||
{t('Showing_current_of_total', { current: data?.history.length, total: data?.total })} | ||
</Box> | ||
</Box> | ||
<Box flexGrow={1} flexShrink={1} overflow='hidden' display='flex'> | ||
<Virtuoso | ||
totalCount={data.history.length} | ||
overscan={25} | ||
data={data?.history} | ||
components={{ Scroller: VirtuosoScrollbars }} | ||
itemContent={(index, data) => <ContactInfoHistoryItem key={index} onClick={() => setChatId(data._id)} {...data} />} | ||
/> | ||
</Box> | ||
</> | ||
)} | ||
</ContextualbarContent> | ||
); | ||
}; | ||
|
||
export default ContactInfoHistory; |
77 changes: 77 additions & 0 deletions
77
...r/client/views/omnichannel/contactInfo/tabs/ContactInfoHistory/ContactInfoHistoryItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import type { Serialized } from '@rocket.chat/core-typings'; | ||
import { css } from '@rocket.chat/css-in-js'; | ||
import { Box, Palette, IconButton } from '@rocket.chat/fuselage'; | ||
import type { ContactSearchChatsResult } from '@rocket.chat/rest-typings'; | ||
import { useTranslation, type TranslationKey } from '@rocket.chat/ui-contexts'; | ||
import React from 'react'; | ||
|
||
import { OmnichannelRoomIcon } from '../../../../../components/RoomIcon/OmnichannelRoomIcon'; | ||
import { usePreventPropagation } from '../../../../../hooks/usePreventPropagation'; | ||
import { useTimeAgo } from '../../../../../hooks/useTimeAgo'; | ||
|
||
type ContactInfoHistoryItemProps = Serialized<ContactSearchChatsResult> & { | ||
onClick: () => void; | ||
}; | ||
|
||
const sourceTypeMap: { [key: string]: string } = { | ||
widget: 'Livechat', | ||
email: 'Email', | ||
sms: 'SMS', | ||
app: 'Apps', | ||
api: 'API', | ||
other: 'Other', | ||
}; | ||
|
||
const ContactInfoHistoryItem = ({ source, lastMessage, closedAt, onClick }: ContactInfoHistoryItemProps) => { | ||
const t = useTranslation(); | ||
const timeAgo = useTimeAgo(); | ||
const preventPropagation = usePreventPropagation(); | ||
|
||
const customClass = css` | ||
&:hover { | ||
cursor: pointer; | ||
} | ||
&:hover, | ||
&:focus { | ||
background: ${Palette.surface['surface-hover']}; | ||
} | ||
`; | ||
|
||
return ( | ||
<Box | ||
tabIndex={0} | ||
borderBlockEndWidth={1} | ||
borderBlockEndColor='stroke-extra-light' | ||
borderBlockEndStyle='solid' | ||
className={['rcx-box--animated', customClass]} | ||
pi={24} | ||
pb={8} | ||
display='flex' | ||
flexDirection='column' | ||
onClick={onClick} | ||
> | ||
<Box display='flex' alignItems='center'> | ||
{source && <OmnichannelRoomIcon source={source} size='x18' placement='default' />} | ||
{source && ( | ||
<Box mi={4} fontScale='p2b'> | ||
{t(sourceTypeMap[source?.type] as TranslationKey)} | ||
</Box> | ||
)} | ||
{lastMessage && ( | ||
<Box mis={4} fontScale='c1'> | ||
{timeAgo(lastMessage.ts)} | ||
</Box> | ||
)} | ||
</Box> | ||
<Box minHeight='x24' alignItems='center' mbs={4} display='flex' justifyContent='space-between'> | ||
<Box>{!closedAt ? t('Conversation_in_progress') : t('Conversation_closed_without_comment')}</Box> | ||
<Box is='span' onClick={preventPropagation}> | ||
<IconButton icon='warning' tiny /> | ||
</Box> | ||
</Box> | ||
</Box> | ||
); | ||
}; | ||
|
||
export default ContactInfoHistoryItem; |
Oops, something went wrong.