@bildvitta/quasar-ui-asteroid 3.0.0-beta.7 → 3.0.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 (106) hide show
  1. package/dist/api/QasAppBar.json +0 -4
  2. package/dist/api/QasBtn.json +2 -1
  3. package/dist/api/QasCard.json +13 -9
  4. package/dist/api/QasDateTimeInput.json +12 -12
  5. package/dist/api/QasDialog.json +6 -2
  6. package/dist/api/QasFilters.json +4 -4
  7. package/dist/api/QasFormGenerator.json +33 -2
  8. package/dist/api/QasFormView.json +43 -15
  9. package/dist/api/QasGridGenerator.json +5 -4
  10. package/dist/api/QasInput.json +1 -1
  11. package/dist/api/QasListItems.json +18 -17
  12. package/dist/api/QasListView.json +21 -7
  13. package/dist/api/QasNestedFields.json +13 -3
  14. package/dist/api/QasNumericInput.json +10 -10
  15. package/dist/api/QasPasswordInput.json +1 -1
  16. package/dist/api/QasSearchBox.json +85 -3
  17. package/dist/api/QasSelect.json +81 -14
  18. package/dist/api/QasSelectList.json +16 -14
  19. package/dist/api/QasSignaturePad.json +1 -1
  20. package/dist/api/QasSingleView.json +13 -4
  21. package/dist/api/QasTabsGenerator.json +5 -2
  22. package/dist/api/QasUploader.json +5 -0
  23. package/dist/asteroid.cjs.css +1 -1
  24. package/dist/asteroid.cjs.js +1522 -706
  25. package/dist/asteroid.cjs.min.js +2 -2
  26. package/dist/asteroid.esm.css +1 -1
  27. package/dist/asteroid.esm.js +1525 -709
  28. package/dist/asteroid.esm.min.js +2 -2
  29. package/dist/asteroid.umd.css +1 -1
  30. package/dist/asteroid.umd.js +1525 -710
  31. package/dist/asteroid.umd.min.js +2 -2
  32. package/dist/vetur/asteroid-attributes.json +176 -100
  33. package/dist/vetur/asteroid-tags.json +60 -41
  34. package/package.json +1 -1
  35. package/src/components/actions-menu/QasActionsMenu.vue +2 -8
  36. package/src/components/app-bar/QasAppBar.vue +16 -12
  37. package/src/components/app-bar/QasAppBar.yml +0 -4
  38. package/src/components/avatar/QasAvatar.vue +0 -4
  39. package/src/components/btn/QasBtn.vue +5 -8
  40. package/src/components/btn/QasBtn.yml +2 -1
  41. package/src/components/card/QasCard.vue +18 -9
  42. package/src/components/card/QasCard.yml +13 -9
  43. package/src/components/date-time-input/QasDateTimeInput.vue +39 -41
  44. package/src/components/date-time-input/QasDateTimeInput.yml +11 -12
  45. package/src/components/delete/QasDelete.vue +15 -1
  46. package/src/components/dialog/QasDialog.vue +26 -3
  47. package/src/components/dialog/QasDialog.yml +6 -3
  48. package/src/components/dialog-router/QasDialogRouter.vue +1 -1
  49. package/src/components/field/QasField.vue +15 -14
  50. package/src/components/filters/QasFilters.vue +27 -10
  51. package/src/components/filters/QasFilters.yml +4 -4
  52. package/src/components/form-generator/QasFormGenerator.vue +87 -12
  53. package/src/components/form-generator/QasFormGenerator.yml +16 -2
  54. package/src/components/form-view/QasFormView.vue +138 -56
  55. package/src/components/form-view/QasFormView.yml +39 -15
  56. package/src/components/grid-generator/QasGridGenerator.vue +23 -7
  57. package/src/components/grid-generator/QasGridGenerator.yml +5 -4
  58. package/src/components/input/QasInput.vue +37 -21
  59. package/src/components/input/QasInput.yml +1 -1
  60. package/src/components/layout/QasLayout.vue +4 -0
  61. package/src/components/list-items/QasListItems.vue +15 -23
  62. package/src/components/list-items/QasListItems.yml +14 -15
  63. package/src/components/list-view/QasListView.vue +45 -24
  64. package/src/components/list-view/QasListView.yml +19 -7
  65. package/src/components/map/QasMap.vue +5 -5
  66. package/src/components/nested-fields/QasNestedFields.vue +29 -21
  67. package/src/components/nested-fields/QasNestedFields.yml +9 -3
  68. package/src/components/numeric-input/QasNumericInput.vue +14 -14
  69. package/src/components/numeric-input/QasNumericInput.yml +10 -10
  70. package/src/components/page-header/QasPageHeader.vue +14 -11
  71. package/src/components/password-input/QasPasswordInput.vue +17 -16
  72. package/src/components/password-input/QasPasswordInput.yml +1 -1
  73. package/src/components/profile/QasProfile.vue +1 -1
  74. package/src/components/search-box/QasSearchBox.vue +138 -42
  75. package/src/components/search-box/QasSearchBox.yml +69 -2
  76. package/src/components/select/QasSelect.vue +63 -53
  77. package/src/components/select/QasSelect.yml +64 -13
  78. package/src/components/select-list/QasSelectList.vue +11 -27
  79. package/src/components/select-list/QasSelectList.yml +13 -14
  80. package/src/components/signature-pad/QasSignaturePad.yml +1 -1
  81. package/src/components/signature-uploader/QasSignatureUploader.vue +7 -5
  82. package/src/components/single-view/QasSingleView.vue +22 -6
  83. package/src/components/single-view/QasSingleView.yml +11 -4
  84. package/src/components/table-generator/QasTableGenerator.vue +13 -2
  85. package/src/components/tabs-generator/QasTabsGenerator.vue +2 -2
  86. package/src/components/tabs-generator/QasTabsGenerator.yml +2 -2
  87. package/src/components/text-truncate/QasTextTruncate.vue +1 -1
  88. package/src/components/uploader/QasUploader.vue +62 -15
  89. package/src/components/uploader/QasUploader.yml +5 -0
  90. package/src/helpers/camelize-fields-name.js +15 -0
  91. package/src/helpers/filters.js +2 -0
  92. package/src/helpers/get-normalized-options.js +20 -0
  93. package/src/helpers/handle-process.js +13 -0
  94. package/src/helpers/index.js +3 -0
  95. package/src/mixins/generator.js +10 -2
  96. package/src/mixins/index.js +2 -0
  97. package/src/mixins/search-filter.js +227 -0
  98. package/src/mixins/view.js +35 -13
  99. package/src/pages/Forbidden.vue +3 -1
  100. package/src/pages/NotFound.vue +3 -1
  101. package/src/pages/ServerError.vue +3 -1
  102. package/src/pages/Unauthorized.vue +28 -0
  103. package/src/plugins/index.js +4 -2
  104. package/src/plugins/logger/Logger.js +44 -0
  105. package/src/plugins/logger/Logger.yml +9 -0
  106. package/src/vue-plugin.js +6 -3
@@ -1,13 +1,13 @@
1
1
  /*!
2
- * @bildvitta/quasar-ui-asteroid v3.0.0-beta.7
2
+ * @bildvitta/quasar-ui-asteroid v3.0.0
3
3
  * (c) 2022 Bild & Vitta <systemteam@bild.com.br>
4
4
  * Released under the MIT License.
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue'), require('humps'), require('date-fns'), require('date-fns/locale'), require('quasar'), require('lodash-es'), require('autonumeric'), require('pica'), require('signature_pad'), require('vue-router'), require('fuse.js'), require('sortablejs'), require('@fawmi/vue-google-maps')) :
8
- typeof define === 'function' && define.amd ? define(['vue', 'humps', 'date-fns', 'date-fns/locale', 'quasar', 'lodash-es', 'autonumeric', 'pica', 'signature_pad', 'vue-router', 'fuse.js', 'sortablejs', '@fawmi/vue-google-maps'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global["{{ umdExportName }}"] = factory(global.Vue, global.humps, global.dateFns, global.dateFnsLocale, global.Quasar, global._, global.AutoNumeric, global.Pica, global.SignaturePad, global.VueRouter, global.Fuse, global.Sortable, global.VueGoogleMaps));
10
- })(this, (function (vue, humps, dateFns, locale, quasar, lodashEs, AutoNumeric, Pica, SignaturePad, vueRouter, Fuse, Sortable, VueGoogleMaps) { 'use strict';
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue'), require('humps'), require('date-fns'), require('date-fns/locale'), require('quasar'), require('lodash-es'), require('autonumeric'), require('pica'), require('signature_pad'), require('vue-router'), require('lodash'), require('fuse.js'), require('sortablejs'), require('@fawmi/vue-google-maps')) :
8
+ typeof define === 'function' && define.amd ? define(['vue', 'humps', 'date-fns', 'date-fns/locale', 'quasar', 'lodash-es', 'autonumeric', 'pica', 'signature_pad', 'vue-router', 'lodash', 'fuse.js', 'sortablejs', '@fawmi/vue-google-maps'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global["{{ umdExportName }}"] = factory(global.Vue, global.humps, global.dateFns, global.dateFnsLocale, global.Quasar, global._, global.AutoNumeric, global.Pica, global.SignaturePad, global.VueRouter, global.lodash, global.Fuse, global.Sortable, global.VueGoogleMaps));
10
+ })(this, (function (vue, humps, dateFns, locale, quasar, lodashEs, AutoNumeric, Pica, SignaturePad, vueRouter, lodash, Fuse, Sortable, VueGoogleMaps) { 'use strict';
11
11
 
12
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
13
 
@@ -46,14 +46,14 @@
46
46
  }
47
47
  };
48
48
 
49
- const _hoisted_1$s = { class: "col-12 col-sm-auto" };
49
+ const _hoisted_1$t = { class: "col-12 col-sm-auto" };
50
50
  const _hoisted_2$l = { class: "col-12 col-sm-auto" };
51
51
 
52
52
  function render$L(_ctx, _cache, $props, $setup, $data, $options) {
53
53
  return (vue.openBlock(), vue.createElementBlock("div", {
54
54
  class: vue.normalizeClass($options.classes)
55
55
  }, [
56
- vue.createElementVNode("div", _hoisted_1$s, [
56
+ vue.createElementVNode("div", _hoisted_1$t, [
57
57
  vue.renderSlot(_ctx.$slots, "secondary")
58
58
  ]),
59
59
  vue.createElementVNode("div", _hoisted_2$l, [
@@ -69,13 +69,14 @@
69
69
  name: 'QasBtn',
70
70
 
71
71
  props: {
72
- hideLabelOnSmallScreen: {
72
+ useLabelOnSmallScreen: {
73
+ default: true,
73
74
  type: Boolean
74
75
  },
75
76
 
76
77
  label: {
77
- type: String,
78
- default: ''
78
+ default: '',
79
+ type: String
79
80
  }
80
81
  },
81
82
 
@@ -87,12 +88,8 @@
87
88
  }
88
89
  },
89
90
 
90
- hasLabel () {
91
- return !!this.label
92
- },
93
-
94
91
  showLabel () {
95
- return this.hasLabel && !(this.hideLabelOnSmallScreen && this.$qas.screen.isSmall)
92
+ return this.useLabelOnSmallScreen || !this.$qas.screen.isSmall
96
93
  },
97
94
 
98
95
  slots () {
@@ -168,8 +165,6 @@
168
165
  }
169
166
  },
170
167
 
171
- emits: ['delete-success'],
172
-
173
168
  computed: {
174
169
  hasDelete () {
175
170
  return !!Object.keys(this.deleteProps).length
@@ -182,15 +177,11 @@
182
177
  const { handler, ...filtered } = item;
183
178
  item.handler(filtered);
184
179
  }
185
- },
186
-
187
- onDeleteSuccess () {
188
- this.$emit('delete-success');
189
180
  }
190
181
  }
191
182
  };
192
183
 
193
- const _hoisted_1$r = { class: "flex items-center justify-center q-gutter-x-md" };
184
+ const _hoisted_1$s = { class: "flex items-center justify-center q-gutter-x-md" };
194
185
  const _hoisted_2$k = { class: "flex items-center justify-center q-gutter-x-sm" };
195
186
 
196
187
  function render$J(_ctx, _cache, $props, $setup, $data, $options) {
@@ -205,11 +196,11 @@
205
196
  return (vue.openBlock(), vue.createBlock(_component_qas_btn, {
206
197
  class: "qas-actions-menu",
207
198
  color: "primary",
208
- "hide-label-on-small-screen": "",
209
199
  icon: $props.icon,
210
200
  label: $props.label,
211
201
  outline: "",
212
- padding: "md"
202
+ padding: "md",
203
+ "use-label-on-small-screen": ""
213
204
  }, {
214
205
  default: vue.withCtx(() => [
215
206
  vue.createVNode(_component_q_menu, { class: "qas-actions-menu__menu" }, {
@@ -231,7 +222,7 @@
231
222
  default: vue.withCtx(() => [
232
223
  vue.createVNode(_component_q_item_section, null, {
233
224
  default: vue.withCtx(() => [
234
- vue.createElementVNode("div", _hoisted_1$r, [
225
+ vue.createElementVNode("div", _hoisted_1$s, [
235
226
  vue.createVNode(_component_q_icon, {
236
227
  name: item.icon,
237
228
  size: "sm"
@@ -250,8 +241,7 @@
250
241
  ? (vue.openBlock(), vue.createBlock(_component_qas_delete, vue.mergeProps({ key: 0 }, $props.deleteProps, {
251
242
  class: "text-negative",
252
243
  clickable: "",
253
- tag: "q-item",
254
- onSuccess: $options.onDeleteSuccess
244
+ tag: "q-item"
255
245
  }), {
256
246
  default: vue.withCtx(() => [
257
247
  vue.createVNode(_component_q_item_section, null, {
@@ -268,7 +258,7 @@
268
258
  })
269
259
  ]),
270
260
  _: 1 /* STABLE */
271
- }, 16 /* FULL_PROPS */, ["onSuccess"]))
261
+ }, 16 /* FULL_PROPS */))
272
262
  : vue.createCommentVNode("v-if", true)
273
263
  ]),
274
264
  _: 3 /* FORWARDED */
@@ -472,6 +462,41 @@
472
462
  return first
473
463
  }
474
464
 
465
+ function camelizeFieldsName (fields) {
466
+ for (const field in fields) {
467
+ const currentField = fields[field];
468
+
469
+ currentField.name = humps.camelize(currentField.name);
470
+
471
+ if (Object.keys(currentField.children || {}).length) {
472
+ camelizeFieldsName(currentField.children);
473
+ }
474
+ }
475
+
476
+ return fields
477
+ }
478
+
479
+ /**
480
+ * param {options: object[], label: string, value: string} object
481
+ *
482
+ * @example getNormalizedOptions({
483
+ * options: [{ name: 'Test 1', uuid: '1' }, { name: 'Test 2', uuid: '2' }],
484
+ * label: 'name'
485
+ * value: 'uuid'
486
+ * }) // retorna [{ label: 'Test 1', value: '1' }, { label: 'Test 2', value: '2' }]
487
+ */
488
+ var getNormalizedOptions = ({ options = [], label, value }) => {
489
+ return options.map(option => {
490
+ const { [label]: labelKey, [value]: valueKey, ...payload } = option;
491
+
492
+ return {
493
+ label: option[label],
494
+ value: option[value],
495
+ ...payload
496
+ }
497
+ })
498
+ };
499
+
475
500
  // Private
476
501
  function __format (value, token, options = {}) {
477
502
  if (!value) {
@@ -569,6 +594,8 @@
569
594
  case 'time': return time(value)
570
595
  case 'radio': return selectLabel(field.options, value)
571
596
  case 'percent': return formatPercent(value)
597
+ case 'money': return money(value)
598
+ case 'decimal': return decimal(value)
572
599
  default: return value
573
600
  }
574
601
  }
@@ -722,7 +749,7 @@
722
749
  }
723
750
  };
724
751
 
725
- const _hoisted_1$q = { class: "q-gutter-md q-mr-lg" };
752
+ const _hoisted_1$r = { class: "q-gutter-md q-mr-lg" };
726
753
  const _hoisted_2$j = {
727
754
  key: 0,
728
755
  class: "text-bold text-h5"
@@ -746,7 +773,7 @@
746
773
  rounded: "",
747
774
  onClick: $options.close
748
775
  }, null, 8 /* PROPS */, ["color", "onClick"]),
749
- vue.createElementVNode("div", _hoisted_1$q, [
776
+ vue.createElementVNode("div", _hoisted_1$r, [
750
777
  vue.renderSlot(_ctx.$slots, "header", {}, () => [
751
778
  ($props.title)
752
779
  ? (vue.openBlock(), vue.createElementBlock("h5", _hoisted_2$j, vue.toDisplayString($props.title), 1 /* TEXT */))
@@ -813,20 +840,16 @@
813
840
  }
814
841
 
815
842
  const contrastColor = this.color ? this.color : this.contrastColor;
816
- // const contrastColor = this.textColor ? this.textColor : this.contrastColor
817
843
 
818
844
  return [
819
845
  this.dark
820
846
  ? `bg-${this.textColor} text-${contrastColor}`
821
847
  : `bg-${contrastColor} text-${this.textColor}`
822
- // ? `bg-${this.color} text-${contrastColor}`
823
- // : `bg-${contrastColor} text-${this.color}`
824
848
  ]
825
849
  },
826
850
 
827
851
  contrastColor () {
828
852
  return `${this.textColor}-contrast`
829
- // return `${this.color}-contrast`
830
853
  },
831
854
 
832
855
  firstLetter () {
@@ -905,10 +928,6 @@
905
928
  type: String
906
929
  },
907
930
 
908
- isAuth: {
909
- type: Boolean
910
- },
911
-
912
931
  title: {
913
932
  type: String,
914
933
  default: ''
@@ -963,6 +982,14 @@
963
982
 
964
983
  showTitle () {
965
984
  return this.title && !this.brand
985
+ },
986
+
987
+ hasUser () {
988
+ return !!Object.keys(this.user).length
989
+ },
990
+
991
+ userName () {
992
+ return this.user.name || this.user.givenName
966
993
  }
967
994
  },
968
995
 
@@ -985,7 +1012,7 @@
985
1012
  }
986
1013
  };
987
1014
 
988
- const _hoisted_1$p = ["alt", "src"];
1015
+ const _hoisted_1$q = ["alt", "src"];
989
1016
  const _hoisted_2$i = {
990
1017
  key: 1,
991
1018
  class: "text-bold text-grey-9 text-subtitle1 text-uppercase"
@@ -1008,11 +1035,10 @@
1008
1035
 
1009
1036
  function render$F(_ctx, _cache, $props, $setup, $data, $options) {
1010
1037
  const _component_q_ajax_bar = vue.resolveComponent("q-ajax-bar");
1011
- const _component_q_btn = vue.resolveComponent("q-btn");
1038
+ const _component_qas_btn = vue.resolveComponent("qas-btn");
1012
1039
  const _component_q_badge = vue.resolveComponent("q-badge");
1013
1040
  const _component_q_toolbar_title = vue.resolveComponent("q-toolbar-title");
1014
1041
  const _component_qas_avatar = vue.resolveComponent("qas-avatar");
1015
- const _component_qas_btn = vue.resolveComponent("qas-btn");
1016
1042
  const _component_q_menu = vue.resolveComponent("q-menu");
1017
1043
  const _component_q_toolbar = vue.resolveComponent("q-toolbar");
1018
1044
  const _component_q_header = vue.resolveComponent("q-header");
@@ -1033,7 +1059,7 @@
1033
1059
  position: "top",
1034
1060
  size: "2px"
1035
1061
  }),
1036
- vue.createVNode(_component_q_btn, {
1062
+ vue.createVNode(_component_qas_btn, {
1037
1063
  color: "grey-7",
1038
1064
  dense: "",
1039
1065
  flat: "",
@@ -1053,7 +1079,7 @@
1053
1079
  alt: $props.title,
1054
1080
  class: "q-mr-sm qas-app-bar__brand",
1055
1081
  src: $props.brand
1056
- }, null, 8 /* PROPS */, _hoisted_1$p))
1082
+ }, null, 8 /* PROPS */, _hoisted_1$q))
1057
1083
  : vue.createCommentVNode("v-if", true),
1058
1084
  ($options.showTitle)
1059
1085
  ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2$i, vue.toDisplayString($props.title), 1 /* TEXT */))
@@ -1073,7 +1099,7 @@
1073
1099
  }),
1074
1100
  ($options.hasNotifications)
