@nixweb/nixloc-ui 0.0.306 → 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.306",
3
+ "version": "0.0.308",
4
4
  "description": "Componentes UI",
5
5
  "author": "Fábio Ávila <fabio@nixweb.com.br>",
6
6
  "private": false,
@@ -55,17 +55,21 @@
55
55
  <b-row>
56
56
  <b-col sm="2" v-if="item.title">
57
57
  <i :class="item.icon"></i>
58
-
59
58
  </b-col>
60
59
  <b-col sm="9">
61
60
  <div v-if="item.groupName" class="div-group">
62
61
  {{ item.groupName }}
63
62
  </div>
64
63
  <span>
64
+
65
65
  <span> {{ item.title }}</span>
66
- <span class="div-support" v-if="item.isVisible == 'support'">
66
+ <span class="div-new" v-if="item.isVisible == 'support'">
67
67
  Suporte
68
68
  </span>
69
+ <span class="div-new"
70
+ v-if="item.showNewUntil && showNewUntil(item.showNewUntil)">
71
+ Novo
72
+ </span>
69
73
  </span>
70
74
  </b-col>
71
75
  </b-row>
@@ -136,6 +140,17 @@ export default {
136
140
  },
137
141
  methods: {
138
142
  ...mapMutations("generic", ["addEvent", "toggleMenu"]),
143
+ showNewUntil(dateStr) {
144
+ const [day, month, year] = dateStr.split('/');
145
+ const inputDate = new Date(year, month - 1, day);
146
+ const today = new Date();
147
+
148
+ // Zerar horas para comparar apenas a data
149
+ inputDate.setHours(0, 0, 0, 0);
150
+ today.setHours(0, 0, 0, 0);
151
+
152
+ return today < inputDate;
153
+ },
139
154
  updatePageSize() {
140
155
  const windowHeight = window.innerHeight;
141
156
  this.pageSize = windowHeight;
@@ -445,11 +460,11 @@ export default {
445
460
  padding: 5px;
446
461
  }
447
462
 
448
- .div-support {
463
+ .div-new {
449
464
  background-color: #0A36DB;
450
465
  font-size: 11px;
451
466
  border-radius: 20px;
452
- padding: 1px 2px 2px 2px;
467
+ padding: 1px 3px 2px 2px;
453
468
  margin-left: 5px;
454
469
  color: white !important;
455
470
  }
@@ -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,14 +1,20 @@
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>
10
16
  </div>
11
- <ScrollBar :minHeight="400" :maxHeight="820">
17
+ <ScrollBar :minHeight="400" :maxHeight="500">
12
18
  <br />
13
19
  <div id="printMeSub" :style="'min-height:' + minHeight + 'px'" class="a4 footer">
14
20
  <HeaderReport :title="titleHeader" />
@@ -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;
@@ -3,19 +3,19 @@
3
3
  <hr class="hr-report" />
4
4
  <div class="text-right">
5
5
  <b-row>
6
- <b-col sm="10">
6
+ <b-col sm="9">
7
7
  <span class="title-report-header"> Total de Registros .................. </span>
8
8
  </b-col>
9
- <b-col sm="2">
9
+ <b-col sm="3">
10
10
  <span class="title-report-header value-report-header"> {{ totalRecords }} </span>
11
11
  </b-col>
12
12
  </b-row>
13
13
  <!-- Utilizado para calculo do subReport -->
14
14
  <b-row v-if="totalizationCustom">
15
- <b-col sm="10">
15
+ <b-col sm="9">
16
16
  <span class="title-report-header"> {{ totalizationCustom[0].title }} .................. </span>
17
17
  </b-col>
18
- <b-col sm="2">
18
+ <b-col sm="3">
19
19
  <span class="title-report-header value-report-header"> {{ totalizationCustom[0].value | currency }} </span>
20
20
  </b-col>
21
21
  </b-row>
@@ -43,6 +43,9 @@
43
43
  <i class="fas fa-file-alt icon-report"></i>
44
44
  </b-col>
45
45
  <b-col sm="11" @click="navegateTo(report)">
46
+ <div v-if="report.showNewUntil && showNewUntil(report.showNewUntil)" class="side-by-side div-new">
47
+ <span>Novo</span>
48
+ </div>
46
49
  <div class="title-report side-by-side">{{ report.name }}</div>
47
50
  <div><span class="description-report">{{ report.description }}</span></div>
48
51
  </b-col>
@@ -80,6 +83,7 @@ export default {
80
83
  },
81
84
  computed: {
82
85
  ...mapState("generic", ["search", "executedSearch", "clearedSearch"]),
86
+
83
87
  },
84
88
  mounted() {
85
89
  this.getAll();
@@ -89,6 +93,16 @@ export default {
89
93
  methods: {
90
94
  ...mapMutations("generic", ["removeLoading"]),
91
95
  ...mapActions("generic", ["getApi", "deleteAllApi"]),
96
+ showNewUntil(dateStr) {
97
+ const [day, month, year] = dateStr.split('/');
98
+ const inputDate = new Date(year, month - 1, day);
99
+ const today = new Date();
100
+
101
+ inputDate.setHours(0, 0, 0, 0);
102
+ today.setHours(0, 0, 0, 0);
103
+
104
+ return today < inputDate;
105
+ },
92
106
  getAll() {
93
107
  let obj = { module: this.panel.module };
94
108
  let params = { url: this.urlGetAll, obj: obj };
@@ -191,6 +205,15 @@ export default {
191
205
  color: #577696;
192
206
  }
193
207
 
208
+ .div-new {
209
+ background-color: #0A36DB;
210
+ font-size: 11px;
211
+ border-radius: 20px;
212
+ padding: 1px 8px 2px 8px;
213
+ margin-right: 10px;
214
+ color: white !important;
215
+ }
216
+
194
217
  .div-molded {
195
218
  margin-bottom: 10px;
196
219
  cursor: pointer;