@mythpe/quasar-ui-qui 0.1.65 → 0.1.67

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.1.65",
3
+ "version": "0.1.67",
4
4
  "description": "MyTh Quasar UI Kit App Extension",
5
5
  "author": {
6
6
  "name": "MyTh Ahmed Faiz",
@@ -13,7 +13,7 @@
13
13
  import type { MDatatableProps } from '../../types'
14
14
  import type { InvalidSubmissionHandler, SubmissionHandler } from 'vee-validate'
15
15
  import { useForm } from 'vee-validate'
16
- import { onMounted, ref, toValue, watch } from 'vue'
16
+ import { computed, onMounted, ref, toValue, watch } from 'vue'
17
17
  import { is as quasarHelpers, QCardSection, QTable, useQuasar } from 'quasar'
18
18
  import lodash from 'lodash'
19
19
  import { useDtHelpers, useMyth } from '../../composable'
@@ -78,6 +78,8 @@ type Props = {
78
78
  imageSize?: MDatatableProps['imageSize'];
79
79
  noBackBtn?: boolean;
80
80
  backIcon?: MDatatableProps['backIcon'];
81
+ urlColumns?: MDatatableProps['urlColumns'];
82
+ colorColumns?: MDatatableProps['colorColumns'];
81
83
  }
82
84
 
83
85
  const props = withDefaults(defineProps<Props>(), {
@@ -138,7 +140,9 @@ const props = withDefaults(defineProps<Props>(), {
138
140
  imageMode: () => 'image',
139
141
  imageSize: () => '35px',
140
142
  noBackBtn: !1,
141
- backIcon: undefined
143
+ backIcon: undefined,
144
+ urlColumns: () => ([]),
145
+ colorColumns: () => ([])
142
146
  })
143
147
 
144
148
  interface Emits {
@@ -155,7 +159,9 @@ const {
155
159
  scrollToElementFromErrors,
156
160
  props: pluginOptions,
157
161
  theme,
158
- isSmall
162
+ isSmall,
163
+ openWindow,
164
+ copyText
159
165
  } = useMyth()
160
166
 
161
167
  const $q = useQuasar()
@@ -363,7 +369,8 @@ const onInvalidSubmit: InvalidSubmissionHandler = ({ errors }) => {
363
369
  }
364
370
  }
365
371
  const defaultSubmitItem = handleSubmit.withControlled(onSuccess, onInvalidSubmit)
366
-
372
+ const urlColumnsProp = computed<string[]>(() => toValue(props.urlColumns) || [])
373
+ const colorColumnsProp = computed<string[]>(() => toValue(props.colorColumns) || [])
367
374
  onMounted(() => refresh())
368
375
  watch(loading, v => {
369
376
  if (pluginOptions.value?.dt?.useQuasarLoading) {
@@ -499,21 +506,6 @@ defineExpose({
499
506
  @update:selected="onUpdateSelectedItems"
500
507
  @virtual-scroll="endReach ? onScroll : undefined"
501
508
  >
502
- <template
503
- v-for="slotName in getSlots"
504
- :key="slotName"
505
- #[slotName]="inputSlot"
506
- >
507
- <slot
508
- :dt="datatableItemsScope"
509
- :form="useFormContext"
510
- :index="dialogItemIndex"
511
- :item="dialogItem"
512
- :name="slotName"
513
- v-bind="inputSlot || {}"
514
- />
515
- </template>
516
-
517
509
  <template #item="iTempProps">
518
510
  <slot
519
511
  :dt="datatableItemsScope"
@@ -599,6 +591,37 @@ defineExpose({
599
591
  </q-img>
600
592
  </template>
601
593
  </template>
594
+ <template v-else-if="urlColumnsProp.indexOf(col.name) !== -1">
595
+ <MBtn
596
+ v-if="!!col.value"
597
+ dense
598
+ fab-mini
599
+ flat
600
+ icon="ion-ios-open"
601
+ @click="openWindow(col.value)"
602
+ >
603
+ <q-tooltip>
604
+ {{ col.value }}
605
+ </q-tooltip>
606
+ </MBtn>
607
+ </template>
608
+ <template v-else-if="colorColumnsProp.indexOf(col.name) !== -1">
609
+ <div
610
+ v-if="!!col.value"
611
+ class="row q-gutter-lg justify-center items-center"
612
+ >
613
+ <div>
614
+ {{ col.value }}
615
+ </div>
616
+ <div
617
+ :style="`width: 20px; height: 20px; background-color: ${col.value};`"
618
+ class="m--input__color-preview cursor-pointer"
619
+ @click="copyText(col.value)"
620
+ >
621
+ <q-tooltip>{{ __('labels.copy') }}</q-tooltip>
622
+ </div>
623
+ </div>
624
+ </template>
602
625
  <template v-else-if="col.name === controlKey">
603
626
  <MRow
604
627
  class="m--dt-context_menu_items"
@@ -631,7 +654,6 @@ defineExpose({
631
654
  </div>
632
655
  </slot>
633
656
  </template>
634
-
635
657
  <template #top="topSlotProps">
636
658
  <MCol col="12">
637
659
  <MContainer
@@ -1073,7 +1095,6 @@ defineExpose({
1073
1095
  </MContainer>
1074
1096
  </MCol>
1075
1097
  </template>
1076
-
1077
1098
  <template
1078
1099
  v-if="endReach"
1079
1100
  #bottom
@@ -1081,7 +1102,6 @@ defineExpose({
1081
1102
  <q-space />
1082
1103
  <div v-text="__('replace.from_to', { from: pagination.rowsNumber, to: getRows.length })" />
1083
1104
  </template>
1084
-
1085
1105
  <template
1086
1106
  v-if="!noBodyControl"
1087
1107
  #[`body-cell-${controlKey}`]="noBodyProps"
@@ -1171,6 +1191,65 @@ defineExpose({
1171
1191
  </template>
1172
1192
  </q-td>
1173
1193
  </template>
1194
+ <template
1195
+ v-for="u in urlColumnsProp"
1196
+ :key="`a-u-${u}`"
1197
+ #[`body-cell-${u}`]="urlProps"
1198
+ >
1199
+ <q-td :props="urlProps">
1200
+ <template v-if="!!urlProps.row[u]">
1201
+ <MBtn
1202
+ dense
1203
+ fab-mini
1204
+ flat
1205
+ icon="ion-ios-open"
1206
+ @click="openWindow(urlProps.row[u])"
1207
+ >
1208
+ <q-tooltip>
1209
+ {{ urlProps.row[u] }}
1210
+ </q-tooltip>
1211
+ </MBtn>
1212
+ </template>
1213
+ </q-td>
1214
+ </template>
1215
+ <template
1216
+ v-for="cc in colorColumnsProp"
1217
+ :key="`a-cc-${cc}`"
1218
+ #[`body-cell-${cc}`]="ccProps"
1219
+ >
1220
+ <q-td :props="ccProps">
1221
+ <div
1222
+ v-if="!!ccProps.row[cc]"
1223
+ class="row q-gutter-lg justify-center items-center"
1224
+ >
1225
+ <div>
1226
+ {{ ccProps.row[cc] }}
1227
+ </div>
1228
+ <div
1229
+ :style="`width: 20px; height: 20px; background-color: ${ccProps.row[cc]};`"
1230
+ class="m--input__color-preview cursor-pointer"
1231
+ @click="copyText(ccProps.row[cc])"
1232
+ >
1233
+ <q-tooltip>{{ __('labels.copy') }}</q-tooltip>
1234
+ </div>
1235
+ </div>
1236
+ </q-td>
1237
+ </template>
1238
+
1239
+ <template
1240
+ v-for="slotName in getSlots"
1241
+ :key="slotName"
1242
+ #[slotName]="inputSlot"
1243
+ >
1244
+ <slot
1245
+ :dt="datatableItemsScope"
1246
+ :form="useFormContext"
1247
+ :index="dialogItemIndex"
1248
+ :item="dialogItem"
1249
+ :name="slotName"
1250
+ v-bind="inputSlot || {}"
1251
+ />
1252
+ </template>
1174
1253
  </q-table>
1175
1254
  <slot
1176
1255
  :dt="datatableItemsScope"
@@ -62,9 +62,21 @@ const prepare = async (fromWatch = !1) => {
62
62
  if (!props.service || loading.value) {
63
63
  return
64
64
  }
65
- const method = typeof props.service === 'string'
66
- ? (isGuest.value ? api.value.services[props.service]?.staticIndex : api.value.services[props.service]?.index)
67
- : props.service
65
+ const s = props.service
66
+ let method: any = null
67
+ if (typeof s === 'string' && s.includes('.')) {
68
+ const args = s.split('.')
69
+ do {
70
+ if (!method) {
71
+ method = api.value.services[args.shift() as any]
72
+ }
73
+ method = method[args.shift() as any]
74
+ }
75
+ while (args.length)
76
+ } else {
77
+ method = typeof s === 'function' ? s : (isGuest.value ? api.value.services[s].staticIndex : api.value.services[s].index)
78
+ }
79
+
68
80
  if (!method) {
69
81
  throw Error(`No service: ${props.service}`)
70
82
  }
@@ -13,7 +13,7 @@
13
13
 
14
14
  import { useField } from 'vee-validate'
15
15
  import type { MOptionsOptionContext, MOptionsProps as Props } from '../../types'
16
- import { reactive, toValue, useTemplateRef } from 'vue'
16
+ import { onMounted, reactive, toValue, useTemplateRef } from 'vue'
17
17
  import { QField, QOptionGroup, type QOptionGroupSlots } from 'quasar'
18
18
  import { useBindInput, useMyth } from '../../composable'
19
19
 
@@ -40,6 +40,7 @@ interface P {
40
40
  type?: Props['type'];
41
41
  keepColor?: Props['keepColor'];
42
42
  service?: Props['service'];
43
+ guest?: boolean;
43
44
  fullWidth?: Props['fullWidth'];
44
45
  fitWidth?: Props['fullWidth'];
45
46
  fieldOptions?: Props['fieldOptions'];
@@ -67,6 +68,7 @@ const props = withDefaults(defineProps<P>(), {
67
68
  color: () => 'primary',
68
69
  type: 'radio',
69
70
  keepColor: undefined,
71
+ guest: !1,
70
72
  service: undefined,
71
73
  fullWidth: () => !1,
72
74
  fitWidth: () => !1,
@@ -91,13 +93,29 @@ const listeners = {
91
93
  const input = useTemplateRef<InstanceType<typeof QField> | InstanceType<typeof QOptionGroup>>('input')
92
94
  const scopes = reactive(inputScope)
93
95
  defineExpose<typeof scopes & { input: typeof input }>({ input, ...scopes })
94
- const { alertError, __, props: pluginProps } = useMyth()
96
+ const { alertError, __, props: pluginProps, api } = useMyth()
95
97
  const fetchData = async () => {
96
98
  if (props.service) {
99
+ const s = props.service
97
100
  loading.value = !0
98
101
  try {
99
- const { _data } = await props.service()
100
- options.value = _data as any
102
+ let method: any = null
103
+ if (typeof s === 'string' && s.includes('.')) {
104
+ const args = s.split('.')
105
+ do {
106
+ if (!method) {
107
+ method = api.value.services[args.shift() as any]
108
+ }
109
+ method = method[args.shift() as any]
110
+ }
111
+ while (args.length)
112
+ } else {
113
+ method = typeof s === 'function' ? s : (props.guest ? api.value.services[s].staticIndex : api.value.services[s].index)
114
+ }
115
+ if (method != null) {
116
+ const { _data } = await method()
117
+ options.value = _data as any
118
+ }
101
119
  } catch (e: any) {
102
120
  alertError(e?._message || e?.message || 'Failed to fetch data')
103
121
  } finally {
@@ -105,7 +123,10 @@ const fetchData = async () => {
105
123
  }
106
124
  }
107
125
  }
108
- fetchData()
126
+
127
+ onMounted(() => {
128
+ fetchData()
129
+ })
109
130
  defineOptions({
110
131
  name: 'MOptions',
111
132
  inheritAttrs: !1
@@ -424,8 +424,8 @@ export const useDtHelpers = (options: MaybeRefOrGetter<MDatatableProps>) => {
424
424
  const resetDialogForm = useResetForm()
425
425
  const resetVeeForm = async (attrs?: Record<string, any>) => {
426
426
  const init: any = {}
427
- for (const k in props.defaultItem) {
428
- init[k] = attrs && k in attrs ? attrs[k] : props.defaultItem[k]
427
+ for (const k in defaultItem.value) {
428
+ init[k] = attrs && k in attrs ? attrs[k] : defaultItem.value[k]
429
429
  }
430
430
  resetDialogForm({ values: init || {} }, { force: !0 })
431
431
  attrs && setValues(attrs, !1)
@@ -546,10 +546,14 @@ export type MOptionsProps = Omit<QOptionGroupProps, 'name' | 'modelValue' | 'opt
546
546
  * Array of objects with value, label, and disable (optional) props. The binary components will be created according to this array; Props from QToggle & QCheckbox or QRadio can also be added as key/value pairs to control the components singularly
547
547
  */
548
548
  options?: MOptionsOptionContext[];
549
+ /**
550
+ * Uset auto static index myth api helpers.
551
+ */
552
+ guest?: boolean | undefined;
549
553
  /**
550
554
  * Get options by function. any send the current value to this function to get options.
551
555
  */
552
- service?: ((value?: any) => Promise<ApiInterface>) | undefined;
556
+ service?: ((value?: any) => Promise<ApiInterface>) | string;
553
557
  /**
554
558
  * Service loading.
555
559
  */
@@ -8,7 +8,7 @@
8
8
 
9
9
  import type { AxiosResponse } from 'axios'
10
10
  import type { NamedColor, QAvatarProps, QAvatarSlots, QTableProps, QTableSlots } from 'quasar'
11
- import type { ComputedRef, MaybeRef, Ref, UnwrapNestedRefs, UnwrapRef, VNode } from 'vue'
11
+ import type { ComputedRef, MaybeRef, MaybeRefOrGetter, Ref, UnwrapNestedRefs, UnwrapRef, VNode } from 'vue'
12
12
  import type { RouteLocationRaw } from 'vue-router'
13
13
  import type { GenericFormValues, MBtnProps, MBtnSlots, MFormSlots } from './components'
14
14
  import type { StubSchema } from './api-helpers'
@@ -297,6 +297,14 @@ export type MDatatableProps<I extends GenericFormValues = GenericFormValues> = O
297
297
  * default back icon.
298
298
  */
299
299
  backIcon?: string;
300
+ /**
301
+ * Names of url/link columns in the table.
302
+ */
303
+ urlColumns?: MaybeRefOrGetter<string[]>;
304
+ /**
305
+ * Names of color pattern columns in the table.
306
+ */
307
+ colorColumns?: MaybeRefOrGetter<string[]>;
300
308
  }
301
309
 
302
310
  export interface MDtAvatarProps extends QAvatarProps {