@bildvitta/quasar-ui-asteroid 2.16.0 → 3.0.0-alpha.2

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 (280) hide show
  1. package/dist/api/QasActions.json +40 -0
  2. package/dist/api/QasActionsMenu.json +64 -0
  3. package/dist/api/QasAlert.json +40 -0
  4. package/dist/api/QasAppBar.json +52 -0
  5. package/dist/api/QasAppMenu.json +38 -0
  6. package/dist/api/QasAvatar.json +44 -0
  7. package/dist/api/QasBox.json +16 -0
  8. package/dist/api/QasBreakline.json +32 -0
  9. package/dist/api/QasBtn.json +16 -0
  10. package/dist/api/QasCard.json +52 -0
  11. package/dist/api/QasCheckboxGroup.json +38 -0
  12. package/dist/api/QasCopy.json +29 -0
  13. package/dist/api/QasDateTimeInput.json +60 -0
  14. package/dist/api/QasDebugger.json +13 -0
  15. package/dist/api/QasDelete.json +64 -0
  16. package/dist/api/QasDialog.json +109 -0
  17. package/dist/api/QasDialogRouter.json +31 -0
  18. package/dist/api/QasField.json +56 -0
  19. package/dist/api/QasFilters.json +111 -0
  20. package/dist/api/QasFormGenerator.json +92 -0
  21. package/dist/api/QasFormView.json +228 -0
  22. package/dist/api/QasGallery.json +54 -0
  23. package/dist/api/QasGridGenerator.json +108 -0
  24. package/dist/api/QasInput.json +40 -0
  25. package/dist/api/QasLabel.json +40 -0
  26. package/dist/api/QasLayout.json +47 -0
  27. package/dist/api/QasListItems.json +72 -0
  28. package/dist/api/QasListView.json +161 -0
  29. package/dist/api/QasMap.json +41 -0
  30. package/dist/api/QasNestedFields.json +223 -0
  31. package/dist/api/QasNumericInput.json +68 -0
  32. package/dist/api/QasPageHeader.json +36 -0
  33. package/dist/api/QasPasswordInput.json +121 -0
  34. package/dist/api/QasPasswordStrengthChecker.json +126 -0
  35. package/dist/api/QasProfile.json +74 -0
  36. package/dist/api/QasResizer.json +34 -0
  37. package/dist/api/QasSearchBox.json +91 -0
  38. package/dist/api/QasSelect.json +88 -0
  39. package/dist/api/QasSelectList.json +134 -0
  40. package/dist/api/QasSignaturePad.json +63 -0
  41. package/dist/api/QasSignatureUploader.json +41 -0
  42. package/dist/api/QasSingleView.json +147 -0
  43. package/dist/api/QasSortable.json +80 -0
  44. package/dist/api/QasTableGenerator.json +56 -0
  45. package/dist/api/QasTabsGenerator.json +90 -0
  46. package/dist/api/QasTextTruncate.json +38 -0
  47. package/dist/api/QasTransfer.json +70 -0
  48. package/dist/api/QasUploader.json +143 -0
  49. package/dist/asteroid.cjs.css +1 -0
  50. package/dist/asteroid.cjs.js +9307 -0
  51. package/dist/asteroid.cjs.min.js +6 -0
  52. package/dist/asteroid.esm.css +1 -0
  53. package/dist/asteroid.esm.js +9298 -0
  54. package/dist/asteroid.esm.min.js +6 -0
  55. package/dist/asteroid.umd.css +1 -0
  56. package/dist/asteroid.umd.js +9301 -0
  57. package/dist/asteroid.umd.min.js +6 -0
  58. package/dist/vetur/asteroid-attributes.json +1178 -0
  59. package/dist/vetur/asteroid-tags.json +535 -0
  60. package/package.json +41 -56
  61. package/src/assets/logo-modular.svg +1 -1
  62. package/src/asteroid.js +1 -0
  63. package/src/components/actions/QasActions.vue +45 -0
  64. package/src/components/actions/QasActions.yml +24 -0
  65. package/src/components/actions-menu/QasActionsMenu.vue +41 -14
  66. package/src/components/actions-menu/QasActionsMenu.yml +63 -0
  67. package/src/components/alert/QasAlert.vue +90 -0
  68. package/src/components/alert/QasAlert.yml +33 -0
  69. package/src/components/app-bar/QasAppBar.vue +16 -13
  70. package/src/components/app-bar/QasAppBar.yml +51 -0
  71. package/src/components/app-menu/QasAppMenu.vue +10 -12
  72. package/src/components/app-menu/QasAppMenu.yml +32 -0
  73. package/src/components/avatar/QasAvatar.vue +17 -9
  74. package/src/components/avatar/QasAvatar.yml +38 -0
  75. package/src/components/box/QasBox.vue +12 -4
  76. package/src/components/box/QasBox.yml +13 -0
  77. package/src/components/breakline/QasBreakline.vue +37 -0
  78. package/src/components/breakline/QasBreakline.yml +25 -0
  79. package/src/components/btn/QasBtn.vue +27 -24
  80. package/src/components/btn/QasBtn.yml +13 -0
  81. package/src/components/card/QasCard.vue +32 -33
  82. package/src/components/card/QasCard.yml +42 -0
  83. package/src/components/checkbox-group/QasCheckboxGroup.vue +50 -17
  84. package/src/components/checkbox-group/QasCheckboxGroup.yml +30 -0
  85. package/src/components/copy/QasCopy.vue +22 -11
  86. package/src/components/copy/QasCopy.yml +20 -0
  87. package/src/components/date-time-input/QasDateTimeInput.vue +18 -26
  88. package/src/components/date-time-input/QasDateTimeInput.yml +54 -0
  89. package/src/components/debugger/QasDebugger.vue +2 -0
  90. package/src/components/debugger/QasDebugger.yml +10 -0
  91. package/src/components/delete/QasDelete.vue +43 -16
  92. package/src/components/delete/QasDelete.yml +52 -0
  93. package/src/components/dialog/QasDialog.vue +63 -67
  94. package/src/components/dialog/QasDialog.yml +86 -0
  95. package/src/components/dialog-router/QasDialogRouter.vue +14 -4
  96. package/src/components/dialog-router/QasDialogRouter.yml +23 -0
  97. package/src/components/field/QasField.vue +21 -24
  98. package/src/components/field/QasField.yml +31 -0
  99. package/src/components/filters/QasFilters.vue +33 -26
  100. package/src/components/filters/QasFilters.yml +91 -0
  101. package/src/components/form-generator/QasFormGenerator.vue +13 -15
  102. package/src/components/form-generator/QasFormGenerator.yml +64 -0
  103. package/src/components/form-view/QasFormView.vue +129 -69
  104. package/src/components/form-view/QasFormView.yml +179 -0
  105. package/src/components/gallery/QasGallery.vue +47 -30
  106. package/src/components/gallery/QasGallery.yml +51 -0
  107. package/src/components/grid-generator/QasGridGenerator.vue +15 -7
  108. package/src/components/grid-generator/QasGridGenerator.yml +73 -0
  109. package/src/components/index.js +0 -0
  110. package/src/components/input/QasInput.vue +43 -36
  111. package/src/components/input/QasInput.yml +32 -0
  112. package/src/components/label/QasLabel.vue +14 -15
  113. package/src/components/label/QasLabel.yml +28 -0
  114. package/src/components/layout/QasLayout.vue +13 -21
  115. package/src/components/layout/QasLayout.yml +38 -0
  116. package/src/components/list-items/QasListItems.vue +15 -12
  117. package/src/components/list-items/QasListItems.yml +57 -0
  118. package/src/components/list-view/QasListView.vue +57 -31
  119. package/src/components/list-view/QasListView.yml +132 -0
  120. package/src/components/map/QasMap.vue +15 -31
  121. package/src/components/map/QasMap.yml +33 -0
  122. package/src/components/nested-fields/QasNestedFields.vue +57 -47
  123. package/src/components/nested-fields/QasNestedFields.yml +180 -0
  124. package/src/components/numeric-input/QasNumericInput.vue +31 -22
  125. package/src/components/numeric-input/QasNumericInput.yml +51 -0
  126. package/src/components/page-header/QasPageHeader.vue +20 -11
  127. package/src/components/page-header/QasPageHeader.yml +24 -0
  128. package/src/components/password-input/QasPasswordInput.vue +24 -21
  129. package/src/components/password-input/QasPasswordInput.yml +103 -0
  130. package/src/components/password-strength-checker/QasPasswordStrengthChecker.vue +51 -34
  131. package/src/components/password-strength-checker/QasPasswordStrengthChecker.yml +103 -0
  132. package/src/components/profile/QasProfile.vue +15 -13
  133. package/src/components/profile/QasProfile.yml +60 -0
  134. package/src/components/resizer/QasResizer.vue +3 -3
  135. package/src/components/resizer/QasResizer.yml +23 -0
  136. package/src/components/search-box/QasSearchBox.vue +50 -21
  137. package/src/components/search-box/QasSearchBox.yml +76 -0
  138. package/src/components/select/QasSelect.vue +51 -50
  139. package/src/components/select/QasSelect.yml +62 -0
  140. package/src/components/select-list/QasSelectList.vue +72 -53
  141. package/src/components/select-list/QasSelectList.yml +116 -0
  142. package/src/components/signature-pad/QasSignaturePad.vue +60 -40
  143. package/src/components/signature-pad/QasSignaturePad.yml +53 -0
  144. package/src/components/signature-uploader/QasSignatureUploader.vue +19 -17
  145. package/src/components/signature-uploader/QasSignatureUploader.yml +36 -0
  146. package/src/components/single-view/QasSingleView.vue +41 -22
  147. package/src/components/single-view/QasSingleView.yml +116 -0
  148. package/src/components/sortable/QasSortable.vue +51 -30
  149. package/src/components/sortable/QasSortable.yml +65 -0
  150. package/src/components/table-generator/QasTableGenerator.vue +112 -21
  151. package/src/components/table-generator/QasTableGenerator.yml +46 -0
  152. package/src/components/tabs-generator/QasTabsGenerator.vue +37 -25
  153. package/src/components/tabs-generator/QasTabsGenerator.yml +67 -0
  154. package/src/components/text-truncate/QasTextTruncate.vue +25 -17
  155. package/src/components/text-truncate/QasTextTruncate.yml +32 -0
  156. package/src/components/transfer/QasTransfer.vue +48 -49
  157. package/src/components/transfer/QasTransfer.yml +59 -0
  158. package/src/components/uploader/QasUploader.vue +169 -48
  159. package/src/components/uploader/QasUploader.yml +117 -0
  160. package/src/css/background.scss +1 -1
  161. package/src/css/border.scss +7 -6
  162. package/src/css/design-system.scss +0 -43
  163. package/src/css/fonts.scss +2 -28
  164. package/src/css/opacity.scss +0 -4
  165. package/src/css/set-brand.scss +15 -0
  166. package/src/css/transitions.scss +1 -1
  167. package/src/helpers/add-counter-suffix.js +3 -0
  168. package/src/helpers/{base64ToBlob.js → base-64-to-blob.js} +0 -0
  169. package/src/helpers/{constructObject.js → construct-object.js} +0 -0
  170. package/src/helpers/filter-object.js +8 -6
  171. package/src/helpers/filters.js +8 -4
  172. package/src/helpers/{greatestCommonDivisor.js → get-greatest-common-divisor.js} +0 -0
  173. package/src/helpers/get-slot-children-text.js +15 -0
  174. package/src/helpers/images.js +28 -0
  175. package/src/helpers/index.js +11 -59
  176. package/src/helpers/{isLocalDevelopment.js → is-local-development.js} +0 -0
  177. package/src/helpers/set-scroll-on-grab.js +61 -0
  178. package/src/index.cjs.js +1 -0
  179. package/src/index.esm.js +4 -0
  180. package/src/index.scss +19 -21
  181. package/src/index.umd.js +2 -0
  182. package/src/mixins/context.js +1 -1
  183. package/src/mixins/dialog-router.js +17 -0
  184. package/src/mixins/form.js +4 -12
  185. package/src/mixins/generator.js +14 -14
  186. package/src/mixins/index.js +2 -8
  187. package/src/mixins/password.js +73 -11
  188. package/src/mixins/screen.js +8 -6
  189. package/src/mixins/view.js +62 -22
  190. package/src/plugins/dialog/Dialog.js +14 -0
  191. package/src/plugins/dialog/Dialog.yml +10 -0
  192. package/src/plugins/index.js +4 -2
  193. package/src/plugins/{NotifyError.js → notify-error/NotifyError.js} +0 -0
  194. package/src/plugins/notify-error/NotifyError.yml +11 -0
  195. package/src/plugins/{NotifySuccess.js → notify-success/NotifySuccess.js} +3 -3
  196. package/src/plugins/notify-success/NotifySuccess.yml +11 -0
  197. package/src/store/history.js +43 -0
  198. package/src/store/index.js +1 -0
  199. package/src/vue-plugin.js +185 -0
  200. package/.babelrc +0 -12
  201. package/.storybook/main.js +0 -35
  202. package/.storybook/preview.js +0 -26
  203. package/debug.log +0 -1
  204. package/index.js +0 -4
  205. package/jest-setup.js +0 -1
  206. package/jest.config.json +0 -22
  207. package/postcss.config.js +0 -5
  208. package/src/components/Introduction.stories.mdx +0 -12
  209. package/src/components/actions-menu/QasActionsMenu.stories.js +0 -73
  210. package/src/components/app-bar/QasAppBar.stories.js +0 -84
  211. package/src/components/app-menu/QasAppMenu.stories.js +0 -66
  212. package/src/components/apps-menu/QasAppsMenu.spec.js +0 -58
  213. package/src/components/apps-menu/QasAppsMenu.stories.js +0 -54
  214. package/src/components/apps-menu/QasAppsMenu.vue +0 -48
  215. package/src/components/avatar/QasAvatar.spec.js +0 -14
  216. package/src/components/avatar/QasAvatar.stories.js +0 -52
  217. package/src/components/box/QasBox.spec.js +0 -18
  218. package/src/components/box/QasBox.stories.js +0 -35
  219. package/src/components/break-line/QasBreakLine.stories.js +0 -57
  220. package/src/components/break-line/QasBreakLine.vue +0 -52
  221. package/src/components/btn/QasBtn.stories.js +0 -45
  222. package/src/components/btn-actions/QasBtnActions.stories.js +0 -77
  223. package/src/components/btn-actions/QasBtnActions.vue +0 -54
  224. package/src/components/card/QasCard.stories.js +0 -126
  225. package/src/components/checkbox-group/QasCheckboxGroup.stories.js +0 -59
  226. package/src/components/copy/QasCopy.stories.js +0 -41
  227. package/src/components/date-time-input/QasDateTimeInput.stories.js +0 -67
  228. package/src/components/debugger/QasDebugger.stories.js +0 -33
  229. package/src/components/delete/QasDelete.stories.js +0 -80
  230. package/src/components/dialog/QasDialog.stories.js +0 -139
  231. package/src/components/dialog-router/QasDialogRouter.stories.js +0 -38
  232. package/src/components/field/QasField.stories.js +0 -181
  233. package/src/components/filters/QasFilters.stories.js +0 -121
  234. package/src/components/form-generator/QasFormGenerator.stories.js +0 -115
  235. package/src/components/form-view/QasFormView.stories.js +0 -236
  236. package/src/components/gallery/QasGallery.stories.js +0 -91
  237. package/src/components/grid-generator/QasGridGenerator.stories.js +0 -142
  238. package/src/components/input/QasInput.stories.js +0 -78
  239. package/src/components/label/QasLabel.stories.js +0 -60
  240. package/src/components/layout/QasLayout.stories.js +0 -104
  241. package/src/components/list-items/QasListItems.stories.js +0 -135
  242. package/src/components/list-view/QasListView.stories.js +0 -168
  243. package/src/components/map/QasMap.stories.js +0 -75
  244. package/src/components/nested-fields/QasNestedFields.stories.js +0 -255
  245. package/src/components/numeric-input/QasNumericInput.stories.js +0 -92
  246. package/src/components/page-header/QasPageHeader.stories.js +0 -61
  247. package/src/components/password-input/QasPasswordInput.stories.js +0 -76
  248. package/src/components/password-strength-checker/QasPasswordStrengthChecker.stories.js +0 -54
  249. package/src/components/profile/QasProfile.stories.js +0 -131
  250. package/src/components/resizer/QasResizer.stories.js +0 -43
  251. package/src/components/search-box/QasSearchBox.stories.js +0 -111
  252. package/src/components/select/QasSelect.stories.js +0 -113
  253. package/src/components/select-list/QasSelectList.stories.js +0 -153
  254. package/src/components/signature-pad/QasSignaturePad.stories.js +0 -51
  255. package/src/components/signature-uploader/QasSignatureUploader.stories.js +0 -69
  256. package/src/components/single-view/QasSingleView.stories.js +0 -130
  257. package/src/components/sortable/QasSortable.stories.js +0 -80
  258. package/src/components/table-generator/QasTableGenerator.stories.js +0 -120
  259. package/src/components/tabs-generator/QasTabsGenerator.stories.js +0 -145
  260. package/src/components/text-truncate/QasTextTruncate.stories.js +0 -55
  261. package/src/components/tip/QasTip.stories.js +0 -57
  262. package/src/components/tip/QasTip.vue +0 -68
  263. package/src/components/tooltip/QasTooltip.stories.js +0 -63
  264. package/src/components/tooltip/QasTooltip.vue +0 -81
  265. package/src/components/transfer/QasTransfer.stories.js +0 -118
  266. package/src/components/uploader/QasCustomUploader.vue +0 -120
  267. package/src/components/uploader/QasUploader.stories.js +0 -139
  268. package/src/directives/Test.js +0 -13
  269. package/src/helpers/historyHandler.js +0 -52
  270. package/src/helpers/label.js +0 -3
  271. package/src/index.js +0 -249
  272. package/src/mixins/map-markers.js +0 -26
  273. package/src/mixins/unsaved-changes.js +0 -24
  274. package/src/mixins/uploader.js +0 -30
  275. package/src/mocks/json/user.json +0 -27
  276. package/src/mocks/json/users-new.json +0 -23
  277. package/src/mocks/json/users.json +0 -97
  278. package/src/mocks/storeModule.js +0 -71
  279. package/src/pages/Forbidden.vue +0 -6
  280. package/src/pages/NotFound.vue +0 -6
