Skip to content

Commit

Permalink
Merge branch 'new/apps_rewrite' of github.com:RocketChat/Rocket.Chat …
Browse files Browse the repository at this point in the history
…into new/apps_rewrite_local

* 'new/apps_rewrite' of github.com:RocketChat/Rocket.Chat:
  [FIX] Typo "coorosponding" (#17840)
  Regression: Infinite loop in CodeSettingInput (#17949)
  [NEW][ENTERPRISE] Download engagement data (#17920)
  [FIX] Hide system message add/remove owner  (#17938)
  • Loading branch information
gabriellsh committed Jun 18, 2020
2 parents f6eeb48 + dc8b6c6 commit e16b270
Show file tree
Hide file tree
Showing 17 changed files with 289 additions and 206 deletions.
8 changes: 6 additions & 2 deletions app/lib/lib/MessageTypes.js
Expand Up @@ -190,10 +190,10 @@ export const MessageTypesValues = [
key: 'rm',
i18nLabel: 'Message_HideType_rm',
}, {
key: 'subscription_role_added',
key: 'subscription-role-added',
i18nLabel: 'Message_HideType_subscription_role_added',
}, {
key: 'subscription_role_removed',
key: 'subscription-role-removed',
i18nLabel: 'Message_HideType_subscription_role_removed',
}, {
key: 'room_archived',
Expand All @@ -202,4 +202,8 @@ export const MessageTypesValues = [
key: 'room_unarchived',
i18nLabel: 'Message_HideType_room_unarchived',
},
{
key: 'room_changed_privacy',
i18nLabel: 'Message_HideType_room_changed_privacy',
},
];
4 changes: 4 additions & 0 deletions client/components/basic/Buttons/ActionButton.js
@@ -0,0 +1,4 @@
import React from 'react';
import { Button, Icon } from '@rocket.chat/fuselage';
// TODO fuselage
export const ActionButton = ({ icon, ...props }) => <Button {...props} square ghost small><Icon name={icon} size='x20'/></Button>;
9 changes: 9 additions & 0 deletions client/lib/saveFile.js
@@ -0,0 +1,9 @@
export const saveFile = (content, name = 'download') => {
const blob = new Blob([content], { type: 'text/plain' });
const anchor = document.createElement('a');

anchor.download = name;
anchor.href = (window.webkitURL || window.URL).createObjectURL(blob);
anchor.dataset.downloadurl = ['text/plain', anchor.download, anchor.href].join(':');
anchor.click();
};
Expand Up @@ -6,6 +6,11 @@ import { useTranslation } from '../../../../../../client/contexts/TranslationCon
import { useEndpointData } from '../../../../../../client/hooks/useEndpointData';
import Growth from '../../../../../../client/components/data/Growth';
import { Section } from '../Section';
import { ActionButton } from '../../../../../../client/components/basic/Buttons/ActionButton';
import { saveFile } from '../../../../../../client/lib/saveFile';

const convertDataToCSV = (data) => `// type, name, messagesCount, updatedAt, createdAt
${ data.map(({ createdAt, messagesCount, name, t, updatedAt }) => `${ t }, ${ name }, ${ messagesCount }, ${ updatedAt }, ${ createdAt }`).join('\n') }`;

export function TableSection() {
const t = useTranslation();
Expand Down Expand Up @@ -73,7 +78,11 @@ export function TableSection() {
}));
}, [data]);

return <Section filter={<Select options={periodOptions} value={periodId} onChange={handlePeriodChange} />}>
const downloadData = () => {
saveFile(convertDataToCSV(channels), `Channels_start_${ params.start }_end_${ params.end }.csv`);
};

return <Section filter={<><Select options={periodOptions} value={periodId} onChange={handlePeriodChange} /><ActionButton mis='x16' disabled={!channels} onClick={downloadData} aria-label={t('Download_Info')} icon='download'/></>}>
<Box>
{channels && !channels.length && <Tile fontScale='p1' color='info' style={{ textAlign: 'center' }}>
{t('No_data_found')}
Expand Down
@@ -1,4 +1,4 @@
import { Box, Margins, Tabs } from '@rocket.chat/fuselage';
import { Box, Tabs } from '@rocket.chat/fuselage';
import React, { useMemo } from 'react';

import { useTranslation } from '../../../../../client/contexts/TranslationContext';
Expand All @@ -7,8 +7,6 @@ import { UsersTab } from './UsersTab';
import { MessagesTab } from './MessagesTab';
import { ChannelsTab } from './ChannelsTab';

const style = { padding: 0 };

export function EngagementDashboardPage({
tab = 'users',
onSelectTab,
Expand All @@ -24,14 +22,12 @@ export function EngagementDashboardPage({
<Tabs.Item selected={tab === 'messages'} onClick={handleTabClick('messages')}>{t('Messages')}</Tabs.Item>
<Tabs.Item selected={tab === 'channels'} onClick={handleTabClick('channels')}>{t('Channels')}</Tabs.Item>
</Tabs>
<Page.Content style={style}>
<Margins all='x24'>
<Box>
{(tab === 'users' && <UsersTab />)
|| (tab === 'messages' && <MessagesTab />)
|| (tab === 'channels' && <ChannelsTab />)}
</Box>
</Margins>
</Page.Content>
<Page.ScrollableContent padding={0}>
<Box m='x24'>
{(tab === 'users' && <UsersTab />)
|| (tab === 'messages' && <MessagesTab />)
|| (tab === 'channels' && <ChannelsTab />)}
</Box>
</Page.ScrollableContent>
</Page>;
}
Expand Up @@ -7,6 +7,11 @@ import { useTranslation } from '../../../../../../client/contexts/TranslationCon
import { useEndpointData } from '../../../../../../client/hooks/useEndpointData';
import { LegendSymbol } from '../data/LegendSymbol';
import { Section } from '../Section';
import { ActionButton } from '../../../../../../client/components/basic/Buttons/ActionButton';
import { saveFile } from '../../../../../../client/lib/saveFile';

const convertDataToCSV = (data) => `// type, messagesSent
${ data.map(({ t, messages }) => `${ t }, ${ messages }`).join('\n') }`;

export function MessagesPerChannelSection() {
const t = useTranslation();
Expand Down Expand Up @@ -64,9 +69,14 @@ export function MessagesPerChannelSection() {
return [pie, table];
}, [period, pieData, tableData]);

const downloadData = () => {
saveFile(convertDataToCSV(pieData.origins), `MessagesPerChannelSection_start_${ params.start }_end_${ params.end }.csv`);
};


return <Section
title={t('Where_are_the_messages_being_sent?')}
filter={<Select options={periodOptions} value={periodId} onChange={handlePeriodChange} />}
filter={<><Select options={periodOptions} value={periodId} onChange={handlePeriodChange} /><ActionButton mis='x16' disabled={!pieData} onClick={downloadData} aria-label={t('Download_Info')} icon='download'/></>}
>
<Flex.Container>
<Margins inline='neg-x12'>
Expand Down
Expand Up @@ -7,6 +7,11 @@ import { useTranslation } from '../../../../../../client/contexts/TranslationCon
import { useEndpointData } from '../../../../../../client/hooks/useEndpointData';
import CounterSet from '../../../../../../client/components/data/CounterSet';
import { Section } from '../Section';
import { ActionButton } from '../../../../../../client/components/basic/Buttons/ActionButton';
import { saveFile } from '../../../../../../client/lib/saveFile';

const convertDataToCSV = (data) => `// date, newMessages
${ data.map(({ date, newMessages }) => `${ date }, ${ newMessages }`).join('\n') }`;

export function MessagesSentSection() {
const t = useTranslation();
Expand Down Expand Up @@ -81,9 +86,13 @@ export function MessagesSentSection() {
];
}, [data, period]);

const downloadData = () => {
saveFile(convertDataToCSV(values), `MessagesSentSection_start_${ params.start }_end_${ params.end }.csv`);
};

return <Section
title={t('Messages_sent')}
filter={<Select options={periodOptions} value={periodId} onChange={handlePeriodChange} />}
filter={<><Select options={periodOptions} value={periodId} onChange={handlePeriodChange} /><ActionButton mis='x16' disabled={!data} onClick={downloadData} aria-label={t('Download_Info')} icon='download'/></>}
>
<CounterSet
counters={[
Expand Down
16 changes: 7 additions & 9 deletions ee/app/engagement-dashboard/client/components/Section.js
Expand Up @@ -8,16 +8,14 @@ export function Section({
}) {
return <Box>
<Margins block='x24'>
<Flex.Container alignItems='center' wrap='no-wrap'>
<Box>
<Flex.Item grow={1}>
<Box fontScale='s2' color='default'>{title}</Box>
</Flex.Item>
{filter && <Flex.Item grow={0}>
<Box display='flex' alignItems='center' wrap='no-wrap'>
<Box flexGrow={1} fontScale='s2' color='default'>{title}</Box>
{filter && <Flex.Item grow={0}>
<Margins mi='x24'>
{filter}
</Flex.Item>}
</Box>
</Flex.Container>
</Margins>
</Flex.Item>}
</Box>
{children}
</Margins>
</Box>;
Expand Down
Expand Up @@ -8,6 +8,11 @@ import { useEndpointData } from '../../../../../../client/hooks/useEndpointData'
import CounterSet from '../../../../../../client/components/data/CounterSet';
import { LegendSymbol } from '../data/LegendSymbol';
import { Section } from '../Section';
import { ActionButton } from '../../../../../../client/components/basic/Buttons/ActionButton';
import { saveFile } from '../../../../../../client/lib/saveFile';

const convertDataToCSV = ({ countDailyActiveUsers, diffDailyActiveUsers, countWeeklyActiveUsers, diffWeeklyActiveUsers, countMonthlyActiveUsers, diffMonthlyActiveUsers, dauValues, wauValues, mauValues }) => `// countDailyActiveUsers, diffDailyActiveUsers, countWeeklyActiveUsers, diffWeeklyActiveUsers, countMonthlyActiveUsers, diffMonthlyActiveUsers, dauValues, wauValues, mauValues
${ countDailyActiveUsers }, ${ diffDailyActiveUsers }, ${ countWeeklyActiveUsers }, ${ diffWeeklyActiveUsers }, ${ countMonthlyActiveUsers }, ${ diffMonthlyActiveUsers }, ${ dauValues }, ${ wauValues }, ${ mauValues }`;

export function ActiveUsersSection() {
const t = useTranslation();
Expand Down Expand Up @@ -91,7 +96,22 @@ export function ActiveUsersSection() {
];
}, [period, data]);

return <Section title={t('Active_users')} filter={null}>
const downloadData = () => {
saveFile(convertDataToCSV({
countDailyActiveUsers,
diffDailyActiveUsers,
countWeeklyActiveUsers,
diffWeeklyActiveUsers,
countMonthlyActiveUsers,
diffMonthlyActiveUsers,
dauValues,
wauValues,
mauValues,
}), `ActiveUsersSection_start_${ params.start }_end_${ params.end }.csv`);
};


return <Section title={t('Active_users')} filter={<ActionButton disabled={!data} onClick={downloadData} aria-label={t('Download_Info')} icon='download'/>}>
<CounterSet
counters={[
{
Expand Down
Expand Up @@ -35,92 +35,82 @@ function ContentForHours({ displacement, onPreviousDateClick, onNextDateClick })
}, [data]);

return <>
<Flex.Container alignItems='center' justifyContent='center'>
<Box>
<Button ghost square small onClick={onPreviousDateClick}>
<Chevron left size='20' style={{ verticalAlign: 'middle' }} />
</Button>
<Flex.Item basis='25%'>
<Margins inline='x8'>
<Box is='span' style={{ textAlign: 'center' }}>
{currentDate.format(displacement < 7 ? 'dddd' : 'L')}
</Box>
</Margins>
</Flex.Item>
<Button ghost square small disabled={displacement === 0} onClick={onNextDateClick}>
<Chevron right size='20' style={{ verticalAlign: 'middle' }} />
</Button>
<Box display='flex' alignItems='center' justifyContent='center'>
<Button ghost square small onClick={onPreviousDateClick}>
<Chevron left size='x20' style={{ verticalAlign: 'middle' }} />
</Button>
<Box mi='x8' flexBasis='25%' is='span' style={{ textAlign: 'center' }}>
{currentDate.format(displacement < 7 ? 'dddd' : 'L')}
</Box>
</Flex.Container>
<Flex.Container>
{data
? <Box style={{ height: 196 }}>
<Flex.Item align='stretch' grow={1} shrink={0}>
<Box style={{ position: 'relative' }}>
<Box style={{ position: 'absolute', width: '100%', height: '100%' }}>
<ResponsiveBar
data={values}
indexBy='hour'
keys={['users']}
groupMode='grouped'
padding={0.25}
margin={{
// TODO: Get it from theme
bottom: 20,
}}
colors={[
// TODO: Get it from theme
'#1d74f5',
]}
enableLabel={false}
enableGridY={false}
axisTop={null}
axisRight={null}
axisBottom={{
tickSize: 0,
// TODO: Get it from theme
tickPadding: 4,
tickRotation: 0,
tickValues: 'every 2 hours',
format: (hour) => moment().set({ hour, minute: 0, second: 0 }).format('LT'),
}}
axisLeft={null}
animate={true}
motionStiffness={90}
motionDamping={15}
theme={{
// TODO: Get it from theme
axis: {
ticks: {
text: {
fill: '#9EA2A8',
fontFamily: 'Inter, -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Meiryo UI", Arial, sans-serif',
fontSize: '10px',
fontStyle: 'normal',
fontWeight: '600',
letterSpacing: '0.2px',
lineHeight: '12px',
},
},
},
tooltip: {
container: {
backgroundColor: '#1F2329',
boxShadow: '0px 0px 12px rgba(47, 52, 61, 0.12), 0px 0px 2px rgba(47, 52, 61, 0.08)',
borderRadius: 2,
},
<Button ghost square small disabled={displacement === 0} onClick={onNextDateClick}>
<Chevron right size='x20' style={{ verticalAlign: 'middle' }} />
</Button>
</Box>
{data
? <Box display='flex' height='196px'>
<Box align='stretch' flexGrow={1} flexShrink={0} position='relative'>
<Box position='absolute' width='100%' height='100%'>
<ResponsiveBar
data={values}
indexBy='hour'
keys={['users']}
groupMode='grouped'
padding={0.25}
margin={{
// TODO: Get it from theme
bottom: 20,
}}
colors={[
// TODO: Get it from theme
'#1d74f5',
]}
enableLabel={false}
enableGridY={false}
axisTop={null}
axisRight={null}
axisBottom={{
tickSize: 0,
// TODO: Get it from theme
tickPadding: 4,
tickRotation: 0,
tickValues: 'every 2 hours',
format: (hour) => moment().set({ hour, minute: 0, second: 0 }).format('LT'),
}}
axisLeft={null}
animate={true}
motionStiffness={90}
motionDamping={15}
theme={{
// TODO: Get it from theme
axis: {
ticks: {
text: {
fill: '#9EA2A8',
fontFamily: 'Inter, -apple-system, system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Meiryo UI", Arial, sans-serif',
fontSize: '10px',
fontStyle: 'normal',
fontWeight: '600',
letterSpacing: '0.2px',
lineHeight: '12px',
},
}}
tooltip={({ value }) => <Box fontScale='p2' color='alternative'>
{t('Value_users', { value })}
</Box>}
/>
</Box>
</Box>
</Flex.Item>
},
},
tooltip: {
container: {
backgroundColor: '#1F2329',
boxShadow: '0px 0px 12px rgba(47, 52, 61, 0.12), 0px 0px 2px rgba(47, 52, 61, 0.08)',
borderRadius: 2,
},
},
}}
tooltip={({ value }) => <Box fontScale='p2' color='alternative'>
{t('Value_users', { value })}
</Box>}
/>
</Box>
</Box>
: <Skeleton variant='rect' height={196} />}
</Flex.Container>
</Box>
: <Skeleton variant='rect' height={196} />}
</>;
}

Expand All @@ -141,7 +131,7 @@ function ContentForDays({ displacement, onPreviousDateClick, onNextDateClick })
<Flex.Container alignItems='center' justifyContent='center'>
<Box>
<Button ghost square small onClick={onPreviousDateClick}>
<Chevron left size='20' style={{ verticalAlign: 'middle' }} />
<Chevron left size='x20' style={{ verticalAlign: 'middle' }} />
</Button>
<Flex.Item basis='50%'>
<Margins inline='x8'>
Expand All @@ -151,7 +141,7 @@ function ContentForDays({ displacement, onPreviousDateClick, onNextDateClick })
</Margins>
</Flex.Item>
<Button ghost square small disabled={displacement === 0} onClick={onNextDateClick}>
<Chevron right size='20' style={{ verticalAlign: 'middle' }} />
<Chevron right size='x20' style={{ verticalAlign: 'middle' }} />
</Button>
</Box>
</Flex.Container>
Expand Down

0 comments on commit e16b270

Please sign in to comment.