@nixweb/nixloc-ui 0.0.307 → 0.0.308

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": "@nixweb/nixloc-ui",
3
- "version": "0.0.307",
3
+ "version": "0.0.308",
4
4
  "description": "Componentes UI",
5
5
  "author": "Fábio Ávila <fabio@nixweb.com.br>",
6
6
  "private": false,
@@ -0,0 +1,109 @@
1
+ <template>
2
+ <div>
3
+ <div class="zoom-controls">
4
+ <transition name="fade">
5
+ <span v-if="showZoomLabel">{{ (zoom * 100).toFixed(0) }}%</span>
6
+ </transition>
7
+ </div>
8
+ <div class="zoom-area" :style="zoomStyle">
9
+ <slot></slot>
10
+ </div>
11
+ </div>
12
+ </template>
13
+
14
+ <script>
15
+ import { mapGetters, mapMutations, mapActions } from "vuex";
16
+
17
+ export default {
18
+ name: 'Zoom',
19
+ data() {
20
+ return {
21
+ zoom: 1,
22
+ zoomStep: 0.1,
23
+ zoomMin: 0.5,
24
+ zoomMax: 2.0,
25
+ showZoomLabel: false,
26
+ zoomTimeout: null
27
+ }
28
+ },
29
+ computed: {
30
+ ...mapGetters("generic", ["event"]),
31
+ zoomStyle() {
32
+ return {
33
+ transform: `scale(${this.zoom})`,
34
+ transformOrigin: 'top left',
35
+ display: 'inline-block',
36
+
37
+ }
38
+ }
39
+ },
40
+ methods: {
41
+ zoomIn() {
42
+ if (this.zoom < this.zoomMax) {
43
+ this.zoom += this.zoomStep
44
+ this.showZoomTemporarily()
45
+ }
46
+ },
47
+ zoomOut() {
48
+ if (this.zoom > this.zoomMin) {
49
+ this.zoom -= this.zoomStep
50
+ this.showZoomTemporarily()
51
+ }
52
+ },
53
+ showZoomTemporarily() {
54
+ this.showZoomLabel = true
55
+ clearTimeout(this.zoomTimeout)
56
+ this.zoomTimeout = setTimeout(() => {
57
+ this.showZoomLabel = false
58
+ }, 3000)
59
+ }
60
+ },
61
+ beforeDestroy() {
62
+ clearTimeout(this.zoomTimeout)
63
+ },
64
+ watch: {
65
+ event: {
66
+ handler(event) {
67
+ if (event.name == "zoomIn") this.zoomIn();
68
+ if (event.name == "zoomOut") this.zoomOut();
69
+ },
70
+ deep: true,
71
+ },
72
+
73
+ },
74
+ }
75
+ </script>
76
+
77
+ <style scoped>
78
+ .zoom-controls {
79
+ margin-bottom: 10px;
80
+ display: flex;
81
+ align-items: center;
82
+ gap: 8px;
83
+ }
84
+
85
+ .zoom-controls button {
86
+ padding: 5px 10px;
87
+ font-weight: bold;
88
+ cursor: pointer;
89
+ }
90
+
91
+ .fade-enter-active,
92
+ .fade-leave-active {
93
+ transition: opacity 0.5s ease;
94
+ }
95
+
96
+ .fade-enter,
97
+ .fade-leave-to {
98
+ opacity: 0;
99
+ }
100
+
101
+ .zoom-controls span {
102
+ font-size: 13px;
103
+ }
104
+
105
+ .zoom-area {
106
+ background: #fff;
107
+
108
+ }
109
+ </style>
@@ -47,9 +47,15 @@
47
47
  </div>
48
48
  <div v-if="show" class="preview">
49
49
  <div class="toolbar">
50
+ <div v-if="loadingFile" class="icon-toolbar">
51
+ <i class="fa-duotone fa-solid fa-spinner-third loading-icon"></i>
52
+ </div>
50
53
  <div class="icon-toolbar" v-print="'#printMe'">
51
54
  <i class="fas fa-print"></i>
52
55
  </div>
56
+ <div @click="generatePDF" class="icon-toolbar">
57
+ <i class="fa-solid fa-file-pdf"></i>
58
+ </div>
53
59
  <div class="icon-toolbar icon-excel">
54
60
  <ExportExcel :nameFile="name" :header="dataConditional" :data="data" />
55
61
  </div>
@@ -90,6 +96,8 @@ import Panel from "@nixweb/nixloc-ui/src/component/layout/Panel.vue";
90
96
  import Alert from "@nixweb/nixloc-ui/src/component/layout/Alert";
91
97
 
92
98
  import print from "vue-print-nb";
99
+ import jsPDF from 'jspdf'
100
+ import html2canvas from 'html2canvas'
93
101
 
94
102
  import { mapMutations, mapActions, mapGetters } from "vuex";
95
103
 
@@ -113,6 +121,7 @@ export default {
113
121
  totalPerPage: 50,
114
122
  pagination: [],
115
123
  cancel: false,
124
+ loadingFile: false,
116
125
  }
117
126
  },