@@ -1,24 +1,25 @@
1
1
  <template>
2
- <q-field borderless :error="hasErrorMessage" :error-message="errorMessage" :hint="hintValue" no-error-icon>
3
- <qas-custom-uploader v-bind="attributes" ref="uploader" auto-upload bordered :class="uploaderClasses" :factory="factory" flat :max-files="maxFiles" method="PUT" :readonly="readonly" v-on="$listeners" @factory-failed="factoryFailed" @uploaded="uploaded">
2
+ <q-field borderless class="qas-uploader" :error="hasErrorMessage" :error-message="errorMessage" :hint="hintValue" no-error-icon>
3
+ <q-uploader ref="uploader" auto-upload bordered :class="uploaderClasses" :factory="factory" flat :max-files="maxFiles" method="PUT" :readonly="readonly" v-bind="attributes" @factory-failed="factoryFailed" @uploaded="uploaded" @uploading="updateUploading(true)">
4
4
  <template #header="scope">
5
5
  <slot name="header" :scope="scope">
6
6
  <div class="flex flex-center full-width justify-between no-border no-wrap q-gutter-xs q-pa-sm text-white transparent">
7
7
  <q-spinner v-if="scope.isUploading" size="24px" />
8
8
 
9
9
  <div class="col column items-start justify-center">
