@bildvitta/quasar-ui-asteroid 3.17.0-beta.8 → 3.17.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 (59) hide show
  1. package/package.json +3 -2
  2. package/src/assets/sounds/nave-notification.mp3 +0 -0
  3. package/src/components/app-menu/QasAppMenu.vue +73 -15
  4. package/src/components/app-menu/QasAppMenu.yml +5 -5
  5. package/src/components/app-user/QasAppUser.vue +49 -40
  6. package/src/components/avatar/QasAvatar.vue +7 -8
  7. package/src/components/badge/QasBadge.vue +3 -29
  8. package/src/components/board-generator/QasBoardGenerator.vue +442 -40
  9. package/src/components/board-generator/QasBoardGenerator.yml +107 -12
  10. package/src/components/card/QasCard.vue +13 -4
  11. package/src/components/chart-view/QasChartView.vue +56 -3
  12. package/src/components/chart-view/QasChartView.yml +6 -0
  13. package/src/components/checkbox/QasCheckbox.vue +67 -11
  14. package/src/components/checkbox/QasCheckbox.yml +18 -0
  15. package/src/components/copy/QasCopy.vue +12 -2
  16. package/src/components/copy/QasCopy.yml +8 -0
  17. package/src/components/expansion-item/QasExpansionItem.vue +108 -76
  18. package/src/components/expansion-item/QasExpansionItem.yml +38 -10
  19. package/src/components/field/QasField.vue +1 -1
  20. package/src/components/form-generator/QasFormGenerator.vue +23 -10
  21. package/src/components/form-generator/QasFormGenerator.yml +2 -2
  22. package/src/components/grabbable/QasGrabbable.vue +14 -6
  23. package/src/components/grabbable/QasGrabbable.yml +4 -0
  24. package/src/components/grid-generator/QasGridGenerator.vue +3 -3
  25. package/src/components/grid-generator/QasGridGenerator.yml +2 -2
  26. package/src/components/grid-item/QasGridItem.vue +1 -1
  27. package/src/components/header/QasHeader.vue +11 -9
  28. package/src/components/infinite-scroll/QasInfiniteScroll.vue +16 -17
  29. package/src/components/infinite-scroll/QasInfiniteScroll.yml +7 -0
  30. package/src/components/list-view/QasListView.vue +16 -2
  31. package/src/components/list-view/QasListView.yml +9 -0
  32. package/src/components/radio/QasRadio.vue +24 -5
  33. package/src/components/radio/QasRadio.yml +6 -0
  34. package/src/components/select/QasSelect.vue +54 -7
  35. package/src/components/select/QasSelect.yml +6 -1
  36. package/src/components/select-filter/QasSelectFilter.vue +65 -0
  37. package/src/components/select-filter/QasSelectFilter.yml +36 -0
  38. package/src/components/stepper/QasStepper.vue +50 -3
  39. package/src/components/stepper-form-view/QasStepperFormView.vue +6 -4
  40. package/src/components/stepper-form-view/QasStepperFormView.yml +1 -1
  41. package/src/components/table-generator/QasTableGenerator.vue +3 -0
  42. package/src/components/text-truncate/QasTextTruncate.vue +77 -14
  43. package/src/components/text-truncate/QasTextTruncate.yml +14 -3
  44. package/src/components/uploader/QasUploader.vue +70 -24
  45. package/src/components/uploader/QasUploader.yml +15 -1
  46. package/src/components/welcome/QasWelcome.vue +8 -0
  47. package/src/components/welcome/QasWelcome.yml +3 -0
  48. package/src/composables/index.js +3 -1
  49. package/src/composables/private/index.js +1 -0
  50. package/src/composables/private/use-auth-user.js +20 -0
  51. package/src/composables/private/use-generator.js +20 -5
  52. package/src/composables/use-default-filters.js +106 -0
  53. package/src/composables/use-notifications.js +14 -0
  54. package/src/composables/use-query-cache.js +1 -1
  55. package/src/css/components/field.scss +13 -6
  56. package/src/helpers/set-scroll-on-grab.js +9 -1
  57. package/src/shared/badge-config.js +29 -0
  58. package/src/vue-plugin.js +3 -0
  59. package/src/components/app-menu/private/PvAppMenuHelpChat.vue +0 -222