1075
1101
  ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$e, [
1076
- vue.createVNode(_component_q_btn, {
1102
+ vue.createVNode(_component_qas_btn, {
1077
1103
  class: "q-mr-md",
1078
1104
  dense: "",
1079
1105
  icon: "o_notifications",
@@ -1100,11 +1126,11 @@
1100
1126
  : vue.createCommentVNode("v-if", true),
1101
1127
  vue.createElementVNode("div", _hoisted_4$a, [
1102
1128
  vue.renderSlot(_ctx.$slots, "tools"),
1103
- ($props.isAuth)
1129
+ ($options.hasUser)
1104
1130
  ? (vue.openBlock(), vue.createElementBlock("div", {
1105
1131
  key: 0,
1106
1132
  class: "cursor-pointer items-center q-mr-sm qas-app-bar__user rounded-borders row text-grey-9",
1107
- title: $props.user.name || $props.user.givenName
1133
+ title: $options.userName
1108
1134
  }, [
1109
1135
  vue.createVNode(_component_qas_avatar, {
1110
1136
  class: "rounded-borders-left",
@@ -1114,10 +1140,10 @@
1114
1140
  rounded: "",
1115
1141
  size: "42px",
1116
1142
  "text-color": "primary",
1117
- title: $props.user.name || $props.user.givenName
1143
+ title: $options.userName
1118
1144
  }, null, 8 /* PROPS */, ["image", "title"]),
1119
1145
  vue.createElementVNode("div", _hoisted_6$4, [
1120
- vue.createElementVNode("div", _hoisted_7$4, vue.toDisplayString($props.user.name || $props.user.givenName), 1 /* TEXT */),
1146
+ vue.createElementVNode("div", _hoisted_7$4, vue.toDisplayString($options.userName), 1 /* TEXT */),
1121
1147
  vue.createElementVNode("div", _hoisted_8$3, vue.toDisplayString($props.user.email), 1 /* TEXT */)
1122
1148
  ]),
1123
1149
  vue.createVNode(_component_q_menu, {
@@ -1137,10 +1163,10 @@
1137
1163
  vue.createVNode(_component_qas_avatar, {
1138
1164
  image: $props.user.photo,
1139
1165
  size: "145px",
1140
- title: $props.user.name || $props.user.givenName
1166
+ title: $options.userName
1141
1167
  }, null, 8 /* PROPS */, ["image", "title"])
1142
1168
  ]),
1143
- vue.createElementVNode("div", _hoisted_11$1, vue.toDisplayString($props.user.name || $props.user.givenName), 1 /* TEXT */),
1169
+ vue.createElementVNode("div", _hoisted_11$1, vue.toDisplayString($options.userName), 1 /* TEXT */),
1144
1170
  vue.createElementVNode("div", _hoisted_12$1, vue.toDisplayString($props.user.email), 1 /* TEXT */),
1145
1171
  vue.createElementVNode("div", _hoisted_13$1, [
1146
1172
  vue.createVNode(_component_qas_btn, {
@@ -1319,7 +1345,7 @@
1319
1345
  }
1320
1346
  };
1321
1347
 
1322
- const _hoisted_1$o = { class: "column flex full-height justify-between no-wrap overflow-x-hidden" };
1348
+ const _hoisted_1$p = { class: "column flex full-height justify-between no-wrap overflow-x-hidden" };
1323
1349
  const _hoisted_2$h = {
1324
1350
  key: 0,
1325
1351
  class: "q-ma-md"
@@ -1352,7 +1378,7 @@
1352
1378
  onMiniState: $options.setMiniState
1353
1379
  }, {
1354
1380
  default: vue.withCtx(() => [
1355
- vue.createElementVNode("div", _hoisted_1$o, [
1381
+ vue.createElementVNode("div", _hoisted_1$p, [
1356
1382
  vue.createElementVNode("div", null, [
1357
1383
  ($options.displayModuleSection)
1358
1384
  ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$h, [
@@ -1529,15 +1555,11 @@
1529
1555
  name: 'QasCard',
1530
1556
 
1531
1557
  props: {
1532
- bgImagePosition: {
1558
+ imagePosition: {
1533
1559
  type: String,
1534
1560
  default: 'center'
1535
1561
  },
1536
1562
 
1537
- formMode: {
1538
- type: Boolean
1539
- },
1540
-
1541
1563
  gutter: {
1542
1564
  type: String,
1543
1565
  default: 'sm'
@@ -1548,6 +1570,14 @@
1548
1570
  type: Array
1549
1571
  },
1550
1572
 
1573
+ outlined: {
1574
+ type: Boolean
1575
+ },
1576
+
1577
+ unelevated: {
1578
+ type: Boolean
1579
+ },
1580
+
1551
1581
  useHeader: {
1552
1582
  type: Boolean
1553
1583
  }
@@ -1560,12 +1590,17 @@
1560
1590
  },
1561
1591
 
1562
1592
  computed: {
1563
- bgImagePositionClass () {
1564
- return `bg-position-${this.bgImagePosition}`
1593
+ imagePositionClass () {
1594
+ return `bg-position-${this.imagePosition}`
1565
1595
  },
1566
1596
 
1567
1597
  cardClasses () {
1568
- return this.formMode ? 'bg-white border-primary no-shadow' : 'shadow-14'
1598
+ return {
1599
+ 'shadow-14': !this.unelevated,
1600
+ 'border-primary': this.outlined,
1601
+ 'no-shadow': this.outlined,
1602
+ 'bg-white': this.outlined
1603
+ }
1569
1604
  },
1570
1605
 
1571
1606
  gutterClass () {
@@ -1596,7 +1631,7 @@
1596
1631
  }
1597
1632
  };
1598
1633
 
1599
- const _hoisted_1$n = { class: "col-12 col-lg-3 col-md-4 col-sm-6" };
1634
+ const _hoisted_1$o = { class: "col-12 col-lg-3 col-md-4 col-sm-6" };
1600
1635
  const _hoisted_2$g = {
1601
1636
  key: 0,
1602
1637
  class: "overflow-hidden relative-position w-full"
@@ -1614,7 +1649,7 @@
1614
1649
  const _component_q_card_section = vue.resolveComponent("q-card-section");
1615
1650
  const _component_q_card = vue.resolveComponent("q-card");
1616
1651
 
1617
- return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$n, [
1652
+ return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$o, [
1618
1653
  vue.createVNode(_component_q_card, {
1619
1654
  class: vue.normalizeClass(["border-radius-lg column full-height overflow-hidden", $options.cardClasses])
1620
1655
  }, {
@@ -1648,7 +1683,7 @@
1648
1683
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($options.imagesList, (item, index) => {
1649
1684
  return (vue.openBlock(), vue.createBlock(_component_q_carousel_slide, {
1650
1685
  key: index,
1651
- class: vue.normalizeClass(["bg-no-repeat", $options.bgImagePositionClass]),
1686
+ class: vue.normalizeClass(["bg-no-repeat", $options.imagePositionClass]),
1652
1687
  "img-src": item,
1653
1688
  name: index
1654
1689
  }, null, 8 /* PROPS */, ["class", "img-src", "name"]))
@@ -1877,7 +1912,7 @@
1877
1912
  }
1878
1913
  };
1879
1914
 
1880
- const _hoisted_1$m = /*#__PURE__*/vue.createTextVNode("Copiar");
1915
+ const _hoisted_1$n = /*#__PURE__*/vue.createTextVNode("Copiar");
1881
1916
 
1882
1917
  function render$A(_ctx, _cache, $props, $setup, $data, $options) {
1883
1918
  const _component_q_tooltip = vue.resolveComponent("q-tooltip");
@@ -1900,7 +1935,7 @@
1900
1935
  default: vue.withCtx(() => [
1901
1936
  vue.createVNode(_component_q_tooltip, null, {
1902
1937
  default: vue.withCtx(() => [
1903
- _hoisted_1$m
1938
+ _hoisted_1$n
1904
1939
  ]),
1905
1940
  _: 1 /* STABLE */
1906
1941
  })
@@ -1924,33 +1959,33 @@
1924
1959
  type: String
1925
1960
  },
1926
1961
 
1927
- dateOnly: {
1928
- type: Boolean
1929
- },
1930
-
1931
1962
  dateProps: {
1932
1963
  default: () => ({}),
1933
1964
  type: Object
1934
1965
  },
1935
1966
 
1936
- gmt: {
1937
- type: Boolean
1938
- },
1939
-
1940
1967
  timeMask: {
1941
1968
  default: 'HH:mm',
1942
1969
  type: String
1943
1970
  },
1944
1971
 
1945
- timeOnly: {
1946
- type: Boolean
1947
- },
1948
-
1949
1972
  timeProps: {
1950
1973
  default: () => ({}),
1951
1974
  type: Object
1952
1975
  },
1953
1976
 
1977
+ useIso: {
1978
+ type: Boolean
1979
+ },
1980
+
1981
+ useTimeOnly: {
1982
+ type: Boolean
1983
+ },
1984
+
1985
+ useDateOnly: {
1986
+ type: Boolean
1987
+ },
1988
+
1954
1989
  modelValue: {
1955
1990
  default: '',
1956
1991
  type: String
@@ -1987,16 +2022,16 @@
1987
2022
  maskDate () {
1988
2023
  const mask = [];
1989
2024
 
1990
- if (!this.timeOnly) { mask.push(this.dateMask); }
1991
- if (!this.dateOnly) { mask.push(this.timeMask); }
2025
+ if (!this.useTimeOnly) { mask.push(this.dateMask); }
2026
+ if (!this.useDateOnly) { mask.push(this.timeMask); }
1992
2027
 
1993
2028
  return mask.join(' ')
1994
2029
  }
1995
2030
  },
1996
2031
 
1997
2032
  watch: {
1998
- value (current, original) {
1999
- if (!current || this.timeOnly) {
2033
+ modelValue (current, original) {
2034
+ if (!current || this.useTimeOnly) {
2000
2035
  this.currentValue = current;
2001
2036
  return
2002
2037
  }
@@ -2022,18 +2057,18 @@
2022
2057
 
2023
2058
  updateModelValue (value) {
2024
2059
  this.currentValue = value;
2025
- const valueLength = value.replace(/_/g, '').length;
2060
+ const valueLength = value?.replace?.(/_/g, '')?.length;
2026
2061
 
2027
2062
  if (value === '' || valueLength === this.mask.length) {
2028
- this.lastValue = this.timeOnly ? value : this.toISOString(value);
2063
+ this.lastValue = this.useTimeOnly ? value : this.toISOString(value);
2029
2064
  this.$emit('update:modelValue', this.lastValue);
2030
2065
  }
2031
2066
 
2032
- if (this.dateOnly) {
2067
+ if (this.useDateOnly) {
2033
2068
  this.$refs.dateProxy.hide();
2034
2069
  }
2035
2070
 
2036
- if (this.timeOnly) {
2071
+ if (this.useTimeOnly) {
2037
2072
  this.$refs.timeProxy.hide();
2038
2073
  }
2039
2074
  },
@@ -2043,11 +2078,11 @@
2043
2078
  return ''
2044
2079
  }
2045
2080
 
2046
- if (this.dateOnly && !this.gmt) {
2081
+ if (this.useDateOnly && !this.useIso) {
2047
2082
  return date(quasar.date.extractDate(value, this.maskDate), 'yyyy-MM-dd')
2048
2083
  }
2049
2084
 
2050
- if (this.timeOnly && !this.gmt) {
2085
+ if (this.useTimeOnly && !this.useIso) {
2051
2086
  return quasar.date.extractDate(value, 'HH:MM')
2052
2087
  }
2053
2088
 
@@ -2055,14 +2090,14 @@
2055
2090
  },
2056
2091
 
2057
2092
  toMask (value) {
2058
- if (!value || this.timeOnly) {
2093
+ if (!value || this.useTimeOnly) {
2059
2094
  return value || ''
2060
2095
  }
2061
2096
 
2062
2097
  const newDate = new Date(value).toISOString();
2063
2098
 
2064
2099
  return quasar.date.formatDate(
2065
- this.dateOnly ? newDate.slice(0, 23) : newDate,
2100
+ this.useDateOnly ? newDate.slice(0, 23) : newDate,
2066
2101
  this.maskDate
2067
2102
  )
2068
2103
  }
@@ -2076,75 +2111,73 @@
2076
2111
  const _component_q_time = vue.resolveComponent("q-time");
2077
2112
  const _component_qas_input = vue.resolveComponent("qas-input");
2078
2113
 
2079
- return (vue.openBlock(), vue.createElementBlock("div", null, [
2080
- vue.createVNode(_component_qas_input, vue.mergeProps({ ref: "input" }, $options.attributes, {
2081
- modelValue: $data.currentValue,
2082
- "onUpdate:modelValue": [
2083
- _cache[2] || (_cache[2] = $event => (($data.currentValue) = $event)),
2084
- $options.updateModelValue
2085
- ],
2086
- "unmasked-value": false
2087
- }), {
2088
- append: vue.withCtx(() => [
2089
- (!$props.timeOnly)
2090
- ? (vue.openBlock(), vue.createBlock(_component_q_icon, {
2091
- key: 0,
2092
- class: "cursor-pointer",
2093
- name: "o_event"
2094
- }, {
2095
- default: vue.withCtx(() => [
2096
- vue.createVNode(_component_q_popup_proxy, {
2097
- ref: "dateProxy",
2098
- "transition-hide": "scale",
2099
- "transition-show": "scale"
2100
- }, {
2101
- default: vue.withCtx(() => [
2102
- vue.createVNode(_component_q_date, vue.mergeProps({
2103
- modelValue: $data.currentValue,
2104
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($data.currentValue) = $event))
2105
- }, $props.dateProps, {
2106
- mask: $options.maskDate,
2107
- "onUpdate:modelValue": $options.updateModelValue
2108
- }), null, 16 /* FULL_PROPS */, ["modelValue", "mask", "onUpdate:modelValue"])
2109
- ]),
2110
- _: 1 /* STABLE */
2111
- }, 512 /* NEED_PATCH */)
2112
- ]),
2113
- _: 1 /* STABLE */
2114
- }))
2115
- : vue.createCommentVNode("v-if", true),
2116
- (!$props.dateOnly)
2117
- ? (vue.openBlock(), vue.createBlock(_component_q_icon, {
2118
- key: 1,
2119
- class: "cursor-pointer q-ml-md",
2120
- name: "o_access_time"
2121
- }, {
2122
- default: vue.withCtx(() => [
2123
- vue.createVNode(_component_q_popup_proxy, {
2124
- ref: "timeProxy",
2125
- "transition-hide": "scale",
2126
- "transition-show": "scale"
2127
- }, {
2128
- default: vue.withCtx(() => [
2129
- vue.createVNode(_component_q_time, vue.mergeProps({
2130
- modelValue: $data.currentValue,
2131
- "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($data.currentValue) = $event))
2132
- }, $props.timeProps, {
2133
- format24h: "",
2134
- mask: $options.maskDate,
2135
- "onUpdate:modelValue": $options.updateModelValue
2136
- }), null, 16 /* FULL_PROPS */, ["modelValue", "mask", "onUpdate:modelValue"])
2137
- ]),
2138
- _: 1 /* STABLE */
2139
- }, 512 /* NEED_PATCH */)
2140
- ]),
2141
- _: 1 /* STABLE */
2142
- }))
2143
- : vue.createCommentVNode("v-if", true)
2144
- ]),
2145
- _: 1 /* STABLE */
2146
- }, 16 /* FULL_PROPS */, ["modelValue", "onUpdate:modelValue"])
2147
- ]))
2114
+ return (vue.openBlock(), vue.createBlock(_component_qas_input, vue.mergeProps({ ref: "input" }, $options.attributes, {
2115
+ modelValue: $data.currentValue,
2116
+ "onUpdate:modelValue": [
2117
+ _cache[2] || (_cache[2] = $event => (($data.currentValue) = $event)),
2118
+ $options.updateModelValue
2119
+ ],
2120
+ "unmasked-value": false
2121
+ }), {
2122
+ append: vue.withCtx(() => [
2123
+ (!$props.useTimeOnly)
2124
+ ? (vue.openBlock(), vue.createBlock(_component_q_icon, {
2125
+ key: 0,
2126
+ class: "cursor-pointer",
2127
+ name: "o_event"
2128
+ }, {
2129
+ default: vue.withCtx(() => [
2130
+ vue.createVNode(_component_q_popup_proxy, {
2131
+ ref: "dateProxy",
2132
+ "transition-hide": "scale",
2133
+ "transition-show": "scale"
2134
+ }, {
2135
+ default: vue.withCtx(() => [
2136
+ vue.createVNode(_component_q_date, vue.mergeProps({
2137
+ modelValue: $data.currentValue,
2138
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($data.currentValue) = $event))
2139
+ }, $props.dateProps, {
2140
+ mask: $options.maskDate,
2141
+ "onUpdate:modelValue": $options.updateModelValue
2142
+ }), null, 16 /* FULL_PROPS */, ["modelValue", "mask", "onUpdate:modelValue"])
2143
+ ]),
2144
+ _: 1 /* STABLE */
2145
+ }, 512 /* NEED_PATCH */)
2146
+ ]),
2147
+ _: 1 /* STABLE */
2148
+ }))
2149
+ : vue.createCommentVNode("v-if", true),
2150
+ (!$props.useDateOnly)
2151
+ ? (vue.openBlock(), vue.createBlock(_component_q_icon, {
2152
+ key: 1,
2153
+ class: "cursor-pointer q-ml-md",
2154
+ name: "o_access_time"
2155
+ }, {
2156
+ default: vue.withCtx(() => [
2157
+ vue.createVNode(_component_q_popup_proxy, {
2158
+ ref: "timeProxy",
2159
+ "transition-hide": "scale",
2160
+ "transition-show": "scale"
2161
+ }, {
2162
+ default: vue.withCtx(() => [
2163
+ vue.createVNode(_component_q_time, vue.mergeProps({
2164
+ modelValue: $data.currentValue,
2165
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($data.currentValue) = $event))
2166
+ }, $props.timeProps, {
2167
+ format24h: "",
2168
+ mask: $options.maskDate,
2169
+ "onUpdate:modelValue": $options.updateModelValue
2170
+ }), null, 16 /* FULL_PROPS */, ["modelValue", "mask", "onUpdate:modelValue"])
2171
+ ]),
2172
+ _: 1 /* STABLE */
2173
+ }, 512 /* NEED_PATCH */)
2174
+ ]),
2175
+ _: 1 /* STABLE */
2176
+ }))
2177
+ : vue.createCommentVNode("v-if", true)
2178
+ ]),
2179
+ _: 1 /* STABLE */
2180
+ }, 16 /* FULL_PROPS */, ["modelValue", "onUpdate:modelValue"]))
2148
2181
  }
2149
2182
 
2150
2183
  script$z.render = render$z;
@@ -2162,12 +2195,12 @@
2162
2195
  }
2163
2196
  };
2164
2197
 
2165
- const _hoisted_1$l = { class: "bg-grey-3 q-my-md q-pa-md rounded-borders" };
2198
+ const _hoisted_1$m = { class: "bg-grey-3 q-my-md q-pa-md rounded-borders" };
2166
2199
  const _hoisted_2$f = /*#__PURE__*/vue.createElementVNode("summary", null, "Debugger", -1 /* HOISTED */);
2167
2200
  const _hoisted_3$b = { class: "row" };
2168
2201
 
2169
2202
  function render$y(_ctx, _cache, $props, $setup, $data, $options) {
2170
- return (vue.openBlock(), vue.createElementBlock("details", _hoisted_1$l, [
2203
+ return (vue.openBlock(), vue.createElementBlock("details", _hoisted_1$m, [
2171
2204
  _hoisted_2$f,
2172
2205
  vue.createElementVNode("div", _hoisted_3$b, [
2173
2206
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($props.inspect, (item, index) => {
@@ -2245,7 +2278,11 @@
2245
2278
  type: Boolean
2246
2279
  },
2247
2280
 
2248
- useCloseIcon: {
2281
+ useCloseButton: {
2282
+ type: Boolean
2283
+ },
2284
+
2285
+ useValidationAllAtOnce: {
2249
2286
  type: Boolean
2250
2287
  }
2251
2288
  },
@@ -2293,7 +2330,26 @@
2293
2330
 
2294
2331
  methods: {
2295
2332
  async submitHandler () {
2296
- this.useForm && this.$emit('validate', await this.$refs.form.validate());
2333
+ if (!this.useForm) return
2334
+
2335
+ if (this.useValidationAllAtOnce) {
2336
+ let isAllComponentValid = true;
2337
+ const components = this.$refs.form.getValidationComponents() || [];
2338
+
2339
+ for (const component of components) {
2340
+ const isValid = component?.validate?.();
2341
+
2342
+ if (!isValid) {
2343
+ isAllComponentValid = false;
2344
+ }
2345
+ }
2346
+
2347
+ this.$emit('validate', isAllComponentValid);
2348
+
2349
+ return
2350
+ }
2351
+
2352
+ this.$emit('validate', await this.$refs.form.validate());
2297
2353
  },
2298
2354
 
2299
2355
  // método para funcionar como plugin
@@ -2312,7 +2368,7 @@
2312
2368
  }
2313
2369
  };
2314
2370
 
2315
- const _hoisted_1$k = { class: "justify-between row" };
2371
+ const _hoisted_1$l = { class: "justify-between row" };
2316
2372
  const _hoisted_2$e = { class: "text-bold text-h6" };
2317
2373
  const _hoisted_3$a = { key: 0 };
2318
2374
 
@@ -2337,9 +2393,9 @@
2337
2393
  vue.createVNode(_component_q_card_section, null, {
2338
2394
  default: vue.withCtx(() => [
2339
2395
  vue.renderSlot(_ctx.$slots, "header", {}, () => [
2340
- vue.createElementVNode("div", _hoisted_1$k, [
2396
+ vue.createElementVNode("div", _hoisted_1$l, [
2341
2397
  vue.createElementVNode("div", _hoisted_2$e, vue.toDisplayString($props.card.title), 1 /* TEXT */),
2342
- ($props.useCloseIcon)
2398
+ ($props.useCloseButton)
2343
2399
  ? vue.withDirectives((vue.openBlock(), vue.createBlock(_component_qas_btn, {
2344
2400
  key: 0,
2345
2401
  dense: "",
@@ -2423,6 +2479,51 @@
2423
2479
  });
2424
2480
  };
2425
2481
 
2482
+ var Logger = () => {
2483
+ const isDebugEnabled = process.env.DEBUGGING;
2484
+
2485
+ const normalizeMessage = msg => `%c ${msg}`;
2486
+ const getStyle = isError => (
2487
+ `
2488
+ background: ${isError ? '#C10015 ' : '#1976d2'};
2489
+ font-weight: bold;
2490
+ color: white;
2491
+ padding: 6px 20px;
2492
+ border-radius: 4px;
2493
+ display: block;
2494
+ width: 100%;
2495
+ font-size: 12px;
2496
+ `
2497
+ );
2498
+
2499
+ return {
2500
+ group (message, payload = [], { error } = {}) {
2501
+ if (!isDebugEnabled) return
2502
+
2503
+ console.groupCollapsed(normalizeMessage(message), getStyle(error));
2504
+
2505
+ for (const item of payload) {
2506
+ if (typeof item === 'string') {
2507
+ console.info(normalizeMessage(item), getStyle(error));
2508
+ continue
2509
+ }
2510
+
2511
+ console.table(item);
2512
+ }
2513
+
2514
+ console.groupEnd();
2515
+ },
2516
+
2517
+ info (message) {
2518
+ isDebugEnabled && console.info(normalizeMessage(message), getStyle());
2519
+ },
2520
+
2521
+ error (message) {
2522
+ isDebugEnabled && console.info(normalizeMessage(message), getStyle(true));
2523
+ }
2524
+ }
2525
+ };
2526
+
2426
2527
  quasar.Notify.registerType('error', {
2427
2528
  color: 'negative',
2428
2529
  progress: true
@@ -2609,7 +2710,13 @@
2609
2710
  try {
2610
2711
  const { destroyRoutes, history } = useHistory();
2611
2712
 
2612
- await this.$store.dispatch(`${this.entity}/destroy`, { id: this.id, url: this.url });
2713
+ const payload = { id: this.id, url: this.url };
2714
+
2715
+ this.$qas.logger.group(
2716
+ `QasDelete - destroy -> Payload do parâmetro do ${this.entity}/destroy`, [payload]
2717
+ );
2718
+
2719
+ await this.$store.dispatch(`${this.entity}/destroy`, payload);
2613
2720
 
2614
2721
  NotifySuccess('Item deletado com sucesso!');
2615
2722
 
@@ -2623,9 +2730,17 @@
2623
2730
  this.createDeleteSuccessEvent();
2624
2731
 
2625
2732
  this.$emit('success');
2733
+
2734
+ this.$qas.logger.info('QasDelete - destroy -> item deletado com sucesso!');
2626
2735
  } catch (error) {
2627
2736
  NotifyError('Ops! Não foi possível deletar o item.');
2628
2737
  this.$emit('error', error);
2738
+
2739
+ this.$qas.logger.group(
2740
+ `QasDelete - destroy -> exceção da action ${this.entity}/destroy`,
2741
+ [error],
2742
+ { error: true }
2743
+ );
2629
2744
  } finally {
2630
2745
  quasar.Loading.hide();
2631
2746
  this.$emit('update:deleting', false);
@@ -2767,8 +2882,8 @@
2767
2882
  ($data.component)
2768
2883
  ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($data.component), {
2769
2884
  key: 0,
2770
- dialog: "",
2771
2885
  route: $data.route,
2886
+ "use-boundary": false,
2772
2887
  onHide: $options.hide
2773
2888
  }, null, 8 /* PROPS */, ["route", "onHide"]))
2774
2889
  : vue.createCommentVNode("v-if", true)
@@ -2792,32 +2907,32 @@
2792
2907
  inheritAttrs: false,
2793
2908
 
2794
2909
  props: {
2910
+ error: {
2911
+ type: Boolean
2912
+ },
2913
+
2914
+ errorMessage: {
2915
+ type: String,
2916
+ default: ''
2917
+ },
2918
+
2795
2919
  modelValue: {
2796
2920
  default: '',
2797
2921
  type: [String, Number]
2798
2922
  },
2799
2923
 
2800
- unmaskedValue: {
2801
- default: true,
2802
- type: Boolean
2803
- },
2804
-
2805
2924
  outlined: {
2806
2925
  default: true,
2807
2926
  type: Boolean
2808
2927
  },
2809
2928
 
2810
- removeErrorOnType: {
2929
+ unmaskedValue: {
2930
+ default: true,
2811
2931
  type: Boolean
2812
2932
  },
2813
2933
 
2814
- error: {
2934
+ useRemoveErrorOnType: {
2815
2935
  type: Boolean
2816
- },
2817
-
2818
- errorMessage: {
2819
- type: String,
2820
- default: ''
2821
2936
  }
2822
2937
  },
2823
2938
 
@@ -2862,7 +2977,7 @@
2862
2977
  },
2863
2978
 
2864
2979
  set (value) {
2865
- if (this.removeErrorOnType && this.error) {
2980
+ if (this.useRemoveErrorOnType && this.error) {
2866
2981
  this.errorData = false;
2867
2982
  this.errorMessageData = '';
2868
2983
  }
@@ -2874,7 +2989,7 @@
2874
2989
 
2875
2990
  watch: {
2876
2991
  mask () {
2877
- const input = this.inputReference.$el?.querySelector('input');
2992
+ const input = this.getInput();
2878
2993
 
2879
2994
  requestAnimationFrame(() => {
2880
2995
  input.selectionStart = input.value ? input.value.length : '';
@@ -2908,12 +3023,30 @@
2908
3023
  },
2909
3024
 
2910
3025
  toggleMask (first, second) {
3026
+ if (!this.modelValue?.length) return
3027
+
2911
3028
  const length = first.split('#').length - 2;
2912
3029
  return this.modelValue?.length > length ? second : first
2913
3030
  },
2914
3031
 
2915
3032
  validate (value) {
2916
3033
  return this.inputReference.validate(value)
3034
+ },
3035
+
3036
+ onPaste (event) {
3037
+ if (!this.mask) return
3038
+
3039
+ const value = event.clipboardData.getData('text');
3040
+ const input = this.getInput();
3041
+
3042
+ requestAnimationFrame(() => {
3043
+ this.$emit('update:modelValue', value);
3044
+ input.selectionStart = input.value ? input.value.length : '';
3045
+ });
3046
+ },
3047
+
3048
+ getInput () {
3049
+ return this.inputReference.$el?.querySelector('input')
2917
3050
  }
2918
3051
  }
2919
3052
  };
@@ -2921,29 +3054,28 @@
2921
3054
  function render$u(_ctx, _cache, $props, $setup, $data, $options) {
2922
3055
  const _component_q_input = vue.resolveComponent("q-input");
2923
3056
 
2924
- return (vue.openBlock(), vue.createElementBlock("div", null, [
2925
- vue.createVNode(_component_q_input, vue.mergeProps({
2926
- ref: "input",
2927
- modelValue: $options.model,
2928
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($options.model) = $event)),
2929
- "bottom-slots": "",
2930
- error: $data.errorData
2931
- }, _ctx.$attrs, {
2932
- "error-message": _ctx.errorMessageData,
2933
- mask: $options.mask,
2934
- outlined: $props.outlined,
2935
- "unmasked-value": $props.unmaskedValue
2936
- }), vue.createSlots({ _: 2 /* DYNAMIC */ }, [
2937
- vue.renderList(_ctx.$slots, (_, name) => {
2938
- return {
2939
- name: name,
2940
- fn: vue.withCtx((context) => [
2941
- vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(context || {})))
2942
- ])
2943
- }
2944
- })
2945
- ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["modelValue", "error", "error-message", "mask", "outlined", "unmasked-value"])
2946
- ]))
3057
+ return (vue.openBlock(), vue.createBlock(_component_q_input, vue.mergeProps({
3058
+ ref: "input",
3059
+ modelValue: $options.model,
3060
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($options.model) = $event)),
3061
+ "bottom-slots": "",
3062
+ error: $data.errorData
3063
+ }, _ctx.$attrs, {
3064
+ "error-message": _ctx.errorMessageData,
3065
+ mask: $options.mask,
3066
+ outlined: $props.outlined,
3067
+ "unmasked-value": $props.unmaskedValue,
3068
+ onPaste: $options.onPaste
3069
+ }), vue.createSlots({ _: 2 /* DYNAMIC */ }, [
3070
+ vue.renderList(_ctx.$slots, (_, name) => {
3071
+ return {
3072
+ name: name,
3073
+ fn: vue.withCtx((context) => [
3074
+ vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(context || {})))
3075
+ ])
3076
+ }
3077
+ })
3078
+ ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["modelValue", "error", "error-message", "mask", "outlined", "unmasked-value", "onPaste"]))
2947
3079
  }
2948
3080
 
2949
3081
  script$u.render = render$u;
@@ -2960,17 +3092,7 @@
2960
3092
  name: 'QasNumericInput',
2961
3093
 
2962
3094
  props: {
2963
- allowNegative: {
2964
- default: true,
2965
- type: Boolean
2966
- },
2967
-
2968
- allowPositive: {
2969
- default: true,
2970
- type: Boolean
2971
- },
2972
-
2973
- autonumericProps: {
3095
+ autonumericOptions: {
2974
3096
  default: () => ({}),
2975
3097
  type: Object
2976
3098
  },
@@ -3002,6 +3124,16 @@
3002
3124
  preset: {
3003
3125
  default: false,
3004
3126
  type: [Boolean, String]
3127
+ },
3128
+
3129
+ useNegative: {
3130
+ default: true,
3131
+ type: Boolean
3132
+ },
3133
+
3134
+ usePositive: {
3135
+ default: true,
3136
+ type: Boolean
3005
3137
  }
3006
3138
  },
3007
3139
 
@@ -3045,11 +3177,11 @@
3045
3177
  Object.assign(options, autoNumericPredefinedOptions[value]);
3046
3178
  }
3047
3179
 
3048
- if (!this.allowNegative) {
3180
+ if (!this.useNegative) {
3049
3181
  options.minimumValue = 0;
3050
3182
  }
3051
3183
 
3052
- if (!this.allowPositive) {
3184
+ if (!this.usePositive) {
3053
3185
  options.maximumValue = 0;
3054
3186
  }
3055
3187
 
@@ -3057,7 +3189,7 @@
3057
3189
  options.decimalPlaces = this.decimalPlaces;
3058
3190
  }
3059
3191
 
3060
- Object.assign(options, this.autonumericProps);
3192
+ Object.assign(options, this.autonumericOptions);
3061
3193
 
3062
3194
  this.$nextTick(() => {
3063
3195
  this.autoNumeric = new AutoNumeric__default["default"](this.$refs.input, options);
@@ -3087,7 +3219,7 @@
3087
3219
  }
3088
3220
  };
3089
3221
 
3090
- const _hoisted_1$j = ["id"];
3222
+ const _hoisted_1$k = ["id"];
3091
3223
 
3092
3224
  function render$t(_ctx, _cache, $props, $setup, $data, $options) {
3093
3225
  const _component_q_field = vue.resolveComponent("q-field");
@@ -3104,7 +3236,7 @@
3104
3236
  onBlur: _cache[0] || (_cache[0] = (...args) => ($options.emitValue && $options.emitValue(...args))),
3105
3237
  onClick: _cache[1] || (_cache[1] = (...args) => ($options.setSelect && $options.setSelect(...args))),
3106
3238
  onInput: _cache[2] || (_cache[2] = $event => ($options.emitUpdateModel($event.target.value)))
3107
- }, null, 40 /* PROPS, HYDRATE_EVENTS */, _hoisted_1$j), [
3239
+ }, null, 40 /* PROPS, HYDRATE_EVENTS */, _hoisted_1$k), [
3108
3240
  [vue.vShow, floatingLabel]
3109
3241
  ])
3110
3242
  ]),
@@ -3267,13 +3399,13 @@
3267
3399
  }
3268
3400
  };
3269
3401
 
3270
- const _hoisted_1$i = { key: 0 };
3402
+ const _hoisted_1$j = { key: 0 };
3271
3403
 
3272
3404
  function render$s(_ctx, _cache, $props, $setup, $data, $options) {
3273
3405
  const _component_q_linear_progress = vue.resolveComponent("q-linear-progress");
3274
3406
 
3275
3407
  return ($options.length)
3276
- ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$i, [
3408
+ ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$j, [
3277
3409
  vue.renderSlot(_ctx.$slots, "default", { level: $options.level }, () => [
3278
3410
  vue.createVNode(_component_q_linear_progress, {
3279
3411
  color: $options.level.color,
@@ -3300,8 +3432,11 @@
3300
3432
 
3301
3433
  mixins: [passwordMixin],
3302
3434
 
3435
+ inheritAttrs: false,
3436
+
3303
3437
  props: {
3304
- hideStrengthChecker: {
3438
+ useStrengthChecker: {
3439
+ default: true,
3305
3440
  type: Boolean
3306
3441
  },
3307
3442
 
@@ -3361,44 +3496,41 @@
3361
3496
  const _component_qas_password_strength_checker = vue.resolveComponent("qas-password-strength-checker");
3362
3497
  const _component_qas_input = vue.resolveComponent("qas-input");
3363
3498
 
3364
- return (vue.openBlock(), vue.createElementBlock("div", null, [
3365
- vue.createVNode(_component_qas_input, vue.mergeProps({
3366
- modelValue: $options.model,
3367
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($options.model) = $event)),
3368
- "bottom-slots": false,
3369
- color: "negative"
3370
- }, _ctx.$attrs, {
3371
- "remove-error-on-type": "",
3372
- type: $options.type
3373
- }), vue.createSlots({
3374
- append: vue.withCtx(() => [
3375
- vue.createVNode(_component_q_icon, {
3376
- class: "cursor-pointer",
3377
- color: $props.iconColor,
3378
- name: $options.icon,
3379
- onClick: $options.toggle
3380
- }, null, 8 /* PROPS */, ["color", "name", "onClick"])
3381
- ]),
3382
- _: 2 /* DYNAMIC */
3383
- }, [
3384
- vue.renderList(_ctx.$slots, (_, name) => {
3385
- return {
3386
- name: name,
3387
- fn: vue.withCtx((context) => [
3388
- vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(context || {})))
3499
+ return (vue.openBlock(), vue.createBlock(_component_qas_input, vue.mergeProps({
3500
+ modelValue: $options.model,
3501
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($options.model) = $event)),
3502
+ "bottom-slots": false
3503
+ }, _ctx.$attrs, {
3504
+ type: $options.type,
3505
+ "use-remove-error-on-type": ""
3506
+ }), vue.createSlots({
3507
+ append: vue.withCtx(() => [
3508
+ vue.createVNode(_component_q_icon, {
3509
+ class: "cursor-pointer",
3510
+ color: $props.iconColor,
3511
+ name: $options.icon,
3512
+ onClick: $options.toggle
3513
+ }, null, 8 /* PROPS */, ["color", "name", "onClick"])
3514
+ ]),
3515
+ _: 2 /* DYNAMIC */
3516
+ }, [
3517
+ vue.renderList(_ctx.$slots, (_, name) => {
3518
+ return {
3519
+ name: name,
3520
+ fn: vue.withCtx((context) => [
3521
+ vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(context || {})))
3522
+ ])
3523
+ }
3524
+ }),
3525
+ ($props.useStrengthChecker)
3526
+ ? {
3527
+ name: "hint",
3528
+ fn: vue.withCtx(() => [
3529
+ vue.createVNode(_component_qas_password_strength_checker, vue.mergeProps($options.strengthCheckerProps, { password: $options.model }), null, 16 /* FULL_PROPS */, ["password"])
3389
3530
  ])
3390
3531
  }
3391
- }),
3392
- (!$props.hideStrengthChecker)
3393
- ? {
3394
- name: "hint",
3395
- fn: vue.withCtx(() => [
3396
- vue.createVNode(_component_qas_password_strength_checker, vue.mergeProps($options.strengthCheckerProps, { password: $options.model }), null, 16 /* FULL_PROPS */, ["password"])
3397
- ])
3398
- }
3399
- : undefined
3400
- ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["modelValue", "type"])
3401
- ]))
3532
+ : undefined
3533
+ ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["modelValue", "type"]))
3402
3534
  }
3403
3535
 
3404
3536
  script$r.render = render$r;
@@ -3472,7 +3604,11 @@
3472
3604
 
3473
3605
  uploading: {
3474
3606
  type: Boolean
3475
- }
3607
+ },
3608
+
3609
+ useObjectModel: {
3610
+ type: Boolean
3611
+ }
3476
3612
  },
3477
3613
 
3478
3614
  emits: ['update:modelValue', 'update:uploading'],
@@ -3585,12 +3721,19 @@
3585
3721
  uploaded (response) {
3586
3722
  const fullPath = response.xhr.responseURL.split('?').shift();
3587
3723
 
3588
- this.$emit(
3589
- 'update:modelValue',
3590
- this.isMultiple ? [...this.modelValue, fullPath] : fullPath || ''
3591
- );
3724
+ const objectValue = {
3725
+ format: response.files[0].type,
3726
+ url: fullPath,
3727
+ name: response.files[0].name
3728
+ };
3729
+
3730
+ const model = this.useObjectModel ? objectValue : fullPath;
3731
+
3732
+ this.$emit('update:modelValue', this.isMultiple ? [...this.modelValue, model] : model || '');
3592
3733
 
3593
3734
  this.updateUploading(false);
3735
+
3736
+ this.$qas.logger.group('QasUploader - uploaded', [this.modelValue]);
3594
3737
  },
3595
3738
 
3596
3739
  async fetchCredentials (filename) {
@@ -3601,6 +3744,12 @@
3601
3744
  entity: this.entity,
3602
3745
  filename
3603
3746
  });
3747
+
3748
+ this.$qas.logger.group(
3749
+ 'QasUploader - fetchCredentials -> resposta de /upload-credentials/',
3750
+ [data]
3751
+ );
3752
+
3604
3753
  return data
3605
3754
  } finally {
3606
3755
  this.isFetching = false;
@@ -3619,8 +3768,16 @@
3619
3768
  }
3620
3769
 
3621
3770
  const clonedValue = quasar.extend(true, [], this.modelValue);
3622
- const numberIndex = this.modelValue.findIndex(file => this.getFileName(file) === index);
3771
+ const numberIndex = this.modelValue.findIndex(file => {
3772
+ if (this.useObjectModel) {
3773
+ return file.uuid === index || file.url.includes(index)
3774
+ }
3775
+
3776
+ return this.getFileName(file) === index
3777
+ });
3778
+
3623
3779
  clonedValue.splice(numberIndex, 1);
3780
+
3624
3781
  this.$emit('update:modelValue', clonedValue);
3625
3782
  },
3626
3783
 
@@ -3629,12 +3786,10 @@
3629
3786
  },
3630
3787
 
3631
3788
  getFilesList (uploadedFiles) {
3632
- const pathsList = Array.isArray(this.modelValue) ? this.modelValue : (this.modelValue ? [this.modelValue] : []);
3633
-
3634
3789
  uploadedFiles = uploadedFiles.map((file, indexToDelete) => {
3635
3790
  return {
3636
3791
  isUploaded: true,
3637
- image: file.xhr ? file.xhr.responseURL.split('?').shift() : '',
3792
+ url: file.xhr ? file.xhr.responseURL.split('?').shift() : '',
3638
3793
  name: file.name,
3639
3794
  progressLabel: file.__progressLabel,
3640
3795
  sizeLabel: file.__sizeLabel,
@@ -3643,11 +3798,20 @@
3643
3798
  }
3644
3799
  });
3645
3800
 
3801
+ const pathsList = Array.isArray(this.modelValue)
3802
+ ? this.modelValue
3803
+ : (this.modelValue ? [this.modelValue] : []);
3804
+
3646
3805
  const mergedList = [...pathsList, ...uploadedFiles];
3647
3806
 
3648
3807
  const files = {};
3649
3808
 
3650
3809
  mergedList.forEach(file => {
3810
+ if (this.useObjectModel && file.uuid) {
3811
+ files[file.uuid] = file;
3812
+ return
3813
+ }
3814
+
3651
3815
  if (file.isFailed) {
3652
3816
  files[file.name] = file;
3653
3817
  return
@@ -3655,16 +3819,18 @@
3655
3819
 
3656
3820
  if (typeof file === 'string') {
3657
3821
  const fileName = this.getFileName(file);
3658
- files[fileName] = { image: file, isUploaded: false, name: fileName };
3822
+ files[fileName] = { url: file, isUploaded: false, name: fileName };
3659
3823
  return
3660
3824
  }
3661
3825
 
3662
- if (file.image) {
3663
- const fileName = this.getFileName(file.image);
3826
+ if (file.url) {
3827
+ const fileName = this.getFileName(file.url);
3664
3828
  files[fileName] = file;
3665
3829
  }
3666
3830
  });
3667
3831
 
3832
+ this.$qas.logger.group('QasUploader - getFilesList', [files]);
3833
+
3668
3834
  return files
3669
3835
  },
3670
3836
 
@@ -3684,6 +3850,8 @@
3684
3850
  const filesList = Array.from(this.hiddenInputElement.files);
3685
3851
  const processedFiles = [];
3686
3852
 
3853
+ this.$refs.hiddenInput.value = '';
3854
+
3687
3855
  filesList.forEach(file => processedFiles.push(this.resizeImage(file)));
3688
3856
  this.uploader.addFiles(await Promise.all(processedFiles));
3689
3857
  },
@@ -3703,7 +3871,14 @@
3703
3871
  // Retorna largura e altura da original da imagem
3704
3872
  const { width, height } = await getImageSize(image);
3705
3873
 
3706
- if (width <= this.sizeLimit) return file
3874
+ if (width <= this.sizeLimit) {
3875
+ this.$qas.logger.info(`
3876
+ QasUploader - resizeImage -> Tamanho da imagem menor que o tamanho limite,
3877
+ sendo assim, não faz o resize
3878
+ `);
3879
+
3880
+ return file
3881
+ }
3707
3882
 
3708
3883
  // Retorna os novos tamanhos redimensionados
3709
3884
  const resizedDimensions = getResizeDimensions(this.sizeLimit, width, height);
@@ -3721,7 +3896,11 @@
3721
3896
  const resizedImage = await pica.resize(image, canvas, this.defaultPicaResizeOptions);
3722
3897
  const blob = await pica.toBlob(resizedImage, type, 0.90);
3723
3898
 
3724
- return new File([blob], file.name, { type })
3899
+ const newFile = new File([blob], file.name, { type });
3900
+
3901
+ this.$qas.logger.group('QasUploader - resizeImage -> nova imagem', [newFile]);
3902
+
3903
+ return newFile
3725
3904
  } catch {
3726
3905
  // Caso não consiga redimensionar retorna o arquivo original
3727
3906
  return file
@@ -3734,7 +3913,7 @@
3734
3913
  }
3735
3914
  };
3736
3915
 
3737
- const _hoisted_1$h = { class: "flex flex-center full-width justify-between no-border no-wrap q-gutter-xs q-pa-sm text-white transparent" };
3916
+ const _hoisted_1$i = { class: "flex flex-center full-width justify-between no-border no-wrap q-gutter-xs q-pa-sm text-white transparent" };
3738
3917
  const _hoisted_2$d = { class: "col column items-start justify-center" };
3739
3918
  const _hoisted_3$9 = {
3740
3919
  key: 0,
@@ -3744,7 +3923,7 @@
3744
3923
  key: 1,
3745
3924
  class: "q-uploader__subtitle"
3746
3925
  };
3747
- const _hoisted_5$5 = ["multiple"];
3926
+ const _hoisted_5$5 = ["accept", "multiple"];
3748
3927
  const _hoisted_6$3 = { class: "col-12 q-col-gutter-md row" };
3749
3928
  const _hoisted_7$3 = { class: "col items-center no-wrap row" };
3750
3929
  const _hoisted_8$2 = {
@@ -3787,7 +3966,7 @@
3787
3966
  }), {
3788
3967
  header: vue.withCtx((scope) => [
3789
3968
  vue.renderSlot(_ctx.$slots, "header", { scope: scope }, () => [
3790
- vue.createElementVNode("div", _hoisted_1$h, [
3969
+ vue.createElementVNode("div", _hoisted_1$i, [
3791
3970
  (scope.isUploading)
3792
3971
  ? (vue.openBlock(), vue.createBlock(_component_q_spinner, {
3793
3972
  key: 0,
@@ -3816,6 +3995,7 @@
3816
3995
  : vue.createCommentVNode("v-if", true),
3817
3996
  vue.createElementVNode("input", {
3818
3997
  ref: "hiddenInput",
3998
+ accept: $options.attributes.accept,
3819
3999
  class: "qas-uploader__input",
3820
4000
  multiple: $options.isMultiple,
3821
4001
  type: "file"
@@ -3863,7 +4043,7 @@
3863
4043
  class: "q-mr-sm",
3864
4044
  color: "contrast-primary",
3865
4045
  icon: "o_attach_file",
3866
- image: file.image,
4046
+ image: file.url,
3867
4047
  rounded: "",
3868
4048
  "text-color": $options.getColorFileIcon(file)
3869
4049
  }, null, 8 /* PROPS */, ["image", "text-color"]),
@@ -4024,7 +4204,7 @@
4024
4204
  }
4025
4205
  };
4026
4206
 
4027
- const _hoisted_1$g = {
4207
+ const _hoisted_1$h = {
4028
4208
  ref: "signatureContainer",
4029
4209
  class: "qas-signature-pad relative-position"
4030
4210
  };
@@ -4034,7 +4214,7 @@
4034
4214
  const _component_qas_btn = vue.resolveComponent("qas-btn");
4035
4215
 
4036
4216
  return (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
4037
- vue.createElementVNode("div", _hoisted_1$g, [
4217
+ vue.createElementVNode("div", _hoisted_1$h, [
4038
4218
  vue.createElementVNode("canvas", {
4039
4219
  id: $data.canvasId,
4040
4220
  ref: _ctx.$attrs.ref,
@@ -4069,6 +4249,7 @@
4069
4249
  name: 'QasSignatureUploader',
4070
4250
 
4071
4251
  components: {
4252
+ QasBtn: script$K,
4072
4253
  QasDialog: script$x,
4073
4254
  QasUploader: script$q,
4074
4255
  QasSignaturePad: script$p
@@ -4197,7 +4378,7 @@
4197
4378
  }
4198
4379
  };
4199
4380
 
4200
- const _hoisted_1$f = { class: "col column items-start justify-center" };
4381
+ const _hoisted_1$g = { class: "col column items-start justify-center" };
4201
4382
  const _hoisted_2$b = {
4202
4383
  key: 0,
4203
4384
  class: "q-uploader__title"
@@ -4205,7 +4386,7 @@
4205
4386
  const _hoisted_3$8 = /*#__PURE__*/vue.createElementVNode("div", { class: "text-bold text-center" }, "Insira sua assinatura digital no campo abaixo", -1 /* HOISTED */);
4206
4387
 
4207
4388
  function render$o(_ctx, _cache, $props, $setup, $data, $options) {
4208
- const _component_q_btn = vue.resolveComponent("q-btn");
4389
+ const _component_qas_btn = vue.resolveComponent("qas-btn");
4209
4390
  const _component_qas_uploader = vue.resolveComponent("qas-uploader");
4210
4391
  const _component_qas_signature_pad = vue.resolveComponent("qas-signature-pad");
4211
4392
  const _component_qas_dialog = vue.resolveComponent("qas-dialog");
@@ -4224,14 +4405,15 @@
4224
4405
  class: vue.normalizeClass(["cursor-pointer flex flex-center full-width justify-between no-border no-wrap q-gutter-xs text-white transparent", $options.headerClass]),
4225
4406
  onClick: _cache[0] || (_cache[0] = (...args) => ($options.openDialog && $options.openDialog(...args)))
4226
4407
  }, [
4227
- vue.createElementVNode("div", _hoisted_1$f, [
4408
+ vue.createElementVNode("div", _hoisted_1$g, [
4228
4409
  ($props.uploadLabel)
4229
4410
  ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$b, vue.toDisplayString($props.uploadLabel), 1 /* TEXT */))
4230
4411
  : vue.createCommentVNode("v-if", true)
4231
4412
  ]),
4232
4413
  (!$props.readonly)
4233
- ? (vue.openBlock(), vue.createBlock(_component_q_btn, {
4414
+ ? (vue.openBlock(), vue.createBlock(_component_qas_btn, {
4234
4415
  key: 0,
4416
+ color: "white",
4235
4417
  dense: "",
4236
4418
  flat: "",
4237
4419
  icon: "o_add",
@@ -4239,12 +4421,12 @@
4239
4421
  onClick: $options.openDialog
4240
4422
  }, null, 8 /* PROPS */, ["onClick"]))
4241
4423
  : vue.createCommentVNode("v-if", true),
4242
- vue.createVNode(_component_q_btn, {
4424
+ vue.createVNode(_component_qas_btn, {
4243
4425
  ref: "forceUpload",
4244
4426
  class: "hidden",
4245
4427
  onClick: $event => ($options.upload(scope))
4246
4428
  }, null, 8 /* PROPS */, ["onClick"]),
4247
- vue.createVNode(_component_q_btn, {
4429
+ vue.createVNode(_component_qas_btn, {
4248
4430
  ref: "buttonCleanFiles",
4249
4431
  class: "hidden",
4250
4432
  onClick: scope.removeUploadedFiles
@@ -4273,7 +4455,7 @@
4273
4455
  ], 4 /* STYLE */)
4274
4456
  ]),
4275
4457
  actions: vue.withCtx(() => [
4276
- vue.createVNode(_component_q_btn, {
4458
+ vue.createVNode(_component_qas_btn, {
4277
4459
  class: "full-width",
4278
4460
  color: "primary",
4279
4461
  disable: $data.isEmpty,
@@ -4281,7 +4463,7 @@
4281
4463
  "no-caps": "",
4282
4464
  onClick: $options.getSignatureData
4283
4465
  }, null, 8 /* PROPS */, ["disable", "onClick"]),
4284
- vue.createVNode(_component_q_btn, {
4466
+ vue.createVNode(_component_qas_btn, {
4285
4467
  class: "full-width q-mt-sm",
4286
4468
  color: "primary",
4287
4469
  flat: "",
@@ -4317,6 +4499,8 @@
4317
4499
  QasSignatureUploader: script$o
4318
4500
  },
4319
4501
 
4502
+ inheritAttrs: false,
4503
+
4320
4504
  props: {
4321
4505
  error: {
4322
4506
  default: '',
@@ -4356,8 +4540,9 @@
4356
4540
  type,
4357
4541
  mask,
4358
4542
  maxFiles,
4359
- searchable,
4360
- gmt
4543
+ useIso,
4544
+ useSearch,
4545
+ useLazyLoading
4361
4546
  } = this.formattedField;
4362
4547
 
4363
4548
  // Default error attributes for Quasar.
@@ -4379,11 +4564,11 @@
4379
4564
  minlength,
4380
4565
  suffix,
4381
4566
  prefix,
4382
- gmt
4567
+ useIso
4383
4568
  };
4384
4569
 
4385
4570
  const numericInput = { is: 'qas-numeric-input', ...input };
4386
- const datetimeInput = { is: 'qas-date-time-input', gmt, ...input };
4571
+ const datetimeInput = { is: 'qas-date-time-input', useIso, ...input };
4387
4572
 
4388
4573
  // It'll generate a list of acceptable files extensions.
4389
4574
  const accept = extensions && extensions.length ? extensions.map(extension => `.${extension}`).join(',') : '';
@@ -4411,9 +4596,9 @@
4411
4596
  money: { ...numericInput, mode: 'money' },
4412
4597
  percent: { ...numericInput, mode: 'percent' },
4413
4598
 
4414
- date: { ...datetimeInput, dateOnly: true },
4599
+ date: { ...datetimeInput, useDateOnly: true },
4415
4600
  datetime: { ...datetimeInput },
4416
- time: { ...datetimeInput, timeOnly: true },
4601
+ time: { ...datetimeInput, useTimeOnly: true },
4417
4602
 
4418
4603
  boolean: { is: 'q-toggle', label, ...error },
4419
4604
  checkbox: { is: 'qas-checkbox-group', label, options, ...error },
@@ -4424,7 +4609,7 @@
4424
4609
 
4425
4610
  'signature-uploader': { is: 'qas-signature-uploader', entity, uploadLabel: label, ...error },
4426
4611
 
4427
- select: { is: 'qas-select', multiple, options, searchable, ...input }
4612
+ select: { is: 'qas-select', entity, name, multiple, options, useSearch, useLazyLoading, ...input }
4428
4613
  };
4429
4614
 
4430
4615
  return { ...(profiles[type] || profiles.default), ...this.$attrs }
@@ -4486,22 +4671,20 @@
4486
4671
  };
4487
4672
 
4488
4673
  function render$n(_ctx, _cache, $props, $setup, $data, $options) {
4489
- return (vue.openBlock(), vue.createElementBlock("div", null, [
4490
- (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($options.component.is), vue.mergeProps($options.component, {
4491
- "data-cy": $props.field.name,
4492
- "model-value": $options.formattedValue,
4493
- "onUpdate:modelValue": $options.updateModel
4494
- }), vue.createSlots({ _: 2 /* DYNAMIC */ }, [
4495
- vue.renderList(_ctx.$slots, (_, name) => {
4496
- return {
4497
- name: name,
4498
- fn: vue.withCtx((context) => [
4499
- vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(context || {})))
4500
- ])
4501
- }
4502
- })
4503
- ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["data-cy", "model-value", "onUpdate:modelValue"]))
4504
- ]))
4674
+ return (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($options.component.is), vue.mergeProps($options.component, {
4675
+ "data-cy": $props.field.name,
4676
+ "model-value": $options.formattedValue,
4677
+ "onUpdate:modelValue": $options.updateModel
4678
+ }), vue.createSlots({ _: 2 /* DYNAMIC */ }, [
4679
+ vue.renderList(_ctx.$slots, (_, name) => {
4680
+ return {
4681
+ name: name,
4682
+ fn: vue.withCtx((context) => [
4683
+ vue.renderSlot(_ctx.$slots, name, vue.normalizeProps(vue.guardReactiveProps(context || {})))
4684
+ ])
4685
+ }
4686
+ })
4687
+ ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["data-cy", "model-value", "onUpdate:modelValue"]))
4505
4688
  }
4506
4689
 
4507
4690
  script$n.render = render$n;
@@ -4520,6 +4703,7 @@
4520
4703
  name: 'QasFilters',
4521
4704
 
4522
4705
  components: {
4706
+ QasBtn: script$K,
4523
4707
  QasField: script$n
4524
4708
  },
4525
4709
 
@@ -4561,7 +4745,7 @@
4561
4745
  type: String
4562
4746
  },
4563
4747
 
4564
- forceRefetch: {
4748
+ useForceRefetch: {
4565
4749
  type: Boolean
4566
4750
  }
4567
4751
  },
@@ -4692,7 +4876,7 @@
4692
4876
  },
4693
4877
 
4694
4878
  async fetchFilters () {
4695
- if (!this.forceRefetch && (this.hasFields || !this.useFilterButton)) {
4879
+ if (!this.useForceRefetch && (this.hasFields || !this.useFilterButton)) {
4696
4880
  return null
4697
4881
  }
4698
4882
 
@@ -4700,11 +4884,26 @@
4700
4884
  this.isFetching = true;
4701
4885
 
4702
4886
  try {
4887
+ this.$qas.logger.group(
4888
+ `QasFilters - fetchFilters -> Payload do parâmetro do ${this.entity}/fetchFilters`,
4889
+ [{ url: this.url }]
4890
+ );
4891
+
4703
4892
  const response = await this.$store.dispatch(`${this.entity}/fetchFilters`, { url: this.url });
4704
4893
  this.$emit('fetch-success', response);
4894
+
4895
+ this.$qas.logger.group(
4896
+ `QasFilters - fetchFilters -> resposta da action ${this.entity}/fetchFilters`, [response]
4897
+ );
4705
4898
  } catch (error) {
4706
4899
  this.hasFetchError = true;
4707
4900
  this.$emit('fetch-error', error);
4901
+
4902
+ this.$qas.logger.group(
4903
+ `QasFilters - fetchFilters -> exceção da action ${this.entity}/fetchFilters`,
4904
+ [error],
4905
+ { error: true }
4906
+ );
4708
4907
  } finally {
4709
4908
  this.isFetching = false;
4710
4909
  }
@@ -4763,7 +4962,7 @@
4763
4962
  }
4764
4963
  };
4765
4964
 
4766
- const _hoisted_1$e = { class: "q-mb-lg" };
4965
+ const _hoisted_1$f = { class: "q-mb-lg" };
4767
4966
  const _hoisted_2$a = {
4768
4967
  key: 0,
4769
4968
  class: "q-gutter-x-md row"
@@ -4787,8 +4986,8 @@
4787
4986
  };
4788
4987
 
4789
4988
  function render$m(_ctx, _cache, $props, $setup, $data, $options) {
4790
- const _component_q_btn = vue.resolveComponent("q-btn");
4791
- const _component_q_input = vue.resolveComponent("q-input");
4989
+ const _component_qas_btn = vue.resolveComponent("qas-btn");
4990
+ const _component_qas_input = vue.resolveComponent("qas-input");
4792
4991
  const _component_q_form = vue.resolveComponent("q-form");
4793
4992
  const _component_q_spinner = vue.resolveComponent("q-spinner");
4794
4993
  const _component_q_icon = vue.resolveComponent("q-icon");
@@ -4796,7 +4995,7 @@
4796
4995
  const _component_q_menu = vue.resolveComponent("q-menu");
4797
4996
  const _component_q_chip = vue.resolveComponent("q-chip");
4798
4997
 
4799
- return (vue.openBlock(), vue.createElementBlock("section", _hoisted_1$e, [
4998
+ return (vue.openBlock(), vue.createElementBlock("section", _hoisted_1$f, [
4800
4999
  ($options.showFilters)
4801
5000
  ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$a, [
4802
5001
  ($options.showSearch)
@@ -4808,26 +5007,32 @@
4808
5007
  onSubmit: _cache[2] || (_cache[2] = vue.withModifiers($event => ($options.filter()), ["prevent"]))
4809
5008
  }, {
4810
5009
  default: vue.withCtx(() => [
4811
- vue.createVNode(_component_q_input, {
5010
+ vue.createVNode(_component_qas_input, {
4812
5011
  modelValue: $data.search,
4813
5012
  "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($data.search) = $event)),
4814
5013
  debounce: $options.debounce,
4815
5014
  dense: "",
5015
+ "hide-bottom-space": "",
5016
+ outlined: false,
4816
5017
  placeholder: $props.searchPlaceholder,
4817
5018
  type: "search"
4818
5019
  }, {
4819
5020
  append: vue.withCtx(() => [
4820
5021
  ($options.hasSearch)
4821
- ? (vue.openBlock(), vue.createBlock(_component_q_btn, {
5022
+ ? (vue.openBlock(), vue.createBlock(_component_qas_btn, {
4822
5023
  key: 0,
5024
+ color: "grey-9",
5025
+ flat: "",
4823
5026
  icon: "o_clear",
4824
5027
  unelevated: "",
4825
5028
  onClick: $options.clearSearch
4826
5029
  }, null, 8 /* PROPS */, ["onClick"]))
4827
5030
  : vue.createCommentVNode("v-if", true),
4828
5031
  (!$options.debounce)
4829
- ? (vue.openBlock(), vue.createBlock(_component_q_btn, {
5032
+ ? (vue.openBlock(), vue.createBlock(_component_qas_btn, {
4830
5033
  key: 1,
5034
+ color: "grey-9",
5035
+ flat: "",
4831
5036
  icon: "o_search",
4832
5037
  type: "submit",
4833
5038
  unelevated: "",
@@ -4850,7 +5055,7 @@
4850
5055
  filter: $options.filter
4851
5056
  }, () => [
4852
5057
  ($props.useFilterButton)
4853
- ? (vue.openBlock(), vue.createBlock(_component_q_btn, {
5058
+ ? (vue.openBlock(), vue.createBlock(_component_qas_btn, {
4854
5059
  key: 0,
4855
5060
  color: $options.filterButtonColor,
4856
5061
  flat: "",
@@ -4895,16 +5100,19 @@
4895
5100
  ]))
4896
5101
  }), 128 /* KEYED_FRAGMENT */)),
4897
5102
  vue.createElementVNode("div", _hoisted_6$2, [
4898
- vue.createVNode(_component_q_btn, {
5103
+ vue.createVNode(_component_qas_btn, {
4899
5104
  class: "q-mr-sm",
5105
+ flat: "",
4900
5106
  label: "Limpar",
5107
+ "no-caps": false,
4901
5108
  size: "12px",
4902
5109
  unelevated: "",
4903
5110
  onClick: $options.clearFilters
4904
5111
  }, null, 8 /* PROPS */, ["onClick"]),
4905
- vue.createVNode(_component_q_btn, {
5112
+ vue.createVNode(_component_qas_btn, {
4906
5113
  color: "primary",
4907
5114
  label: "Filtrar",
5115
+ "no-caps": false,
4908
5116
  size: "12px",
4909
5117
  type: "submit",
4910
5118
  unelevated: ""
@@ -4973,7 +5181,9 @@
4973
5181
  gutter: {
4974
5182
  default: 'md',
4975
5183
  type: [String, Boolean],
4976
- validator: value => ['xs', 'sm', 'md', 'lg', 'xl'].includes(value)
5184
+ validator: value => {
5185
+ return typeof value === 'boolean' || ['xs', 'sm', 'md', 'lg', 'xl'].includes(value)
5186
+ }
4977
5187
  }
4978
5188
  },
4979
5189
 
@@ -5022,7 +5232,13 @@
5022
5232
  },
5023
5233
 
5024
5234
  mx_handleColumnsByIndex (index, isGridGenerator) {
5025
- const fields = isGridGenerator ? this.fields : this.groupedFields.visible;
5235
+ const fields = isGridGenerator ? this.fields : {};
5236
+
5237
+ if (!isGridGenerator) {
5238
+ for (const key in this.normalizedFields) {
5239
+ Object.assign(fields, this.normalizedFields[key].fields.visible);
5240
+ }
5241
+ }
5026
5242
 
5027
5243
  if (!Array.isArray(fields)) {
5028
5244
  index = Object.keys(fields).findIndex(field => field === index);
@@ -5072,6 +5288,19 @@
5072
5288
  default: () => ({}),
5073
5289
  required: true,
5074
5290
  type: Object
5291
+ },
5292
+
5293
+ fieldset: {
5294
+ default: () => ({}),
5295
+ type: Object
5296
+ },
5297
+
5298
+ fieldsetGutter: {
5299
+ default: 'lg',
5300
+ type: [String, Boolean],
5301
+ validator: value => {
5302
+ return typeof value === 'boolean' || ['xs', 'sm', 'md', 'lg', 'xl'].includes(value)
5303
+ }
5075
5304
  }
5076
5305
  },
5077
5306
 
@@ -5081,6 +5310,8 @@
5081
5310
  groupedFields () {
5082
5311
  const fields = { hidden: {}, visible: {} };
5083
5312
 
5313
+ if (this.hasFieldset) return fields
5314
+
5084
5315
  for (const key in this.fields) {
5085
5316
  const field = this.fields[key];
5086
5317
  fields[field.type === 'hidden' ? 'hidden' : 'visible'][key] = field;
@@ -5097,6 +5328,58 @@
5097
5328
  }
5098
5329
 
5099
5330
  return fields
5331
+ },
5332
+
5333
+ normalizedFields () {
5334
+ if (!this.hasFieldset) {
5335
+ return {
5336
+ default: {
5337
+ fields: this.groupedFields
5338
+ }
5339
+ }
5340
+ }
5341
+
5342
+ const fields = {};
5343
+
5344
+ for (const fieldsetKey in this.fieldset) {
5345
+ const fieldsetItem = this.fieldset[fieldsetKey];
5346
+
5347
+ fields[fieldsetKey] = {
5348
+ label: fieldsetItem.label,
5349
+ fields: { hidden: {}, visible: {} }
5350
+ };
5351
+
5352
+ for (const fieldName of fieldsetItem.fields) {
5353
+ const field = this.fields[fieldName];
5354
+
5355
+ if (!field) continue
5356
+
5357
+ Object.assign(
5358
+ fields[fieldsetKey].fields[
5359
+ field.type === 'hidden' ? 'hidden' : 'visible'
5360
+ ],
5361
+ {
5362
+ [fieldName]: field
5363
+ }
5364
+ );
5365
+ }
5366
+ }
5367
+
5368
+ return fields
5369
+ },
5370
+
5371
+ hasFieldset () {
5372
+ return !!Object.keys(this.fieldset).length
5373
+ },
5374
+
5375
+ fieldsetClasses () {
5376
+ const classes = ['row'];
5377
+
5378
+ if (this.fieldsetGutter) {
5379
+ classes.push(`q-col-gutter-y-${this.fieldsetGutter}`);
5380
+ }
5381
+
5382
+ return classes
5100
5383
  }
5101
5384
  },
5102
5385
 
@@ -5111,51 +5394,290 @@
5111
5394
  };
5112
5395
 
5113
5396
  function render$l(_ctx, _cache, $props, $setup, $data, $options) {
5397
+ const _component_qas_label = vue.resolveComponent("qas-label");
5114
5398
  const _component_qas_field = vue.resolveComponent("qas-field");
5115
5399
 
5116
- return (vue.openBlock(), vue.createElementBlock("div", null, [
5117
- vue.createElementVNode("div", {
5118
- class: vue.normalizeClass(_ctx.mx_classes)
5119
- }, [
5120
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($options.groupedFields.visible, (field, key) => {
5121
- return (vue.openBlock(), vue.createElementBlock("div", {
5122
- key: key,
5123
- class: vue.normalizeClass(_ctx.mx_getFieldClass(key))
5124
- }, [
5125
- vue.renderSlot(_ctx.$slots, `field-${field.name}`, { field: field }, () => [
5126
- vue.createVNode(_component_qas_field, vue.mergeProps($props.fieldsProps[field.name], {
5127
- error: $props.errors[key],
5128
- field: field,
5129
- "model-value": $props.modelValue[field.name],
5130
- "onUpdate:modelValue": $event => ($options.updateModelValue(field.name, $event))
5131
- }), null, 16 /* FULL_PROPS */, ["error", "field", "model-value", "onUpdate:modelValue"])
5132
- ])
5133
- ], 2 /* CLASS */))
5134
- }), 128 /* KEYED_FRAGMENT */))
5135
- ], 2 /* CLASS */),
5136
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($options.groupedFields.hidden, (field, key) => {
5137
- return (vue.openBlock(), vue.createElementBlock("div", { key: key }, [
5138
- vue.renderSlot(_ctx.$slots, `field-${field.name}`, { field: field }, () => [
5139
- vue.createVNode(_component_qas_field, vue.mergeProps($props.fieldsProps[field.name], {
5140
- field: field,
5141
- "model-value": $props.modelValue[field.name],
5142
- "onUpdate:modelValue": $event => ($options.updateModelValue(field.name, $event))
5143
- }), null, 16 /* FULL_PROPS */, ["field", "model-value", "onUpdate:modelValue"])
5400
+ return (vue.openBlock(), vue.createElementBlock("div", {
5401
+ class: vue.normalizeClass($options.fieldsetClasses)
5402
+ }, [
5403
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($options.normalizedFields, (fieldsetItem, fieldsetItemKey) => {
5404
+ return (vue.openBlock(), vue.createElementBlock("div", {
5405
+ key: fieldsetItemKey,
5406
+ class: "full-width"
5407
+ }, [
5408
+ (fieldsetItem.label)
5409
+ ? vue.renderSlot(_ctx.$slots, `legend-${fieldsetItemKey}`, { key: 0 }, () => [
5410
+ vue.createVNode(_component_qas_label, {
5411
+ label: fieldsetItem.label
5412
+ }, null, 8 /* PROPS */, ["label"])
5413
+ ])
5414
+ : vue.createCommentVNode("v-if", true),
5415
+ vue.createElementVNode("div", null, [
5416
+ vue.createElementVNode("div", {
5417
+ class: vue.normalizeClass(_ctx.mx_classes)
5418
+ }, [
5419
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(fieldsetItem.fields.visible, (field, key) => {
5420
+ return (vue.openBlock(), vue.createElementBlock("div", {
5421
+ key: key,
5422
+ class: vue.normalizeClass(_ctx.mx_getFieldClass(key))
5423
+ }, [
5424
+ vue.renderSlot(_ctx.$slots, `field-${field.name}`, { field: field }, () => [
5425
+ vue.createVNode(_component_qas_field, vue.mergeProps($props.fieldsProps[field.name], {
5426
+ error: $props.errors[key],
5427
+ field: field,
5428
+ "model-value": $props.modelValue[field.name],
5429
+ "onUpdate:modelValue": $event => ($options.updateModelValue(field.name, $event))
5430
+ }), null, 16 /* FULL_PROPS */, ["error", "field", "model-value", "onUpdate:modelValue"])
5431
+ ])
5432
+ ], 2 /* CLASS */))
5433
+ }), 128 /* KEYED_FRAGMENT */))
5434
+ ], 2 /* CLASS */),
5435
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(fieldsetItem.fields.hidden, (field, key) => {
5436
+ return (vue.openBlock(), vue.createElementBlock("div", { key: key }, [
5437
+ vue.renderSlot(_ctx.$slots, `field-${field.name}`, { field: field }, () => [
5438
+ vue.createVNode(_component_qas_field, vue.mergeProps($props.fieldsProps[field.name], {
5439
+ field: field,
5440
+ "model-value": $props.modelValue[field.name],
5441
+ "onUpdate:modelValue": $event => ($options.updateModelValue(field.name, $event))
5442
+ }), null, 16 /* FULL_PROPS */, ["field", "model-value", "onUpdate:modelValue"])
5443
+ ])
5444
+ ]))
5445
+ }), 128 /* KEYED_FRAGMENT */))
5144
5446
  ])
5145
5447
  ]))
5146
5448
  }), 128 /* KEYED_FRAGMENT */))
5147
- ]))
5449
+ ], 2 /* CLASS */))
5148
5450
  }
5149
5451
 
5150
5452
  script$l.render = render$l;
5151
5453
  script$l.__file = "src/components/form-generator/QasFormGenerator.vue";
5152
5454
 
5153
- var viewMixin = {
5455
+ var searchFilterMixin = {
5154
5456
  props: {
5155
- dialog: {
5457
+ entity: {
5458
+ default: '',
5459
+ type: String
5460
+ },
5461
+
5462
+ lazyLoadingProps: {
5463
+ default: () => ({}),
5464
+ type: Object
5465
+ },
5466
+
5467
+ name: {
5468
+ default: '',
5469
+ type: String
5470
+ },
5471
+
5472
+ useLazyLoading: {
5473
+ type: Boolean
5474
+ },
5475
+
5476
+ fetching: {
5156
5477
  type: Boolean
5478
+ }
5479
+ },
5480
+
5481
+ emits: [
5482
+ 'update:modelValue',
5483
+ 'update:fetching',
5484
+ 'fetch-options-success',
5485
+ 'fetch-options-error'
5486
+ ],
5487
+
5488
+ data () {
5489
+ return {
5490
+ mx_filteredOptions: [],
5491
+ mx_hasFetchError: false,
5492
+ mx_isFetching: false,
5493
+ mx_isScrolling: false,
5494
+ mx_search: '',
5495
+ mx_fetchCount: 0,
5496
+ mx_pagination: {
5497
+ page: 1,
5498
+ lastPage: null,
5499
+ hasCount: true,
5500
+ hasNextPage: false
5501
+ }
5502
+ }
5503
+ },
5504
+
5505
+ computed: {
5506
+ mx_defaultLazyLoadingProps () {
5507
+ const {
5508
+ url,
5509
+ params,
5510
+ decamelizeFieldName
5511
+ } = this.lazyLoadingProps;
5512
+
5513
+ const defaultParams = { limit: 48 };
5514
+
5515
+ return {
5516
+ url: url || '',
5517
+ params: {
5518
+ ...defaultParams,
5519
+ ...params
5520
+ },
5521
+ decamelizeFieldName: decamelizeFieldName === undefined ? true : decamelizeFieldName
5522
+ }
5523
+ },
5524
+
5525
+ mx_hasFilteredOptions () {
5526
+ return !!this.mx_filteredOptions.length
5527
+ },
5528
+
5529
+ mx_isFilterByFuse () {
5530
+ return !this.useLazyLoading
5531
+ }
5532
+ },
5533
+
5534
+ watch: {
5535
+ lazyLoadingProps: {
5536
+ handler (value, oldValue) {
5537
+ if (lodash.isEqual(value, oldValue)) return
5538
+
5539
+ this.mx_filterOptionsByStore('');
5540
+ this.$emit('update:modelValue', '');
5541
+ }
5542
+ }
5543
+ },
5544
+
5545
+ methods: {
5546
+ async mx_filterOptionsByStore (search) {
5547
+ this.mx_resetFilter(search);
5548
+ await this.mx_setFetchOptions();
5549
+ },
5550
+
5551
+ mx_resetFilter (search) {
5552
+ this.mx_filteredOptions = [];
5553
+ this.mx_search = search;
5554
+ this.mx_pagination = {
5555
+ page: 1,
5556
+ lastPage: null,
5557
+ hasCount: true,
5558
+ hasNextPage: false
5559
+ };
5157
5560
  },
5158
5561
 
5562
+ async mx_onVirtualScroll ({ index, ref }) {
5563
+ const lastIndex = this.mx_filteredOptions.length - 1;
5564
+
5565
+ if (index === lastIndex && this.mx_canFetchOptions()) {
5566
+ await this.mx_loadMoreOptions();
5567
+
5568
+ this.$nextTick(() => {
5569
+ ref.reset();
5570
+ ref.refresh(lastIndex);
5571
+ });
5572
+ }
5573
+ },
5574
+
5575
+ async mx_loadMoreOptions () {
5576
+ this.mx_isScrolling = true;
5577
+
5578
+ const options = await this.mx_fetchOptions();
5579
+ this.mx_filteredOptions.push(...options);
5580
+
5581
+ // this is to prevent the virtual-scroll event to be fired again
5582
+ this.$nextTick(() => {
5583
+ this.mx_isScrolling = false;
5584
+ });
5585
+ },
5586
+
5587
+ async mx_fetchOptions () {
5588
+ this.mx_fetchCount++;
5589
+
5590
+ try {
5591
+ if (!this.entity) this.mx_setMissingPropsMessage('entity');
5592
+ if (!this.name) this.mx_setMissingPropsMessage('name');
5593
+
5594
+ this.mx_hasFetchError = false;
5595
+ this.mx_isFetching = true;
5596
+
5597
+ this.$emit('update:fetching', true);
5598
+
5599
+ const { url, params, decamelizeFieldName } = this.mx_defaultLazyLoadingProps;
5600
+
5601
+ const { data } = await this.$store.dispatch(`${this.entity}/fetchFieldOptions`, {
5602
+ url,
5603
+ field: decamelizeFieldName ? humps.decamelize(this.name, { separator: '-' }) : this.name,
5604
+ params: {
5605
+ ...params,
5606
+ search: this.mx_search,
5607
+ offset: (this.mx_pagination.page - 1) * params.limit
5608
+ }
5609
+ });
5610
+
5611
+ const { results, count, hasNextPage } = data;
5612
+ const hasCount = count !== undefined;
5613
+
5614
+ this.mx_pagination = {
5615
+ page: this.mx_pagination.page + 1,
5616
+ lastPage: hasCount ? Math.ceil(count / params.limit) : null,
5617
+ hasCount,
5618
+ hasNextPage
5619
+ };
5620
+
5621
+ this.$emit('fetch-options-success', data);
5622
+
5623
+ return this.mx_handleOptions(results)
5624
+ } catch (error) {
5625
+ this.$qas.logger.group(
5626
+ `Mixin: searchFilterMixin - mx_fetchOptions -> exceção da action ${this.entity}/fetchFieldOptions`,
5627
+ [error],
5628
+ { error: true }
5629
+ );
5630
+
5631
+ this.mx_hasFetchError = true;
5632
+ this.$emit('fetch-options-error', error);
5633
+
5634
+ return []
5635
+ } finally {
5636
+ this.mx_isFetching = false;
5637
+ this.$emit('update:fetching', false);
5638
+ }
5639
+ },
5640
+
5641
+ async mx_setFetchOptions () {
5642
+ this.mx_filteredOptions = await this.mx_fetchOptions();
5643
+ },
5644
+
5645
+ mx_canFetchOptions () {
5646
+ const { lastPage, page, hasCount, hasNextPage } = this.mx_pagination;
5647
+
5648
+ const hasMorePages = hasCount ? lastPage && page <= lastPage : hasNextPage;
5649
+
5650
+ return hasMorePages && !this.mx_isFetching && !this.mx_isScrolling && this.useLazyLoading
5651
+ },
5652
+
5653
+ mx_handleOptions (options) {
5654
+ if (this.labelKey && this.valueKey) {
5655
+ return getNormalizedOptions({
5656
+ options,
5657
+ label: this.labelKey,
5658
+ value: this.valueKey
5659
+ })
5660
+ }
5661
+
5662
+ return options
5663
+ },
5664
+
5665
+ mx_getMissingPropsMessage (prop) {
5666
+ return `A propriedade "${prop}" é obrigatória quando a propriedade "useLazyLoading" está ativa.`
5667
+ },
5668
+
5669
+ mx_setMissingPropsMessage (prop) {
5670
+ throw new Error(this.mx_getMissingPropsMessage(prop))
5671
+ },
5672
+
5673
+ mx_getNormalizedFuseResults (results = []) {
5674
+ return results.map(({ item }) => item)
5675
+ }
5676
+ }
5677
+ };
5678
+
5679
+ var viewMixin = {
5680
+ props: {
5159
5681
  entity: {
5160
5682
  required: true,
5161
5683
  type: String
@@ -5183,6 +5705,16 @@
5183
5705
 
5184
5706
  fetching: {
5185
5707
  type: Boolean
5708
+ },
5709
+
5710
+ useBoundary: {
5711
+ default: true,
5712
+ type: Boolean
5713
+ },
5714
+
5715
+ beforeFetch: {
5716
+ default: null,
5717
+ type: Function
5186
5718
  }
5187
5719
  },
5188
5720
 
@@ -5198,7 +5730,7 @@
5198
5730
  mx_errors: {},
5199
5731
  mx_fields: {},
5200
5732
  mx_metadata: {},
5201
-
5733
+ mx_cancelBeforeFetch: false,
5202
5734
  mx_isFetching: false
5203
5735
  }
5204
5736
  },
@@ -5211,11 +5743,11 @@
5211
5743
 
5212
5744
  computed: {
5213
5745
  mx_componentTag () {
5214
- return this.dialog ? 'div' : 'q-page'
5746
+ return this.useBoundary ? 'q-page' : 'div'
5215
5747
  },
5216
5748
 
5217
5749
  mx_componentClass () {
5218
- return !this.dialog && 'container spaced'
5750
+ return this.useBoundary && 'container spaced'
5219
5751
  },
5220
5752
 
5221
5753
  mx_hasFooterSlot () {
@@ -5235,7 +5767,9 @@
5235
5767
  this.$qas.error('Ops! Erro ao obter os dados.', exception);
5236
5768
 
5237
5769
  const status = response?.status;
5238
- const redirect = ({ 403: 'Forbidden', 404: 'NotFound' })[status];
5770
+ const redirect = status >= 500
5771
+ ? 'ServerError'
5772
+ : ({ 401: 'Unauthorized', 403: 'Forbidden', 404: 'NotFound' })[status];
5239
5773
 
5240
5774
  if (redirect) {
5241
5775
  this.$router.replace({ name: redirect });
@@ -5247,11 +5781,9 @@
5247
5781
  },
5248
5782
 
5249
5783
  mx_setFields (fields = {}) {
5250
- for (const field in fields) {
5251
- fields[field].name = humps.camelize(fields[field].name);
5252
- }
5784
+ const camelizedFields = camelizeFieldsName(fields);
5253
5785
 
5254
- this.mx_fields = vue.markRaw(fields);
5786
+ this.mx_fields = vue.markRaw(camelizedFields);
5255
5787
  },
5256
5788
 
5257
5789
  mx_setMetadata (metadata = {}) {
@@ -5264,6 +5796,22 @@
5264
5796
 
5265
5797
  this.$emit(`update:${key}`, models[key]);
5266
5798
  }
5799
+ },
5800
+
5801
+ mx_fetchHandler (payload, resolve) {
5802
+ const hasBeforeFetch = typeof this.beforeFetch === 'function';
5803
+
5804
+ if (hasBeforeFetch && !this.mx_cancelBeforeFetch) {
5805
+ return this.beforeFetch({
5806
+ payload,
5807
+ resolve: payload => resolve(payload),
5808
+ done: () => {
5809
+ this.mx_cancelBeforeFetch = true;
5810
+ }
5811
+ })
5812
+ }
5813
+
5814
+ resolve();
5267
5815
  }
5268
5816
  }
5269
5817
  };
@@ -5279,7 +5827,7 @@
5279
5827
  mixins: [viewMixin],
5280
5828
 
5281
5829
  props: {
5282
- cancelButton: {
5830
+ cancelButtonLabel: {
5283
5831
  default: 'Cancelar',
5284
5832
  type: String
5285
5833
  },
@@ -5303,16 +5851,12 @@
5303
5851
  type: String
5304
5852
  },
5305
5853
 
5306
- readOnly: {
5307
- type: Boolean
5308
- },
5309
-
5310
5854
  route: {
5311
5855
  default: () => ({}),
5312
5856
  type: Object
5313
5857
  },
5314
5858
 
5315
- showDialogOnUnsavedChanges: {
5859
+ useDialogOnUnsavedChanges: {
5316
5860
  default: true,
5317
5861
  type: Boolean
5318
5862
  },
@@ -5322,7 +5866,7 @@
5322
5866
  type: Array
5323
5867
  },
5324
5868
 
5325
- submitButton: {
5869
+ submitButtonLabel: {
5326
5870
  default: 'Salvar',
5327
5871
  type: String
5328
5872
  },
@@ -5334,6 +5878,26 @@
5334
5878
 
5335
5879
  submitting: {
5336
5880
  type: Boolean
5881
+ },
5882
+
5883
+ useActions: {
5884
+ default: true,
5885
+ type: Boolean
5886
+ },
5887
+
5888
+ useCancelButton: {
5889
+ default: true,
5890
+ type: Boolean
5891
+ },
5892
+
5893
+ useSubmitButton: {
5894
+ default: true,
5895
+ type: Boolean
5896
+ },
5897
+
5898
+ beforeSubmit: {
5899
+ default: null,
5900
+ type: Function
5337
5901
  }
5338
5902
  },
5339
5903
 
@@ -5350,7 +5914,6 @@
5350
5914
  data () {
5351
5915
  return {
5352
5916
  cachedResult: {},
5353
- hasResult: false,
5354
5917
  isSubmitting: false,
5355
5918
  showDialog: false,
5356
5919
  ignoreRouterGuard: false,
@@ -5378,7 +5941,7 @@
5378
5941
  },
5379
5942
 
5380
5943
  hasCancelButton () {
5381
- return !(typeof this.cancelRoute === 'boolean' && !this.cancelRoute)
5944
+ return !(typeof this.cancelRoute === 'boolean' && !this.cancelRoute) && this.useCancelButton
5382
5945
  },
5383
5946
 
5384
5947
  id () {
@@ -5397,37 +5960,27 @@
5397
5960
  return this.$route
5398
5961
  },
5399
5962
 
5400
- saveButtonClass () {
5963
+ submitButtonClass () {
5401
5964
  return this.$qas.screen.isSmall && 'order-first'
5402
5965
  },
5403
5966
 
5404
5967
  isCancelButtonDisabled () {
5405
5968
  return this.disable || this.isSubmitting
5406
- },
5407
-
5408
- fieldsNameWithDefaultValue () {
5409
- return Object.keys(this.fields).filter(field => 'default' in this.fields[field])
5410
5969
  }
5411
5970
  },
5412
5971
 
5413
5972
  watch: {
5414
- mx_fields (fields) {
5415
- const models = { ...this.getModelsByFields(fields), ...this.modelValue };
5416
-
5417
- if (!this.hasResult && this.showDialogOnUnsavedChanges) {
5418
- this.cachedResult = quasar.extend(true, {}, models);
5419
- }
5420
- },
5421
-
5422
5973
  isSubmitting (value) {
5423
5974
  this.$emit('update:submitting', value);
5424
5975
  }
5425
5976
  },
5426
5977
 
5427
5978
  created () {
5428
- vueRouter.onBeforeRouteLeave(this.beforeRouteLeave);
5979
+ this.useDialogOnUnsavedChanges && vueRouter.onBeforeRouteLeave(this.beforeRouteLeave);
5980
+
5429
5981
  window.addEventListener('delete-success', this.setIgnoreRouterGuard);
5430
- this.fetch();
5982
+
5983
+ this.mx_fetchHandler({ form: true, id: this.id, url: this.fetchURL }, this.fetchSingle);
5431
5984
  },
5432
5985
 
5433
5986
  onUnmounted () {
@@ -5436,14 +5989,32 @@
5436
5989
 
5437
5990
  methods: {
5438
5991
  beforeRouteLeave (to, from, next) {
5992
+ const clonedModelValue = quasar.extend(true, {}, this.modelValue);
5993
+ const clonedCachedResult = quasar.extend(true, {}, this.cachedResult);
5994
+
5995
+ /**
5996
+ * Se a propriedade "useDialogOnUnsavedChanges" for false ou a variável
5997
+ * "ignoreRouterGuard" for true, então **não** iremos checar se o usuário
5998
+ * alterou algum campo antes de sair da pagina, senão iremos validar pela função isEqualWith
5999
+ * e mostrar um dialog antes do usuário sair da página.
6000
+ */
5439
6001
  if (
5440
- !this.showDialogOnUnsavedChanges ||
6002
+ !this.useDialogOnUnsavedChanges ||
5441
6003
  this.ignoreRouterGuard ||
5442
- lodashEs.isEqualWith(this.modelValue, this.cachedResult, this.handleIgnoreKeysInUnsavedChanges)
6004
+ lodashEs.isEqualWith(
6005
+ clonedModelValue,
6006
+ clonedCachedResult,
6007
+ this.handleIgnoreKeysInUnsavedChanges
6008
+ )
5443
6009
  ) {
5444
6010
  return next()
5445
6011
  }
5446
6012
 
6013
+ this.$qas.logger.group(
6014
+ 'QasFormView - beforeRouteLeave -> dialog chamado, modelValue diferente do cachedResult',
6015
+ [{ modelValue: clonedModelValue, cachedResult: clonedCachedResult }]
6016
+ );
6017
+
5447
6018
  this.handleDialog(() => {
5448
6019
  this.ignoreRouterGuard = true;
5449
6020
  next();
@@ -5451,41 +6022,64 @@
5451
6022
  },
5452
6023
 
5453
6024
  cancel () {
5454
- if (!this.dialog) {
5455
- this.handleCancelRoute();
5456
- }
6025
+ this.handleCancelRoute();
5457
6026
  },
5458
6027
 
5459
- async fetch (params) {
6028
+ async fetchSingle (externalPayload = {}) {
5460
6029
  this.mx_isFetching = true;
5461
6030
 
5462
6031
  try {
5463
- const response = await this.$store.dispatch(
5464
- `${this.entity}/fetchSingle`, { form: true, id: this.id, params, url: this.fetchURL }
6032
+ const payload = {
6033
+ form: true,
6034
+ id: this.id,
6035
+ url: this.fetchURL,
6036
+ ...externalPayload
6037
+ };
6038
+
6039
+ this.$qas.logger.group(
6040
+ `QasFormView - fetchSingle -> payload do parâmetro do ${this.entity}/fetchSingle`, [payload]
5465
6041
  );
5466
6042
 
6043
+ const response = await this.$store.dispatch(`${this.entity}/fetchSingle`, payload);
6044
+
5467
6045
  const { errors, fields, metadata, result } = response.data;
5468
6046
 
6047
+ const modelValue = { ...this.getModelsByFields(fields), ...this.modelValue };
6048
+
5469
6049
  this.mx_setErrors(errors);
5470
6050
  this.mx_setFields(fields);
5471
6051
  this.mx_setMetadata(metadata);
5472
6052
 
5473
6053
  this.mx_updateModels({
5474
- errors: errors,
6054
+ errors,
5475
6055
  fields: this.mx_fields,
5476
6056
  metadata
5477
6057
  });
5478
6058
 
5479
- if (result) {
5480
- this.hasResult = true;
5481
- this.$emit('update:modelValue', { ...this.modelValue, ...result });
5482
- this.cachedResult = this.showDialogOnUnsavedChanges && quasar.extend(true, {}, result);
6059
+ result && Object.assign(modelValue, result);
6060
+
6061
+ this.$qas.logger.group(
6062
+ `QasFormView - fetchSingle -> resposta da action ${this.entity}/fetchSingle`, [response]
6063
+ );
6064
+
6065
+ if (this.useDialogOnUnsavedChanges) {
6066
+ this.cachedResult = quasar.extend(true, {}, result || modelValue);
6067
+ this.$qas.logger.group('QasFormView - fetchSingle -> cachedResult', [this.cachedResult]);
5483
6068
  }
5484
6069
 
6070
+ this.$emit('update:modelValue', modelValue);
5485
6071
  this.$emit('fetch-success', response, this.modelValue);
6072
+
6073
+ this.$qas.logger.group('QasFormView - fetchSingle -> modelValue', [modelValue]);
5486
6074
  } catch (error) {
5487
6075
  this.mx_fetchError(error);
5488
6076
  this.$emit('fetch-error', error);
6077
+
6078
+ this.$qas.logger.group(
6079
+ `QasFormView - fetchSingle -> exceção da action ${this.entity}/fetchSingle`,
6080
+ [error],
6081
+ { error: true }
6082
+ );
5489
6083
  } finally {
5490
6084
  this.mx_isFetching = false;
5491
6085
  }
@@ -5522,6 +6116,7 @@
5522
6116
  const { addRoute } = useHistory();
5523
6117
 
5524
6118
  this.defaultDialogProps.ok.onClick = () => addRoute(this.$route);
6119
+
5525
6120
  this.defaultDialogProps.cancel.onClick = next;
5526
6121
  },
5527
6122
 
@@ -5531,48 +6126,76 @@
5531
6126
 
5532
6127
  // ignora chaves na hora de validar quando usuário está saindo da página
5533
6128
  handleIgnoreKeysInUnsavedChanges (firstValue, secondValue) {
5534
- const toIgnore = [
5535
- ...this.fieldsNameWithDefaultValue,
5536
- ...this.ignoreKeysInUnsavedChanges
5537
- ];
6129
+ if (!this.ignoreKeysInUnsavedChanges.length) return
5538
6130
 
5539
- if (!toIgnore.length) return
6131
+ this.ignoreKeysInUnsavedChanges.forEach(key => {
6132
+ if (!firstValue) return
5540
6133
 
5541
- toIgnore.forEach(key => {
5542
6134
  delete firstValue[key];
5543
6135
  delete secondValue[key];
5544
6136
  });
5545
6137
  },
5546
6138
 
5547
- async submit (event) {
6139
+ /**
6140
+ * Se existe a propriedade com callback "beforeSubmit", então o controle de quando e como chamar o método "submit"
6141
+ * está sendo controlado fora do QasFormView, se não existir a propriedade "beforeSubmit", então o controle do método
6142
+ * submit é feito pelo próprio QasFormView, chamado pelo evento @submit.
6143
+ */
6144
+ submitHandler (event) {
5548
6145
  if (event) {
5549
6146
  event.preventDefault();
5550
6147
  }
5551
6148
 
5552
- if (this.disable || this.readyOnly) {
5553
- return null
6149
+ const hasBeforeSubmit = typeof this.beforeSubmit === 'function';
6150
+
6151
+ if (hasBeforeSubmit) {
6152
+ return this.beforeSubmit({
6153
+ payload: { id: this.id, payload: this.modelValue, url: this.url },
6154
+ resolve: payload => this.submit(payload)
6155
+ })
5554
6156
  }
5555
6157
 
6158
+ this.submit();
6159
+ },
6160
+
6161
+ async submit (externalPayload = {}) {
6162
+ if (this.disable) return null
6163
+
5556
6164
  this.isSubmitting = true;
5557
6165
 
5558
6166
  try {
5559
- const response = await this.$store.dispatch(
5560
- `${this.entity}/${this.mode}`,
5561
- { id: this.id, payload: this.modelValue, url: this.url }
6167
+ const payload = {
6168
+ id: this.id,
6169
+ payload: this.modelValue,
6170
+ url: this.url,
6171
+ ...externalPayload
6172
+ };
6173
+
6174
+ this.$qas.logger.group(
6175
+ `QasFormView - submit -> payload do ${this.entity}/${this.mode}`, [payload]
5562
6176
  );
5563
6177
 
5564
- if (this.showDialogOnUnsavedChanges) {
6178
+ const response = await this.$store.dispatch(`${this.entity}/${this.mode}`, payload);
6179
+
6180
+ if (this.useDialogOnUnsavedChanges) {
5565
6181
  this.cachedResult = quasar.extend(true, {}, this.modelValue);
5566
6182
  }
5567
6183
 
5568
6184
  this.mx_setErrors();
5569
6185
  NotifySuccess(response.data.status.text || 'Item salvo com sucesso!');
5570
6186
  this.$emit('submit-success', response, this.modelValue);
6187
+
6188
+ this.$qas.logger.group(
6189
+ `QasFormView - submit -> resposta da action ${this.entity}/${this.mode}`, [response]
6190
+ );
5571
6191
  } catch (error) {
5572
6192
  const errors = error?.response?.data?.errors;
5573
6193
  const message = error?.response?.data?.status?.text;
5574
6194
  const exceptionResponse = error?.response?.data?.exception;
5575
- const exception = errors ? 'Existem erros de validação no formulário.' : exceptionResponse || error.message;
6195
+
6196
+ const exception = errors
6197
+ ? 'Existem erros de validação no formulário.'
6198
+ : exceptionResponse || error.message;
5576
6199
 
5577
6200
  this.mx_setErrors(errors);
5578
6201
  this.$emit('update:errors', this.mx_errors);
@@ -5580,6 +6203,12 @@
5580
6203
  NotifyError(message || 'Ops! Erro ao salvar item.', exception);
5581
6204
 
5582
6205
  this.$emit('submit-error', error);
6206
+
6207
+ this.$qas.logger.group(
6208
+ `QasFormView - submit -> exceção da action ${this.entity}/${this.mode}`,
6209
+ [error],
6210
+ { error: true }
6211
+ );
5583
6212
  } finally {
5584
6213
  this.isSubmitting = false;
5585
6214
  }
@@ -5591,7 +6220,7 @@
5591
6220
  }
5592
6221
  };
5593
6222
 
5594
- const _hoisted_1$d = { key: 0 };
6223
+ const _hoisted_1$e = { key: 0 };
5595
6224
  const _hoisted_2$9 = { class: "justify-end q-col-gutter-md q-my-lg row" };
5596
6225
  const _hoisted_3$6 = { key: 1 };
5597
6226
 
@@ -5608,17 +6237,17 @@
5608
6237
  }, {
5609
6238
  default: vue.withCtx(() => [
5610
6239
  (_ctx.mx_hasHeaderSlot)
5611
- ? (vue.openBlock(), vue.createElementBlock("header", _hoisted_1$d, [
6240
+ ? (vue.openBlock(), vue.createElementBlock("header", _hoisted_1$e, [
5612
6241
  vue.renderSlot(_ctx.$slots, "header")
5613
6242
  ]))
5614
6243
  : vue.createCommentVNode("v-if", true),
5615
6244
  vue.createVNode(_component_q_form, {
5616
6245
  ref: "form",
5617
- onSubmit: $options.submit
6246
+ onSubmit: $options.submitHandler
5618
6247
  }, {
5619
6248
  default: vue.withCtx(() => [
5620
6249
  vue.renderSlot(_ctx.$slots, "default"),
5621
- (!$props.readOnly)
6250
+ ($props.useActions)
5622
6251
  ? vue.renderSlot(_ctx.$slots, "actions", { key: 0 }, () => [
5623
6252
  vue.createElementVNode("div", _hoisted_2$9, [
5624
6253
  ($options.hasCancelButton)
@@ -5630,27 +6259,30 @@
5630
6259
  class: "full-width",
5631
6260
  "data-cy": `btnCancel-${_ctx.entity}`,
5632
6261
  disable: $options.isCancelButtonDisabled,
5633
- label: $props.cancelButton,
6262
+ label: $props.cancelButtonLabel,
5634
6263
  outline: "",
5635
6264
  type: "button",
5636
6265
  onClick: $options.cancel
5637
6266
  }, null, 8 /* PROPS */, ["data-cy", "disable", "label", "onClick"]), [
5638
- [_directive_close_popup, _ctx.dialog]
6267
+ [_directive_close_popup]
5639
6268
  ])
5640
6269
  ], 2 /* CLASS */))
5641
6270
  : vue.createCommentVNode("v-if", true),
5642
- vue.createElementVNode("div", {
5643
- class: vue.normalizeClass(["col-12 col-sm-2", $options.saveButtonClass])
5644
- }, [
5645
- vue.createVNode(_component_qas_btn, {
5646
- class: "full-width",
5647
- "data-cy": `btnSave-${_ctx.entity}`,
5648
- disable: $props.disable,
5649
- label: $props.submitButton,
5650
- loading: $data.isSubmitting,
5651
- type: "submit"
5652
- }, null, 8 /* PROPS */, ["data-cy", "disable", "label", "loading"])
5653
- ], 2 /* CLASS */)
6271
+ ($props.useSubmitButton)
6272
+ ? (vue.openBlock(), vue.createElementBlock("div", {
6273
+ key: 1,
6274
+ class: vue.normalizeClass(["col-12 col-sm-2", $options.submitButtonClass])
6275
+ }, [
6276
+ vue.createVNode(_component_qas_btn, {
6277
+ class: "full-width",
6278
+ "data-cy": `btnSave-${_ctx.entity}`,
6279
+ disable: $props.disable,
6280
+ label: $props.submitButtonLabel,
6281
+ loading: $data.isSubmitting,
6282
+ type: "submit"
6283
+ }, null, 8 /* PROPS */, ["data-cy", "disable", "label", "loading"])
6284
+ ], 2 /* CLASS */))
6285
+ : vue.createCommentVNode("v-if", true)
5654
6286
  ])
5655
6287
  ])
5656
6288
  : vue.createCommentVNode("v-if", true)
@@ -5802,7 +6434,7 @@
5802
6434
  }
5803
6435
  };
5804
6436
 
5805
- const _hoisted_1$c = { class: "q-col-gutter-md row" };
6437
+ const _hoisted_1$d = { class: "q-col-gutter-md row" };
5806
6438
  const _hoisted_2$8 = {
5807
6439
  key: 0,
5808
6440
  class: "full-width text-center"
@@ -5824,7 +6456,7 @@
5824
6456
 
5825
6457
  return (vue.openBlock(), vue.createBlock(_component_qas_box, { class: "gallery" }, {
5826
6458
  default: vue.withCtx(() => [
5827
- vue.createElementVNode("div", _hoisted_1$c, [
6459
+ vue.createElementVNode("div", _hoisted_1$d, [
5828
6460
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($options.initialImages(), (image, index) => {
5829
6461
  return (vue.openBlock(), vue.createElementBlock("div", {
5830
6462
  key: index,
@@ -5946,10 +6578,6 @@
5946
6578
  type: [Array, Object, String]
5947
6579
  },
5948
6580
 
5949
- hideEmptyResult: {
5950
- type: Boolean
5951
- },
5952
-
5953
6581
  emptyResultText: {
5954
6582
  default: '-',
5955
6583
  type: String
@@ -5958,6 +6586,11 @@
5958
6586
  result: {
5959
6587
  default: () => ({}),
5960
6588
  type: Object
6589
+ },
6590
+
6591
+ useEmptyResult: {
6592
+ default: true,
6593
+ type: Boolean
5961
6594
  }
5962
6595
  },
5963
6596
 
@@ -5969,7 +6602,12 @@
5969
6602
 
5970
6603
  computed: {
5971
6604
  formattedFields () {
5972
- if (!this.hideEmptyResult) {
6605
+ if (this.useEmptyResult) {
6606
+ this.$qas.logger.group(
6607
+ 'QasGridGenerator - formattedFields -> this.useEmptyResult tem valor "true"',
6608
+ [this.fields]
6609
+ );
6610
+
5973
6611
  return this.fields
5974
6612
  }
5975
6613
 
@@ -5987,6 +6625,8 @@
5987
6625
  }
5988
6626
  }
5989
6627
 
6628
+ this.$qas.logger.group('QasGridGenerator - formattedFields', [fields]);
6629
+
5990
6630
  return fields
5991
6631
  },
5992
6632
 
@@ -6002,11 +6642,19 @@
6002
6642
 
6003
6643
  for (const key in result) {
6004
6644
  if (this.formattedFields[key]?.type) {
6005
- formattedResult[key] = humanize(this.formattedFields[key], result[key]) || this.emptyResultText;
6006
- this.slotValue[key] = { ...this.formattedFields[key], formattedResult: formattedResult[key] };
6645
+ formattedResult[key] = (
6646
+ humanize(this.formattedFields[key], result[key]) || this.emptyResultText
6647
+ );
6648
+
6649
+ this.slotValue[key] = {
6650
+ ...this.formattedFields[key],
6651
+ formattedResult: formattedResult[key]
6652
+ };
6007
6653
  }
6008
6654
  }
6009
6655
 
6656
+ this.$qas.logger.group('QasGridGenerator - getResultsByFields', [formattedResult]);
6657
+
6010
6658
  return formattedResult
6011
6659
  }
6012
6660
  }
@@ -6142,6 +6790,10 @@
6142
6790
  }
6143
6791
  },
6144
6792
 
6793
+ mounted () {
6794
+ this.menuDrawer = !this.$qas.screen.untilMedium;
6795
+ },
6796
+
6145
6797
  methods: {
6146
6798
  toggleMenuDrawer () {
6147
6799
  this.menuDrawer = !this.menuDrawer;
@@ -6202,42 +6854,34 @@
6202
6854
  type: Array
6203
6855
  },
6204
6856
 
6205
- redirectKey: {
6206
- default: 'uuid',
6207
- type: String
6208
- },
6209
-
6210
- redirectOnIcon: {
6211
- default: true,
6857
+ useClickableItem: {
6212
6858
  type: Boolean
6213
6859
  },
6214
6860
 
6215
- to: {
6216
- default: () => ({}),
6217
- type: Object
6218
- },
6219
-
6220
6861
  useSectionActions: {
6221
6862
  default: true,
6222
6863
  type: Boolean
6223
6864
  }
6224
6865
  },
6225
6866
 
6867
+ emits: ['click-item'],
6868
+
6226
6869
  methods: {
6227
- getRedirectPayload (item) {
6228
- return {
6229
- params: { [this.redirectKey]: item[this.redirectKey] },
6230
- ...this.to
6231
- }
6232
- },
6870
+ onClick ({ item, index }, fromItem) {
6871
+ /**
6872
+ * se o click veio do q-item e "useClickableItem" for "false", ou
6873
+ * se o click não veio do q-item e "useClickableItem" for "true", então retorna sem emitir.
6874
+ */
6875
+ if (
6876
+ (fromItem && !this.useClickableItem) || (!fromItem && this.useClickableItem)
6877
+ ) return
6233
6878
 
6234
- redirect (item) {
6235
- return this.redirectOnIcon ? undefined : this.getRedirectPayload(item)
6879
+ this.$emit('click-item', { item, index });
6236
6880
  }
6237
6881
  }
6238
6882
  };
6239
6883
 
6240
- const _hoisted_1$b = { class: "qas-list-items shadow-14" };
6884
+ const _hoisted_1$c = { class: "qas-list-items shadow-14" };
6241
6885
 
6242
6886
  function render$f(_ctx, _cache, $props, $setup, $data, $options) {
6243
6887
  const _component_q_item_section = vue.resolveComponent("q-item-section");
@@ -6247,7 +6891,7 @@
6247
6891
  const _component_q_list = vue.resolveComponent("q-list");
6248
6892
  const _directive_ripple = vue.resolveDirective("ripple");
6249
6893
 
6250
- return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$b, [
6894
+ return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$c, [
6251
6895
  vue.createVNode(_component_q_list, {
6252
6896
  bordered: "",
6253
6897
  class: "rounded-borders",
@@ -6257,8 +6901,8 @@
6257
6901
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList($props.list, (item, index) => {
6258
6902
  return vue.withDirectives((vue.openBlock(), vue.createBlock(_component_q_item, {
6259
6903
  key: index,
6260
- clickable: !$props.redirectOnIcon,
6261
- to: $options.redirect(item)
6904
+ clickable: $props.useClickableItem,
6905
+ onClick: $event => ($options.onClick({ item, index }, true))
6262
6906
  }, {
6263
6907
  default: vue.withCtx(() => [
6264
6908
  vue.renderSlot(_ctx.$slots, "item", {
@@ -6267,7 +6911,7 @@
6267
6911
  }, () => [
6268
6912
  vue.createVNode(_component_q_item_section, null, {
6269
6913
  default: vue.withCtx(() => [
6270
- vue.renderSlot(_ctx.$slots, "item-section-left", {
6914
+ vue.renderSlot(_ctx.$slots, "item-section", {
6271
6915
  index: index,
6272
6916
  item: item
6273
6917
  })
@@ -6287,13 +6931,13 @@
6287
6931
  vue.createVNode(_component_qas_btn, {
6288
6932
  flat: "",
6289
6933
  round: "",
6290
- to: $options.getRedirectPayload(item)
6934
+ onClick: $event => ($options.onClick({ item, index }))
6291
6935
  }, {
6292
6936
  default: vue.withCtx(() => [
6293
6937
  vue.createVNode(_component_q_icon, vue.normalizeProps(vue.guardReactiveProps($props.iconProps)), null, 16 /* FULL_PROPS */)
6294
6938
  ]),
6295
6939
  _: 2 /* DYNAMIC */
6296
- }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["to"])
6940
+ }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["onClick"])
6297
6941
  ])
6298
6942
  ]),
6299
6943
  _: 2 /* DYNAMIC */
@@ -6302,7 +6946,7 @@
6302
6946
  ])
6303
6947
  ]),
6304
6948
  _: 2 /* DYNAMIC */
6305
- }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["clickable", "to"])), [
6949
+ }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["clickable", "onClick"])), [
6306
6950
  [_directive_ripple]
6307
6951
  ])
6308
6952
  }), 128 /* KEYED_FRAGMENT */))
@@ -6323,15 +6967,6 @@
6323
6967
  mixins: [contextMixin, viewMixin],
6324
6968
 
6325
6969
  props: {
6326
- disableRefresh: {
6327
- type: Boolean
6328
- },
6329
-
6330
- useFilter: {
6331
- default: true,
6332
- type: Boolean
6333
- },
6334
-
6335
6970
  filtersProps: {
6336
6971
  default: () => ({}),
6337
6972
  type: Object
@@ -6340,6 +6975,20 @@
6340
6975
  results: {
6341
6976
  default: () => [],
6342
6977
  type: Array
6978
+ },
6979
+
6980
+ useRefresh: {
6981
+ default: true,
6982
+ type: Boolean
6983
+ },
6984
+
6985
+ useFilter: {
6986
+ default: true,
6987
+ type: Boolean
6988
+ },
6989
+
6990
+ useResultsAreaOnly: {
6991
+ type: Boolean
6343
6992
  }
6344
6993
  },
6345
6994
 
@@ -6375,13 +7024,17 @@
6375
7024
 
6376
7025
  totalPages () {
6377
7026
  return this.$store.getters[`${this.entity}/totalPages`]
7027
+ },
7028
+
7029
+ showResults () {
7030
+ return this.hasResults || this.useResultsAreaOnly
6378
7031
  }
6379
7032
  },
6380
7033
 
6381
7034
  watch: {
6382
7035
  $route (to, from) {
6383
7036
  if (to.name === from.name) {
6384
- this.fetchList();
7037
+ this.mx_fetchHandler({ ...this.mx_context, url: this.url }, this.fetchList);
6385
7038
  this.setCurrentPage();
6386
7039
  }
6387
7040
  },
@@ -6396,7 +7049,8 @@
6396
7049
  },
6397
7050
 
6398
7051
  created () {
6399
- this.fetchList();
7052
+ this.mx_fetchHandler({ ...this.mx_context, url: this.url }, this.fetchList);
7053
+
6400
7054
  this.setCurrentPage();
6401
7055
  },
6402
7056
 
@@ -6406,21 +7060,22 @@
6406
7060
  this.$router.push({ query });
6407
7061
  },
6408
7062
 
6409
- async fetchList (filters = {}) {
7063
+ async fetchList (externalPayload = {}) {
6410
7064
  this.mx_isFetching = true;
6411
7065
 
6412
- const hasFilters = !!Object.keys(filters).length;
6413
-
6414
7066
  try {
6415
- const response = await this.$store.dispatch(
6416
- `${this.entity}/fetchList`,
6417
- {
6418
- ...this.mx_context,
6419
- url: this.url,
6420
- ...(hasFilters && { filters })
6421
- }
7067
+ const payload = {
7068
+ ...this.mx_context,
7069
+ url: this.url,
7070
+ ...externalPayload
7071
+ };
7072
+
7073
+ this.$qas.logger.group(
7074
+ `QasListView - fetchList -> Payload do parâmetro do ${this.entity}/fetchList`, [payload]
6422
7075
  );
6423
7076
 
7077
+ const response = await this.$store.dispatch(`${this.entity}/fetchList`, payload);
7078
+
6424
7079
  const { errors, fields, metadata } = response.data;
6425
7080
 
6426
7081
  this.mx_setErrors(errors);
@@ -6434,17 +7089,27 @@
6434
7089
  });
6435
7090
 
6436
7091
  this.$emit('fetch-success', response);
7092
+
7093
+ this.$qas.logger.group(
7094
+ `QasListView - fetchList -> resposta da action ${this.entity}/fetchList`, [response]
7095
+ );
6437
7096
  } catch (error) {
6438
7097
  this.mx_fetchError(error);
6439
7098
  this.$emit('update:errors', error);
6440
7099
  this.$emit('fetch-error', error);
7100
+
7101
+ this.$qas.logger.group(
7102
+ `QasListView - fetchSingle -> exceção da action ${this.entity}/fetchList`,
7103
+ [error],
7104
+ { error: true }
7105
+ );
6441
7106
  } finally {
6442
7107
  this.mx_isFetching = false;
6443
7108
  }
6444
7109
  },
6445
7110
 
6446
7111
  async refresh (done) {
6447
- await this.fetchList();
7112
+ await this.mx_fetchHandler({ ...this.mx_context, url: this.url }, this.fetchList);
6448
7113
 
6449
7114
  if (typeof done === 'function') {
6450
7115
  done();
@@ -6457,7 +7122,7 @@
6457
7122
  }
6458
7123
  };
6459
7124
 
6460
- const _hoisted_1$a = { key: 0 };
7125
+ const _hoisted_1$b = { key: 0 };
6461
7126
  const _hoisted_2$7 = { class: "relative-position" };
6462
7127
  const _hoisted_3$4 = { key: 0 };
6463
7128
  const _hoisted_4$4 = { key: 1 };
@@ -6485,12 +7150,12 @@
6485
7150
  }, {
6486
7151
  default: vue.withCtx(() => [
6487
7152
  vue.createVNode(_component_q_pull_to_refresh, {
6488
- disable: $props.disableRefresh,
7153
+ disable: !$props.useRefresh,
6489
7154
  onRefresh: $options.refresh
6490
7155
  }, {
6491
7156
  default: vue.withCtx(() => [
6492
7157
  ($options.hasHeaderSlot)
6493
- ? (vue.openBlock(), vue.createElementBlock("header", _hoisted_1$a, [
7158
+ ? (vue.openBlock(), vue.createElementBlock("header", _hoisted_1$b, [
6494
7159
  vue.renderSlot(_ctx.$slots, "header")
6495
7160
  ]))
6496
7161
  : vue.createCommentVNode("v-if", true),
@@ -6500,7 +7165,7 @@
6500
7165
  ])
6501
7166
  : vue.createCommentVNode("v-if", true),
6502
7167
  vue.createElementVNode("main", _hoisted_2$7, [
6503
- ($options.hasResults)
7168
+ ($options.showResults)
6504
7169
  ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$4, [
6505
7170
  vue.renderSlot(_ctx.$slots, "default")
6506
7171
  ]))
@@ -6577,13 +7242,13 @@
6577
7242
  default: () => []
6578
7243
  },
6579
7244
 
6580
- usePopup: {
6581
- type: Boolean
6582
- },
6583
-
6584
7245
  zoom: {
6585
7246
  type: Number,
6586
7247
  default: 17
7248
+ },
7249
+
7250
+ usePopup: {
7251
+ type: Boolean
6587
7252
  }
6588
7253
  },
6589
7254
 
@@ -6617,7 +7282,7 @@
6617
7282
  }
6618
7283
  };
6619
7284
 
6620
- const _hoisted_1$9 = { class: "qas-map" };
7285
+ const _hoisted_1$a = { class: "qas-map" };
6621
7286
  const _hoisted_2$6 = { class: "text-weight-bold" };
6622
7287
 
6623
7288
  function render$d(_ctx, _cache, $props, $setup, $data, $options) {
@@ -6625,7 +7290,7 @@
6625
7290
  const _component_g_map_marker = vue.resolveComponent("g-map-marker");
6626
7291
  const _component_g_map_map = vue.resolveComponent("g-map-map");
6627
7292
 
6628
- return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$9, [
7293
+ return (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$a, [
6629
7294
  vue.createVNode(_component_g_map_map, {
6630
7295
  center: $props.centerPosition,
6631
7296
  class: "qas-map__draw",
@@ -6684,7 +7349,7 @@
6684
7349
  default: 'Inserir novo campo'
6685
7350
  },
6686
7351
 
6687
- btnDestroyProps: {
7352
+ buttonDestroyProps: {
6688
7353
  type: Object,
6689
7354
  default: () => {
6690
7355
  return {
@@ -6696,14 +7361,14 @@
6696
7361
  }
6697
7362
  },
6698
7363
 
6699
- btnDuplicateProps: {
7364
+ buttonDuplicateProps: {
6700
7365
  type: Object,
6701
7366
  default: () => {
6702
7367
  return {
6703
7368
  label: 'Duplicar',
6704
7369
  icon: 'o_content_copy',
6705
7370
  flat: true,
6706
- hideMobileLabel: true,
7371
+ useLabelOnSmallScreen: false,
6707
7372
  dense: true
6708
7373
  }
6709
7374
  }
@@ -6748,6 +7413,11 @@
6748
7413
  }
6749
7414
  },
6750
7415
 
7416
+ identifierItemKey: {
7417
+ type: String,
7418
+ default: 'uuid'
7419
+ },
7420
+
6751
7421
  rowLabel: {
6752
7422
  type: String,
6753
7423
  default: ''
@@ -6813,13 +7483,7 @@
6813
7483
  },
6814
7484
 
6815
7485
  children () {
6816
- const field = quasar.extend(true, {}, this.field);
6817
-
6818
- for (const key in field?.children) {
6819
- field.children[key].name = humps.camelize(field?.children[key].name);
6820
- }
6821
-
6822
- return field?.children
7486
+ return this.field?.children
6823
7487
  },
6824
7488
 
6825
7489
  showDestroyBtn () {
@@ -6846,8 +7510,7 @@
6846
7510
 
6847
7511
  return {
6848
7512
  tag: 'div',
6849
- enterActiveClass: 'animated slideInDown',
6850
- leaveActiveClass: 'animated slideOutUp'
7513
+ enterActiveClass: 'animated slideInDown'
6851
7514
  }
6852
7515
  }
6853
7516
  },
@@ -6860,9 +7523,9 @@
6860
7523
  immediate: true
6861
7524
  },
6862
7525
 
6863
- field: {
7526
+ rowObject: {
6864
7527
  handler () {
6865
- !this.modelValue.length && this.setDefaultNestedValue();
7528
+ if (!this.nested.length) return this.setDefaultNestedValue()
6866
7529
  },
6867
7530
  immediate: true
6868
7531
  }
@@ -6870,13 +7533,22 @@
6870
7533
 
6871
7534
  methods: {
6872
7535
  add (row = {}) {
6873
- this.nested.push({ ...this.rowObject, ...row });
7536
+ const payload = { ...this.rowObject, ...row };
7537
+ const hasIdentifierKey = payload[this.identifierItemKey];
7538
+
7539
+ if (hasIdentifierKey) {
7540
+ delete payload[this.identifierItemKey];
7541
+ }
7542
+
7543
+ this.nested.push(payload);
6874
7544
 
6875
7545
  this.$nextTick(() => {
6876
7546
  this.useAnimation && this.setScroll();
6877
7547
  this.setFocus();
6878
7548
  });
6879
7549
 
7550
+ this.$qas.logger.group('QasNestedFields - add', [payload]);
7551
+
6880
7552
  return this.updateModelValue()
6881
7553
  },
6882
7554
 
@@ -6892,10 +7564,12 @@
6892
7564
  },
6893
7565
 
6894
7566
  destroy (index, row) {
6895
- this.useRemoveOnDestroy
7567
+ !row[this.identifierItemKey] && this.useRemoveOnDestroy
6896
7568
  ? this.nested.splice(index, 1)
6897
7569
  : this.nested.splice(index, 1, { [this.destroyKey]: true, ...row });
6898
7570
 
7571
+ this.$qas.logger.group('QasNestedFields - destroy', [{ index, row }]);
7572
+
6899
7573
  return this.updateModelValue()
6900
7574
  },
6901
7575
 
@@ -6921,7 +7595,7 @@
6921
7595
  });
6922
7596
  },
6923
7597
 
6924
- setRowLabel (rowKey) {
7598
+ getRowLabel (rowKey) {
6925
7599
  if (this.rowLabel) {
6926
7600
  return this.useIndexLabel ? `${this.rowLabel} ${rowKey + 1}` : this.rowLabel
6927
7601
  }
@@ -6931,7 +7605,7 @@
6931
7605
  }
6932
7606
  };
6933
7607
 
6934
- const _hoisted_1$8 = ["id"];
7608
+ const _hoisted_1$9 = ["id"];
6935
7609
  const _hoisted_2$5 = { class: "text-left" };
6936
7610
  const _hoisted_3$3 = { ref: "inputContent" };
6937
7611
  const _hoisted_4$3 = ["id"];
@@ -6992,18 +7666,18 @@
6992
7666
  (!$props.useSingleLabel)
6993
7667
  ? (vue.openBlock(), vue.createBlock(_component_qas_label, {
6994
7668
  key: 0,
6995
- label: $options.setRowLabel(index)
7669
+ label: $options.getRowLabel(index)
6996
7670
  }, null, 8 /* PROPS */, ["label"]))
6997
7671
  : vue.createCommentVNode("v-if", true),
6998
7672
  (!$props.useInlineActions)
6999
7673
  ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6, [
7000
7674
  ($props.useDuplicate)
7001
- ? (vue.openBlock(), vue.createBlock(_component_qas_btn, vue.mergeProps({ key: 0 }, $props.btnDuplicateProps, {
7675
+ ? (vue.openBlock(), vue.createBlock(_component_qas_btn, vue.mergeProps({ key: 0 }, $props.buttonDuplicateProps, {
7002
7676
  onClick: $event => ($options.add(row))
7003
7677
  }), null, 16 /* FULL_PROPS */, ["onClick"]))
7004
7678
  : vue.createCommentVNode("v-if", true),
7005
7679
  ($options.showDestroyBtn)
7006
- ? (vue.openBlock(), vue.createBlock(_component_qas_btn, vue.mergeProps({ key: 1 }, $props.btnDestroyProps, {
7680
+ ? (vue.openBlock(), vue.createBlock(_component_qas_btn, vue.mergeProps({ key: 1 }, $props.buttonDestroyProps, {
7007
7681
  onClick: $event => ($options.destroy(index, row))
7008
7682
  }), null, 16 /* FULL_PROPS */, ["onClick"]))
7009
7683
  : vue.createCommentVNode("v-if", true)
@@ -7130,7 +7804,7 @@
7130
7804
  ])
7131
7805
  ])
7132
7806
  ], 512 /* NEED_PATCH */)
7133
- ], 8 /* PROPS */, _hoisted_1$8))
7807
+ ], 8 /* PROPS */, _hoisted_1$9))
7134
7808
  }
7135
7809
 
7136
7810
  script$c.render = render$c;
@@ -7141,17 +7815,20 @@
7141
7815
  var script$b = {
7142
7816
  name: 'QasPageHeader',
7143
7817
 
7818
+ mixins: [
7819
+ quasar.createMetaMixin(function () {
7820
+ return {
7821
+ title: this.title
7822
+ }
7823
+ })
7824
+ ],
7825
+
7144
7826
  props: {
7145
7827
  breadcrumbs: {
7146
7828
  default: '',
7147
7829
  type: [Array, String]
7148
7830
  },
7149
7831
 
7150
- useBreadcrumbs: {
7151
- default: true,
7152
- type: Boolean
7153
- },
7154
-
7155
7832
  root: {
7156
7833
  default: '',
7157
7834
  type: [Object, String]
@@ -7160,6 +7837,11 @@
7160
7837
  title: {
7161
7838
  default: '',
7162
7839
  type: String
7840
+ },
7841
+
7842
+ useBreadcrumbs: {
7843
+ default: true,
7844
+ type: Boolean
7163
7845
  }
7164
7846
  },
7165
7847
 
@@ -7203,16 +7885,10 @@
7203
7885
 
7204
7886
  return lastIndex === index ? 'text-grey-7' : 'text-primary'
7205
7887
  }
7206
- },
7207
-
7208
- meta () {
7209
- return {
7210
- title: this.title
7211
- }
7212
7888
  }
7213
7889
  };
7214
7890
 
7215
- const _hoisted_1$7 = { class: "ellipsis" };
7891
+ const _hoisted_1$8 = { class: "ellipsis" };
7216
7892
 
7217
7893
  function render$b(_ctx, _cache, $props, $setup, $data, $options) {
7218
7894
  const _component_q_icon = vue.resolveComponent("q-icon");
@@ -7223,7 +7899,7 @@
7223
7899
 
7224
7900
  return (vue.openBlock(), vue.createBlock(_component_q_toolbar, { class: "justify-between q-mb-lg q-px-none" }, {
7225
7901
  default: vue.withCtx(() => [
7226
- vue.createElementVNode("div", _hoisted_1$7, [
7902
+ vue.createElementVNode("div", _hoisted_1$8, [
7227
7903
  ($props.title)
7228
7904
  ? (vue.openBlock(), vue.createBlock(_component_q_toolbar_title, {
7229
7905
  key: 0,
@@ -7339,7 +8015,7 @@
7339
8015
  }
7340
8016
  };
7341
8017
 
7342
- const _hoisted_1$6 = { class: "q-col-gutter-md row" };
8018
+ const _hoisted_1$7 = { class: "q-col-gutter-md row" };
7343
8019
  const _hoisted_2$4 = { class: "col-lg-5 col-xs-12" };
7344
8020
  const _hoisted_3$2 = { class: "justify-center lg:q-mb-none md:q-mr-lg row xs:q-mb-md" };
7345
8021
  const _hoisted_4$2 = { class: "text-bold text-h6" };
@@ -7351,7 +8027,7 @@
7351
8027
 
7352
8028
  return (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($props.tag), null, {
7353
8029
  default: vue.withCtx(() => [
7354
- vue.createElementVNode("div", _hoisted_1$6, [
8030
+ vue.createElementVNode("div", _hoisted_1$7, [
7355
8031
  vue.createElementVNode("div", _hoisted_2$4, [
7356
8032
  vue.createElementVNode("div", {
7357
8033
  class: vue.normalizeClass(["no-wrap q-col-gutter-md", $options.directionClasses])
@@ -7376,8 +8052,8 @@
7376
8052
  class: "col-lg-7 col-xs-12 items-center",
7377
8053
  columns: $props.columns,
7378
8054
  fields: $options.filterObject($props.fields, $props.list),
7379
- "hide-empty-result": "",
7380
- result: $props.result
8055
+ result: $props.result,
8056
+ "use-empty-result": false
7381
8057
  }, vue.createSlots({ _: 2 /* DYNAMIC */ }, [
7382
8058
  vue.renderList(_ctx.$slots, (_, name) => {
7383
8059
  return {
@@ -7477,7 +8153,7 @@
7477
8153
  }
7478
8154
  };
7479
8155
 
7480
- const _hoisted_1$5 = /*#__PURE__*/vue.createElementVNode("div", { class: "absolute-full bg-grey-2 flex flex-center text-grey" }, "⚠︎", -1 /* HOISTED */);
8156
+ const _hoisted_1$6 = /*#__PURE__*/vue.createElementVNode("div", { class: "absolute-full bg-grey-2 flex flex-center text-grey" }, "⚠︎", -1 /* HOISTED */);
7481
8157
 
7482
8158
  function render$9(_ctx, _cache, $props, $setup, $data, $options) {
7483
8159
  const _component_q_img = vue.resolveComponent("q-img");
@@ -7488,7 +8164,7 @@
7488
8164
  src: $options.imageSource
7489
8165
  }, {
7490
8166
  error: vue.withCtx(() => [
7491
- _hoisted_1$5
8167
+ _hoisted_1$6
7492
8168
  ]),
7493
8169
  _: 1 /* STABLE */
7494
8170
  }, 8 /* PROPS */, ["ratio", "src"]))
@@ -7501,15 +8177,23 @@
7501
8177
  name: 'QasSearchBox',
7502
8178
 
7503
8179
  components: {
7504
- QasBox: script$D
8180
+ QasBox: script$D,
8181
+ QInfiniteScroll: quasar.QInfiniteScroll
7505
8182
  },
7506
8183
 
8184
+ mixins: [searchFilterMixin],
8185
+
7507
8186
  props: {
7508
8187
  emptyListHeight: {
7509
8188
  default: '100px',
7510
8189
  type: String
7511
8190
  },
7512
8191
 
8192
+ emptyResultText: {
8193
+ default: 'Não há resultados disponíveis.',
8194
+ type: String
8195
+ },
8196
+
7513
8197
  fuseOptions: {
7514
8198
  default: () => ({}),
7515
8199
  type: Object
@@ -7554,110 +8238,184 @@
7554
8238
 
7555
8239
  data () {
7556
8240
  return {
7557
- fuse: null,
7558
- searchResults: this.list,
7559
- search: ''
8241
+ fuse: null
7560
8242
  }
7561
8243
  },
7562
8244
 
7563
8245
  computed: {
7564
- contentStyle () {
7565
- return { height: this.list.length ? this.height : this.emptyListHeight }
8246
+ attributes () {
8247
+ return {
8248
+ clearable: true,
8249
+ disable: this.isDisabled,
8250
+ debounce: this.useLazyLoading ? 500 : 0,
8251
+ outlined: true,
8252
+ placeholder: this.placeholder,
8253
+ hideBottomSpace: true,
8254
+ error: this.mx_hasFetchError,
8255
+ loading: this.mx_isFetching
8256
+ }
8257
+ },
8258
+
8259
+ containerStyle () {
8260
+ return { height: this.containerHeight }
8261
+ },
8262
+
8263
+ hasNoOptionsOnFirstFetch () {
8264
+ return this.mx_fetchCount === 1 && !this.mx_hasFilteredOptions
8265
+ },
8266
+
8267
+ containerHeight () {
8268
+ const hasEmptyList = (!this.list.length && !this.useLazyLoading) || this.hasNoOptionsOnFirstFetch;
8269
+
8270
+ return hasEmptyList ? this.emptyListHeight : this.height
8271
+ },
8272
+
8273
+ component () {
8274
+ const infiniteScrollProps = {
8275
+ offset: 100,
8276
+ scrollTarget: this.$refs.scrollContainer,
8277
+ ref: 'infiniteScrollRef'
8278
+ };
8279
+
8280
+ return {
8281
+ is: this.useLazyLoading ? 'q-infinite-scroll' : 'div',
8282
+ props: {
8283
+ ...(this.useLazyLoading && infiniteScrollProps),
8284
+ ...(this.useLazyLoading && { onLoad: this.onInfiniteScroll })
8285
+ }
8286
+ }
7566
8287
  },
7567
8288
 
7568
8289
  defaultFuseOptions () {
7569
8290
  return {
7570
- distance: 100,
7571
- location: 0,
7572
- maxPatternLength: 32,
7573
- minMatchCharLength: 1,
7574
- shouldSort: true,
7575
8291
  threshold: 0.1,
7576
- tokenize: true,
8292
+ ignoreLocation: true,
7577
8293
 
7578
8294
  ...this.fuseOptions
7579
8295
  }
7580
8296
  },
7581
8297
 
7582
- hasResults () {
7583
- return !!this.searchResults.length
8298
+ isDisabled () {
8299
+ return (!this.useLazyLoading && !this.list.length) || this.mx_isFetching || this.hasNoOptionsOnFirstFetch
8300
+ },
8301
+
8302
+ showEmptyResult () {
8303
+ return this.useEmptySlot && !this.mx_hasFilteredOptions && !this.mx_isFetching
8304
+ },
8305
+
8306
+ showSpinnerDots () {
8307
+ return this.mx_hasFilteredOptions && this.mx_isFetching
8308
+ },
8309
+
8310
+ showInnerLoading () {
8311
+ return !this.mx_hasFilteredOptions && this.mx_isFetching
7584
8312
  }
7585
8313
  },
7586
8314
 
7587
8315
  watch: {
7588
8316
  defaultFuseOptions (value) {
8317
+ if (this.useLazyLoading) return
8318
+
7589
8319
  this.fuse.options = { ...this.fuse.options, ...value };
7590
8320
  },
7591
8321
 
7592
- hasResults (value) {
8322
+ mx_hasFilteredOptions (value) {
7593
8323
  !value && this.$emit('empty-result');
7594
8324
  },
7595
8325
 
7596
- list: {
7597
- handler (value) {
7598
- this.fuse = new Fuse__default["default"](value, this.defaultFuseOptions);
8326
+ mx_search: {
8327
+ async handler (value) {
8328
+ this.$emit('update:modelValue', value);
7599
8329
 
7600
- this.setResults(this.search);
7601
- this.updateResultsModel(value);
7602
- },
8330
+ if (this.useLazyLoading) {
8331
+ await this.mx_filterOptionsByStore(value);
8332
+
8333
+ this.$refs.infiniteScrollRef.resume();
8334
+ this.$refs.search.focus();
8335
+
8336
+ return
8337
+ }
7603
8338
 
7604
- deep: true
8339
+ this.filterOptionsByFuse(value);
8340
+ }
7605
8341
  },
7606
8342
 
7607
- search: {
8343
+ modelValue: {
7608
8344
  handler (value) {
7609
- this.setResults(value);
7610
- this.$emit('update:modelValue', value);
8345
+ this.mx_search = value;
7611
8346
  },
7612
8347
 
7613
8348
  immediate: true
7614
8349
  },
7615
8350
 
7616
- searchResults: {
7617
- handler (value) {
7618
- this.updateResultsModel(value);
8351
+ mx_filteredOptions: {
8352
+ handler (options) {
8353
+ this.$emit('update:results', options);
7619
8354
  },
8355
+
7620
8356
  immediate: true
7621
8357
  }
7622
8358
  },
7623
8359
 
7624
8360
  created () {
7625
- this.search = this.modelValue;
8361
+ if (this.useLazyLoading) return
8362
+
8363
+ this.mx_filteredOptions = this.list;
7626
8364
  this.fuse = new Fuse__default["default"](this.list, this.defaultFuseOptions);
7627
- this.setResults();
8365
+
8366
+ this.setListWatcher();
7628
8367
  },
7629
8368
 
7630
8369
  methods: {
7631
- setResults (value) {
7632
- this.searchResults = value
7633
- ? this.fuse.search(value)
7634
- : this.list;
8370
+ filterOptionsByFuse (value) {
8371
+ this.mx_filteredOptions = value ? this.mx_getNormalizedFuseResults(this.fuse.search(value)) : this.list;
8372
+ },
8373
+
8374
+ async onInfiniteScroll (_, done) {
8375
+ // Se tiver erro no primeiro fetch, retorna o "done" na proxima.
8376
+ if (((this.mx_hasFetchError && !this.mx_hasFilteredOptions) || this.hasNoOptionsOnFirstFetch)) return done()
8377
+
8378
+ if (!this.mx_hasFilteredOptions && !this.mx_search) {
8379
+ await this.mx_setFetchOptions();
8380
+ return done()
8381
+ }
8382
+
8383
+ if (this.mx_canFetchOptions()) {
8384
+ await this.mx_loadMoreOptions();
8385
+ return done()
8386
+ }
8387
+
8388
+ done(true);
7635
8389
  },
7636
8390
 
7637
- updateResultsModel (value) {
7638
- this.$emit('update:results', value.map(result => result.item || result));
8391
+ setListWatcher () {
8392
+ this.$watch('list', value => {
8393
+ this.fuse = new Fuse__default["default"](value, this.defaultFuseOptions);
8394
+
8395
+ this.filterOptionsByFuse(this.mx_search);
8396
+ }, { deep: true });
7639
8397
  }
7640
8398
  }
7641
8399
  };
7642
8400
 
7643
- const _hoisted_1$4 = { class: "absolute-center text-center" };
7644
- const _hoisted_2$3 = /*#__PURE__*/vue.createElementVNode("div", null, "Não há resultados disponíveis.", -1 /* HOISTED */);
8401
+ const _hoisted_1$5 = { class: "flex justify-center q-pb-sm" };
8402
+ const _hoisted_2$3 = { class: "absolute-center text-center" };
7645
8403
 
7646
8404
  function render$8(_ctx, _cache, $props, $setup, $data, $options) {
7647
8405
  const _component_q_icon = vue.resolveComponent("q-icon");
7648
- const _component_q_input = vue.resolveComponent("q-input");
8406
+ const _component_qas_input = vue.resolveComponent("qas-input");
8407
+ const _component_q_spinner_dots = vue.resolveComponent("q-spinner-dots");
8408
+ const _component_q_spinner = vue.resolveComponent("q-spinner");
8409
+ const _component_q_inner_loading = vue.resolveComponent("q-inner-loading");
7649
8410
  const _component_qas_box = vue.resolveComponent("qas-box");
7650
8411
 
7651
8412
  return (vue.openBlock(), vue.createBlock(_component_qas_box, null, {
7652
8413
  default: vue.withCtx(() => [
7653
- vue.createVNode(_component_q_input, {
7654
- modelValue: $data.search,
7655
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($data.search) = $event)),
7656
- clearable: "",
7657
- disable: !$props.list.length,
7658
- outlined: "",
7659
- placeholder: $props.placeholder
7660
- }, {
8414
+ vue.createVNode(_component_qas_input, vue.mergeProps($options.attributes, {
8415
+ ref: "search",
8416
+ modelValue: _ctx.mx_search,
8417
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((_ctx.mx_search) = $event))
8418
+ }), {
7661
8419
  append: vue.withCtx(() => [
7662
8420
  vue.createVNode(_component_q_icon, {
7663
8421
  color: "primary",
@@ -7665,26 +8423,52 @@
7665
8423
  })
7666
8424
  ]),
7667
8425
  _: 1 /* STABLE */
7668
- }, 8 /* PROPS */, ["modelValue", "disable", "placeholder"]),
8426
+ }, 16 /* FULL_PROPS */, ["modelValue"]),
7669
8427
  vue.createElementVNode("div", {
8428
+ ref: "scrollContainer",
7670
8429
  class: "overflow-auto q-mt-xs relative-position",
7671
- style: vue.normalizeStyle($options.contentStyle)
8430
+ style: vue.normalizeStyle($options.containerStyle)
7672
8431
  }, [
7673
- ($options.hasResults)
7674
- ? vue.renderSlot(_ctx.$slots, "default", { key: 0 })
7675
- : ($props.useEmptySlot)
7676
- ? vue.renderSlot(_ctx.$slots, "empty-result", { key: 1 }, () => [
7677
- vue.createElementVNode("div", _hoisted_1$4, [
7678
- vue.createVNode(_component_q_icon, {
7679
- class: "q-mb-sm text-center",
7680
- color: "primary",
7681
- name: "o_search",
7682
- size: "38px"
7683
- }),
7684
- _hoisted_2$3
7685
- ])
8432
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($options.component.is), vue.normalizeProps(vue.guardReactiveProps($options.component.props)), {
8433
+ default: vue.withCtx(() => [
8434
+ (_ctx.mx_hasFilteredOptions)
8435
+ ? vue.renderSlot(_ctx.$slots, "default", { key: 0 })
8436
+ : vue.createCommentVNode("v-if", true)
8437
+ ]),
8438
+ _: 3 /* FORWARDED */
8439
+ }, 16 /* FULL_PROPS */)),
8440
+ ($options.showSpinnerDots)
8441
+ ? vue.renderSlot(_ctx.$slots, "loading", { key: 0 }, () => [
8442
+ vue.createElementVNode("div", _hoisted_1$5, [
8443
+ vue.createVNode(_component_q_spinner_dots, {
8444
+ color: "primary",
8445
+ size: "20px"
8446
+ })
7686
8447
  ])
7687
- : vue.createCommentVNode("v-if", true)
8448
+ ])
8449
+ : vue.createCommentVNode("v-if", true),
8450
+ ($options.showEmptyResult)
8451
+ ? vue.renderSlot(_ctx.$slots, "empty-result", { key: 1 }, () => [
8452
+ vue.createElementVNode("div", _hoisted_2$3, [
8453
+ vue.createVNode(_component_q_icon, {
8454
+ class: "q-mb-sm text-center",
8455
+ color: "primary",
8456
+ name: "o_search",
8457
+ size: "38px"
8458
+ }),
8459
+ vue.createElementVNode("div", null, vue.toDisplayString($props.emptyResultText), 1 /* TEXT */)
8460
+ ])
8461
+ ])
8462
+ : vue.createCommentVNode("v-if", true),
8463
+ vue.createVNode(_component_q_inner_loading, { showing: $options.showInnerLoading }, {
8464
+ default: vue.withCtx(() => [
8465
+ vue.createVNode(_component_q_spinner, {
8466
+ color: "grey",
8467
+ size: "3em"
8468
+ })
8469
+ ]),
8470
+ _: 1 /* STABLE */
8471
+ }, 8 /* PROPS */, ["showing"])
7688
8472
  ], 4 /* STYLE */)
7689
8473
  ]),
7690
8474
  _: 3 /* FORWARDED */
@@ -7697,6 +8481,8 @@
7697
8481
  var script$7 = {
7698
8482
  name: 'QasSelect',
7699
8483
 
8484
+ mixins: [searchFilterMixin],
8485
+
7700
8486
  props: {
7701
8487
  fuseOptions: {
7702
8488
  default: () => ({}),
@@ -7710,7 +8496,7 @@
7710
8496
 
7711
8497
  modelValue: {
7712
8498
  default: () => [],
7713
- type: [Array, Object, String, Number]
8499
+ type: [Array, Object, String, Number, Boolean]
7714
8500
  },
7715
8501
 
7716
8502
  noOptionLabel: {
@@ -7723,13 +8509,13 @@
7723
8509
  type: Array
7724
8510
  },
7725
8511
 
7726
- searchable: {
7727
- type: Boolean
7728
- },
7729
-
7730
8512
  valueKey: {
7731
8513
  default: '',
7732
8514
  type: String
8515
+ },
8516
+
8517
+ useSearch: {
8518
+ type: Boolean
7733
8519
  }
7734
8520
  },
7735
8521
 
@@ -7737,7 +8523,6 @@
7737
8523
 
7738
8524
  data () {
7739
8525
  return {
7740
- filteredOptions: [],
7741
8526
  fuse: null
7742
8527
  }
7743
8528
  },
@@ -7745,40 +8530,45 @@
7745
8530
  computed: {
7746
8531
  attributes () {
7747
8532
  return {
7748
- clearable: this.searchable,
8533
+ clearable: this.isSearchable,
7749
8534
  emitValue: true,
7750
8535
  mapOptions: true,
7751
8536
  outlined: true,
7752
-
7753
8537
  ...this.$attrs,
7754
8538
 
7755
- options: this.filteredOptions,
7756
- useInput: this.searchable
8539
+ options: this.mx_filteredOptions,
8540
+ useInput: this.isSearchable,
8541
+ error: this.hasError,
8542
+ loading: this.hasLoading,
8543
+ ...(this.useLazyLoading && { onVirtualScroll: this.mx_onVirtualScroll }),
8544
+ ...(this.isSearchable && { onFilter: this.onFilter })
7757
8545
  }
7758
8546
  },
7759
8547
 
7760
8548
  defaultFuseOptions () {
7761
8549
  return {
7762
- distance: 100,
7763
- includeScore: true,
8550
+ ignoreLocation: true,
7764
8551
  keys: ['label', 'value'],
7765
- location: 0,
7766
- maxPatternLength: 32,
7767
- minMatchCharLength: 1,
7768
- shouldSort: true,
7769
8552
  threshold: 0.1,
7770
- tokenize: true,
7771
8553
 
7772
8554
  ...this.fuseOptions
7773
8555
  }
7774
8556
  },
7775
8557
 
7776
- formattedResult () {
7777
- if (!this.labelKey && !this.valueKey) {
7778
- return this.options
7779
- }
8558
+ isSearchable () {
8559
+ return this.useSearch || this.useLazyLoading
8560
+ },
8561
+
8562
+ defaultOptions () {
8563
+ return this.mx_handleOptions(this.options)
8564
+ },
8565
+
8566
+ hasError () {
8567
+ return this.mx_hasFetchError || this.$attrs.error
8568
+ },
7780
8569
 
7781
- return this.options.map(item => this.renameKey(item))
8570
+ hasLoading () {
8571
+ return this.mx_isFetching || this.$attrs.loading
7782
8572
  },
7783
8573
 
7784
8574
  model: {
@@ -7799,11 +8589,11 @@
7799
8589
 
7800
8590
  options: {
7801
8591
  handler () {
7802
- if (this.fuse) {
7803
- this.fuse.list = this.formattedResult;
7804
- }
8592
+ if (this.useLazyLoading && this.mx_hasFilteredOptions) return
8593
+
8594
+ if (this.fuse) this.setFuse();
7805
8595
 
7806
- this.filteredOptions = this.formattedResult;
8596
+ this.mx_filteredOptions = this.defaultOptions;
7807
8597
  },
7808
8598
 
7809
8599
  immediate: true
@@ -7812,59 +8602,57 @@
7812
8602
 
7813
8603
  created () {
7814
8604
  this.setFuse();
8605
+ this.useLazyLoading && this.mx_setFetchOptions('');
7815
8606
  },
7816
8607
 
7817
8608
  methods: {
7818
- filterOptions (value, update) {
7819
- update(() => {
7820
- if (!this.searchable) return
7821
-
7822
- if (value === '') {
7823
- this.filteredOptions = this.formattedResult;
7824
- } else {
7825
- const results = this.fuse.search(value);
7826
- this.filteredOptions = results.map(item => item.item);
7827
- }
7828
- });
8609
+ setFuse () {
8610
+ if (this.useSearch) {
8611
+ this.fuse = new Fuse__default["default"](this.defaultOptions, this.defaultFuseOptions);
8612
+ }
7829
8613
  },
7830
8614
 
7831
- renameKey (item) {
7832
- const mapKeys = {
7833
- label: this.labelKey,
7834
- value: this.valueKey
7835
- };
8615
+ async onFilter (value, update) {
8616
+ if (this.useLazyLoading && value !== this.mx_search) {
8617
+ await this.mx_filterOptionsByStore(value);
8618
+ }
7836
8619
 
7837
- for (const newKey in mapKeys) {
7838
- if (!item.hasOwnProperty.call(newKey)) {
7839
- item[newKey] = item[mapKeys[newKey]];
7840
- delete item[mapKeys[newKey]];
7841
- }
8620
+ if (!this.useLazyLoading && this.useSearch) {
8621
+ this.filterOptionsByFuse(value);
7842
8622
  }
7843
8623
 
7844
- return item
8624
+ update();
7845
8625
  },
7846
8626
 
7847
- setFuse () {
7848
- if (this.searchable) {
7849
- this.fuse = new Fuse__default["default"](this.options, this.defaultFuseOptions);
8627
+ filterOptionsByFuse (value) {
8628
+ if (value === '') {
8629
+ this.mx_filteredOptions = this.defaultOptions;
8630
+ return
7850
8631
  }
8632
+
8633
+ const results = this.fuse.search(value);
8634
+
8635
+ this.mx_filteredOptions = this.mx_getNormalizedFuseResults(results);
7851
8636
  }
7852
8637
  }
7853
8638
  };
7854
8639
 
8640
+ const _hoisted_1$4 = { class: "flex justify-center q-pb-sm" };
8641
+
7855
8642
  function render$7(_ctx, _cache, $props, $setup, $data, $options) {
7856
8643
  const _component_q_icon = vue.resolveComponent("q-icon");
7857
8644
  const _component_q_item_section = vue.resolveComponent("q-item-section");
7858
8645
  const _component_q_item = vue.resolveComponent("q-item");
8646
+ const _component_q_spinner_dots = vue.resolveComponent("q-spinner-dots");
7859
8647
  const _component_q_select = vue.resolveComponent("q-select");
7860
8648
 
7861
8649
  return (vue.openBlock(), vue.createBlock(_component_q_select, vue.mergeProps({
7862
8650
  modelValue: $options.model,
7863
8651
  "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($options.model) = $event))
7864
- }, $options.attributes, { onFilter: $options.filterOptions }), vue.createSlots({
8652
+ }, $options.attributes), vue.createSlots({
7865
8653
  append: vue.withCtx(() => [
7866
8654
  vue.renderSlot(_ctx.$slots, "append", {}, () => [
7867
- ($props.searchable)
8655
+ ($options.isSearchable)
7868
8656
  ? (vue.openBlock(), vue.createBlock(_component_q_icon, {
7869
8657
  key: 0,
7870
8658
  name: "o_search"
@@ -7873,19 +8661,33 @@
7873
8661
  ])
7874
8662
  ]),
7875
8663
  "no-option": vue.withCtx(() => [
7876
- vue.renderSlot(_ctx.$slots, "no-option", {}, () => [
7877
- vue.createVNode(_component_q_item, null, {
7878
- default: vue.withCtx(() => [
7879
- vue.createVNode(_component_q_item_section, { class: "text-grey" }, {
8664
+ (!_ctx.mx_isFetching)
8665
+ ? vue.renderSlot(_ctx.$slots, "no-option", { key: 0 }, () => [
8666
+ vue.createVNode(_component_q_item, null, {
7880
8667
  default: vue.withCtx(() => [
7881
- vue.createTextVNode(vue.toDisplayString($props.noOptionLabel), 1 /* TEXT */)
8668
+ vue.createVNode(_component_q_item_section, { class: "text-grey" }, {
8669
+ default: vue.withCtx(() => [
8670
+ vue.createTextVNode(vue.toDisplayString($props.noOptionLabel), 1 /* TEXT */)
8671
+ ]),
8672
+ _: 1 /* STABLE */
8673
+ })
7882
8674
  ]),
7883
8675
  _: 1 /* STABLE */
7884
8676
  })
7885
- ]),
7886
- _: 1 /* STABLE */
7887
- })
7888
- ])
8677
+ ])
8678
+ : vue.createCommentVNode("v-if", true)
8679
+ ]),
8680
+ "after-options": vue.withCtx(() => [
8681
+ (_ctx.mx_isFetching)
8682
+ ? vue.renderSlot(_ctx.$slots, "after-options", { key: 0 }, () => [
8683
+ vue.createElementVNode("div", _hoisted_1$4, [
8684
+ vue.createVNode(_component_q_spinner_dots, {
8685
+ color: "primary",
8686
+ size: "20px"
8687
+ })
8688
+ ])
8689
+ ])
8690
+ : vue.createCommentVNode("v-if", true)
7889
8691
  ]),
7890
8692
  _: 2 /* DYNAMIC */
7891
8693
  }, [
@@ -7897,7 +8699,7 @@
7897
8699
  ])
7898
8700
  }
7899
8701
  })
7900
- ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["modelValue", "onFilter"]))
8702
+ ]), 1040 /* FULL_PROPS, DYNAMIC_SLOTS */, ["modelValue"]))
7901
8703
  }
7902
8704
 
7903
8705
  script$7.render = render$7;
@@ -7931,26 +8733,16 @@
7931
8733
  default: () => []
7932
8734
  },
7933
8735
 
7934
- to: {
7935
- default: () => ({}),
7936
- type: Object
7937
- },
7938
-
7939
- redirectKey: {
7940
- default: 'uuid',
7941
- type: String
7942
- },
7943
-
7944
- paramKey: {
7945
- default: 'id',
7946
- type: String
8736
+ useClickableLabel: {
8737
+ type: Boolean
7947
8738
  }
7948
8739
  },
7949
8740
 
7950
8741
  emits: [
7951
8742
  'added',
7952
- 'update:modelValue',
7953
- 'removed'
8743
+ 'click-label',
8744
+ 'removed',
8745
+ 'update:modelValue'
7954
8746
  ],
7955
8747
 
7956
8748
  data () {
@@ -7962,12 +8754,8 @@
7962
8754
  },
7963
8755
 
7964
8756
  computed: {
7965
- isRedirectEnabled () {
7966
- return Object.keys(this.to).length
7967
- },
7968
-
7969
8757
  labelClass () {
7970
- return this.isRedirectEnabled ? 'cursor-pointer' : ''
8758
+ return this.useClickableLabel && 'cursor-pointer'
7971
8759
  },
7972
8760
 
7973
8761
  slotData () {
@@ -7996,6 +8784,7 @@
7996
8784
  this.values = [...value];
7997
8785
  },
7998
8786
 
8787
+ deep: true,
7999
8788
  immediate: true
8000
8789
  }
8001
8790
  },
@@ -8017,7 +8806,7 @@
8017
8806
 
8018
8807
  return {
8019
8808
  dense: this.$qas.screen.isSmall,
8020
- hideLabelOnSmallScreen: true,
8809
+ useLabelOnSmallScreen: false,
8021
8810
  icon: !this.$qas.screen.isSmall ? undefined : isSelected ? 'o_close' : 'o_add',
8022
8811
  label: isSelected ? 'Remover' : 'Adicionar',
8023
8812
  outline: isSelected,
@@ -8042,11 +8831,8 @@
8042
8831
  });
8043
8832
  },
8044
8833
 
8045
- redirectRoute (item) {
8046
- return this.isRedirectEnabled && this.$router.push({
8047
- params: { [this.paramKey]: item[this.redirectKey] },
8048
- ...this.to
8049
- })
8834
+ onClickLabel ({ item, index }) {
8835
+ this.useClickableLabel && this.$emit('click-label', { item, index });
8050
8836
  },
8051
8837
 
8052
8838
  remove (item) {
@@ -8100,7 +8886,7 @@
8100
8886
  default: vue.withCtx(() => [
8101
8887
  vue.createElementVNode("div", {
8102
8888
  class: vue.normalizeClass($options.labelClass),
8103
- onClick: $event => ($options.redirectRoute(result))
8889
+ onClick: $event => ($options.onClickLabel({ item: result, index: _ctx.index }))
8104
8890
  }, vue.toDisplayString(result.label), 11 /* TEXT, CLASS, PROPS */, _hoisted_1$3)
8105
8891
  ]),
8106
8892
  _: 2 /* DYNAMIC */
@@ -8171,7 +8957,9 @@
8171
8957
 
8172
8958
  watch: {
8173
8959
  $route (to, from) {
8174
- to.name === from.name && this.fetchSingle();
8960
+ if (to.name === from.name) {
8961
+ this.mx_fetchHandler({ id: this.id, url: this.url }, this.fetchSingle);
8962
+ }
8175
8963
  },
8176
8964
 
8177
8965
  resultModel (value) {
@@ -8180,19 +8968,23 @@
8180
8968
  },
8181
8969
 
8182
8970
  created () {
8183
- this.fetchSingle();
8971
+ this.mx_fetchHandler({ id: this.id, url: this.url }, this.fetchSingle);
8184
8972
  },
8185
8973
 
8186
8974
  methods: {
8187
- async fetchSingle (params = {}) {
8975
+ async fetchSingle (externalPayload = {}) {
8188
8976
  this.mx_isFetching = true;
8189
8977
 
8190
8978
  try {
8191
- const response = await this.$store.dispatch(
8192
- `${this.entity}/fetchSingle`,
8193
- { id: this.id, url: this.url, params }
8979
+ const payload = { id: this.id, url: this.url, ...externalPayload };
8980
+
8981
+ this.$qas.logger.group(
8982
+ `QasSingleView - fetchSingle -> payload do parâmetro do ${this.entity}/fetchSingle`,
8983
+ [payload]
8194
8984
  );
8195
8985
 
8986
+ const response = await this.$store.dispatch(`${this.entity}/fetchSingle`, payload);
8987
+
8196
8988
  const { errors, fields, metadata } = response.data;
8197
8989
 
8198
8990
  this.mx_setErrors(errors);
@@ -8205,10 +8997,20 @@
8205
8997
  metadata: this.mx_metadata
8206
8998
  });
8207
8999
 
9000
+ this.$qas.logger.group(
9001
+ `QasSingleView - fetchSingle -> resposta da action ${this.entity}/fetchSingle`, [response]
9002
+ );
9003
+
8208
9004
  this.$emit('fetch-success', response);
8209
9005
  } catch (error) {
8210
9006
  this.mx_fetchError(error);
8211
9007
  this.$emit('fetch-error', error);
9008
+
9009
+ this.$qas.logger.group(
9010
+ `QasSingleView - fetchSingle -> exceção da action ${this.entity}/fetchSingle`,
9011
+ [error],
9012
+ { error: true }
9013
+ );
8212
9014
  } finally {
8213
9015
  this.mx_isFetching = false;
8214
9016
  }
@@ -8500,6 +9302,8 @@
8500
9302
  columnByField(this.fields[index]);
8501
9303
  }
8502
9304
 
9305
+ this.$qas.logger.group('QasTableGenerator - Automatic columns', [columns]);
9306
+
8503
9307
  return columns
8504
9308
  }
8505
9309
 
@@ -8512,6 +9316,8 @@
8512
9316
  }
8513
9317
  });
8514
9318
 
9319
+ this.$qas.logger.group('QasTableGenerator - columns', [columns]);
9320
+
8515
9321
  return columns
8516
9322
  },
8517
9323
 
@@ -8528,16 +9334,22 @@
8528
9334
  },
8529
9335
 
8530
9336
  resultsByFields () {
9337
+ if (!Object.keys(this.fields).length) return []
9338
+
8531
9339
  const results = quasar.extend(true, [], this.results);
8532
9340
 
8533
- return results.map((result, index) => {
9341
+ const mappedResults = results.map((result, index) => {
8534
9342
  for (const key in result) {
8535
9343
  result.default = this.results[index];
8536
9344
  result[key] = humanize(this.fields[key], result[key]) || this.emptyResultText;
8537
9345
  }
8538
9346
 
8539
9347
  return result
8540
- })
9348
+ });
9349
+
9350
+ this.$qas.logger.group('QasTableGenerator - resultsByFields', [mappedResults]);
9351
+
9352
+ return mappedResults
8541
9353
  },
8542
9354
 
8543
9355
  rowsPerPage () {
@@ -8598,10 +9410,11 @@
8598
9410
  handleScrollOnGrab () {
8599
9411
  const fullTableWidth = this.getFullTableWidth();
8600
9412
  const containerTableWidth = this.getContainerTableWidth();
9413
+ const hasScrollOnGrab = !!Object.keys(this.scrollOnGrab).length;
8601
9414
 
8602
9415
  if (fullTableWidth > containerTableWidth) {
8603
9416
  this.initializeScrollOnGrab();
8604
- } else if (this.hasScrollOnGrab) {
9417
+ } else if (hasScrollOnGrab) {
8605
9418
  this.scrollOnGrab.destroyEvents();
8606
9419
  this.scrollOnGrab.element.style.cursor = 'auto';
8607
9420
  this.scrollOnGrab = {};
@@ -8698,7 +9511,7 @@
8698
9511
  tabs: {
8699
9512
  default: () => ({}),
8700
9513
  required: true,
8701
- type: Object
9514
+ type: [Object, Array]
8702
9515
  }
8703
9516
  },
8704
9517
 
@@ -8755,7 +9568,7 @@
8755
9568
  (vue.openBlock(), vue.createBlock(_component_q_tab, vue.mergeProps({ key: key }, tab, {
8756
9569
  class: $props.tabClass,
8757
9570
  label: tab.label,
8758
- name: key
9571
+ name: tab.value
8759
9572
  }), {
8760
9573
  default: vue.withCtx(() => [
8761
9574
  vue.renderSlot(_ctx.$slots, `tab-after-${tab.value}`, { item: tab }, () => [
@@ -8840,7 +9653,7 @@
8840
9653
  return {
8841
9654
  cancel: false,
8842
9655
  ok: false,
8843
- useCloseIcon: true,
9656
+ useCloseButton: true,
8844
9657
  ...this.dialogProps,
8845
9658
  card: {
8846
9659
  title: this.dialogTitle,
@@ -9250,7 +10063,7 @@
9250
10063
 
9251
10064
  var name = "@bildvitta/quasar-ui-asteroid";
9252
10065
  var description = "Asteroid";
9253
- var version$1 = "3.0.0-beta.7";
10066
+ var version$1 = "3.0.0";
9254
10067
  var author = "Bild & Vitta <systemteam@bild.com.br>";
9255
10068
  var license = "MIT";
9256
10069
  var main = "dist/asteroid.cjs.min.js";
@@ -9406,8 +10219,9 @@
9406
10219
  app.config.globalProperties.$qas = {
9407
10220
  dialog: Dialog,
9408
10221
  error: NotifyError,
9409
- success: NotifySuccess,
9410
- screen: Screen()
10222
+ logger: Logger(),
10223
+ screen: Screen(),
10224
+ success: NotifySuccess
9411
10225
  };
9412
10226
 
9413
10227
  app.directive(Test.name, Test);
@@ -9465,6 +10279,7 @@
9465
10279
  QasTransfer: script,
9466
10280
  QasUploader: script$q,
9467
10281
  Dialog: Dialog,
10282
+ Logger: Logger,
9468
10283
  NotifyError: NotifyError,
9469
10284
  NotifySuccess: NotifySuccess,
9470
10285
  Screen: Screen,