vue-intergrall-plugins 1.1.66 → 1.1.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-intergrall-plugins",
3
- "version": "1.1.66",
3
+ "version": "1.1.67",
4
4
  "description": "",
5
5
  "main": "dist/vue-intergrall-plugins.ssr.js",
6
6
  "browser": "dist/vue-intergrall-plugins.esm.js",
@@ -54,5 +54,8 @@
54
54
  },
55
55
  "engines": {
56
56
  "node": ">=12"
57
+ },
58
+ "dependencies": {
59
+ "vue-html2pdf": "^1.8.0"
57
60
  }
58
61
  }
@@ -20,6 +20,14 @@
20
20
  <span v-else v-html="button.svgIcon" :class="button.svgClass ? button.svgClass : ''"></span>
21
21
  </span>
22
22
  </template>
23
+ <span
24
+ v-if="status === 'C'"
25
+ class="email-pdf-download cursor-pointer"
26
+ @click.stop="generatePdf"
27
+ title="Baixar e-mail em PDF"
28
+ >
29
+ <fa-icon :icon="['fas', 'file-pdf']" />
30
+ </span>
23
31
  <span
24
32
  v-if="isOpen && filteredFiles && filteredFiles.length"
25
33
  class="email-clip-anchor cursor-pointer"
@@ -213,6 +221,59 @@
213
221
  </span>
214
222
  <!-- Status de mensagem deletada -->
215
223
  </transition>
224
+ <vue-html2pdf
225
+ :show-layout="false"
226
+ :enable-download="true"
227
+ :preview-modal="false"
228
+ :paginate-elements-by-height="1400"
229
+ :filename="pdfFilename"
230
+ :pdf-quality="2"
231
+ ref="html2pdf"
232
+ :manual-pagination="true"
233
+ :html-to-pdf-options="htmlToPdfOptions"
234
+ >
235
+ <section slot="pdf-content" id="conteudo-pdf">
236
+ <div class="pdf-content">
237
+ <h1 class="pdf-title">{{ htmlEntityToEmoji(replaceUnicodeWithEmoji(assunto)) || '(Sem assunto)' }}</h1>
238
+
239
+ <table class="pdf-info-table">
240
+ <tbody>
241
+ <tr>
242
+ <th>De:</th>
243
+ <td>{{ formatPdfRecipients(from) }}</td>
244
+ </tr>
245
+ <tr>
246
+ <th>Para:</th>
247
+ <td>{{ formatPdfRecipients(para) }}</td>
248
+ </tr>
249
+ <tr v-if="copia && copia.length">
250
+ <th>Cópia:</th>
251
+ <td>{{ formatPdfRecipients(copia) }}</td>
252
+ </tr>
253
+ <tr>
254
+ <th>Data:</th>
255
+ <td>{{ formataDataHora(dataHora, true, false) }} - {{ formattedDate }}</td>
256
+ </tr>
257
+ </tbody>
258
+ </table>
259
+
260
+ <hr class="pdf-divisor" />
261
+
262
+ <div class="pdf-email-content">
263
+ <div v-html="formatContentForPdf()"></div>
264
+ </div>
265
+
266
+ <div v-if="filteredFiles && filteredFiles.length" class="pdf-attachments">
267
+ <h3>Anexos ({{ filteredFiles.length }}):</h3>
268
+ <ul>
269
+ <li v-for="(anexo, index) in filteredFiles" :key="index">
270
+ {{ anexo.name || `Anexo ${index + 1}` }}
271
+ </li>
272
+ </ul>
273
+ </div>
274
+ </div>
275
+ </section>
276
+ </vue-html2pdf>
216
277
  </div>
217
278
  </template>
218
279
 
@@ -221,6 +282,7 @@ import EmailFile from "./EmailFile.vue";
221
282
  import EmailTo from "./EmailTo.vue";
222
283
  import { textoLongo } from "@/mixins/formatarTexto";
223
284
  import Clickaway from '@/directives/clickaway';
285
+ import VueHtml2pdf from 'vue-html2pdf';
224
286
  import '../../styles/style.css';
225
287
 
