@nixweb/nixloc-ui 1.19.0 → 1.21.0

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.
Files changed (110) hide show
  1. package/package.json +1 -1
  2. package/src/component/forms/ButtonFilter.vue +104 -104
  3. package/src/component/forms/ButtonGroup.vue +66 -66
  4. package/src/component/forms/ButtonGroupInline.vue +210 -210
  5. package/src/component/forms/ButtonSub.vue +97 -97
  6. package/src/component/forms/ButtonToggle.vue +76 -76
  7. package/src/component/forms/DateYearMonth.vue +192 -192
  8. package/src/component/forms/ImageUpload.vue +214 -214
  9. package/src/component/forms/IncrementDecrement.vue +151 -151
  10. package/src/component/forms/InputAddressGoogle.vue +171 -171
  11. package/src/component/forms/InputCallToAction.vue +135 -135
  12. package/src/component/forms/InputDecimalDiscount.vue +146 -146
  13. package/src/component/forms/InputTag.vue +124 -124
  14. package/src/component/forms/InputTextEdit.vue +69 -69
  15. package/src/component/forms/InputWhatsApp.vue +47 -47
  16. package/src/component/forms/SideBar.vue +99 -99
  17. package/src/component/forms/Toggle.vue +72 -72
  18. package/src/component/layout/Account.vue +131 -131
  19. package/src/component/layout/AnimatedPhrase.vue +68 -68
  20. package/src/component/layout/BarFloating.vue +67 -67
  21. package/src/component/layout/BottomActionsBar.vue +205 -205
  22. package/src/component/layout/ColorPicker.vue +175 -175
  23. package/src/component/layout/Gantt.vue +128 -128
  24. package/src/component/layout/HideShow.vue +61 -61
  25. package/src/component/layout/IconMolded.vue +58 -58
  26. package/src/component/layout/IconPicker.vue +161 -161
  27. package/src/component/layout/NewAccount.vue +136 -136
  28. package/src/component/layout/NewHeader.vue +59 -59
  29. package/src/component/layout/NewIconMolded.vue +70 -70
  30. package/src/component/layout/NewMenu.vue +472 -472
  31. package/src/component/layout/Tab.vue +259 -259
  32. package/src/component/layout/Tag.vue +97 -97
  33. package/src/component/layout/Tooltip.vue +155 -155
  34. package/src/component/layout/Zoom.vue +111 -111
  35. package/src/component/rental/DisplayCalculatePeriod.vue +48 -48
  36. package/src/component/rental/DisplayPeriodRent.vue +55 -55
  37. package/src/component/rental/DisplayTotalization.vue +86 -86
  38. package/src/component/report/Fields.vue +108 -108
  39. package/src/component/report/Report.vue +377 -377
  40. package/src/component/report/ReportTable.vue +111 -111
  41. package/src/component/report/Totalization.vue +33 -33
  42. package/src/component/shared/CodeEditor.vue +128 -128
  43. package/src/component/shared/Confirmation.vue +74 -74
  44. package/src/component/shared/DocumentEditor.vue +99 -99
  45. package/src/component/shared/DocumentPreview.vue +117 -105
  46. package/src/component/shared/DocumentPublic.vue +33 -33
  47. package/src/component/shared/ExportExcel.vue +56 -56
  48. package/src/component/shared/FullCalendar.vue +175 -175
  49. package/src/component/shared/HeaderReport.vue +47 -47
  50. package/src/component/shared/ListNotifications.vue +70 -70
  51. package/src/component/shared/Loading.vue +1 -4
  52. package/src/component/shared/LoadingCard.vue +64 -64
  53. package/src/component/shared/ParameterLegend.vue +169 -169
  54. package/src/component/shared/Report.vue +250 -250
  55. package/src/component/shared/SaveCancel.vue +99 -117
  56. package/src/component/shared/SelectOption.vue +162 -162
  57. package/src/component/shared/TableDraggable.vue +117 -117
  58. package/src/component/shared/TableImport.vue +93 -93
  59. package/src/component/shared/TableItem.vue +228 -228
  60. package/src/component/shared/TableTotalPerPage.vue +114 -114
  61. package/src/component/shared/TableTotalRecords.vue +44 -44
  62. package/src/component/shared/TimeLine.vue +41 -41
  63. package/src/component/shared/Timer.vue +77 -77
  64. package/src/component/shared/ToggleTheme.vue +127 -127
  65. package/src/component/shared/TotalizationReport.vue +86 -86
  66. package/src/component/shared/actions/ActionButtons.vue +53 -53
  67. package/src/component/shared/actions/ActionErrorContent.vue +103 -103
  68. package/src/component/shared/actions/ActionFooter.vue +93 -99
  69. package/src/component/shared/actions/ActionHeader.vue +110 -110
  70. package/src/component/shared/actions/ActionItemList.vue +143 -143
  71. package/src/component/shared/actions/ActionsOptions.vue +209 -209
  72. package/src/component/shared/actions/ActionsSelected.vue +262 -262
  73. package/src/component/shared/automation/ActivitiesList.vue +43 -43
  74. package/src/component/shared/automation/AddRule.vue +60 -60
  75. package/src/component/shared/automation/AutomationBuilder.vue +26 -26
  76. package/src/component/shared/automation/DynamicComponentList.vue +85 -85
  77. package/src/component/shared/automation/SelectRule.vue +97 -97
  78. package/src/component/shared/automation/components/BillingByRent.vue +97 -97
  79. package/src/component/shared/automation/components/SendEmail.vue +93 -93
  80. package/src/component/shared/file-manager/FileManager.vue +390 -390
  81. package/src/component/shared/filter-builder/FilterBuilder.vue +220 -220
  82. package/src/component/shared/filter-builder/FilterQuery.vue +95 -95
  83. package/src/component/shared/query-builder/ConvertToOdata.js +86 -86
  84. package/src/component/shared/query-builder/DynamicComponent.vue +161 -161
  85. package/src/component/shared/query-builder/Fields.vue +93 -93
  86. package/src/component/shared/query-builder/Rules.vue +68 -68
  87. package/src/component/shared/query-builder/SelectRule.vue +97 -97
  88. package/src/component/shared/query-builder/Tags.vue +59 -59
  89. package/src/component/signature/Payment.vue +160 -160
  90. package/src/component/signature/Warning.vue +75 -75
  91. package/src/component/template/ReportCreateUpdate.vue +110 -110
  92. package/src/component/template/ViewTemplateDocumentView.vue +213 -213
  93. package/src/component/template/ViewTemplateImportFile.vue +347 -347
  94. package/src/component/template/ViewTemplateReportList.vue +240 -240
  95. package/src/component/template/ViewTemplateReportPreview.vue +521 -521
  96. package/src/component/template/ViewTemplateSelectOption.vue +46 -46
  97. package/src/component/template/model/Report.js +5 -5
  98. package/src/component/training/Course.vue +343 -343
  99. package/src/component/training/CourseView.vue +198 -198
  100. package/src/component/value-objects/Address.js +10 -10
  101. package/src/component/value-objects/Address.vue +173 -173
  102. package/src/component/value-objects/Contact.js +6 -6
  103. package/src/component/value-objects/Contact.vue +106 -106
  104. package/src/component/value-objects/Person.js +10 -10
  105. package/src/component/value-objects/Person.vue +130 -130
  106. package/src/store/modules/automation.js +30 -30
  107. package/src/store/modules/generic.js +16 -6
  108. package/src/store/modules/report.js +277 -277
  109. package/src/store/modules/user.js +69 -69
  110. package/src/store/modules/util.js +25 -25