10
- <div v-if="scope.label" class="q-uploader__title">{{ scope.label }}</div>
11
- <div v-if="scope.files.length" class="q-uploader__subtitle">{{ scope.uploadProgressLabel }} ({{ scope.uploadSizeLabel }})</div>
10
+ <div v-if="$attrs.label" class="q-uploader__title">{{ $attrs.label }}</div>
11
+ <div v-if="scope.files.length" class="q-uploader__subtitle">
12
+ {{ scope.uploadProgressLabel }} ({{ scope.uploadSizeLabel }})
13
+ </div>
12
14
  </div>
13
15
 
14
- <q-btn v-if="showAddFile" ref="buttonUpload" dense flat icon="o_add" round />
15
-
16
- <q-uploader-add-trigger v-if="showAddFile" ref="uploaderTrigger" />
16
+ <qas-btn v-if="showAddFile" ref="buttonUpload" color="white" dense flat icon="o_add" round @click="$refs.hiddenInput.click()" />
17
17
 
18
- <q-btn ref="buttonCleanFiles" class="hidden" @click="scope.removeUploadedFiles" />
18
+ <input ref="hiddenInput" class="qas-uploader__input" :multiple="isMultiple" type="file">
19
19
 
20
- <q-btn v-if="scope.canUpload" dense flat icon="o_cloud_upload" round @click="scope.upload" />
21
- <q-btn v-if="scope.isUploading" dense flat icon="o_clear" round @click="scope.abort" />
20
+ <qas-btn ref="buttonCleanFiles" class="hidden" color="white" @click="scope.removeUploadedFiles" />
21
+ <qas-btn v-if="scope.canUpload" color="white" dense flat icon="o_cloud_upload" round @click="scope.upload" />
22
+ <qas-btn v-if="scope.isUploading" color="white" dense flat icon="o_clear" round @click="scope.abort" />
22
23
  </div>