@@ -1,41 +1,47 @@
1
1
  <template>
2
- <qas-grabbable class="qas-board-generator" use-scroll-bar>
2
+ <qas-grabbable class="qas-board-generator" v-bind="grabbableProps">
3
3
  <div class="no-wrap q-col-gutter-sm q-px-xl row">
4
4
  <div v-for="(header, index) in headers" :key="index" class="q-mr-sm">
5
- <qas-box class="q-mb-md">
6
- <slot :fields="getFieldsByHeader(header)" :header="header" name="header-column" />
5
+ <qas-box class="q-mb-md" v-bind="headerBoxProps">
6
+ <slot :fields="getFieldsByHeader(header)" :header="header" :index="index" name="header-column" />
7
7
  </qas-box>
8
8
 
9
- <div ref="columnContainer" class="qas-board-generator__column secondary-scroll" :style="containerStyle">
10
- <slot v-for="item in getItemsByHeader(header)" :fields="getFieldsByHeader(header)" :item="item" name="column-item" />
9
+ <div ref="columnContainer" class="qas-board-generator__column secondary-scroll" :data-header-key="getKeyByHeader(header)" :style="containerStyle">
10
+ <div v-for="item in getItemsByHeader(header)" :id="item[props.itemIdKey]" :key="item[props.itemIdKey]" class="qas-board-generator__item">
11
+ <slot :column-index="index" :fields="getFieldsByHeader(header)" :item="item" name="column-item" />
12
+ </div>
11
13
 
12
- <div class="full-width justify-center q-mb-md q-mt-sm row">
14
+ <div class="full-width justify-center row">
13
15
  <qas-btn v-if="hasSeeMore(header)" icon="sym_r_add" label="Ver mais" :use-label-on-small-screen="false" variant="tertiary" @click="fetchColumn(header)" />
14
16
 
15
- <q-spinner v-if="columnsLoading[getKeyByHeader(header)]" color="grey-4" size="3em" />
16
-
17
- <qas-empty-result-text v-if="hasEmptyResultText(header)" />
17
+ <q-spinner v-if="columnsLoading[getKeyByHeader(header)]" class="q-mb-md" color="grey-4" size="3em" />
18
18
  </div>
19
+
20
+ <qas-empty-result-text v-if="hasEmptyResultText(header)" />
19
21
  </div>
20
22
  </div>
21
23
  </div>
24
+
25
+ <qas-dialog v-model="showConfirmDialog" v-bind="defaultConfirmDialogProps" />
22
26
  </qas-grabbable>
23
27
  </template>
24
28
 
25
29
  <script setup>
26
- import { ref, watch, computed, onMounted, markRaw, inject } from 'vue'
27
- import promiseHandler from '../../helpers/promise-handler'
30
+ import QasDialog from '../dialog/QasDialog.vue'
28
31
 
29
- defineOptions({ name: 'QasBoardGenerator' })
32
+ import { ref, watch, computed, onUnmounted, markRaw, inject, onMounted } from 'vue'
33
+ import promiseHandler from '../../helpers/promise-handler'
30
34
 
31
- const columnContainer = ref(null)
32
- const columnsPagination = ref({})
33
- const columnsLoading = ref({})
34
- const columnsFieldsModel = ref({})
35
+ import Sortable from 'sortablejs'
35
36
 
36
- const axios = inject('axios')
37
+ defineOptions({ name: 'QasBoardGenerator' })
37
38
 
