vue-intergrall-plugins 0.0.263 → 0.0.265

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.
@@ -19,7 +19,18 @@
19
19
  </div>
20
20
  <template v-if="selectedTemplate">
21
21
  <div class="tg-component" v-if="selectedTemplate.components">
22
- <TemplateSingle :template="selectedTemplate" @set-vars="setFinalMessage" :hasButton="hasButton" :iconButton="iconButton" @click-trigger="$emit('click-trigger')" :identifier="identifier" :allVariables="allVariables" :dictionary="dictionary" />
22
+ <TemplateSingle
23
+ :key="codTemplate"
24
+ :template="selectedTemplate"
25
+ @set-vars="setFinalMessage"
26
+ @set-file-var="setFileVar"
27
+ :hasButton="hasButton"
28
+ :iconButton="iconButton"
29
+ @click-trigger="$emit('click-trigger')"
30
+ :identifier="identifier"
31
+ :allVariables="allVariables"
32
+ :dictionary="dictionary"
33
+ />
23
34
  </div>
24
35
  <div class="tg-component" v-else>
25
36
  <TemplateMessage @final-message="setMessage" :hasButton="hasButton" :iconButton="iconButton" @click-trigger="$emit('click-trigger', true)" :dictionary="dictionary" />
@@ -84,7 +95,8 @@
84
95
  return {
85
96
  templateOptions: [],
86
97
  codTemplate: {},
87
- selectedTemplate: null
98
+ selectedTemplate: null,
99
+ // hasFile: false
88
100
  }
89
101
  },
90
102
  mounted() {
@@ -144,6 +156,7 @@
144
156
  }else{
145
157
  this.selectedTemplate = null
146
158
  }
159
+ // if(this.hasFile) this.setFileVar(false)
147
160
  this.adjustOnSelect()
148
161
  },
149
162
  focusSelect() {
@@ -215,6 +228,10 @@
215
228
 
216
229
  this.$emit("template-data", this.selectedTemplate)
217
230
  },
231
+ setFileVar(file) {
232
+ // this.hasFile = file ? true : false
233
+ this.$emit("set-file-var", file)
234
+ },
218
235
  setMessage(message) {
219
236
  this.$emit("static-message", message)
220
237
  }
@@ -249,6 +266,50 @@ h1, h2, h3, h4, p { margin: 0; padding: 0 }
249
266
  margin-right: 5px;
250
267
  }
251
268
 
269
+ .ts-image-type {
270
+ display: flex;
271
+ align-items: center;
272
+ }
273
+
274
+ .ts-image-type img {
275
+ cursor: pointer;
276
+ }
277
+
278
+ .ts-image-type svg {
279
+ font-size: 25px;
280
+ cursor: pointer;
281
+ }
282
+
283
+ .ts-image-type .select-image {
284
+ color: #838383;
285
+ }
286
+
287
+ .color-red {
288
+ color: #E74C3C;
289
+ }
290
+
291
+ .color-blue {
292
+ color: #007BFF;
293
+ }
294
+
295
+ .color-black {
296
+ color: #333
297
+ }
298
+
299
+ .ts-button {
300
+ background-color: #FFF;
301
+ border-radius: 10px;
302
+ display: flex;
303
+ justify-content: center;
304
+ align-items: center;
305
+ padding: 3px 15px;
306
+ transition: background-color 150ms ease-in-out;
307
+ }
308
+
309
+ .ts-button:hover {
310
+ background-color: rgb(253, 253, 253);
311
+ }
312
+
252
313
  .tg-select {
253
314
  flex: 1;
254
315
  height: 34px;
@@ -270,9 +331,6 @@ h1, h2, h3, h4, p { margin: 0; padding: 0 }
270
331
  text-overflow: ellipsis;
271
332
  flex: 1;
272
333
  }
273
- .tg-select .vs__selected-options > input {
274
- flex-grow: 0;
275
- }
276
334
 
