@mythpe/quasar-ui-qui 0.4.97 → 0.4.99

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mythpe/quasar-ui-qui",
3
- "version": "0.4.97",
3
+ "version": "0.4.99",
4
4
  "description": "MyTh Quasar UI Kit App Extension",
5
5
  "author": {
6
6
  "name": "MyTh Ahmed Faiz",
@@ -10,5 +10,5 @@ import { boot } from 'quasar/wrappers'
10
10
  import { install } from '../utils'
11
11
 
12
12
  export default boot(({ app }) => {
13
- app.use(install)
13
+ app.use(install, {} as any)
14
14
  })
@@ -232,7 +232,7 @@ const $q = useQuasar()
232
232
  const $router = useRouter()
233
233
  const { te } = useI18n({ useScope: 'global' })
234
234
  const useFormContext = useForm<any, any>()
235
- const { resetForm: resetDialogForm, handleSubmit } = useFormContext
235
+ const { resetForm: resetDialogForm, handleSubmit, errors, meta } = useFormContext
236
236
 
237
237
  const {
238
238
  onRowContextmenu,
@@ -254,6 +254,7 @@ const {
254
254
  dialogErrors,
255
255
  setDialogErrors,
256
256
  resetDialogs,
257
+ resetVeeForm,
257
258
  getHeaders,
258
259
  getSortedHeaders,
259
260
  arrangementColumns,
@@ -417,6 +418,7 @@ const onSuccess: SubmissionHandler = async (form) => {
417
418
  if (isUpdateMode.value) {
418
419
  if (_data) {
419
420
  updateDatatableItem(_data as any, dialogItemIndex.value)
421
+ resetVeeForm(_data)
420
422
  }
421
423
  emit('update', response)
422
424
  if (!props.noUpdateClose && !props.noAutoClose) {
@@ -495,9 +497,17 @@ watch(loading, v => {
495
497
  watch([filterForm, () => $q.lang.nativeName], () => refreshNoUpdate(), { deep: !0 })
496
498
  watch(formDialogModel, (v) => {
497
499
  if (!v) {
500
+ const keys = { ...dialogErrors.value, ...errors.value }
501
+ for (const k in keys) {
502
+ useFormContext.setFieldError(k, undefined)
503
+ useFormContext.setFieldTouched(k, !1)
504
+ }
498
505
  dialogErrors.value = {}
499
506
  }
500
507
  })
508
+ watch(dialogErrors, (v) => {
509
+ useFormContext.setErrors(v || {})
510
+ }, { deep: !0 })
501
511
  const table = ref<InstanceType<typeof QTable>>()
502
512
  const mainAttrs = computed(() => ({
503
513
  title: getTableTitle.value,
@@ -557,6 +567,7 @@ defineOptions({
557
567
  defineExpose({
558
568
  formContext: useFormContext,
559
569
  resetDialogs,
570
+ resetVeeForm,
560
571
  tableOptions,
561
572
  getMythApiServicesSchema,
562
573
  updateSelectedItems,
@@ -1691,8 +1702,10 @@ defineExpose({
1691
1702
  >
1692
1703
  <MBtn
1693
1704
  :class="{'full-width': $q.screen.xs}"
1705
+ :disable="isUpdateMode ? (!meta.dirty && !meta.touched) || (!meta.dirty && meta.touched) : false"
1694
1706
  :label="__(`myth.titles.${isUpdateMode ? 'save' : 'store'}`)"
1695
1707
  :loading="loading"
1708
+ style="min-width: 120px"
1696
1709
  type="submit"
1697
1710
  v-bind="pluginOptions.dt?.dialogButtonsProps"
1698
1711
  />
@@ -1702,6 +1715,7 @@ defineExpose({
1702
1715
  :disable="loading"
1703
1716
  label="myth.titles.close"
1704
1717
  outline
1718
+ style="min-width: 120px"
1705
1719
  text-color="body"
1706
1720
  v-bind="pluginOptions.dt?.dialogButtonsProps"
1707
1721
  @click="closeFormDialog"
@@ -241,7 +241,7 @@ defineOptions({
241
241
  <MRow
242
242
  v-if="label !== undefined"
243
243
  key="label"
244
- class="items-center q-mb-md"
244
+ class="items-center q-mb-sm"
245
245
  >
246
246
  <q-skeleton
247
247
  v-if="loading"
@@ -261,6 +261,7 @@ defineOptions({
261
261
  <MHelpRow
262
262
  v-if="!!help && !loading"
263
263
  :text="help"
264
+ style="margin-top: 0"
264
265
  tooltip
265
266
  />
266
267
  </MRow>
@@ -316,6 +317,12 @@ defineOptions({
316
317
  class="text-white text-h3"
317
318
  v-text="getAvatarText"
318
319
  />
320
+ <div v-else>
321
+ <q-icon
322
+ :name="`ion-ios-${readonly ? 'aperture' : 'cloud-upload'}`"
323
+ color="primary"
324
+ />
325
+ </div>
319
326
  </q-avatar>
320
327
  </MTransition>
321
328
  </div>
@@ -166,7 +166,7 @@ defineOptions({
166
166
  <MHelpRow
167
167
  v-if="!!help"
168
168
  :text="help"
169
- class="q-ml-md"
169
+ class="q-ml-sm"
170
170
  tooltip
171
171
  />
172
172
  </MInputLabel>
@@ -255,13 +255,13 @@ defineOptions({
255
255
  <MHelpRow
256
256
  v-if="!!help"
257
257
  :text="help"
258
- class="q-ml-lg"
258
+ class="q-ml-sm"
259
259
  tooltip
260
260
  />
261
261
  <template v-if="loading">
262
262
  <div class="flex-break" />
263
263
  <q-spinner-dots
264
- class="q-mt-lg q-ml-lg"
264
+ class="q-mt-lg q-ml-sm"
265
265
  color="primary"
266
266
  size="25px"
267
267
  />
@@ -200,6 +200,7 @@ defineOptions({
200
200
  >
201
201
  <MHelpRow
202
202
  v-if="!!help"
203
+ class="q-ml-sm"
203
204
  :text="help"
204
205
  tooltip
205
206
  />
@@ -261,6 +261,7 @@ defineOptions({
261
261
  <MHelpRow
262
262
  v-if="!!help"
263
263
  :text="help"
264
+ class="q-ml-sm"
264
265
  tooltip
265
266
  />
266
267
  </MInputLabel>
@@ -169,6 +169,7 @@ defineOptions({
169
169
  <MHelpRow
170
170
  v-if="!!help"
171
171
  :text="help"
172
+ class="q-ml-sm"
172
173
  tooltip
173
174
  />
174
175
  </MInputLabel>
@@ -365,15 +365,15 @@ defineOptions({
365
365
  <div class="col">
366
366
  <div
367
367
  v-if="!!label"
368
- class="q-uploader__title"
368
+ class="q-uploader__title text-large"
369
369
  >
370
370
  {{ __(label) }}
371
371
  </div>
372
372
  <div
373
- v-if="!readonly"
373
+ v-if="!readonly && (scope.uploadSizeLabel !== '0.0B' && scope.uploadProgressLabel !== '0.00%')"
374
374
  class="q-uploader__subtitle"
375
375
  >
376
- {{ scope.uploadSizeLabel }} / {{ scope.uploadProgressLabel }}
376
+ {{ scope.uploadSizeLabel }} {{ scope.uploadProgressLabel }}
377
377
  </div>
378
378
  </div>
379
379
  <template v-if="!readonly">
@@ -472,8 +472,8 @@ defineOptions({
472
472
  </MRow>
473
473
  <q-list
474
474
  v-else
475
- :class="{'row': displayMode === 'card','q-gutter-sm': displayMode === 'card'}"
476
- :separator="displayMode === 'list' ? !0 : undefined"
475
+ :class="{'row q-gutter-sm': displayMode === 'card' && !$q.screen.xs}"
476
+ :separator="displayMode === 'list' || $q.screen.xs ? !0 : undefined"
477
477
  >
478
478
  <template
479
479
  v-for="(file,i) in scope.files"
@@ -508,6 +508,7 @@ defineOptions({
508
508
  >
509
509
  <MUploaderItem
510
510
  :audio-props="audioProps"
511
+ :class="{'q-mb-sm': $q.screen.xs}"
511
512
  :collection="collection"
512
513
  :default-file-icon="defaultFileIcon"
513
514
  :delete-media-icon="deleteMediaIcon"
@@ -61,7 +61,7 @@ const props = withDefaults(defineProps<P>(), {
61
61
  defaultFileIcon: undefined,
62
62
  deleteMediaIcon: undefined,
63
63
  downloadFileIcon: undefined,
64
- mediaLabel: () => '',
64
+ mediaLabel: undefined,
65
65
  ratio: 16 / 9,
66
66
  videoProps: undefined,
67
67
  audioProps: undefined
@@ -83,7 +83,7 @@ const emit = defineEmits<Emits>()
83
83
 
84
84
  const q = useQuasar()
85
85
  const { te } = useI18n({ useScope: 'global' })
86
- const { alertError, alertSuccess, confirmMessage, __, props: pluginOptions, api: mApi } = useMyth()
86
+ const { alertError, alertSuccess, confirmMessage, __, props: pluginOptions, api: mApi, ucFirst } = useMyth()
87
87
  const api = computed(() => mApi.value.services)
88
88
  const setModelValue = (value: Props['modelValue']) => emit('values', value)
89
89
  const deleting = ref(!1)
@@ -199,7 +199,7 @@ defineOptions({
199
199
  />
200
200
  </q-item-section>
201
201
  <q-item-section :class="{'overflow-hidden': displayMode === 'card'}">
202
- <q-item-label v-if="!!mediaProp[mediaLabel]">
202
+ <q-item-label v-if="mediaLabel && !!mediaProp[mediaLabel]">
203
203
  {{ mediaProp[mediaLabel] }}
204
204
  <q-icon
205
205
  v-if="updateBtn"
@@ -274,8 +274,9 @@ defineOptions({
274
274
  caption
275
275
  class="print-hide"
276
276
  >
277
- <span v-if="!!mediaProp.size_to_string">{{ mediaProp.size_to_string }} | {{ modelValue.type_to_string || modelValue.type }}</span>
278
- <span v-if="modelValue.__sizeLabel">{{ modelValue.__sizeLabel }} / {{ modelValue.__progressLabel }}</span>
277
+ <span v-if="!!mediaProp.size_to_string && modelValue.type_to_string">{{ mediaProp.size_to_string }} {{ modelValue.type_to_string }}</span>
278
+ <span v-else-if="!!mediaProp.size_to_string">{{ mediaProp.size_to_string }}</span>
279
+ <span v-if="modelValue.__sizeLabel">{{ modelValue.__sizeLabel }} • {{ modelValue.__progressLabel }}</span>
279
280
  </q-item-label>
280
281
  <q-item-label
281
282
  v-if="(mediaProp.id && mediaProp.url) || (!hideDeleteMedia || (hideDeleteMedia && !mediaProp.id))"
@@ -7,17 +7,9 @@
7
7
  -->
8
8
 
9
9
  <script lang="ts" setup>
10
- import type { QIconProps } from 'quasar'
11
- import { computed } from 'vue'
12
10
 
13
- type Props = QIconProps
14
- const noDefault = defineModel<boolean>('noDefault', { required: !1, default: !1 })
15
- const props = defineProps<Props>()
16
- const getSize = computed<any>(() => ({
17
- size: noDefault.value ? props.size : (props.size || '100%')
18
- }))
19
11
  defineOptions({
20
- name: 'MSarString',
12
+ name: 'MSarIcon',
21
13
  inheritAttrs: !1
22
14
  })
23
15
  </script>
@@ -25,20 +17,8 @@ defineOptions({
25
17
  <template>
26
18
  <q-icon
27
19
  class="m-sar-icon"
28
- v-bind="Object.assign({},$props,$attrs,getSize)"
20
+ v-bind="{...$attrs, name: 'myth-sar'}"
29
21
  >
30
- <slot name="default">
31
- <svg
32
- viewBox="0 0 1124.14 1256.39"
33
- xmlns="http://www.w3.org/2000/svg"
34
- >
35
- <path
36
- d="M699.62,1113.02h0c-20.06,44.48-33.32,92.75-38.4,143.37l424.51-90.24c20.06-44.47,33.31-92.75,38.4-143.37l-424.51,90.24Z"
37
- />
38
- <path
39
- d="M1085.73,895.8c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.33v-135.2l292.27-62.11c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.27V66.13c-50.67,28.45-95.67,66.32-132.25,110.99v403.35l-132.25,28.11V0c-50.67,28.44-95.67,66.32-132.25,110.99v525.69l-295.91,62.88c-20.06,44.47-33.33,92.75-38.42,143.37l334.33-71.05v170.26l-358.3,76.14c-20.06,44.47-33.32,92.75-38.4,143.37l375.04-79.7c30.53-6.35,56.77-24.4,73.83-49.24l68.78-101.97v-.02c7.14-10.55,11.3-23.27,11.3-36.97v-149.98l132.25-28.11v270.4l424.53-90.28Z"
40
- />
41
- </svg>
42
- </slot>
22
+ <slot />
43
23
  </q-icon>
44
24
  </template>
@@ -21,7 +21,7 @@ import { useMyth } from './useMyth'
21
21
  import { extend, is, useQuasar } from 'quasar'
22
22
  import { useRoute, useRouter } from 'vue-router'
23
23
  import type { AxiosRequestConfig } from 'axios'
24
- import { useResetForm, useSetFormValues } from 'vee-validate'
24
+ import { useResetForm } from 'vee-validate'
25
25
  import { MFrameDialog } from '../components'
26
26
 
27
27
  const initPaginationOptions: MDatatablePagination = {
@@ -491,15 +491,16 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>, emit?:
491
491
  }
492
492
  }
493
493
  const openDialogTimeout = 100
494
- const setValues = useSetFormValues()
495
494
  const resetDialogForm = useResetForm()
496
495
  const resetVeeForm = async (attrs?: Record<string, any>) => {
497
- const init: any = {}
496
+ let init: any = {}
498
497
  for (const k in defaultItem.value) {
499
498
  init[k] = attrs && k in attrs ? attrs[k] : defaultItem.value[k]
500
499
  }
501
- resetDialogForm({ values: init || {} }, { force: !0 })
502
- attrs && setValues(attrs, !1)
500
+ if (attrs) {
501
+ init = { ...init, ...attrs }
502
+ }
503
+ resetDialogForm({ values: init || {}, errors: undefined }, { force: !0 })
503
504
  }
504
505
  const beforeShowFilterDialog = async () => {
505
506
  resetDialogForm({ values: {}, errors: {} }, { force: !0 })
@@ -633,11 +634,10 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>, emit?:
633
634
  getRows.value[index] = { ..._data } as any
634
635
  nextTick(() => setTimeout(() => (selected.value = [getRows.value[index] as any]), openDialogTimeout))
635
636
  }
636
- setTimeout(() => {
637
- resetVeeForm(_data)
638
- nextTick(() => {
639
- formDialogModel.value = !0
640
- })
637
+ setTimeout(async () => {
638
+ await resetVeeForm(_data)
639
+ await nextTick()
640
+ formDialogModel.value = !0
641
641
  }, openDialogTimeout)
642
642
  })
643
643
  .catch((e: any) => {
@@ -1024,6 +1024,7 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>, emit?:
1024
1024
  dialogErrors,
1025
1025
  setDialogErrors,
1026
1026
  resetDialogs,
1027
+ resetVeeForm,
1027
1028
  getHeaders,
1028
1029
  getSortedHeaders,
1029
1030
  arrangementColumns,
@@ -0,0 +1,13 @@
1
+ /*
2
+ * MyTh Ahmed Faiz Copyright © 2016-2026 All rights reserved.
3
+ * Email: mythpe@gmail.com
4
+ * Mobile: +966590470092
5
+ * Website: https://www.4myth.com
6
+ * Github: https://github.com/mythpe
7
+ */
8
+
9
+ export const iconSet = 'myth-'
10
+ export const icons = {
11
+ sar: 'M699.62,1113.02h0c-20.06,44.48-33.32,92.75-38.4,143.37l424.51-90.24c20.06-44.47,33.31-92.75,38.4-143.37l-424.51,90.24Z&&M1085.73,895.8c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.33v-135.2l292.27-62.11c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.27V66.13c-50.67,28.45-95.67,66.32-132.25,110.99v403.35l-132.25,28.11V0c-50.67,28.44-95.67,66.32-132.25,110.99v525.69l-295.91,62.88c-20.06,44.47-33.33,92.75-38.42,143.37l334.33-71.05v170.26l-358.3,76.14c-20.06,44.47-33.32,92.75-38.4,143.37l375.04-79.7c30.53-6.35,56.77-24.4,73.83-49.24l68.78-101.97v-.02c7.14-10.55,11.3-23.27,11.3-36.97v-149.98l132.25-28.11v270.4l424.53-90.28Z|0 0 1124.14 1256.39'
12
+ }
13
+ export default {}
@@ -0,0 +1,10 @@
1
+ /*
2
+ * MyTh Ahmed Faiz Copyright © 2016-2026 All rights reserved.
3
+ * Email: mythpe@gmail.com
4
+ * Mobile: +966590470092
5
+ * Website: https://www.4myth.com
6
+ * Github: https://github.com/mythpe
7
+ */
8
+
9
+ export * from './config'
10
+ export default {}
@@ -34,3 +34,6 @@ $text-underline-styles: ("solid": solid, "double": double, "dotted": dotted, "da
34
34
  .text-underline-#{$style-name}
35
35
  text-decoration-line: underline !important
36
36
  text-decoration-style: $style-value !important
37
+
38
+ .text-large
39
+ font-size: large
@@ -9,7 +9,7 @@
9
9
  import type { VNode } from 'vue'
10
10
  import type { QIconProps } from 'quasar'
11
11
 
12
- export type MSarIconProps = Omit<QIconProps, 'name'> & Record<string, any>;
12
+ export type MSarIconProps = Omit<QIconProps, 'name'>;
13
13
 
14
14
  export interface MSarIconSlots {
15
15
  default: () => VNode[]
@@ -20,22 +20,27 @@ export interface MUploaderMediaItem {
20
20
  name: string;
21
21
  file_name: string;
22
22
  type: MediaType;
23
- type_to_string: string;
23
+ type_to_string: string | null;
24
+ mime_type: string;
24
25
  size: number;
25
26
  size_to_string: string;
27
+ collection_name: string;
28
+ collection_to_string: string;
26
29
  url: string;
27
30
  download_url: string;
28
- icon: string;
29
- description: string;
30
- attachment_type: string;
31
- collection_to_string: string;
31
+ icon: string | null;
32
+ description: string | null;
33
+ attachment_type: string | null;
32
34
  attachment_type_id: number | null;
33
- attachment_type_id_to_string: string;
35
+ attachment_type_id_to_string: string | null;
34
36
  user_id: number | null;
35
- user_id_to_string: string;
37
+ user_id_to_string: string | null;
36
38
  order_column: number;
37
39
  original_url: boolean;
38
40
  preview_url: boolean;
41
+ model_id: number;
42
+ model_id_to_string: string;
43
+ model_type: string;
39
44
  model_type_to_string: string;
40
45
  is_image: boolean;
41
46
  is_pdf: boolean;
@@ -13,6 +13,8 @@ import { defineComponents } from '../plugin/defineComponents'
13
13
 
14
14
  import { createMyth, extendOptions } from './createMyth'
15
15
  import { MythKey } from './const'
16
+ import { icons, iconSet } from '../icons'
17
+ import { Str } from './Str'
16
18
 
17
19
  function install (app: App, options: InstallOptions) {
18
20
  const opts = extendOptions(options)
@@ -35,6 +37,20 @@ function install (app: App, options: InstallOptions) {
35
37
  // for (const routesKey in routes) {
36
38
  // console.log(routesKey)
37
39
  // }
40
+ const otherIconMapFn = app.config.globalProperties.$q.iconMapFn
41
+ app.config.globalProperties.$q.iconMapFn = (iconName) => {
42
+ if (iconName.startsWith(iconSet)) {
43
+ const name = Str.camelCase(iconName.slice(iconSet.length))
44
+ if (Object.keys(icons).includes(name)) {
45
+ return {
46
+ icon: icons[name]
47
+ }
48
+ }
49
+ }
50
+ if (typeof otherIconMapFn === 'function') {
51
+ return otherIconMapFn(iconName)
52
+ }
53
+ }
38
54
  }
39
55
 
40
56
  export {