226
288
  export default {
@@ -228,7 +290,7 @@ export default {
228
290
  directives: {
229
291
  clickaway: Clickaway
230
292
  },
231
- components: { EmailFile, EmailTo },
293
+ components: { EmailFile, EmailTo, VueHtml2pdf },
232
294
  props: {
233
295
  dominio: {
234
296
  type: String,
@@ -355,6 +417,29 @@ export default {
355
417
  hasError: false,
356
418
  errorCount: 0,
357
419
  scrollToFile: false,
420
+ htmlToPdfOptions: {
421
+ margin: [15, 0, 15, 0],
422
+ filename: 'email.pdf',
423
+ image: {
424
+ type: 'jpeg',
425
+ quality: 0.98
426
+ },
427
+ enableLinks: false,
428
+ html2canvas: {
429
+ scale: 2,
430
+ useCORS: true,
431
+ letterRendering: true,
432
+ logging: false,
433
+ scrollY: 0,
434
+ scrollX: 0
435
+ },
436
+ jsPDF: {
437
+ unit: 'mm',
438
+ format: 'a4',
439
+ orientation: 'portrait',
440
+ compress: true
441
+ }
442
+ }
358
443
  };
359
444
  },
360
445
  computed: {
@@ -456,6 +541,12 @@ export default {
456
541
  const text = index === 0 ? `${this.dicionario.tit_copia || 'Cópia'}: ${name || ''}` : name ? `${name}${addVirgulaDps ? ', ' : ''}` : '';
457
542
  return text
458
543
  }
544
+ },
545
+ pdfFilename() {
546
+ const subject = this.assunto || 'email';
547
+ const sanitized = subject.replace(/[^a-z0-9]/gi, '_').substring(0, 50);
548
+ const date = this.dataHora ? new Date(this.dataHora).toISOString().split('T')[0] : '';
549
+ return `email_${sanitized}_${date}`;
459
550
  }
460
551
  },
461
552
  watch: {
@@ -745,7 +836,97 @@ export default {
745
836
  });
746
837
 
747
838
  return Object.keys(customParams).length ? customParams : defaultParams;
839
+ },
840
+ generatePdf() {
841
+ if (this.$refs.html2pdf) {
842
+ this.$refs.html2pdf.generatePdf();
843
+ }
844
+ },
845
+ formatPdfRecipients(recipients) {
846
+ if (!recipients || !recipients.length) return '--';
847
+ return recipients.map(r => {
848
+ if (r.name && r.email) return `${r.name} <${r.email}>`;
849
+ return r.name || r.email || '';
850
+ }).join(', ');
851
+ },
852
+ formatContentForPdf() {
853
+ let content = this.html || this.mensagem || '';
854
+
855
+ if (!/<[a-z][\s\S]*>/i.test(content)) {
856
+ content = content.replace(/\n/g, '<br>');
857
+ content = this.gerarMensagemEstilizada(content);
858
+ content = `<p>${content}</p>`;
859
+ }
860
+
861
+ return content;
748
862
  }
749
863
  }
750
864
  };
751
- </script>
865
+ </script>
866
+
867
+ <style scoped>
868
+ .email-pdf-download {
869
+ padding: 5px 8px;
870
+ color: #d54286;
871
+ font-size: 16px;
872
+ transition: opacity 0.2s;
873
+ display: flex;
874
+ align-items: center;
875
+ justify-content: center;
876
+ }
877
+
878
+ .email-pdf-download:hover {
879
+ opacity: 0.7;
880
+ }
881
+
882
+ .pdf-content {
883
+ padding: 20px;
884
+ }
885
+
886
+ .pdf-title {
887
+ font-size: 20px;
888
+ color: #d54286;
889
+ margin: 0 0 15px 0;
890
+ padding-bottom: 10px;
891
+ border-bottom: 2px solid #e2e6ea;
892
+ word-wrap: break-word;
893
+ overflow-wrap: break-word;
894
+ page-break-after: avoid;
895
+ page-break-inside: avoid;
896
+ }
897
+
898
+ .pdf-info-table {
899
+ width: 100%;
900
+ margin: 0 0 20px 0;
901
+ border-collapse: collapse;
902
+ table-layout: fixed;
903
+ page-break-inside: avoid;
904
+ }
905
+
906
+ .pdf-info-table th {
907
+ text-align: left;
908
+ padding: 10px;
909
+ font-weight: bold;
910
+ background-color: #f8f9fa;
911
+ border: 1px solid #e2e6ea;
912
+ width: 100px;
913
+ vertical-align: top;
914
+ font-size: 14px;
915
+ }
916
+
917
+ .pdf-info-table td {
918
+ padding: 10px;
919
+ border: 1px solid #e2e6ea;
920
+ word-wrap: break-word;
921
+ overflow-wrap: break-word;
922
+ word-break: break-word;
923
+ font-size: 14px;
924
+ line-height: 1.5;
925
+ max-width: 100%;
926
+ }
927
+
928
+ .pdf-info-table tr {
929
+ page-break-inside: avoid;
930
+ page-break-after: auto;
931
+ }
932
+ </style>