277
335
  .vs__dropdown-option.vs__dropdown-option--selected {
278
336
  background-color: rgb(26, 95, 173)!important;
@@ -312,10 +370,22 @@ h1, h2, h3, h4, p { margin: 0; padding: 0 }
312
370
  --input-border-default: #007BFF;
313
371
  --input-border-error: #E74C3C;
314
372
  --placeholder-color: #BBB;
373
+ --border-radius: 5px;
315
374
 
316
375
  flex: 2;
317
376
  font-size: .7rem;
318
377
  padding: 10px 0;
378
+ display: flex;
379
+ flex-direction: column;
380
+ }
381
+ .order-1 {
382
+ order: 1
383
+ }
384
+ .custom-box-shadow-bottom {
385
+ box-shadow: 0px 3px 4px -3px rgba(0, 0, 0, .3);
386
+ }
387
+ .custom-border-gray {
388
+ border: 1px solid var(--border-color)!important;
319
389
  }
320
390
  .ts-content header, .ts-content section, .ts-content footer {
321
391
  padding: 3px 5px;
@@ -326,8 +396,8 @@ h1, h2, h3, h4, p { margin: 0; padding: 0 }
326
396
  border-left: 1px solid var(--border-color);
327
397
  }
328
398
  .ts-content header {
329
- border-top-left-radius: 2.5px;
330
- border-top-right-radius: 2.5px;
399
+ border-top-left-radius: var(--border-radius);
400
+ border-top-right-radius: var(--border-radius);
331
401
  border-top: 1px solid var(--border-color);
332
402
  }
333
403
  .ts-content header { font-weight: 550 }
@@ -335,15 +405,15 @@ h1, h2, h3, h4, p { margin: 0; padding: 0 }
335
405
  line-height: 25px;
336
406
  }
337
407
  .ts-content section.margin-bottom {
338
- border-bottom-left-radius: 2.5px;
339
- border-bottom-right-radius: 2.5px;
408
+ border-bottom-left-radius: var(--border-radius);
409
+ border-bottom-right-radius: var(--border-radius);
340
410
  border-bottom: 1px solid var(--border-color);
341
411
  }