23
24
  </slot>
24
25
  </template>
@@ -26,24 +27,24 @@
26
27
  <template #list="scope">
27
28
  <slot name="list" :scope="scope">
28
29
  <div class="col-12 q-col-gutter-md row">
29
- <div v-for="(file, index) in filesList(scope.files, scope)" :key="index" class="row" :class="itemClass">
30
- <qas-avatar class="q-mr-sm" color="grey-3" icon="o_attach_file" :image="file.image" rounded :text-color="colorFileIcon(file)" />
30
+ <div v-for="(file, index) in getFilesList(scope.files, scope)" :key="index" class="row" :class="itemClass">
31
+ <qas-avatar class="q-mr-sm" color="grey-3" icon="o_attach_file" :image="file.image" rounded :text-color="getColorFileIcon(file)" />
31
32
 
32
33
  <div class="col items-center no-wrap row">
33
34
  <div class="column no-wrap" :class="{ col: isMultiple }">
34
- <div class="ellipsis" :class="fileNameClass(file.isFailed)">{{ file.name }}</div>
35
+ <div class="ellipsis" :class="getFileNameClass(file.isFailed)">{{ file.name }}</div>
35
36
  <div v-if="file.isUploaded" class="text-caption">{{ file.progressLabel }} ({{ file.sizeLabel }})</div>
