[FIX] Margins on contextual bar information (#21457)

pull/21509/head^2
Douglas Fabris 5 years ago committed by GitHub
parent 2e22fcfd20
commit 18c01bdfd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      client/views/InfoPanel/Field.tsx
  2. 2
      client/views/InfoPanel/Title.tsx
  3. 13
      client/views/omnichannel/components/CustomField.js
  4. 6
      client/views/omnichannel/components/Field.js
  5. 2
      client/views/omnichannel/components/Info.js
  6. 2
      client/views/omnichannel/components/Label.js
  7. 13
      client/views/omnichannel/directory/ChatsContextualBar.js
  8. 22
      client/views/omnichannel/directory/ContactContextualBar.js
  9. 9
      client/views/omnichannel/directory/chats/contextualBar/AgentField.js
  10. 49
      client/views/omnichannel/directory/chats/contextualBar/ChatInfo.js
  11. 6
      client/views/omnichannel/directory/chats/contextualBar/ChatsContextualBar.js
  12. 9
      client/views/omnichannel/directory/chats/contextualBar/ContactField.js
  13. 9
      client/views/omnichannel/directory/chats/contextualBar/DepartmentField.js
  14. 14
      client/views/omnichannel/directory/chats/contextualBar/Info.js
  15. 9
      client/views/omnichannel/directory/chats/contextualBar/PriorityField.js
  16. 13
      client/views/omnichannel/directory/chats/contextualBar/VisitorClientInfo.js
  17. 41
      client/views/omnichannel/directory/contacts/contextualBar/ContactInfo.js
  18. 6
      client/views/omnichannel/directory/contacts/contextualBar/ContactsContextualBar.js
  19. 31
      client/views/omnichannel/directory/contacts/contextualBar/CustomField.js
  20. 6
      client/views/omnichannel/directory/contacts/contextualBar/Label.js
  21. 8
      client/views/room/contextualBar/Info/RoomInfo/RoomInfoWithData.js

@ -1,6 +1,6 @@
import { Box } from '@rocket.chat/fuselage';
import React, { FC } from 'react';
const Field: FC = ({ children }) => <Box mb='x12'>{children}</Box>;
const Field: FC = ({ children }) => <Box mb='x16'>{children}</Box>;
export default Field;

@ -17,7 +17,7 @@ const Title: FC<TitleProps> = ({ title, icon }) => (
withTruncatedText
>
{typeof icon === 'string' ? <Icon name={icon} size='x22' /> : icon}
<Box mis='x16' flexGrow={1} withTruncatedText>
<Box mis='x8' flexGrow={1} withTruncatedText>
{title}
</Box>
</Box>

@ -1,10 +1,11 @@
import { Box } from '@rocket.chat/fuselage';
import React from 'react';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../../../lib/asyncState';
import { FormSkeleton } from '../../Skeleton';
import { useTranslation } from '../../../contexts/TranslationContext';
import { AsyncStatePhase } from '../../../hooks/useAsyncState';
import { useEndpointData } from '../../../hooks/useEndpointData';
import { FormSkeleton } from '../directory/Skeleton';
import Field from './Field';
import Info from './Info';
import Label from './Label';
@ -20,10 +21,10 @@ const CustomField = ({ id, value }) => {
const { label } = data.customField;
return (
label && (
<>
<Field>
<Label>{label}</Label>
<Info>{value}</Info>
</>
</Field>
)
);
};

@ -0,0 +1,6 @@
import { Box } from '@rocket.chat/fuselage';
import React from 'react';
const Field = ({ children }) => <Box mb='x16'>{children}</Box>;
export default Field;

@ -1,7 +1,7 @@
import { css } from '@rocket.chat/css-in-js';
import React from 'react';
import UserCard from '../../../../../components/UserCard';
import UserCard from '../../../components/UserCard';
const wordBreak = css`
word-break: break-word;

@ -1,6 +1,6 @@
import { Box } from '@rocket.chat/fuselage';
import React from 'react';
const Label = (props) => <Box fontScale='p2' color='default' {...props} />;
const Label = (props) => <Box mbe='x8' fontScale='p2' color='default' {...props} />;
export default Label;

@ -1,4 +1,3 @@
import { Icon, Box } from '@rocket.chat/fuselage';
import React from 'react';
import VerticalBar from '../../../components/VerticalBar';
@ -29,9 +28,8 @@ const ChatsContextualBar = ({ chatReload }) => {
<VerticalBar.Header>
{context === 'info' && (
<>
<Box flexShrink={1} flexGrow={1} withTruncatedText mi='x8'>
<Icon name='info-circled' size='x20' /> {t('Room_Info')}
</Box>
<VerticalBar.Icon name='info-circled' />
<VerticalBar.Text>{t('Room_Info')}</VerticalBar.Text>
<VerticalBar.Action
title={t('View_full_conversation')}
name={'new-window'}
@ -40,9 +38,10 @@ const ChatsContextualBar = ({ chatReload }) => {
</>
)}
{context === 'edit' && (
<Box flexShrink={1} flexGrow={1} withTruncatedText mi='x8'>
<Icon name='pencil' size='x20' /> {t('edit-room')}
</Box>
<>
<VerticalBar.Icon name='pencil' />
<VerticalBar.Text>{t('edit-room')}</VerticalBar.Text>
</>
)}
<VerticalBar.Close onClick={handleChatsVerticalBarCloseButtonClick} />
</VerticalBar.Header>

@ -1,4 +1,3 @@
import { Icon, Box } from '@rocket.chat/fuselage';
import React from 'react';
import VerticalBar from '../../../components/VerticalBar';
@ -23,19 +22,22 @@ const ContactContextualBar = ({ contactReload }) => {
<VerticalBar className={'contextual-bar'}>
<VerticalBar.Header>
{context === 'new' && (
<Box flexShrink={1} flexGrow={1} withTruncatedText mi='x8'>
<Icon name='user' size='x20' /> {t('New_Contact')}
</Box>
<>
<VerticalBar.Icon name='user' />
<VerticalBar.Text>{t('New_Contact')}</VerticalBar.Text>
</>
)}
{context === 'info' && (
<Box flexShrink={1} flexGrow={1} withTruncatedText mi='x8'>
<Icon name='user' size='x20' /> {t('Contact_Info')}
</Box>
<>
<VerticalBar.Icon name='user' />
<VerticalBar.Text>{t('New_Contact')}</VerticalBar.Text>
</>
)}
{context === 'edit' && (
<Box flexShrink={1} flexGrow={1} withTruncatedText mi='x8'>
<Icon name='pencil' size='x20' /> {t('Edit_Contact_Profile')}
</Box>
<>
<VerticalBar.Icon name='pencil' />
<VerticalBar.Text>{t('Edit_Contact_Profile')}</VerticalBar.Text>
</>
)}
<VerticalBar.Close onClick={handleContactsVerticalBarCloseButtonClick} />
</VerticalBar.Header>

@ -7,9 +7,10 @@ import UserAvatar from '../../../../../components/avatar/UserAvatar';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { AsyncStatePhase } from '../../../../../hooks/useAsyncState';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import Field from '../../../components/Field';
import Info from '../../../components/Info';
import Label from '../../../components/Label';
import { FormSkeleton } from '../../Skeleton';
import Info from './Info';
import Label from './Label';
const AgentField = ({ agent }) => {
const t = useTranslation();
@ -27,7 +28,7 @@ const AgentField = ({ agent }) => {
const displayName = name || username;
return (
<>
<Field>
<Label>{t('Agent')}</Label>
<Info style={{ display: 'flex' }}>
<UserAvatar size='x40' title={username} username={username} />
@ -38,7 +39,7 @@ const AgentField = ({ agent }) => {
</Box>
)}
</Info>
</>
</Field>
);
};

@ -13,13 +13,14 @@ import { AsyncStatePhase } from '../../../../../hooks/useAsyncState';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import { useFormatDateAndTime } from '../../../../../hooks/useFormatDateAndTime';
import { useFormatDuration } from '../../../../../hooks/useFormatDuration';
import CustomField from '../../../components/CustomField';
import Field from '../../../components/Field';
import Info from '../../../components/Info';
import Label from '../../../components/Label';
import { FormSkeleton } from '../../Skeleton';
import AgentField from './AgentField';
import ContactField from './ContactField';
import CustomField from './CustomField';
import DepartmentField from './DepartmentField';
import Info from './Info';
import Label from './Label';
import PriorityField from './PriorityField';
import VisitorClientInfo from './VisitorClientInfo';
@ -93,7 +94,11 @@ function ChatInfo({ id, route }) {
});
if (state === AsyncStatePhase.LOADING) {
return <FormSkeleton />;
return (
<Box pi='x24'>
<FormSkeleton />
</Box>
);
}
if (error || !data || !data.room) {
@ -109,7 +114,7 @@ function ChatInfo({ id, route }) {
{servedBy && <AgentField agent={servedBy} />}
{departmentId && <DepartmentField departmentId={departmentId} />}
{tags && tags.length > 0 && (
<>
<Field>
<Label>{t('Tags')}</Label>
<Info>
{tags.map((tag) => (
@ -120,59 +125,59 @@ function ChatInfo({ id, route }) {
</Box>
))}
</Info>
</>
</Field>
)}
{topic && (
<>
<Field>
<Label>{t('Topic')}</Label>
<Info>{topic}</Info>
</>
</Field>
)}
{ts && (
<>
<Field>
<Label>{t('Queue_Time')}</Label>
{servedBy ? (
<Info>{moment(servedBy.ts).from(moment(ts), true)}</Info>
) : (
<Info>{moment(ts).fromNow(true)}</Info>
)}
</>
</Field>
)}
{closedAt && (
<>
<Field>
<Label>{t('Chat_Duration')}</Label>
<Info>{moment(closedAt).from(moment(ts), true)}</Info>
</>
</Field>
)}
{ts && (
<>
<Field>
<Label>{t('Created_at')}</Label>
<Info>{formatDateAndTime(ts)}</Info>
</>
</Field>
)}
{closedAt && (
<>
<Field>
<Label>{t('Closed_At')}</Label>
<Info>{formatDateAndTime(closedAt)}</Info>
</>
</Field>
)}
{servedBy?.ts && (
<>
<Field>
<Label>{t('Taken_at')}</Label>
<Info>{formatDateAndTime(servedBy.ts)}</Info>
</>
</Field>
)}
{metrics?.response?.avg && formatDuration(metrics.response.avg) && (
<>
<Field>
<Label>{t('Avg_response_time')}</Label>
<Info>{formatDuration(metrics.response.avg)}</Info>
</>
</Field>
)}
{!waitingResponse && responseBy?.lastMessageTs && (
<>
<Field>
<Label>{t('Inactivity_Time')}</Label>
<Info>{moment(responseBy.lastMessageTs).fromNow(true)}</Info>
</>
</Field>
)}
{canViewCustomFields() &&
livechatData &&

@ -1,4 +1,3 @@
import { Icon, Box } from '@rocket.chat/fuselage';
import React from 'react';
import VerticalBar from '../../../../../components/VerticalBar';
@ -27,9 +26,8 @@ const ChatsContextualBar = ({ rid }) => {
return (
<>
<VerticalBar.Header>
<Box flexShrink={1} flexGrow={1} withTruncatedText mi='x8'>
<Icon name='info-circled' size='x20' /> {t('Room_Info')}
</Box>
<VerticalBar.Icon name='info-circled' />
<VerticalBar.Text>{t('Room_Info')}</VerticalBar.Text>
<VerticalBar.Close onClick={closeContextualBar} />
</VerticalBar.Header>
{context === 'edit' ? (

@ -7,9 +7,10 @@ import { UserStatus } from '../../../../../components/UserStatus';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../../../lib/asyncState';
import Field from '../../../components/Field';
import Info from '../../../components/Info';
import Label from '../../../components/Label';
import { FormSkeleton } from '../../Skeleton';
import Info from './Info';
import Label from './Label';
const ContactField = ({ contact, room }) => {
const t = useTranslation();
@ -36,7 +37,7 @@ const ContactField = ({ contact, room }) => {
const displayName = name || username;
return (
<>
<Field>
<Label>{t('Contact')}</Label>
<Info style={{ display: 'flex' }}>
<Avatar size='x40' title={fname} url={avatarUrl} />
@ -47,7 +48,7 @@ const ContactField = ({ contact, room }) => {
</Box>
)}
</Info>
</>
</Field>
);
};

@ -3,9 +3,10 @@ import React from 'react';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { AsyncStatePhase } from '../../../../../hooks/useAsyncState';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import Field from '../../../components/Field';
import Info from '../../../components/Info';
import Label from '../../../components/Label';
import { FormSkeleton } from '../../Skeleton';
import Info from './Info';
import Label from './Label';
const DepartmentField = ({ departmentId }) => {
const t = useTranslation();
@ -17,10 +18,10 @@ const DepartmentField = ({ departmentId }) => {
department: { name },
} = data || { department: {} };
return (
<>
<Field>
<Label>{t('Department')}</Label>
<Info>{name}</Info>
</>
</Field>
);
};

@ -1,14 +0,0 @@
import { css } from '@rocket.chat/css-in-js';
import React from 'react';
import UserCard from '../../../../../components/UserCard';
const wordBreak = css`
word-break: break-word;
`;
const Info = ({ className, ...props }) => (
<UserCard.Info className={[className, wordBreak]} flexShrink={0} {...props} />
);
export default Info;

@ -4,9 +4,10 @@ import React from 'react';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../../../lib/asyncState';
import Field from '../../../components/Field';
import Info from '../../../components/Info';
import Label from '../../../components/Label';
import { FormSkeleton } from '../../Skeleton';
import Info from './Info';
import Label from './Label';
const PriorityField = ({ id }) => {
const t = useTranslation();
@ -21,10 +22,10 @@ const PriorityField = ({ id }) => {
}
const { name } = data;
return (
<>
<Field>
<Label>{t('Priority')}</Label>
<Info>{name}</Info>
</>
</Field>
);
};

@ -4,9 +4,10 @@ import UAParser from 'ua-parser-js';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import { AsyncStatePhase } from '../../../../../lib/asyncState';
import Field from '../../../components/Field';
import Info from '../../../components/Info';
import Label from '../../../components/Label';
import { FormSkeleton } from '../../Skeleton';
import Info from './Info';
import Label from './Label';
const VisitorClientInfo = ({ uid }) => {
const t = useTranslation();
@ -30,16 +31,16 @@ const VisitorClientInfo = ({ uid }) => {
return (
<>
{clientData.os && (
<>
<Field>
<Label>{t('OS')}</Label>
<Info>{clientData.os}</Info>
</>
</Field>
)}
{clientData.browser && (
<>
<Field>
<Label>{t('Browser')}</Label>
<Info>{clientData.browser}</Info>
</>
</Field>
)}
</>
);

@ -14,12 +14,13 @@ import { useTranslation } from '../../../../../contexts/TranslationContext';
import { AsyncStatePhase } from '../../../../../hooks/useAsyncState';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import { useFormatDate } from '../../../../../hooks/useFormatDate';
import CustomField from '../../../components/CustomField';
import Field from '../../../components/Field';
import Info from '../../../components/Info';
import Label from '../../../components/Label';
import { FormSkeleton } from '../../Skeleton';
import CustomField from './CustomField';
import Info from './Info';
import Label from './Label';
function ContactInfo({ id, rid, route }) {
const ContactInfo = ({ id, rid, route }) => {
const t = useTranslation();
const routePath = useRoute(route || 'omnichannel-directory');
@ -73,7 +74,11 @@ function ContactInfo({ id, rid, route }) {
contact: { name, username, visitorEmails, phone, livechatData, ts, lastChat, contactManager },
} = data || { contact: {} };
if (state === AsyncStatePhase.LOADING) {
return <FormSkeleton />;
return (
<Box pi='x24'>
<FormSkeleton />
</Box>
);
}
if (error || !data || !data.contact) {
@ -102,7 +107,7 @@ function ContactInfo({ id, rid, route }) {
<VerticalBar.ScrollableContent p='x24'>
<Margins block='x4'>
{displayName && (
<>
<Field>
<Label>{`${t('Name')} / ${t('Username')}`}</Label>
<Info style={{ display: 'flex' }}>
<UserAvatar size='x40' title={username} username={username} />
@ -117,32 +122,32 @@ function ContactInfo({ id, rid, route }) {
</Box>
)}
</Info>
</>
</Field>
)}
{visitorEmails && visitorEmails.length && (
<>
<Field>
<Label>{t('Email')}</Label>
<Info>{visitorEmails[0].address}</Info>
</>
</Field>
)}
{phone && phone.length && (
<>
<Field>
<Label>{t('Phone')}</Label>
<Info>{phone[0].phoneNumber}</Info>
</>
</Field>
)}
{ts && (
<>
<Field>
<Label>{t('Created_at')}</Label>
<Info>{formatDate(ts)}</Info>
</>
</Field>
)}
{lastChat && (
<>
<Field>
<Label>{t('Last_Chat')}</Label>
<Info>{formatDate(lastChat.ts)}</Info>
</>
</Field>
)}
{canViewCustomFields() &&
livechatData &&
@ -152,10 +157,10 @@ function ContactInfo({ id, rid, route }) {
livechatData[key] && <CustomField key={key} id={key} value={livechatData[key]} />,
)}
{contactManager && (
<>
<Field>
<Label>{t('Contact_Manager')}</Label>
<ContactManagerInfo username={contactManager.username} />
</>
</Field>
)}
</Margins>
</VerticalBar.ScrollableContent>
@ -173,6 +178,6 @@ function ContactInfo({ id, rid, route }) {
</VerticalBar.Footer>
</>
);
}
};
export default ContactInfo;

@ -1,4 +1,3 @@
import { Icon, Box } from '@rocket.chat/fuselage';
import React from 'react';
import VerticalBar from '../../../../../components/VerticalBar';
@ -34,9 +33,8 @@ const ContactsContextualBar = ({ rid }) => {
return (
<>
<VerticalBar.Header>
<Box flexShrink={1} flexGrow={1} withTruncatedText mi='x8'>
<Icon name='user' size='x20' /> {t('Contact_Info')}
</Box>
<VerticalBar.Icon name='user' />
<VerticalBar.Text>{t('Contact_Info')}</VerticalBar.Text>
<VerticalBar.Close onClick={closeContextualBar} />
</VerticalBar.Header>
{context === 'edit' ? (

@ -1,31 +0,0 @@
import { Box } from '@rocket.chat/fuselage';
import React from 'react';
import { useTranslation } from '../../../../../contexts/TranslationContext';
import { AsyncStatePhase } from '../../../../../hooks/useAsyncState';
import { useEndpointData } from '../../../../../hooks/useEndpointData';
import { FormSkeleton } from '../../Skeleton';
import Info from './Info';
import Label from './Label';
const CustomField = ({ id, value }) => {
const t = useTranslation();
const { value: data, phase: state, error } = useEndpointData(`livechat/custom-fields/${id}`);
if (state === AsyncStatePhase.LOADING) {
return <FormSkeleton />;
}
if (error || !data || !data.customField) {
return <Box mbs='x16'>{t('Custom_Field_Not_Found')}</Box>;
}
const { label } = data.customField;
return (
label && (
<Box>
<Label>{label}</Label>
<Info>{value}</Info>
</Box>
)
);
};
export default CustomField;

@ -1,6 +0,0 @@
import { Box } from '@rocket.chat/fuselage';
import React from 'react';
const Label = (props) => <Box fontScale='p2' color='default' {...props} />;
export default Label;

@ -195,9 +195,11 @@ const RoomInfoWithData = ({ rid, openEditing, onClickBack, onEnterRoom, resetSta
onClickConvertToTeam={!room.teamId && canConvertRoomToTeam && onConvertToTeam}
onClickEnterRoom={onEnterRoom && onClickEnterRoom}
{...room}
announcement={room.announcement && <MarkdownText content={room.announcement} />}
description={room.description && <MarkdownText content={room.description} />}
topic={room.topic && <MarkdownText content={room.topic} />}
announcement={
room.announcement && <MarkdownText variant='inline' content={room.announcement} />
}
description={room.description && <MarkdownText variant='inline' content={room.description} />}
topic={room.topic && <MarkdownText variant='inline' content={room.topic} />}
/>
);
};

Loading…
Cancel
Save