342
- .ts-content footer {
412
+ .ts-content footer, .custom-footer-style {
343
413
  border: 1px solid var(--border-color);
344
414
  border-top: unset;
345
- border-bottom-left-radius: 2.5px;
346
- border-bottom-right-radius: 2.5px;
415
+ border-bottom-left-radius: var(--border-radius);
416
+ border-bottom-right-radius: var(--border-radius);
347
417
  }
348
418
  .ts-content input {
349
419
  border: 1px solid transparent;
@@ -468,7 +538,7 @@ h1, h2, h3, h4, p { margin: 0; padding: 0 }
468
538
 
469
539
  .tm-container {
470
540
  border: 1px solid var(--border-color);
471
- border-radius: 2.5px;
541
+ border-radius: 5px;
472
542
  display: flex;
473
543
  }
474
544
 
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="ts-container">
3
3
  <div class="ts-content">
4
- <section :class="{'tm-container' : hasButton}">
4
+ <section :class="{'tm-container custom-box-shadow-bottom' : hasButton}">
5
5
  <TextFooter
6
6
  :textId="'var_1'"
7
7
  width="full"
@@ -1,9 +1,14 @@
1
1
  <template>
2
2
  <div class="ts-container">
3
3
  <div class="ts-content">
4
- <div v-for="(component, cIndex) in template.components" :key="cIndex">
4
+ <div
5
+ v-for="(component, cIndex) in template.components"
6
+ :key="cIndex"
7
+ :class="`${component.type == 'footer' ? 'order-1 custom-box-shadow-bottom' : ''}${template.components.length == 1 ? 'custom-box-shadow-bottom' : ''}`"
8
+ >
5
9
  <header
6
10
  v-if="component.type === 'header'"
11
+ :class="`${template.components.length == 1 ? 'border-radius-5 custom-border-gray' : ''}`"
7
12
  id="template_header"
8
13
  >
9
14
  <div v-for="(param, pIndex) in component.parameters" :key="pIndex">
@@ -19,11 +24,40 @@
19
24
  ></div>
20
25
  <p v-else v-html="param.text"></p>
21
26
  </template>
27
+ <div v-else-if="param.type == 'image'" class="ts-image-type">
28
+ <input class="d-none" type="file" :ref="`ts-input-header-${pIndex}`" :accept="acceptedExtensions" @change="fileUpload($event)" />
29
+ <template v-if="headerFiles[0]">
30
+ <img
31
+ v-if="headerFiles[0].image_preview"
32
+ :src="headerFiles[0].image_preview"
33
+ alt="Previa da imagem"
34
+ @click="triggerInputFile(`header-${pIndex}`)"
35
+ v-tippy="{placement: 'right'}"
36
+ :content="headerFiles[0].name"
37
+ />
38
+ <fa-icon
39
+ v-else
40
+ :icon="['fas', headerFiles[0].current_icon]"
41
+ :class="`color-${headerFiles[0].current_color}`"
42
+ @click="triggerInputFile(`header-${pIndex}`)"
43
+ v-tippy="{placement: 'right'}"
44
+ :content="headerFiles[0].name"
45
+ />
46
+ </template>
47
+ <fa-icon
48
+ v-else
49
+ class="select-image"
50
+ :icon="['fas', 'image']"
51
+ @click="triggerInputFile(`header-${pIndex}`)"
52
+ v-tippy="{placement: 'right'}"
53
+ :content="`Selecionar anexo`"
54
+ />
55
+ </div>
22
56
  </div>
23
57
  </header>
24
58
  <section
25
59
  v-if="component.type === 'body'"
26
- :class="{'margin-bottom' : template.components.length === 2 }"
60
+ :class="`${template.components.length == 1 ? 'border-radius-5 custom-border-gray' : ''} ${!hasButtonOrFooterComponent ? 'custom-footer-style custom-box-shadow-bottom custom-border-gray' : ''}`"
27
61
  id="template_body"
28
62
  >
29
63
  <div v-for="(param, pIndex) in component.parameters" :key="pIndex">
@@ -41,8 +75,18 @@
41
75
  </template>
42
76
  </div>
43
77
  </section>
78
+ <section
79
+ v-if="component.type == 'button'"
80
+ :class="`${template.components.length == 1 ? 'border-radius-5 custom-border-gray' : ''} ${!hasFooterComponent ? 'custom-footer-style custom-box-shadow-bottom' : ''}`"
81
+ id="template_buttons"
82
+ >
83
+ <div v-for="(param, pIndex) in component.parameters" :key="pIndex" class="ts-button">
84
+ <p v-if="param.text" v-html="param.text"></p>
85
+ </div>
86
+ </section>
44
87
  <footer
45
88
  v-if="component.type == 'footer'"
89
+ :class="`${template.components.length == 1 ? 'border-radius-5 custom-border-gray' : ''}`"
46
90
  id="template_footer"
47
91
  >
48
92
  <div v-for="(param, pIndex) in component.parameters" :key="pIndex">
@@ -71,7 +115,9 @@ export default {
71
115
  regexVars: /{{var_\d}}/g,
72
116
  lastVar: 0,
73
117
  htmlInputString: `<input type='text' class='input-var input-var-${this.identifier}' autocomplete='off' />`,
74
- varListValues: ""
118
+ varListValues: "",
119
+ acceptedExtensions: "audio/aac, audio/mp4, audio/mpeg, audio/amr, audio/ogg, text/plain, application/pdf, application/vnd.ms-powerpoint, application/msword, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreasheetml.sheet, image/jpeg, image/png, video/mp4, video/3gp, image/webp",
120
+ headerFiles: [],
75
121
  };
76
122
  },
77
123
  props: {
@@ -103,12 +149,29 @@ export default {
103
149
  required: true
104
150
  }
105
151
  },
152
+ computed: {
153
+ hasFooterComponent() {
154
+ if(!this.template.components || !this.template.components.length) return false
155
+ const types = []
156
+ this.template.components.forEach(({ type }) => types.push(type))
157
+ if(types.includes('footer')) return true
158
+ return false
159
+ },
160
+ hasButtonOrFooterComponent() {
161
+ if(!this.template.components || !this.template.components.length) return false
162
+ const types = []
163
+ this.template.components.forEach(({ type }) => types.push(type))
164
+ if(types.includes('button')) return true
165
+ return this.hasFooterComponent
166
+ },
167
+ },
106
168
  created() {
107
169
  this.$root.$refs[`template-single-${this.identifier}`] = this
108
170
  },
109
171
  mounted() {
110
172
  if(this.allVariables) this.getListOpts()
111
173
  this.setInputs();
174
+ this.setImageVar(false)
112
175
  },
113
176
  updated() {
114
177
  this.lastVar = 0;
@@ -134,6 +197,7 @@ export default {
134
197
  input.blur();
135
198
  this.setVar({ target: input }, input.id.replace(/[{}]+/g, ''));
136
199
  })
200
+ this.setImageVar(false)
137
201
  },