118
127
  mounted() {
@@ -205,6 +214,26 @@ export default {
205
214
  });
206
215
  }
207
216
  },
217
+ async generatePDF() {
218
+ this.loadingFile = true;
219
+ const tabela = document.getElementById('printMe')
220
+ const canvas = await html2canvas(tabela, {
221
+ scale: 4
222
+ })
223
+ const imgData = canvas.toDataURL('image/png')
224
+
225
+ const pdf = new jsPDF('l', 'mm', 'a4')
226
+ const pageWidth = pdf.internal.pageSize.getWidth()
227
+ const pageHeight = pdf.internal.pageSize.getHeight()
228
+
229
+ const imgProps = pdf.getImageProperties(imgData)
230
+ const pdfWidth = pageWidth
231
+ const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width
232
+
233
+ pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight)
234
+ pdf.save(this.name + '.pdf')
235
+ this.loadingFile = false;
236
+ },
208
237
  verifyIfPagination() {
209
238
  if (this.pagination.length > 0) {
210
239
  this.currentPage++;
@@ -262,6 +291,18 @@ export default {
262
291
  height: 100%;
263
292
  }
264
293
 
294
+ .loading-icon {
295
+ color: orange;
296
+ font-size: 19px;
297
+ animation: spin 1s linear infinite;
298
+ }
299
+
300
+ @keyframes spin {
301
+ 100% {
302
+ transform: rotate(360deg);
303
+ }
304
+ }
305
+
265
306
  .toolbar {
266
307
  height: 40px;
267
308
  border-bottom: 1px hsl(0, 0%, 82.7%) solid;
@@ -1,9 +1,15 @@
1
1
  <template>
2
2
  <div class="preview">
3
3
  <div class="toolbar">
4
+ <div v-if="loadingFile" class="icon-toolbar">
5
+ <i class="fa-duotone fa-solid fa-spinner-third loading-icon"></i>
6
+ </div>
4
7
  <div class="icon-toolbar" v-print="'#printMeSub'">
5
8
  <i class="fas fa-print"></i>
6
9
  </div>
10
+ <div @click="generatePDF" class="icon-toolbar">
11
+ <i class="fa-solid fa-file-pdf"></i>
12
+ </div>
7
13
  <div class="icon-toolbar icon-excel">
8
14
  <ExportExcel :nameFile="name" :header="header" :data="data" />
9
15
  </div>
@@ -67,6 +73,9 @@ import ScrollBar from "@nixweb/nixloc-ui/src/component/layout/ScrollBar.vue";
67
73
  import HeaderReport from "../shared/HeaderReport.vue";
68
74
  import TotalizationReport from "../shared/TotalizationReport.vue";
69
75
  import ExportExcel from "@nixweb/nixloc-ui/src/component/shared/ExportExcel";
76
+
77
+ import jsPDF from 'jspdf'
78
+ import html2canvas from 'html2canvas'
70
79
  import print from "vue-print-nb";
71
80
 
72
81
  import { mapMutations } from "vuex";
@@ -77,6 +86,11 @@ export default {
77
86
  },
78
87
  props: ["name", "titleHeader", "header", "data", "totalization", "totalizationCustom", "minHeight"],
79
88
  components: { ScrollBar, HeaderReport, TotalizationReport, ExportExcel },
89
+ data() {
90
+ return {
91
+ loadingFile: false,
92
+ }
93
+ },
80
94
  methods: {
81
95
  ...mapMutations("generic", ["addEvent"]),
82
96
  convertClass(fieldComparison, classCssBody) {
@@ -96,6 +110,26 @@ export default {
96
110
  sendEvent(eventName, data) {
97
111
  if (eventName) this.addEvent({ name: eventName, data: data });
98
112
  },
113
+ async generatePDF() {
114
+ this.loadingFile = true;
115
+ const tabela = document.getElementById('printMeSub')
116
+ const canvas = await html2canvas(tabela, {
117
+ scale: 4
118
+ })
119
+ const imgData = canvas.toDataURL('image/png')
120
+
121
+ const pdf = new jsPDF('l', 'mm', 'a4')
122
+ const pageWidth = pdf.internal.pageSize.getWidth()
123
+ const pageHeight = pdf.internal.pageSize.getHeight()
124
+
125
+ const imgProps = pdf.getImageProperties(imgData)
126
+ const pdfWidth = pageWidth
127
+ const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width
128
+
129
+ pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight)
130
+ pdf.save(this.name + '.pdf')
131
+ this.loadingFile = false;
132
+ },
99
133
  },
100
134
  };
101
135
  </script>
@@ -150,6 +184,18 @@ table tbody tr td {
150
184
  border: 1px solid #e4e6ec;
151
185
  }
152
186
 
187
+ .loading-icon {
188
+ color: orange;
189
+ font-size: 19px;
190
+ animation: spin 1s linear infinite;
191
+ }
192
+
193
+ @keyframes spin {
194
+ 100% {
195
+ transform: rotate(360deg);
196
+ }
197
+ }
198
+
153
199
  .toolbar {
154
200
  height: 40px;
155
201
  border-bottom: 1px hsl(0, 0%, 82.7%) solid;