@@ -1,391 +1,391 @@
1
- <template>
2
- <div>
3
- <Alert v-if="!success" type="danger">
4
- Não é permitido enviar arquivos com mais de 5 megabytes.
5
- </Alert>
6
- <div v-if="loading">
7
- <Loading type="line" :center="false" />
8
- </div>
9
- <div>
10
- <b-row>
11
- <b-col sm="3">
12
- <div class="file">
13
- <button class="button small primary" @click="openCamera">
14
- <span><i class="fa-regular fa-camera-web"></i> Câmera</span>
15
- </button>
16
- </div>
17
- <div class="file">
18
- <button class="button small primary">
19
- <span><i class="fa-solid fa-upload"></i> Carregar</span>
20
- </button>
21
- <input type="file" name="myfile" ref="file" @change="confirm" multiple />
22
- </div>
23
- </b-col>
24
- <b-col sm="9" v-if="!showCapture">
25
- <div class="side-by-side" v-for="attachment in attachments">
26
- <div class="text-center box-file">
27
- <div class="div-image"
28
- v-if="attachment.extension == '.png' || attachment.extension == '.jpg'"
29
- @click="openImage(baseUrl + attachment.fileName)">
30
- <img class="img" :src="baseUrl + attachment.fileName">
31
- </div>
32
- <div class="icon-generic" v-else>
33
- <i class="fa-light fa-file"></i>
34
- <div><span class="name">{{ attachment.name }}</span></div>
35
- </div>
36
- <div v-if="idSelected != attachment.id">
37
- <div class="icon side-by-side">
38
- <a :href="baseUrl + attachment.fileName">
39
- <i class="fa-solid fa-download"></i>
40
- </a>
41
- </div>
42
- <div class="icon icon-close side-by-side" @click="confirmRemove(attachment.id)">
43
- <i class="fa-solid fa-circle-xmark"></i>
44
- </div>
45
- </div>
46
- <div v-else>
47
- <div class="icon icon-confirm side-by-side" @click="removeSelected(attachment.id)">
48
- <i class="fa-solid fa-circle-check"></i>
49
- </div>
50
- <div class="icon icon-close side-by-side" @click="cancel()">
51
- <i class="fa-solid fa-xmark"></i>
52
- </div>
53
- </div>
54
- </div>
55
- </div>
56
- <div class="title" v-if="attachments.length == 0">
57
- Nenhum arquivo adicionado!
58
- </div>
59
- </b-col>
60
- </b-row>
61
- </div>
62
- <div v-show="showInModal">
63
- <Modal title="Câmera" :width="600" :height="750" v-if="showModal('webcam')" :onHideModal="stopCamera">
64
- <div class="text-center">
65
- <WebCam ref="webcam" :autoplay="false" width="400" height="100%"></WebCam>
66
- <br>
67
- <div class="side-by-side">
68
- <button class="button primary" @click="captureImage">
69
- <i class="fa-solid fa-camera"></i>
70
- Capturar
71
- </button>
72
- </div>
73
- </div>
74
- </Modal>
75
- <Modal title="Imagem" :width="800" v-show="showModal('image')">
76
- <div class="text-center">
77
- <img class="img-selected" :src="imageSelected">
78
- </div>
79
- </Modal>
80
- </div>
81
- <div v-if="!showInModal && showCapture">
82
- <div class="text-center">
83
- <WebCam ref="webcam" :autoplay="false" width="400" height="100%"></WebCam>
84
- <br>
85
- <div class="side-by-side">
86
- <button class="button small primary" @click="captureImage">
87
- <i class="fa-solid fa-camera"></i>
88
- Capturar
89
- </button>
90
- <button class="button small danger" @click="stopCamera">
91
- <i class="fa-solid fa-circle-xmark"></i>
92
- Fechar
93
- </button>
94
- </div>
95
- </div>
96
- </div>
97
- </div>
98
- </template>
99
- <script>
100
-
101
- import Modal from "@nixweb/nixloc-ui/src/component/forms/Modal";
102
- import Loading from "@nixweb/nixloc-ui/src/component/shared/Loading.vue";
103
- import Confirmation from "@nixweb/nixloc-ui/src/component/shared/Confirmation.vue";
104
- import Alert from "@nixweb/nixloc-ui/src/component/layout/Alert";
105
-
106
- import { WebCam } from 'vue-cam-vision'
107
-
108
- import { mapActions, mapGetters, mapMutations } from "vuex";
109
-
110
- export default {
111
- components: {
112
- WebCam,
113
- Modal,
114
- Loading,
115
- Confirmation,
116
- Alert,
117
- },
118
- props: {
119
- baseUrl: {
120
- type: String,
121
- default: "https://espaco.blob.core.windows.net/nixloc-attachments/",
122
- },
123
- showInModal: {
124
- type: Boolean,
125
- default: true
126
- },
127
- source: String,
128
- genericId: String
129
- },
130
- data() {
131
- return {
132
- urlPost: "/api/v1/adm/attachment/upload",
133
- urlGet: "/api/v1/adm/attachment/get-all",
134
- urlDelete: "/api/v1/adm/attachment/delete",
135
- files: [],
136
- attachments: [],
137
- captures: [],
138
- imgReport: [],
139
- idSelected: "",
140
- imageSelected: "",
141
- loading: false,
142
- success: true,
143
- showCapture: false,
144
- };
145
- },
146
- mounted() {
147
- this.getAll();
148
- },
149
- methods: {
150
- ...mapMutations("generic", ["openModal", "hideModal", "removeLoading"]),
151
- ...mapActions("generic", ["postFileApi", "getApi", "deleteAllApi"]),
152
- confirm() {
153
- this.files = Object.values(this.$refs.file.files);
154
- this.loadFiles();
155
- },
156
- confirmRemove(id) {
157
- this.idSelected = id;
158
- },
159
- cancel() {
160
- this.idSelected = '';
161
- },
162
- removeSelected(id) {
163
- let params = {
164
- url: this.urlDelete,
165
- selected: [id],
166
- };
167
- this.deleteAllApi(params).then(() => {
168
- this.getAll();
169
- });
170
- },
171
- async loadFiles() {
172
- if (this.showInModal) this.hideModal("confirm");
173
- this.loading = true;
174
- let self = this;
175
- for (const file of this.files) {
176
- await self.upload(file);
177
- }
178
-
179
- this.loading = false;
180
- },
181
- async upload(file) {
182
- this.loading = true;
183
- let params = {
184
- url: this.urlPost,
185
- file: file,
186
- name: this.source,
187
- container: this.genericId,
188
- };
189
- const response = await this.postFileApi(params);
190
- this.success = response.content == "erro" ? false : true;
191
- this.loading = false;
192
- let self = this;
193
- setTimeout(function () {
194
- self.success = true;
195
- }, 5000);
196
- this.getAll();
197
- },
198
- getAll() {
199
- this.idSelected = "";
200
- this.loading = true;
201
- let params = { url: this.urlGet, obj: { any: this.source, id: this.genericId } };
202
- this.getApi(params).then((response) => {
203
- this.attachments = response.content.data;
204
- this.loading = false;
205
- });
206
- },
207
- openImage(url) {
208
- this.openModal("image");
209
- this.imageSelected = url;
210
- },
211
- openCamera() {
212
- if (this.showInModal)
213
- this.openModal("webcam");
214
- this.showCapture = true;
215
- this.startCamera();
216
- },
217
- startCamera() {
218
- if (this.$refs.webcam) {
219
- this.$refs.webcam.start();
220
- }
221
- },
222
- stopCamera() {
223
- if (this.$refs.webcam) {
224
- this.$refs.webcam.stop();
225
- this.showCapture = false;
226
- if (this.showInModal) this.hideModal();
227
- }
228
- },
229
- captureImage() {
230
- if (this.$refs.webcam) {
231
- this.$refs.webcam.capture().then((base64String) => {
232
- this.upload(this.convertToFile(base64String));
233
- this.stopCamera();
234
- this.showCapture = false;
235
- });
236
- }
237
- },
238
- convertToFile(base64String) {
239
- const base64Data = base64String.split(',')[1];
240
- const base64ToByte = (char) => {
241
- const charCode = char.charCodeAt(0);
242
-
243
- if (charCode >= 65 && charCode <= 90) {
244
- return charCode - 65; // A-Z
245
- } else if (charCode >= 97 && charCode <= 122) {
246
- return charCode - 71; // a-z
247
- } else if (charCode >= 48 && charCode <= 57) {
248
- return charCode + 4; // 0-9
249
- } else if (charCode === 43) {
250
- return 62; // +
251
- } else if (charCode === 47) {
252
- return 63; // /
253
- }
254
-
255
- return 0; // Caracteres inválidos
256
- };
257
-
258
- const byteArray = new Uint8Array(base64Data.length / 4 * 3);
259
- for (let i = 0, j = 0; i < base64Data.length; i += 4, j += 3) {
260
- const block = (
261
- (base64ToByte(base64Data[i]) << 18) |
262
- (base64ToByte(base64Data[i + 1]) << 12) |
263
- (base64ToByte(base64Data[i + 2]) << 6) |
264
- base64ToByte(base64Data[i + 3])
265
- );
266
-
267
- byteArray[j] = (block >> 16) & 0xff;
268
- byteArray[j + 1] = (block >> 8) & 0xff;
269
- byteArray[j + 2] = block & 0xff;
270
- }
271
-
272
- const blob = new Blob([byteArray], { type: 'image/png' });
273
- return new File([blob], "imagem.png", { type: 'image/png' });
274
-
275
- }
276
- },
277
- computed: {
278
- ...mapGetters("generic", ["showModal"]),
279
- },
280
- };
281
- </script>
282
-
283
- <style scoped>
284
- .file {
285
- position: relative;
286
- overflow: hidden;
287
- display: inline-block;
288
- cursor: pointer;
289
- }
290
-
291
- .button {
292
- padding: 8px 12px;
293
- cursor: pointer;
294
- border: none;
295
- border-radius: 40px !important;
296
- font-size: 14px;
297
- font-weight: 400;
298
- margin-left: 10px;
299
- }
300
-
301
- .primary {
302
- background: #577696;
303
- border-color: #577696;
304
- color: #fff;
305
- }
306
-
307
- .primary:hover {
308
- background: #355472;
309
- }
310
-
311
- .danger {
312
- background: red;
313
- border-color: red;
314
- color: #fff;
315
- }
316
-
317
- .file input[type="file"] {
318
- font-size: 100px;
319
- position: absolute;
320
- left: 0;
321
- top: 0;
322
- opacity: 0;
323
- }
324
-
325
- .div-image {
326
- cursor: pointer;
327
- }
328
-
329
-
330
- .small {
331
- padding: 3px 8px;
332
- font-size: 13px;
333
- }
334
-
335
- .box-file {
336
- width: 120px !important;
337
- height: 110px !important;
338
- border: 1px solid #e8eaed;
339
- background-color: #fff;
340
- border-radius: 13px;
341
- margin: 10px;
342
- font-size: 23px;
343
- font-weight: 400;
344
- align-items: center;
345
- justify-content: center;
346
- }
347
-
348
- .img {
349
- margin: 10px;
350
- width: 45px;
351
- height: 45px;
352
- }
353
-
354
- .img-selected {
355
- width: 80%;
356
- }
357
-
358
- .icon-generic {
359
- font-size: 16px;
360
- }
361
-
362
- .name {
363
- font-size: 12px;
364
- width: 50px;
365
- white-space: nowrap;
366
- text-overflow: ellipsis;
367
- }
368
-
369
- .icon {
370
- font-size: 20px;
371
- cursor: pointer;
372
- padding: 5px;
373
- }
374
-
375
- .icon-close {
376
- color: red;
377
- }
378
-
379
- .icon-confirm {
380
- color: green;
381
- }
382
-
383
- .title-file {
384
- font-size: 18px;
385
- margin-bottom: 20px;
386
- }
387
-
388
- .div-btn {
389
- margin-bottom: 50px;
390
- }
1
+ <template>
2
+ <div>
3
+ <Alert v-if="!success" type="danger">
4
+ Não é permitido enviar arquivos com mais de 5 megabytes.
5
+ </Alert>
6
+ <div v-if="loading">
7
+ <Loading type="line" :center="false" />
8
+ </div>
9
+ <div>
10
+ <b-row>
11
+ <b-col sm="3">
12
+ <div class="file">
13
+ <button class="button small primary" @click="openCamera">
14
+ <span><i class="fa-regular fa-camera-web"></i> Câmera</span>
15
+ </button>
16
+ </div>
17
+ <div class="file">
18
+ <button class="button small primary">
19
+ <span><i class="fa-solid fa-upload"></i> Carregar</span>
20
+ </button>
21
+ <input type="file" name="myfile" ref="file" @change="confirm" multiple />
22
+ </div>
23
+ </b-col>
24
+ <b-col sm="9" v-if="!showCapture">
25
+ <div class="side-by-side" v-for="attachment in attachments">
26
+ <div class="text-center box-file">
27
+ <div class="div-image"
28
+ v-if="attachment.extension == '.png' || attachment.extension == '.jpg'"
29
+ @click="openImage(baseUrl + attachment.fileName)">
30
+ <img class="img" :src="baseUrl + attachment.fileName">
31
+ </div>
32
+ <div class="icon-generic" v-else>
33
+ <i class="fa-light fa-file"></i>
34
+ <div><span class="name">{{ attachment.name }}</span></div>
35
+ </div>
36
+ <div v-if="idSelected != attachment.id">
37
+ <div class="icon side-by-side">
38
+ <a :href="baseUrl + attachment.fileName">
39
+ <i class="fa-solid fa-download"></i>
40
+ </a>
41
+ </div>
42
+ <div class="icon icon-close side-by-side" @click="confirmRemove(attachment.id)">
43
+ <i class="fa-solid fa-circle-xmark"></i>
44
+ </div>
45
+ </div>
46
+ <div v-else>
47
+ <div class="icon icon-confirm side-by-side" @click="removeSelected(attachment.id)">
48
+ <i class="fa-solid fa-circle-check"></i>
49
+ </div>
50
+ <div class="icon icon-close side-by-side" @click="cancel()">
51
+ <i class="fa-solid fa-xmark"></i>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ <div class="title" v-if="attachments.length == 0">
57
+ Nenhum arquivo adicionado!
58
+ </div>
59
+ </b-col>
60
+ </b-row>
61
+ </div>
62
+ <div v-show="showInModal">
63
+ <Modal title="Câmera" :width="600" :height="750" v-if="showModal('webcam')" :onHideModal="stopCamera">
64
+ <div class="text-center">
65
+ <WebCam ref="webcam" :autoplay="false" width="400" height="100%"></WebCam>
66
+ <br>
67
+ <div class="side-by-side">
68
+ <button class="button primary" @click="captureImage">
69
+ <i class="fa-solid fa-camera"></i>
70
+ Capturar
71
+ </button>
72
+ </div>
73
+ </div>
74
+ </Modal>
75
+ <Modal title="Imagem" :width="800" v-show="showModal('image')">
76
+ <div class="text-center">
77
+ <img class="img-selected" :src="imageSelected">
78
+ </div>
79
+ </Modal>
80
+ </div>
81
+ <div v-if="!showInModal && showCapture">
82
+ <div class="text-center">
83
+ <WebCam ref="webcam" :autoplay="false" width="400" height="100%"></WebCam>
84
+ <br>
85
+ <div class="side-by-side">
86
+ <button class="button small primary" @click="captureImage">
87
+ <i class="fa-solid fa-camera"></i>
88
+ Capturar
89
+ </button>
90
+ <button class="button small danger" @click="stopCamera">
91
+ <i class="fa-solid fa-circle-xmark"></i>
92
+ Fechar
93
+ </button>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </template>
99
+ <script>
100
+
101
+ import Modal from "@nixweb/nixloc-ui/src/component/forms/Modal";
102
+ import Loading from "@nixweb/nixloc-ui/src/component/shared/Loading.vue";
103
+ import Confirmation from "@nixweb/nixloc-ui/src/component/shared/Confirmation.vue";
104
+ import Alert from "@nixweb/nixloc-ui/src/component/layout/Alert";
105
+
106
+ import { WebCam } from 'vue-cam-vision'
107
+
108
+ import { mapActions, mapGetters, mapMutations } from "vuex";
109
+
110
+ export default {
111
+ components: {
112
+ WebCam,
113
+ Modal,
114
+ Loading,
115
+ Confirmation,
116
+ Alert,
117
+ },
118
+ props: {
119
+ baseUrl: {
120
+ type: String,
121
+ default: "https://espaco.blob.core.windows.net/nixloc-attachments/",
122
+ },
123
+ showInModal: {
124
+ type: Boolean,
125
+ default: true
126
+ },
127
+ source: String,
128
+ genericId: String
129
+ },
130
+ data() {
131
+ return {
132
+ urlPost: "/api/v1/adm/attachment/upload",
133
+ urlGet: "/api/v1/adm/attachment/get-all",
134
+ urlDelete: "/api/v1/adm/attachment/delete",
135
+ files: [],
136
+ attachments: [],
137
+ captures: [],
138
+ imgReport: [],
139
+ idSelected: "",
140
+ imageSelected: "",
141
+ loading: false,
142
+ success: true,
143
+ showCapture: false,
144
+ };
145
+ },
146
+ mounted() {
147
+ this.getAll();
148
+ },
149
+ methods: {
150
+ ...mapMutations("generic", ["openModal", "hideModal", "removeLoading"]),
151
+ ...mapActions("generic", ["postFileApi", "getApi", "deleteAllApi"]),
152
+ confirm() {
153
+ this.files = Object.values(this.$refs.file.files);
154
+ this.loadFiles();
155
+ },
156
+ confirmRemove(id) {
157
+ this.idSelected = id;
158
+ },
159
+ cancel() {
160
+ this.idSelected = '';
161
+ },
162
+ removeSelected(id) {
163
+ let params = {
164
+ url: this.urlDelete,
165
+ selected: [id],
166
+ };
167
+ this.deleteAllApi(params).then(() => {
168
+ this.getAll();
169
+ });
170
+ },
171
+ async loadFiles() {
172
+ if (this.showInModal) this.hideModal("confirm");
173
+ this.loading = true;
174
+ let self = this;
175
+ for (const file of this.files) {
176
+ await self.upload(file);
177
+ }
178
+
179
+ this.loading = false;
180
+ },
181
+ async upload(file) {
182
+ this.loading = true;
183
+ let params = {
184
+ url: this.urlPost,
185
+ file: file,
186
+ name: this.source,
187
+ container: this.genericId,
188
+ };
189
+ const response = await this.postFileApi(params);
190
+ this.success = response.content == "erro" ? false : true;
191
+ this.loading = false;
192
+ let self = this;
193
+ setTimeout(function () {
194
+ self.success = true;
195
+ }, 5000);
196
+ this.getAll();
197
+ },
198
+ getAll() {
199
+ this.idSelected = "";
200
+ this.loading = true;
201
+ let params = { url: this.urlGet, obj: { any: this.source, id: this.genericId } };
202
+ this.getApi(params).then((response) => {
203
+ this.attachments = response.content.data;
204
+ this.loading = false;
205
+ });
206
+ },
207
+ openImage(url) {
208
+ this.openModal("image");
209
+ this.imageSelected = url;
210
+ },
211
+ openCamera() {
212
+ if (this.showInModal)
213
+ this.openModal("webcam");
214
+ this.showCapture = true;
215
+ this.startCamera();
216
+ },
217
+ startCamera() {
218
+ if (this.$refs.webcam) {
219
+ this.$refs.webcam.start();
220
+ }
221
+ },
222
+ stopCamera() {
223
+ if (this.$refs.webcam) {
224
+ this.$refs.webcam.stop();
225
+ this.showCapture = false;
226
+ if (this.showInModal) this.hideModal();
227
+ }
228
+ },
229
+ captureImage() {
230
+ if (this.$refs.webcam) {
231
+ this.$refs.webcam.capture().then((base64String) => {
232
+ this.upload(this.convertToFile(base64String));
233
+ this.stopCamera();
234
+ this.showCapture = false;
235
+ });
236
+ }
237
+ },
238
+ convertToFile(base64String) {
239
+ const base64Data = base64String.split(',')[1];
240
+ const base64ToByte = (char) => {
241
+ const charCode = char.charCodeAt(0);
242
+
243
+ if (charCode >= 65 && charCode <= 90) {
244
+ return charCode - 65; // A-Z
245
+ } else if (charCode >= 97 && charCode <= 122) {
246
+ return charCode - 71; // a-z
247
+ } else if (charCode >= 48 && charCode <= 57) {
248
+ return charCode + 4; // 0-9
249
+ } else if (charCode === 43) {
250
+ return 62; // +
251
+ } else if (charCode === 47) {
252
+ return 63; // /
253
+ }
254
+
255
+ return 0; // Caracteres inválidos
256
+ };
257
+
258
+ const byteArray = new Uint8Array(base64Data.length / 4 * 3);
259
+ for (let i = 0, j = 0; i < base64Data.length; i += 4, j += 3) {
260
+ const block = (
261
+ (base64ToByte(base64Data[i]) << 18) |
262
+ (base64ToByte(base64Data[i + 1]) << 12) |
263
+ (base64ToByte(base64Data[i + 2]) << 6) |
264
+ base64ToByte(base64Data[i + 3])
265
+ );
266
+
267
+ byteArray[j] = (block >> 16) & 0xff;
268
+ byteArray[j + 1] = (block >> 8) & 0xff;
269
+ byteArray[j + 2] = block & 0xff;
270
+ }
271
+
272
+ const blob = new Blob([byteArray], { type: 'image/png' });
273
+ return new File([blob], "imagem.png", { type: 'image/png' });
274
+
275
+ }
276
+ },
277
+ computed: {
278
+ ...mapGetters("generic", ["showModal"]),
279
+ },
280
+ };
281
+ </script>
282
+
283
+ <style scoped>
284
+ .file {
285
+ position: relative;
286
+ overflow: hidden;
287
+ display: inline-block;
288
+ cursor: pointer;
289
+ }
290
+
291
+ .button {
292
+ padding: 8px 12px;
293
+ cursor: pointer;
294
+ border: none;
295
+ border-radius: 40px !important;
296
+ font-size: 14px;
297
+ font-weight: 400;
298
+ margin-left: 10px;
299
+ }
300
+
301
+ .primary {
302
+ background: #577696;
303
+ border-color: #577696;
304
+ color: #fff;
305
+ }
306
+
307
+ .primary:hover {
308
+ background: #355472;
309
+ }
310
+
311
+ .danger {
312
+ background: red;
313
+ border-color: red;
314
+ color: #fff;
315
+ }
316
+
317
+ .file input[type="file"] {
318
+ font-size: 100px;
319
+ position: absolute;
320
+ left: 0;
321
+ top: 0;
322
+ opacity: 0;
323
+ }
324
+
325
+ .div-image {
326
+ cursor: pointer;
327
+ }
328
+
329
+
330
+ .small {
331
+ padding: 3px 8px;
332
+ font-size: 13px;
333
+ }
334
+
335
+ .box-file {
336
+ width: 120px !important;
337
+ height: 110px !important;
338
+ border: 1px solid #e8eaed;
339
+ background-color: #fff;
340
+ border-radius: 13px;
341
+ margin: 10px;
342
+ font-size: 23px;
343
+ font-weight: 400;
344
+ align-items: center;
345
+ justify-content: center;
346
+ }
347
+
348
+ .img {
349
+ margin: 10px;
350
+ width: 45px;
351
+ height: 45px;
352
+ }
353
+
354
+ .img-selected {
355
+ width: 80%;
356
+ }
357
+
358
+ .icon-generic {
359
+ font-size: 16px;
360
+ }
361
+
362
+ .name {
363
+ font-size: 12px;
364
+ width: 50px;
365
+ white-space: nowrap;
366
+ text-overflow: ellipsis;
367
+ }
368
+
369
+ .icon {
370
+ font-size: 20px;
371
+ cursor: pointer;
372
+ padding: 5px;
373
+ }
374
+
375
+ .icon-close {
376
+ color: red;
377
+ }
378
+
379
+ .icon-confirm {
380
+ color: green;
381
+ }
382
+
383
+ .title-file {
384
+ font-size: 18px;
385
+ margin-bottom: 20px;
386
+ }
387
+
388
+ .div-btn {
389
+ margin-bottom: 50px;
390
+ }
391
391
  </style>