36
37
  </div>
37
38
  <div class="items-center q-ml-sm row">
38
39
  <q-icon v-if="file.isFailed" color="negative" name="o_warning" size="20px" />
39
- <q-btn v-if="!scope.readonly" dense flat icon="o_delete" round @click="removeItem(index, scope, file)" />
40
+ <qas-btn v-if="!scope.readonly" dense flat icon="o_delete" round @click="removeItem(index, scope, file)" />
40
41
  </div>
41
42
  </div>
42
43
  </div>
43
44
  </div>
44
45
  </slot>
45
46
  </template>
46
- </qas-custom-uploader>
47
+ </q-uploader>
47
48
 
48
49
  <slot :context="self" name="custom-upload" />
49
50
 
@@ -54,24 +55,37 @@
54
55
  </template>
55
56
 
56
57
  <script>
57
- import QasAvatar from '../avatar/QasAvatar'
58
- import QasCustomUploader from '../uploader/QasCustomUploader'
59
- import api from 'axios'
58
+ import QasAvatar from '../avatar/QasAvatar.vue'
59
+
60
60
  import { uid, extend } from 'quasar'
61
61
  import { NotifyError } from '../../plugins'
62
- import uploaderMixin from '../../mixins/uploader'
62
+ import { getImageSize, getResizeDimensions } from '../../helpers/images'
63
+
64
+ import Pica from 'pica'
65
+ import api from 'axios'
63
66
 
