Skip to content

Commit 170a413

Browse files
feat: Improve PDF message exportation content (#36339)
Co-authored-by: Tasso Evangelista <2263066+tassoevan@users.noreply.github.com>
1 parent d7edd91 commit 170a413

File tree

4 files changed

+109
-32
lines changed

4 files changed

+109
-32
lines changed

.changeset/orange-tips-doubt.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@rocket.chat/meteor": minor
3+
"@rocket.chat/i18n": minor
4+
---
5+
6+
Improves the message exportation content for PDF method including images and information about threads and files

apps/meteor/client/views/room/contextualBar/ExportMessages/ExportMessages.tsx

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ const ExportMessages = () => {
111111
// Remove HTML from download options
112112
const downloadOutputOptions = outputOptions.slice(1);
113113

114-
const roomExportMutation = useRoomExportMutation();
115-
const downloadExportMutation = useDownloadExportMutation();
114+
const { mutateAsync: exportRoom } = useRoomExportMutation();
115+
const { mutateAsync: exportAndDownload } = useDownloadExportMutation();
116116

117117
const { selectedMessageStore } = useContext(SelectedMessageContext);
118118
const messageCount = useCountSelected();
@@ -123,6 +123,10 @@ const ExportMessages = () => {
123123
if (type === 'email') {
124124
setValue('format', 'html');
125125
}
126+
127+
if (type === 'download') {
128+
setValue('format', 'json');
129+
}
126130
}, [type, setValue]);
127131

128132
useEffect(() => {
@@ -139,34 +143,45 @@ const ExportMessages = () => {
139143
setValue('messagesCount', messageCount, { shouldDirty: true });
140144
}, [messageCount, setValue]);
141145

142-
const { mutate: exportAsPDF } = useExportMessagesAsPDFMutation();
146+
const { mutateAsync: exportAsPDF } = useExportMessagesAsPDFMutation();
143147

144-
const handleExport = async ({ type, toUsers, dateFrom, dateTo, format, subject, additionalEmails }: ExportMessagesFormValues) => {
148+
const handleExport = async ({
149+
type,
150+
toUsers,
151+
dateFrom,
152+
dateTo,
153+
format,
154+
subject,
155+
additionalEmails,
156+
}: ExportMessagesFormValues): Promise<void> => {
145157
const messages = selectedMessageStore.getSelectedMessages();
146158

147159
if (type === 'download') {
148160
if (format === 'pdf') {
149-
return exportAsPDF(messages);
161+
await exportAsPDF(messages);
162+
return;
150163
}
151164

152165
if (format === 'json') {
153-
return downloadExportMutation.mutateAsync({
166+
await exportAndDownload({
154167
mids: messages,
155168
});
169+
return;
156170
}
157171
}
158172

159173
if (type === 'file') {
160-
return roomExportMutation.mutateAsync({
174+
await exportRoom({
161175
rid: room._id,
162176
type: 'file',
163177
...(dateFrom && { dateFrom }),
164178
...(dateTo && { dateTo }),
165179
format: format as 'html' | 'json',
166180
});
181+
return;
167182
}
168183

169-
roomExportMutation.mutateAsync({
184+
await exportRoom({
170185
rid: room._id,
171186
type: 'email',
172187
toUsers,

apps/meteor/client/views/room/contextualBar/ExportMessages/useExportMessagesAsPDFMutation.tsx

Lines changed: 79 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,53 @@
1-
import { Document, Page, pdf, Text, View } from '@react-pdf/renderer';
2-
import type { IMessage } from '@rocket.chat/core-typings';
1+
import { Document, Image, Page, pdf, StyleSheet, Text, View } from '@react-pdf/renderer';
2+
import type { IMessage, MessageAttachmentDefault } from '@rocket.chat/core-typings';
33
import { escapeHTML } from '@rocket.chat/string-helpers';
4-
import { useSetting } from '@rocket.chat/ui-contexts';
4+
import { useSetting, useToastMessageDispatch } from '@rocket.chat/ui-contexts';
55
import { useMutation } from '@tanstack/react-query';
66
import { useTranslation } from 'react-i18next';
77

88
import { Messages } from '../../../../../app/models/client';
99
import { MessageTypes } from '../../../../../app/ui-utils/lib/MessageTypes';
1010
import { useFormatDateAndTime } from '../../../../hooks/useFormatDateAndTime';
1111

12+
const leftTab = {
13+
marginLeft: 20,
14+
};
15+
16+
const pdfStyles = StyleSheet.create({
17+
messageHeader: {
18+
display: 'flex',
19+
flexDirection: 'row',
20+
alignItems: 'flex-end',
21+
gap: 10,
22+
},
23+
username: {
24+
color: '#000',
25+
fontSize: 14,
26+
},
27+
dateTime: {
28+
color: '#aaa',
29+
fontSize: 12,
30+
},
31+
threadMessagesCount: {
32+
color: '#000',
33+
fontSize: 14,
34+
},
35+
threadMessage: {
36+
color: '#555',
37+
fontSize: 12,
38+
...leftTab,
39+
},
40+
message: {
41+
color: '#555',
42+
fontSize: 14,
43+
},
44+
});
45+
1246
export const useExportMessagesAsPDFMutation = () => {
1347
const { t } = useTranslation();
1448
const chatopsUsername = useSetting('Chatops_Username');
1549
const formatDateAndTime = useFormatDateAndTime();
50+
const dispatchToastMessage = useToastMessageDispatch();
1651

1752
return useMutation({
1853
mutationFn: async (messageIds: IMessage['_id'][]) => {
@@ -48,12 +83,21 @@ export const useExportMessagesAsPDFMutation = () => {
4883
{messages.map((message) => {
4984
const dateTime = formatDateAndTime(message.ts);
5085
return (
51-
<Text key={message._id} style={{ marginBottom: 5 }}>
52-
<Text style={{ color: '#555', fontSize: 14 }}>{message.u.username}</Text>{' '}
53-
<Text style={{ color: '#aaa', fontSize: 12 }}>{dateTime}</Text>
54-
<Text>{'\n'}</Text>
55-
{parseMessage(message)}
56-
</Text>
86+
<View key={message._id} style={{ marginBottom: 10 }}>
87+
<View style={pdfStyles.messageHeader}>
88+
<Text style={{ ...(message.tmid ? leftTab : {}), ...pdfStyles.username }}>{message.u.username}</Text>
89+
<Text style={pdfStyles.dateTime}>{dateTime}</Text>
90+
{message.tcount && <Text style={pdfStyles.threadMessagesCount}>{`${message.tcount} ${t('thread_messages')}`}</Text>}
91+
</View>
92+
<Text style={message.tmid ? pdfStyles.threadMessage : pdfStyles.message}>{parseMessage(message)}</Text>
93+
{message.attachments?.map((attachment: MessageAttachmentDefault, index) => (
94+
<View key={index}>
95+
{attachment.description && <Text style={pdfStyles.message}>{attachment.description}</Text>}
96+
{attachment.image_url && <Image src={attachment.title_link} style={attachment.image_dimensions} />}
97+
<Text style={pdfStyles.message}>{attachment.title}</Text>
98+
</View>
99+
))}
100+
</View>
57101
);
58102
})}
59103
</View>
@@ -63,22 +107,33 @@ export const useExportMessagesAsPDFMutation = () => {
63107

64108
const instance = pdf();
65109

66-
const callback = async () => {
67-
const link = document.createElement('a');
68-
link.href = URL.createObjectURL(await instance.toBlob());
69-
link.download = `exportedMessages-${new Date().toISOString()}.pdf`;
70-
document.body.appendChild(link);
71-
link.click();
72-
document.body.removeChild(link);
73-
URL.revokeObjectURL(link.href);
74-
};
110+
await new Promise<void>((resolve, reject) => {
111+
const callback = async () => {
112+
const link = document.createElement('a');
113+
link.href = URL.createObjectURL(await instance.toBlob());
114+
link.download = `exportedMessages-${new Date().toISOString()}.pdf`;
115+
document.body.appendChild(link);
116+
link.click();
117+
document.body.removeChild(link);
118+
URL.revokeObjectURL(link.href);
119+
resolve();
120+
};
75121

76-
try {
77-
instance.on('change', callback);
78-
instance.updateContainer(jsx);
79-
} finally {
80-
instance.removeListener('change', callback);
81-
}
122+
try {
123+
instance.on('change', callback);
124+
instance.updateContainer(jsx);
125+
} catch (error) {
126+
reject(error);
127+
} finally {
128+
instance.removeListener('change', callback);
129+
}
130+
});
131+
},
132+
onError: (error) => {
133+
dispatchToastMessage({ type: 'error', message: error });
134+
},
135+
onSuccess: () => {
136+
dispatchToastMessage({ type: 'success', message: t('Messages_exported_successfully') });
82137
},
83138
});
84139
};

packages/i18n/src/locales/en.i18n.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6694,6 +6694,7 @@
66946694
"this_app_is_included_with_subscription": "This app is included with {{bundleName}} plans",
66956695
"thread": "thread",
66966696
"thread_message": "thread message",
6697+
"thread_messages": "thread messages",
66976698
"thread_message_preview": "thread message preview",
66986699
"threads_counter_one": "{{count}} unread threaded message",
66996700
"threads_counter_other": "{{count}} unread threaded messages",

0 commit comments

Comments
 (0)