38
39
  const props = defineProps({
40
+ beforeUpdatePosition: {
41
+ type: Function,
42
+ default: undefined
43
+ },
44
+
39
45
  headers: {
40
46
  type: Array,
41
47
  default: () => []
@@ -46,6 +52,11 @@ const props = defineProps({
46
52
  default: () => ({})
47
53
  },
48
54
 
55
+ headerBoxProps: {
56
+ type: Object,
57
+ default: () => ({})
58
+ },
59
+
49
60
  columnIdKey: {
50
61
  type: String,
51
62
  required: true
@@ -61,11 +72,21 @@ const props = defineProps({
61
72
  required: true
62
73
  },
63
74
 
75
+ confirmDialogProps: {
76
+ type: Object,
77
+ default: () => ({})
78
+ },
79
+
64
80
  height: {
65
81
  type: String,
66
82
  default: ''
67
83
  },
68
84
 
85
+ itemIdKey: {
86
+ type: String,
87
+ default: ''
88
+ },
89
+
69
90
  limitPerColumn: {
70
91
  type: Number,
71
92
  default: 12
@@ -76,11 +97,34 @@ const props = defineProps({
76
97
  default: '300px'
77
98
  },
78
99
 
100
+ sortableConfig: {
101
+ type: Object,
102
+ default: () => ({})
103
+ },
104
+
79
105
  useMarkRaw: {
80
106
  type: Boolean,
81
107
  default: true
82
108
  },
83
109
 
110
+ useDragAndDropX: {
111
+ type: Boolean
112
+ },
113
+
114
+ useDragAndDropY: {
115
+ type: Boolean
116
+ },
117
+
118
+ updatePositionUrl: {
119
+ type: String,
120
+ default: ''
121
+ },
122
+
123
+ updatePositionParams: {
124
+ type: Object,
125
+ default: () => ({})
126
+ },
127
+
84
128
  lazyLoadingFieldsKeys: {
85
129
  type: Array,
86
130
  default: () => []
@@ -92,28 +136,94 @@ const emit = defineEmits([
92
136
  'fetch-column-success',
93
137
  'fetch-column-error',
94
138
  'fetch-columns-success',
95
- 'fetch-columns-error'
139
+ 'fetch-columns-error',
140
+ 'update-success',
141
+ 'update-error'
96
142
  ])
97
143
 
144
+ defineExpose({ fetchColumns, fetchColumn, reset, cancelDrop })
145
+
146
+ // Inject
147
+ const axios = inject('axios')
148
+
149
+ const isFetchSuccessHeader = inject('isFetchListSucceeded', false)
150
+
151
+ const isInsideListView = inject('isListView', false)
152
+
153
+ // Refs
154
+ const columnContainer = ref(null)
155
+ const columnsPagination = ref({})
156
+ const columnsLoading = ref({})
157
+ const columnsFieldsModel = ref({})
158
+ const showConfirmDialog = ref(false)
159
+ const isDragging = ref(false)
160
+ const isLoadingUpdatePosition = ref(false)
161
+
162
+ /**
163
+ * Instâncias do sortable, que são utilizadas para realizar o destroy ao sair da página
164
+ */
165
+ const sortableInstances = ref([])
166
+
167
+ /**
168
+ * Callbacks que recebe o event de movimentação
169
+ */
170
+ const onCancelDrop = ref(() => {})
171
+ const onConfirmDrop = ref(() => {})
172
+
173
+ /**
174
+ * Variável auxiliar que controla quando estou atualizando o header em caso de drag and drop
175
+ */
176
+ const isUpdatingPosition = ref(false)
177
+
178
+ // Consts
179
+ const hasDragAndDrop = !!props.useDragAndDropX || !!props.useDragAndDropY
180
+
181
+ const grabbableProps = {
182
+ useScrollBar: true,
183
+
184
+ ...(hasDragAndDrop && {
185
+ cancelMouseDownTarget: 'qas-board-generator__item'
186
+ })
187
+ }
188
+
189
+ // Watchers
190
+ watch(
191
+ () => isFetchSuccessHeader.value,
192
+ value => {
193
+ /**
194
+ * isFetchSuccessHeader é uma variavel que pego do listView por inject/provide, no qual caso eu faça request do header e dê sucesso, eu chamo as demais funções.
195
+ * Valido se não houve sucesso na requisição do header ou se não é uma atualização de posição, para assim não bater novamente nas colunas apenas no header.
196
+ */
197
+ if (!value || isUpdatingPosition.value) return
198
+
199
+ fetchColumnsValues()
200
+ }
201
+ )
202
+
98
203
  watch(
99
204
  () => props.headers,
100
205
  () => {
101
- reset()
102
- setColumnHeightContainer()
103
- setColumnsPagination()
104
- fetchColumns()
206
+ if (isUpdatingPosition.value) return
207
+
208
+ isUpdatingPosition.value = false
105
209
  }
106
210
  )
107
211
 
108
212
  watch(columnContainer, setColumnHeightContainer)
109
213
 
214
+ // Lifecycles
110
215
  onMounted(() => {
111
- setColumnsPagination()
112
- fetchColumns()
216
+ /**
217
+ * Caso eu use o listView (valor pego por provide), a request é feito pelo watch quando se ocorre o sucesso do `fetchList`
218
+ */
219
+ if (isInsideListView) return
220
+
221
+ fetchColumnsValues()
113
222
  })
114
223
 
115
- defineExpose({ fetchColumns, fetchColumn, reset })
224
+ onUnmounted(destroySortable)
116
225
 
226
+ // Computeds
117
227
  const columnsResultsModel = computed({
118
228
  get () {
119
229
  return props.results
@@ -124,10 +234,32 @@ const columnsResultsModel = computed({
124
234
  }
125
235
  })
126
236
 
127
- const hasColumnsLength = computed(() => Object.keys(columnsResultsModel.value).length)
237
+ const hasColumnsLength = computed(() => !!Object.keys(columnsResultsModel.value).length)
128
238
 
129
239
  const containerStyle = computed(() => `width: ${props.columnWidth};`)
130
240
 
241
+ const hasConfirmDialogProps = computed(() => !!Object.keys(props.confirmDialogProps).length)
242
+
243
+ const defaultConfirmDialogProps = computed(() => {
244
+ const defaultProps = {
245
+ ok: {
246
+ label: 'Confirmar',
247
+ onClick: onConfirmDrop.value,
248
+ loading: isLoadingUpdatePosition.value
249
+ },
250
+
251
+ cancel: {
252
+ onClick: onCancelDrop.value
253
+ }
254
+ }
255
+
256
+ return {
257
+ ...props.confirmDialogProps,
258
+ ...defaultProps
259
+ }
260
+ })
261
+
262
+ // functions
131
263
  /*
132
264
  * Setar o tamanho do container do board, onde deverá ser a altura passada via prop, ou o default será ocupar o maximo
133
265
  * de espaço que ele conseguir considerando a altura do container em relação ao topo.
@@ -157,6 +289,8 @@ async function fetchColumns () {
157
289
  }
158
290
 
159
291
  emit('fetch-columns-success')
292
+
293
+ if (hasDragAndDrop) handleElementsList()
160
294
  }
161
295
 
162
296
  /*
@@ -189,22 +323,25 @@ async function fetchColumn (header) {
189
323
  throw error
190
324
  }
191
325
 
192
- /*
193
- * exemplo de como columnsResultsModel irá ficar:
194
- *
195
- * {
196
- * '2024-02-15': [...],
197
- * '2024-02-16': [...]
198
- * }
199
- *
200
- * onde cada item do objeto é uma coluna no board. O mesmo vale para "columnsFieldsModel", "columnsLoading" e
201
- * "columnPagination", organizando os fields, loadings e o controle de paginação por chave identificadora do header.
202
- */
326
+ const newValues = response.data?.results || []
327
+ const resultsModel = columnsResultsModel.value[headerKey] || []
328
+
203
329
  const newColumnValues = [
204
- ...columnsResultsModel.value[headerKey] || [],
205
- ...response.data?.results || []
330
+ ...resultsModel,
331
+ ...newValues
206
332
  ]
207
333
 
334
+ /**
335
+ * exemplo de como columnsResultsModel irá ficar:
336
+ *
337
+ * {
338
+ * '2024-02-15': [...],
339
+ * '2024-02-16': [...]
340
+ * }
341
+ *
342
+ * onde cada item do objeto é uma coluna no board. O mesmo vale para "columnsFieldsModel", "columnsLoading" e
343
+ * "columnPagination", organizando os fields, loadings e o controle de paginação por chave identificadora do header.
344
+ */
208
345
  columnsResultsModel.value[headerKey] = props.useMarkRaw ? markRaw(newColumnValues) : newColumnValues
209
346
 
210
347
  /*
@@ -261,6 +398,20 @@ function getItemsByHeader (header) {
261
398
  return hasColumnsLength.value ? columnsResultsModel.value[getKeyByHeader(header)] : []
262
399
  }
263
400
 
401
+ function getColumnItemById (id) {
402
+ return Object.values(columnsResultsModel.value).flat().find(item => item[props.itemIdKey] === id)
403
+ }
404
+
405
+ /**
406
+ * Recupera o payload do header por id:
407
+ *
408
+ * @example getHeaderById('2024-02-15')
409
+ * @returns {Object} // { date: '2024-02-15'... }
410
+ */
411
+ function getHeaderById (id) {
412
+ return props.headers.find(header => String(getKeyByHeader(header)) === String(id))
413
+ }
414
+
264
415
  /**
265
416
  * Pegar key com base na chave identificador, exemplo:
266
417
  * header -> { date: '2024-02-12', ... }
@@ -293,8 +444,24 @@ function setColumnsPagination () {
293
444
  })
294
445
  }
295
446
 
447
+ function fetchColumnsValues () {
448
+ reset()
449
+ setColumnHeightContainer()
450
+ setColumnsPagination()
451
+ fetchColumns()
452
+ }
453
+
454
+ /**
455
+ * Descricao:
456
+ * Exibe o texto quando:
457
+ * - Nao esta carregando a coluna
458
+ * - Nao tem itens na coluna
459
+ * - Nao estou fazendo o drag and drop
460
+ *
461
+ * @param {Object} header
462
+ */
296
463
  function hasEmptyResultText (header) {
297
- return !columnsLoading.value[getKeyByHeader(header)] && !getItemsByHeader(header)?.length
464
+ return !columnsLoading.value[getKeyByHeader(header)] && !getItemsByHeader(header)?.length && !isDragging.value
298
465
  }
299
466
 
300
467
  /*
@@ -319,6 +486,236 @@ function getFieldsByHeader (header) {
319
486
 
320
487
  return columnsFieldsModel.value[headerKey] || {}
321
488
  }
489
+
490
+ /**
491
+ * Loopa todos os itens da coluna com base no ref para pegar o elemento HTML e setar e instaciar o sortable.
492
+ */
493
+ function handleElementsList () {
494
+ columnContainer.value.forEach((element, index) => {
495
+ const sortable = setSortable(element, index)
496
+
497
+ sortableInstances.value.push(sortable)
498
+ })
499
+ }
500
+
501
+ /**
502
+ * Descrição:
503
+ * Seta a instancia do sortable, no qual varia de acordo com as props passadas.
504
+ *
505
+ * @param {HTMLElement} element
506
+ * @param {Number} index
507
+ */
508
+ function setSortable (element, index) {
509
+ const defaultSortableConfig = {
510
+ animation: 500,
511
+ swapThreshold: 1,
512
+ delay: 50,
513
+ delayOnTouchOnly: true,
514
+ emptyInsertThreshold: 0
515
+ }
516
+
517
+ /**
518
+ * Caso seja apenas drag and drop no eixo Y
519
+ */
520
+ const useOnlyDragAndDropY = !!props.useDragAndDropY && !props.useDragAndDropX
521
+
522
+ const sortable = new Sortable(element, {
523
+ sort: props.useDragAndDropY,
524
+
525
+ ...defaultSortableConfig,
526
+
527
+ ...props.sortableConfig,
528
+
529
+ group: useOnlyDragAndDropY ? `column-${index}` : 'shared',
530
+
531
+ direction: useOnlyDragAndDropY ? 'vertical' : 'horizontal',
532
+
533
+ onStart: toggleIsDragging,
534
+
535
+ onAdd: event => onDropCard(event),
536
+
537
+ ...(props.useDragAndDropY && {
538
+ onSort: event => onDropCard(event)
539
+ })
540
+ })
541
+
542
+ return sortable
543
+ }
544
+
545
+ function toggleIsDragging () {
546
+ isDragging.value = !isDragging.value
547
+ }
548
+
549
+ function onDropCard (event) {
550
+ onCancelDrop.value = () => cancelDrop(event)
551
+
552
+ onConfirmDrop.value = () => confirmDrop(event)
553
+
554
+ if (typeof props.beforeUpdatePosition === 'function') {
555
+ props.beforeUpdatePosition({
556
+ event,
557
+ cancel: onCancelDrop.value,
558
+ getItem: () => getColumnItemById(event.item.id),
559
+ getColumnTo: () => getHeaderById(event.to.dataset.headerKey),
560
+ getColumnFrom: () => getHeaderById(event.from.dataset.headerKey),
561
+ openConfirmDialog,
562
+ update: () => confirmDrop(event)
563
+ })
564
+
565
+ return
566
+ }
567
+
568
+ hasConfirmDialogProps.value
569
+ ? openConfirmDialog()
570
+ : confirmDrop(event)
571
+ }
572
+
573
+ function openConfirmDialog () {
574
+ showConfirmDialog.value = true
575
+ }
576
+
577
+ function closeConfirmDialog () {
578
+ showConfirmDialog.value = false
579
+ }
580
+
581
+ /**
582
+ * @param {event} event
583
+ */
584
+ function cancelDrop (event) {
585
+ /**
586
+ * Insere na posição antiga que pertencia (event.oldIndex) dentro do seu antigo pai (event.from)
587
+ */
588
+ if (props.useDragAndDropX) event.from.insertBefore(event.item, event.from.children[event.oldIndex])
589
+
590
+ if (props.useDragAndDropY) {
591
+ const oldIndex = event.oldIndex
592
+
593
+ /**
594
+ * Se oldIndex for 0, o targetIndex deverá ser 0, pois isso indica que se o item é o primeiro da lista, ele não será movido para outra posição.
595
+ *
596
+ * Caso o oldIndex for diferente, devo incrementar 1 para adicionar, pois isso permite que o item seja inserido logo após sua posição original.
597
+ */
598
+ const targetIndex = oldIndex === 0 ? oldIndex : oldIndex + 1
599
+
600
+ /**
601
+ * Verifica se o índice alvo é válido, caso contrário, define como o final
602
+ */
603
+ const insertBeforeElement = targetIndex < event.from.children.length
604
+ ? event.from.children[targetIndex]
605
+ : null
606
+
607
+ event.from.insertBefore(event.item, insertBeforeElement)
608
+ }
609
+
610
+ if (hasConfirmDialogProps.value) closeConfirmDialog()
611
+
612
+ toggleIsDragging()
613
+ }
614
+
615
+ function confirmDrop (event) {
616
+ const { from, to, item: { id: itemId } } = event
617
+
618
+ const { headerKey: newHeaderKey } = to.dataset
619
+ const { headerKey: oldHeaderKey } = from.dataset
620
+
621
+ updatePosition({ newHeaderKey, oldHeaderKey, itemId, event })
622
+ }
623
+
624
+ /**
625
+ *
626
+ * @param {{
627
+ * headerKey: string,
628
+ * itemId: string
629
+ * }}
630
+ */
631
+ function removeItemFromList ({ headerKey, itemId }) {
632
+ /**
633
+ * Coluna referente ao model de resultado
634
+ */
635
+ const columnItemList = columnsResultsModel.value[headerKey]
636
+
637
+ /**
638
+ * Busca o item com base em seu ID na lista de itens da coluna
639
+ */
640
+ const itemIndex = columnItemList.findIndex(itemContent => itemContent[props.itemIdKey] === itemId)
641
+
642
+ /**
643
+ * Remove o item da listagem com base no index, sendo que preciso subtrair 1 para pegar o index correto
644
+ */
645
+ columnItemList.splice(itemIndex, 1)
646
+
647
+ /**
648
+ * Remove o item do count da coluna para não mostrar o botão de "Ver mais¨.
649
+ */
650
+ columnsPagination.value[headerKey].count -= 1
651
+ }
652
+
653
+ /**
654
+ * Método que realiza a request de update
655
+ *
656
+ * @param {{
657
+ * newHeaderKey: string - ID da coluna de destino,
658
+ * oldHeaderKey: string - ID da antiga coluna,
659
+ * itemId: string - ID do meu item a ser movimento,
660
+ * event: event
661
+ * }}
662
+ */
663
+ async function updatePosition ({ newHeaderKey, oldHeaderKey, itemId, event }) {
664
+ const params = {
665
+ [props.columnIdKey]: newHeaderKey,
666
+ ...(props.useDragAndDropY && { newIndex: event.newIndex }),
667
+ ...props.updatePositionParams
668
+ }
669
+
670
+ const { data, error } = await promiseHandler(
671
+ axios.patch(`${props.updatePositionUrl}/${itemId}/update-position`, params),
672
+ {
673
+ errorMessage: 'Ocorreu um erro ao atualizar a posição de seu item.',
674
+ useLoading: false,
675
+ onLoading: value => {
676
+ isLoadingUpdatePosition.value = value
677
+
678
+ columnsLoading.value[newHeaderKey] = value
679
+ }
680
+ }
681
+ )
682
+
683
+ if (error) {
684
+ onCancelDrop.value()
685
+
686
+ emit('update-error', error)
687
+
688
+ return
689
+ }
690
+
691
+ removeItemFromList({ headerKey: oldHeaderKey, itemId })
692
+
693
+ setItemList({ headerKey: newHeaderKey, data: data.data, index: event.newIndex })
694
+
695
+ isUpdatingPosition.value = true
696
+
697
+ toggleIsDragging()
698
+
699
+ closeConfirmDialog()
700
+
701
+ emit('update-success', data.data)
702
+ }
703
+
704
+ function setItemList ({ headerKey, data, index }) {
705
+ /**
706
+ * Coluna referente ao model de resultado
707
+ */
708
+ const columnItemList = columnsResultsModel.value[headerKey]
709
+
710
+ /**
711
+ * Adiciona o item na posição do event escolhido.
712
+ */
713
+ columnItemList.splice(index, 0, data.result)
714
+ }
715
+
716
+ function destroySortable () {
717
+ sortableInstances.value.forEach(sortable => sortable.destroy())
718
+ }
322
719
  </script>
323
720
 
324
721
  <style lang="scss">
@@ -341,5 +738,10 @@ function getFieldsByHeader (header) {
341
738
  display: none;
342
739
  }
343
740
  }
741
+
742
+ // 60px é o valor do padding definido no container da column.
743
+ &__column-items {
744
+ height: calc(100% - 60px);
745
+ }
344
746
  }
345
747
  </style>