64
67
  export default {
65
68
  name: 'QasUploader',
66
69
 
67
70
  components: {
68
- QasAvatar,
69
- QasCustomUploader
71
+ QasAvatar
70
72
  },
71
73
 
72
- mixins: [uploaderMixin],
74
+ inheritAttrs: false,
73
75
 
74
76
  props: {
77
+ acceptResizeTypes: {
78
+ default: () => [
79
+ 'image/jpeg',
80
+ 'image/png',
81
+ 'image/gif',
82
+ 'image/bmp',
83
+ 'image/webp',
84
+ 'image/jpg'
85
+ ],
86
+ type: Array
87
+ },
88
+
75
89
  entity: {
76
90
  required: true,
77
91
  type: String
@@ -92,20 +106,43 @@ export default {
92
106
  type: Number
93
107
  },
94
108
 
109
+ picaResizeOptions: {
110
+ default: () => ({}),
111
+ type: Object
112
+ },
113
+
114
+ sizeLimit: {
115
+ default: 1280,
116
+ type: Number
117
+ },
118
+
119
+ useResize: {
120
+ default: true,
121
+ type: Boolean
122
+ },
123
+
95
124
  readonly: {
96
125
  type: Boolean
97
126
  },
98
127
 
99
- value: {
128
+ modelValue: {
100
129
  default: '',
101
130
  type: [Array, String]
131
+ },
132
+
133
+ uploading: {
134
+ type: Boolean
102
135
  }
103
136
  },
104
137
 
138
+ emits: ['update:modelValue', 'update:uploading'],
139
+
105
140
  data () {
106
141
  return {
107
142
  isFetching: false,
108
- isUploading: false
143
+ isUploading: false,
144
+ hiddenInputElement: null,
145
+ uploader: null
109
146
  }
110
147
  },
111
148
 
@@ -121,7 +158,7 @@ export default {
121
158
  showAddFile () {
122
159
  if (this.readonly) return
123
160
 
124
- return this.maxFiles ? this.value.length < this.maxFiles : true
161
+ return this.maxFiles ? this.modelValue.length < this.maxFiles : true
125
162
  },
126
163
 
127
164
  isMultiple () {
@@ -129,7 +166,7 @@ export default {
129
166
  },
130
167
 
131
168
  hasCustomUpload () {
132
- return this.$slots['custom-upload'] || this.$scopedSlots['custom-upload']
169
+ return this.$slots['custom-upload']
133
170
  },
134
171
 
135
172
  itemClass () {
@@ -141,7 +178,7 @@ export default {
141
178
  },
142
179
 
143
180
  hasHeaderSlot () {
144
- return this.$slots.header || this.$scopedSlots.header
181
+ return this.$slots.header
145
182
  },
146
183
 
147
184
  hasErrorMessage () {
@@ -153,19 +190,37 @@ export default {
153
190
  ...this.$attrs,
154
191
  ...this.$props
155
192
  }
193
+ },
194
+
195
+ defaultPicaResizeOptions () {
196
+ return {
197
+ unsharpAmount: 160,
198
+ unsharpRadius: 0.6,
199
+ unsharpThreshold: 1,
200
+ ...this.picaResizeOptions
201
+ }
156
202
  }
157
203
  },
158
204
 
159
- methods: {
160
- NotifyError,
205
+ mounted () {
206
+ this.hiddenInputElement = this.$refs.hiddenInput
207
+ this.uploader = this.$refs.uploader
208
+
209
+ this.hiddenInputElement?.addEventListener?.('change', this.addFiles)
210
+ },
161
211
 
212
+ unmounted () {
213
+ this.hiddenInputElement?.removeEventListener?.('change', this.addFiles)
214
+ },
215
+
216
+ methods: {
162
217
  async factory ([file]) {
163
218
  if (!this.isMultiple && !this.hasHeaderSlot) {
164
219
  this.$refs.buttonCleanFiles.$el.click()
165
220
  }
166
221
 
167
222
  const name = `${uid()}.${file.name.split('.').pop()}`
168
- const { endpoint } = await this.fetch(name)
223
+ const { endpoint } = await this.fetchCredentials(name)
169
224
 
170
225
  return {
171
226
  headers: [
@@ -178,16 +233,27 @@ export default {
178
233
  },
179
234
 
180
235
  factoryFailed () {
236
+ this.updateUploading(false)
181
237
  NotifyError('Ops! Erro ao enviar o arquivo.')
182
238
  },
183
239
 
240
+ dispatchUpload () {
241
+ this.$refs.buttonCleanFiles.$el.click()
242
+ this.hiddenInputElement.click()
243
+ },
244
+
184
245
  uploaded (response) {
185
246
  const fullPath = response.xhr.responseURL.split('?').shift()
186
247
 
187
- this.$emit('input', this.isMultiple ? [...this.value, fullPath] : fullPath || '')
248
+ this.$emit(
249
+ 'update:modelValue',
250
+ this.isMultiple ? [...this.modelValue, fullPath] : fullPath || ''
251
+ )
252
+
253
+ this.updateUploading(false)
188
254
  },
189
255
 
190
- async fetch (filename) {
256
+ async fetchCredentials (filename) {
191
257
  this.isFetching = true
192
258
 
193
259
  try {
@@ -209,26 +275,21 @@ export default {
209
275
  if (file.isFailed) return
210
276
 
211
277
  if (!this.isMultiple) {
212
- return this.$emit('input')
278
+ return this.$emit('update:modelValue')
213
279
  }
214
280
 
215
- const clonedValue = extend(true, [], this.value)
216
- const numberIndex = this.value.findIndex(file => this.fileName(file) === index)
281
+ const clonedValue = extend(true, [], this.modelValue)
282
+ const numberIndex = this.modelValue.findIndex(file => this.getFileName(file) === index)
217
283
  clonedValue.splice(numberIndex, 1)
218
- this.$emit('input', clonedValue)
219
- },
220
-
221
- dispatchUpload () {
222
- this.$refs.buttonCleanFiles.$el.click()
223
- this.$refs.uploaderTrigger.$el.click()
284
+ this.$emit('update:modelValue', clonedValue)
224
285
  },
225
286
 
226
- fileName (value) {
287
+ getFileName (value) {
227
288
  return value.split('/').pop()
228
289
  },
229
290
 
230
- filesList (uploadedFiles) {
231
- const pathsList = Array.isArray(this.value) ? this.value : (this.value ? [this.value] : [])
291
+ getFilesList (uploadedFiles) {
292
+ const pathsList = Array.isArray(this.modelValue) ? this.modelValue : (this.modelValue ? [this.modelValue] : [])
232
293
 
233
294
  uploadedFiles = uploadedFiles.map((file, indexToDelete) => {
234
295
  return {
@@ -253,13 +314,13 @@ export default {
253
314
  }
254
315
 
255
316
  if (typeof file === 'string') {
256
- const fileName = this.fileName(file)
317
+ const fileName = this.getFileName(file)
257
318
  files[fileName] = { image: file, isUploaded: false, name: fileName }
258
319
  return
259
320
  }
260
321
 
261
322
  if (file.image) {
262
- const fileName = this.fileName(file.image)
323
+ const fileName = this.getFileName(file.image)
263
324
  files[fileName] = file
264
325
  }
265
326
  })
@@ -267,7 +328,7 @@ export default {
267
328
  return files
268
329
  },
269
330
 
270
- fileNameClass (isFailed) {
331
+ getFileNameClass (isFailed) {
271
332
  return isFailed ? 'text-negative' : 'text-grey-8'
272
333
  },
273
334
 
@@ -275,9 +336,69 @@ export default {
275
336
  return file.__status === 'failed'
276
337
  },
277
338
 
278
- colorFileIcon (file) {
339
+ getColorFileIcon (file) {
279
340
  return this.isFailed(file) ? 'negative' : 'primary'
341
+ },
342
+
343
+ async addFiles () {
344
+ const filesList = Array.from(this.hiddenInputElement.files)
345
+ const processedFiles = []
346
+
347
+ filesList.forEach(file => processedFiles.push(this.resizeImage(file)))
348
+ this.uploader.addFiles(await Promise.all(processedFiles))
349
+ },
350
+
351
+ // Função para redimensionar imagens
352
+ async resizeImage (file) {
353
+ const { type } = file
354
+
355
+ if (!this.acceptResizeTypes.includes(type) || !this.useResize) return file
356
+
357
+ try {
358
+ const image = new Image()
359
+ const canvas = document.createElement('canvas')
360
+
361
+ image.src = URL.createObjectURL(file)
362
+
363
+ // Retorna largura e altura da original da imagem
364
+ const { width, height } = await getImageSize(image)
365
+
366
+ if (width <= this.sizeLimit) return file
367
+
368
+ // Retorna os novos tamanhos redimensionados
369
+ const resizedDimensions = getResizeDimensions(this.sizeLimit, width, height)
370
+
371
+ canvas.width = resizedDimensions.width
372
+ canvas.height = resizedDimensions.height
373
+
374
+ // Resolve problemas com cors
375
+ image.crossOrigin = ''
376
+
377
+ image.width = width
378
+ image.height = height
379
+
380
+ const pica = Pica()
381
+ const resizedImage = await pica.resize(image, canvas, this.defaultPicaResizeOptions)
382
+ const blob = await pica.toBlob(resizedImage, type, 0.90)
383
+
384
+ return new File([blob], file.name, { type })
385
+ } catch {
386
+ // Caso não consiga redimensionar retorna o arquivo original
387
+ return file
388
+ }
389
+ },
390
+
391
+ updateUploading (uploading) {
392
+ this.$emit('update:uploading', uploading)
280
393
  }
281
394
  }
282
395
  }
283
396
  </script>
397
+
398
+ <style lang="scss">
399
+ .qas-uploader {
400
+ &__input {
401
+ display: none;
402
+ }
403
+ }
404
+ </style>
@@ -0,0 +1,117 @@
1
+ type: component
2
+
3
+ mixins:
4
+ - quasar/dist/api/QField.json
5
+ - quasar/dist/api/QUploader.json
6
+
7
+ meta:
8
+ desc: Componente para upload com auto redimensionamento que implementa o "QField" e "QUploader".
9
+
10
+ props:
11
+ accept-resize-types:
12
+ desc: Tipos de arquivos aceitos para fazer o redimensionamento antes de upar.
13
+ type: Array
14
+ debugger: true
15
+ default: [
16
+ 'image/jpeg',
17
+ 'image/png',
18
+ 'image/gif',
19
+ 'image/bmp',
20
+ 'image/webp',
21
+ 'image/jpg'
22
+ ]
23
+
24
+ entity:
25
+ desc: Entidade enviada para a API do `/upload-credentials/`.
26
+ required: true
27
+ type: String
28
+
29
+ error-message:
30
+ desc: Mensagem de erro.
31
+ type: String
32
+
33
+ hint:
34
+ desc: Mensagem de dica que aparece embaixo do campo.
35
+ type: String
36
+
37
+ max-files:
38
+ desc: Quantidade maxima de arquivos no upload.
39
+ default: undefined
40
+ type: Number
41
+
42
+ pica-resize-options:
43
+ desc: Opções para a biblioteca "pica" que é responsável por fazer o redimensionamento antes do upload (https://github.com/nodeca/pica).
44
+ type: Object
45
+ debugger: true
46
+ default:
47
+ unsharpAmount: 160
48
+ unsharpRadius: 0.6
49
+ unsharpThreshold: 1
50
+
51
+ size-limit:
52
+ desc: Se o tamanho da imagem for menor ou igual ao passado nesta prop, não será feito um redimensionamento.
53
+ default: 1280
54
+ type: Number
55
+
56
+ use-resize:
57
+ desc: Controla se o componente vai fazer o redimensionamento antes de upar as imagens.
58
+ default: true
59
+ type: Number
60
+
61
+ readonly:
62
+ desc: O componente não faz mais upload, apenas exibe.
63
+ default: true
64
+ type: Number
65
+
66
+ model-value:
67
+ desc: Model do componente, caso seja múltiplo, retorna um array de string, senão somente uma string.
68
+ default: true
69
+ type: [Array, String]
70
+ examples: [v-model="value"]
71
+ model: true
72
+
73
+ uploading:
74
+ desc: Model que retorna se o componente está fazendo algum upload.
75
+ type: Boolean
76
+ examples: [v-model:uploading="isUploading"]
77
+ model: true
78
+
79
+ slots:
80
+ header:
81
+ desc: Acesso ao header do <q-uploader />.
82
+ scope:
83
+ scope:
84
+ desc: Payload repassado pelo QUploader.
85
+ default: {}
86
+ type: Object
87
+
88
+ list:
89
+ desc: Acesso ao conteúdo onde fica a listagem de arquivos.
90
+ scope:
91
+ scope:
92
+ desc: Payload repassado pelo QUploader.
93
+ default: {}
94
+ type: Object
95
+
96
+ custom-upload:
97
+ desc: Acesso ao conteúdo onde fica a listagem de arquivos.
98
+ scope:
99
+ context:
100
+ desc: Repassa todo o payload do próprio componente `QasUploader` como computada, data, props, methods, etc.
101
+ default: {}
102
+ type: Object
103
+
104
+ events:
105
+ '@update:model-value -> function(value)':
106
+ desc: Dispara quando o model-value altera, também usado para v-model.
107
+ params:
108
+ value:
109
+ desc: Novo valor do model.
110
+ type: [Array, String]
111
+
112
+ '@update:uploading -> function(value)':
113
+ desc: Dispara começa e termina um upload.
114
+ params:
115
+ value:
116
+ desc: Retorna se está ou não fazendo um upload.
117
+ type: Boolean
@@ -1,4 +1,4 @@
1
- // Reapeat
1
+ // Repeat
2
2
  .bg-no-repeat {
3
3
  background-repeat: no-repeat !important;
4
4
  }
@@ -5,17 +5,18 @@
5
5
  }
6
6
  }
7
7
 
8
- @mixin setBorderColor($name, $color) {
8
+ @mixin set-border-color($name, $color) {
9
9
  .border-#{$name} {
10
- @extend %border-color;
11
10
  border: 0 solid $color !important;
11
+
12
+ @extend %border-color;
12
13
  }
13
14
  }
14
15
 
15
- @include setBorderColor(primary, $primary);
16
- @include setBorderColor(primary-contrast, $primary-contrast);
17
- @include setBorderColor(secondary, $secondary);
18
- @include setBorderColor(secondary-contrast, $secondary-contrast);
16
+ @include set-border-color(primary, $primary);
17
+ @include set-border-color(primary-contrast, $primary-contrast);
18
+ @include set-border-color(secondary, $secondary);
19
+ @include set-border-color(secondary-contrast, $secondary-contrast);
19
20
 
20
21
  // Direction
21
22
  .border-top {
@@ -2,34 +2,6 @@ body {
2
2
  background-color: $background-color;
3
3
  }
4
4
 
5
- // Layout
6
- // .q-layout {
7
- // > .q-header::before,
8
- // > .q-drawer-container .q-drawer__content::before {
9
- // content: '';
10
- // height: 100%;
11
- // left: 0;
12
- // position: absolute;
13
- // width: 100%;
14
- // }
15
-
16
- // // Header
17
- // > .q-header::before {
18
- // background: linear-gradient(to right, rgba(black, 0.7), rgba(black, 0.1));
19
- // }
20
-
21
- // // Menu
22
- // > .q-drawer-container .q-drawer__content {
23
- // background-color: $primary;
24
- // color: white;
25
- // position: relative;
26
-
27
- // &::before {
28
- // background: linear-gradient(to right, rgba(black, 0.85), rgba(black, 0.4));
29
- // }
30
- // }
31
- // }
32
-
33
5
  // Fields
34
6
  .q-field--outlined .q-field__inner {
35
7
  background-color: white;
@@ -44,18 +16,3 @@ body {
44
16
  .q-tabs__arrow {
45
17
  color: $primary;
46
18
  }
47
-
48
- // Scrollbar
49
- ::-webkit-scrollbar {
50
- height: 7px;
51
- width: 7px;
52
- }
53
-
54
- ::-webkit-scrollbar-thumb {
55
- background-color: $primary;
56
- border-radius: $generic-border-radius;
57
- }
58
-
59
- ::-webkit-scrollbar-track {
60
- background-color: $primary-contrast;
61
- }