138
202
  getListOpts() {
139
203
  this.varListValues =
@@ -142,26 +206,110 @@ export default {
142
206
  ${this.allVariables ? '<li> telefone </li>' : ''}
143
207
  </ul>`
144
208
  },
209
+ fileUpload(event) {
210
+ try {
211
+ const allFiles = event.target.files ? event.target.files : event.dataTransfer.files ? event.dataTransfer.files : false
212
+ if(!allFiles || !allFiles.length) return this.setImageVar(false)
213
+ if(allFiles.length > 1) {
214
+ this.$toasted.global.defaultInfo({ msg: `Limite de 1 arquivo por vez` })
215
+ return this.setImageVar(false)
216
+ }
217
+ const file = allFiles[0]
218
+ const { type, name } = file
219
+ const validTypes = ['audio/aac', 'audio/mp4', 'audio/mpeg', 'audio/amr', 'audio/ogg', 'text/plain', 'application/pdf', 'application/vnd.ms-powerpoint', 'application/msword', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.spreasheetml.sheet', 'image/jpeg', 'image/png', 'video/mp4', 'video/3gp', 'image/webp']
220
+ if(!validTypes.includes(type)) {
221
+ this.$toasted.global.defaultInfo({ msg: `(${type}) ${this.dictionary.msg_arquivo_invalido}` })
222
+ return this.setImageVar(false)
223
+ }
224
+ const returnArrType = str => {
225
+ const arr = []
226
+ validTypes.forEach(currentType => {
227
+ if(currentType.indexOf(str) > -1) arr.push(currentType)
228
+ })
229
+ return arr
230
+ }
231
+
232
+ const imageTypes = returnArrType('image/')
233
+ const docTypes = returnArrType('application/')
234
+ const audioTypes = returnArrType('audio/')
235
+ const videoTypes = returnArrType('video/')
236
+ const isPdf = type.indexOf('application/pdf') > -1
237
+
238
+ let sizeInBytes = 0
239
+ Array.from(allFiles).forEach(file => sizeInBytes += file.size)
240
+ const sizeInMb = parseFloat((sizeInBytes / (1024*1024)).toFixed(2))
241
+ if(sizeInMb == 0 && sizeInBytes == 0) {
242
+ this.$toasted.global.defaultInfo({ msg: this.dictionary.msg_arquivo_invalido })
243
+ return this.setImageVar(false)
244
+ }
245
+ const max = imageTypes.includes(type) ? 5 : 15
246
+ if(sizeInMb >= max) {
247
+ this.$toasted.global.defaultInfo({ msg: `Limite de ${max} MB por arquivo` })
248
+ return this.setImageVar(false)
249
+ }
250
+
251
+ const fileReader = new FileReader()
252
+ let current_icon = 'file-alt', current_color = 'blue', setValues = true
253
+ if(imageTypes.includes(type)) {
254
+ setValues = false
255
+ fileReader.readAsDataURL(file)
256
+ fileReader.onload = () => {
257
+ const image_preview = fileReader.result
258
+ this.headerFiles[0] = { file, image_preview, current_icon, current_color, name }
259
+ this.$forceUpdate()
260
+ this.setImageVar(file)
261
+ }
262
+ }else if(docTypes.includes(type) && isPdf) {
263
+ current_icon = 'file-pdf'
264
+ current_color = 'red'
265
+ }else if(audioTypes.includes(type)) {
266
+ current_icon = 'microphone'
267
+ current_color = 'black'
268
+ }else if(videoTypes.includes(type)) {
269
+ current_icon = 'video',
270
+ current_color = 'black'
271
+ }
272
+
273
+ if(setValues) {
274
+ this.headerFiles[0] = { file, current_icon, current_color, name }
275
+ this.$forceUpdate()
276
+ this.setImageVar(file)
277
+ }
278
+ }catch(error) {
279
+ console.error("Erro file upload: ", error)
280
+ }
281
+ },
282
+ triggerInputFile(origin) {
283
+ if(this.$refs[`ts-input-${origin}`]) {
284
+ const elem = this.$refs[`ts-input-${origin}`][0] ? this.$refs[`ts-input-${origin}`][0] : this.$refs[`ts-input-${origin}`]
285
+ elem && elem.click()
286
+ }
287
+ },
145
288
  setInputs() {
146
289
  let qtdInputs = 0
147
290
  const header = document.querySelector("#template_header");
148
291
  const body = document.querySelector("#template_body");
149
292
  const footer = document.querySelector("#template_footer");
293
+
294
+ let hasText = false
150
295
  if (header !== null) {
151
296
  header.querySelectorAll(`.input-var-${this.identifier}`).forEach((input) => { this.setEvent(input) })
152
297
  qtdInputs += header.querySelectorAll(`.input-var-${this.identifier}`).length
298
+ if(qtdInputs > 0 && header.innerText) hasText = true
153
299
  }
154
300
  if (this.lastVar === 0) this.lastVar += 1
155
301
  if (body !== null) {
156
302
  body.querySelectorAll(`.input-var-${this.identifier}`).forEach((input) => { this.setEvent(input) });
157
303
  qtdInputs += body.querySelectorAll(`.input-var-${this.identifier}`).length
304
+ if(qtdInputs > 0 && body.innerText) hasText = true
158
305
  }
159
306
  if (footer !== null) {
160
307
  footer.querySelectorAll(`.input-var-${this.identifier}`).forEach((input) => { this.setEvent(input) });
161
308
  qtdInputs += footer.querySelectorAll(`.input-var-${this.identifier}`).length
309
+ if(qtdInputs > 0 && footer.innerText) hasText = true
162
310
  }
163
311
 
164
- if(qtdInputs === 1) {
312
+ if(qtdInputs === 1 && !hasText) {
165
313
  document.querySelector(`.input-var-${this.identifier}`).parentElement.style.width = "100%"
166
314
  document.querySelector(`.input-var-${this.identifier}`).style.width = "100%"
167
315
  }else if(qtdInputs === 0) {
@@ -263,6 +411,17 @@ export default {
263
411
 
264
412
  return isValueValid
265
413
  },
414
+ setImageVar(file) {
415
+ this.$emit("set-file-var", file)
416
+ if(!file) {
417
+ this.headerFiles = []
418
+ return this.$forceUpdate()
419
+ }else {
420
+ if(this.lastVar == 0) return this.$emit("set-vars", this.template)
421
+ if(Object.keys(this.varValues).length) return this.$emit("set-vars", this.varValues)
422
+ this.handleInitialFocus()
423
+ }
424
+ },
266
425
  setVar(event, key, notificar) {
267
426
  if (event && event.target) {
268
427
  key = event.target.id.replace(/[{}]+/g, '')