@ramathibodi/nuxt-commons 0.1.11 → 0.1.13

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 (28) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/TabsGroup.vue +12 -8
  3. package/dist/runtime/components/form/Birthdate.vue +199 -0
  4. package/dist/runtime/components/form/CodeEditor.vue +3 -3
  5. package/dist/runtime/components/form/Dialog.vue +3 -2
  6. package/dist/runtime/components/form/Pad.vue +31 -9
  7. package/dist/runtime/components/form/Table.vue +4 -4
  8. package/dist/runtime/components/master/Combobox.vue +29 -25
  9. package/dist/runtime/components/master/RadioGroup.vue +40 -30
  10. package/dist/runtime/components/master/Select.vue +34 -23
  11. package/dist/runtime/components/model/Pad.vue +122 -0
  12. package/dist/runtime/components/model/Table.vue +126 -103
  13. package/dist/runtime/components/model/iterator.vue +312 -0
  14. package/dist/runtime/composables/graphql.mjs +1 -1
  15. package/dist/runtime/composables/graphqlModel.d.ts +5 -18
  16. package/dist/runtime/composables/graphqlModel.mjs +16 -86
  17. package/dist/runtime/composables/graphqlModelItem.d.ts +20 -0
  18. package/dist/runtime/composables/graphqlModelItem.mjs +103 -0
  19. package/dist/runtime/composables/graphqlModelOperation.d.ts +21 -0
  20. package/dist/runtime/composables/graphqlModelOperation.mjs +77 -0
  21. package/dist/runtime/composables/graphqlOperation.d.ts +2 -2
  22. package/dist/runtime/composables/graphqlOperation.mjs +9 -9
  23. package/dist/runtime/types/formDialog.d.ts +3 -3
  24. package/dist/runtime/types/graphqlOperation.d.ts +14 -14
  25. package/package.json +1 -1
  26. package/scripts/postInstall.cjs +38 -35
  27. package/templates/.codegen/codegen.ts +8 -8
  28. package/templates/.codegen/plugin-schema-object.js +103 -97
@@ -1,16 +1,17 @@
1
1
  <script setup lang="ts">
2
- import { VSelect } from "vuetify/components/VSelect";
3
- import { useGraphQl } from '../../composables/graphql'
4
- import { concat } from "lodash-es";
5
- import { useAlert } from "../../composables/alert";
6
- import {computed, ref, watch} from "vue";
2
+ import {VSelect} from 'vuetify/components/VSelect'
3
+ import {concat} from 'lodash-es'
4
+ import {computed, ref, watch} from 'vue'
5
+ import {useGraphQl} from '../../composables/graphql'
6
+ import {useAlert} from '../../composables/alert'
7
+
7
8
  interface Props extends /* @vue-ignore */ InstanceType<typeof VSelect['$props']> {
8
9
  modelValue?: string
9
10
  groupKey: string
10
- fields?:string[]
11
+ fields?: string[]
11
12
  }
12
- const props = withDefaults(defineProps<Props>(),{
13
- lang: 'TH'
13
+ const props = withDefaults(defineProps<Props>(), {
14
+ lang: 'TH',
14
15
  })
15
16
 
16
17
  const emit = defineEmits(['update:modelValue'])
@@ -22,12 +23,12 @@ function query() {
22
23
  let fields: any[] = ['itemCode', 'itemValue', 'itemValueAlternative']
23
24
  if (props.fields) fields = concat(fields, props.fields)
24
25
 
25
- useGraphQl().queryPromise('masterItemByGroupKey',fields, variables).then((result : any)=>{
26
+ useGraphQl().queryPromise('masterItemByGroupKey', fields, variables).then((result: any) => {
26
27
  items.value = result
27
- }).catch((error)=>{
28
+ }).catch((error) => {
28
29
  alert?.addAlert({
29
- message : `${error.message}`,
30
- alertType:"error"
30
+ message: `${error.message}`,
31
+ alertType: 'error',
31
32
  })
32
33
  })
33
34
  }
@@ -47,27 +48,37 @@ const itemTitleField = computed(() => {
47
48
 
48
49
  query()
49
50
  </script>
51
+
50
52
  <template>
51
- <v-select v-model="selectedItem" :item-title="itemTitleField" :items="items" item-value="itemCode">
53
+ <v-select
54
+ v-model="selectedItem"
55
+ :item-title="itemTitleField"
56
+ :items="items"
57
+ item-value="itemCode"
58
+ >
52
59
  <template
53
- v-for="(_, name, index) in ($slots as {})"
54
- :key="index"
55
- #[name]="slotData"
60
+ v-for="(_, name, index) in ($slots as {})"
61
+ :key="index"
62
+ #[name]="slotData"
56
63
  >
57
64
  <slot
58
- :name="name"
59
- v-bind="(slotData as object)"
60
- :operation="operation"
65
+ :name="name"
66
+ v-bind="(slotData as object)"
67
+ :operation="operation"
61
68
  />
62
69
  </template>
63
70
  <template
64
- v-if="!$slots.item"
65
- #item="{ props, item }">
66
- <v-list-item v-bind="props" :title="item.raw.itemValue"></v-list-item>
71
+ v-if="!$slots.item"
72
+ #item="{ props, item }"
73
+ >
74
+ <v-list-item
75
+ v-bind="props"
76
+ :title="item.raw.itemValue"
77
+ />
67
78
  </template>
68
79
  </v-select>
69
80
  </template>
70
81
 
71
82
  <style scoped>
72
83
 
73
- </style>
84
+ </style>
@@ -0,0 +1,122 @@
1
+ <script lang="ts" setup>
2
+ import { computed, ref, watchEffect } from 'vue'
3
+ import { cloneDeep, isEqual } from 'lodash-es'
4
+ import { type GraphqlModelItemProps, useGraphqlModelItem } from '../../composables/graphqlModelItem'
5
+
6
+ defineOptions({
7
+ inheritAttrs: false,
8
+ })
9
+
10
+ interface Props {
11
+ title?: string
12
+ initialData?: object
13
+ saveCaption?: string
14
+ cancelCaption?: string
15
+ }
16
+
17
+ const props = withDefaults(defineProps<Props & GraphqlModelItemProps>(), {
18
+ saveCaption: 'บันทึก',
19
+ cancelCaption: 'ยกเลิก',
20
+ fields: () => ['*'],
21
+ })
22
+
23
+ const { item,
24
+ canCreate, canUpdate,
25
+ createItem, updateItem,
26
+ reload, isLoading } = useGraphqlModelItem(props)
27
+
28
+ const formPadRef = ref()
29
+ const formData = ref<object>({})
30
+
31
+ const canSave = computed(() => { return (canCreate.value && isCreating.value) || canUpdate.value })
32
+
33
+ const isDataChange = computed(() => {
34
+ return !((isCreating.value) ? isEqual(formData.value, createOriginalValue.value) : isEqual(formData.value, item.value))
35
+ })
36
+
37
+ const isCreating = computed(() => {
38
+ return !item.value
39
+ })
40
+
41
+ const createOriginalValue = computed(() => {
42
+ return Object.assign({}, props.initialData)
43
+ })
44
+
45
+ const loadFormData = () => {
46
+ if (item.value) {
47
+ formData.value = cloneDeep(item.value)
48
+ }
49
+ else {
50
+ formData.value = Object.assign({}, props.initialData)
51
+ }
52
+ }
53
+
54
+ watchEffect(loadFormData)
55
+
56
+ function save() {
57
+ if (formPadRef.value.isValid) {
58
+ if (isCreating.value) createItem(formData.value)
59
+ else updateItem(formData.value)
60
+ }
61
+ }
62
+
63
+ function cancel() {
64
+ formPadRef.value.reset()
65
+ loadFormData()
66
+ }
67
+
68
+ defineExpose({ save, cancel, reload, item, isLoading })
69
+ </script>
70
+
71
+ <template>
72
+ <VCard>
73
+ <VToolbar>
74
+ <VToolbarTitle>
75
+ <slot name="title">
76
+ {{ title }}
77
+ <v-icon
78
+ size="small"
79
+ @click="reload"
80
+ >
81
+ mdi mdi-refresh
82
+ </v-icon>
83
+ </slot>
84
+ </VToolbarTitle>
85
+ </VToolbar>
86
+ <VCardText>
87
+ <form-pad
88
+ ref="formPadRef"
89
+ v-model="formData"
90
+ isolated
91
+ >
92
+ <template #default="slotData">
93
+ <slot
94
+ v-bind="slotData"
95
+ :is-creating="isCreating"
96
+ :is-data-change="isDataChange"
97
+ />
98
+ </template>
99
+ </form-pad>
100
+ </VCardText>
101
+ <VCardActions>
102
+ <VSpacer />
103
+ <VBtn
104
+ color="primary"
105
+ variant="flat"
106
+ :loading="isLoading"
107
+ :disabled="!isDataChange || !canSave"
108
+ @click="save"
109
+ >
110
+ {{ saveCaption }}
111
+ </VBtn>
112
+ <VBtn
113
+ color="error"
114
+ variant="flat"
115
+ :disabled="isLoading"
116
+ @click="cancel"
117
+ >
118
+ {{ cancelCaption }}
119
+ </VBtn>
120
+ </VCardActions>
121
+ </VCard>
122
+ </template>
@@ -1,9 +1,9 @@
1
1
  <script lang="ts" setup>
2
2
  import {computed, nextTick, ref, useAttrs} from 'vue'
3
- import type {GraphqlModelProps, HeaderProps} from '../../composables/graphqlModel'
3
+ import {VDataTable} from 'vuetify/components/VDataTable'
4
+ import {omit} from 'lodash-es'
5
+ import type {GraphqlModelProps} from '../../composables/graphqlModel'
4
6
  import {useGraphqlModel} from '../../composables/graphqlModel'
5
- import {VDataTable} from "vuetify/components/VDataTable";
6
- import {omit} from "lodash-es";
7
7
 
8
8
  defineOptions({
9
9
  inheritAttrs: false,
@@ -19,7 +19,7 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VDataTable['$props
19
19
  exportable?: boolean
20
20
  }
21
21
 
22
- const props = withDefaults(defineProps<Props & GraphqlModelProps & HeaderProps>(), {
22
+ const props = withDefaults(defineProps<Props & GraphqlModelProps>(), {
23
23
  noDataText: 'ไม่พบข้อมูล',
24
24
  dialogFullscreen: false,
25
25
  toolbarColor: 'primary',
@@ -27,24 +27,24 @@ const props = withDefaults(defineProps<Props & GraphqlModelProps & HeaderProps>(
27
27
  exportable: true,
28
28
  modelKey: 'id',
29
29
  modelBy: undefined,
30
- fields: ()=>[]
30
+ fields: () => [],
31
31
  })
32
32
 
33
33
  const attrs = useAttrs()
34
34
  const plainAttrs = computed(() => {
35
- let returnAttrs = omit(attrs, ['modelValue', 'onUpdate:modelValue'])
35
+ const returnAttrs = omit(attrs, ['modelValue', 'onUpdate:modelValue'])
36
36
  if (props.headers) returnAttrs['headers'] = props.headers
37
37
  return returnAttrs
38
38
  })
39
39
  const currentItem = ref<Record<string, any> | undefined>(undefined)
40
40
  const isDialogOpen = ref<boolean>(false)
41
41
 
42
- const {items,itemsLength,
42
+ const { items, itemsLength,
43
43
  search,
44
- canServerPageable,canServerSearch,canCreate,canUpdate,canDelete,
45
- createItem,importItems,updateItem,deleteItem,
46
- loadItems,reload,
47
- isLoading} = useGraphqlModel(props)
44
+ canServerPageable, canServerSearch, canCreate, canUpdate, canDelete,
45
+ createItem, importItems, updateItem, deleteItem,
46
+ loadItems, reload,
47
+ isLoading } = useGraphqlModel(props)
48
48
 
49
49
  function openDialog(item?: object) {
50
50
  currentItem.value = item
@@ -53,28 +53,50 @@ function openDialog(item?: object) {
53
53
  })
54
54
  }
55
55
 
56
+ const operation = ref({ openDialog, createItem, importItems, updateItem, deleteItem, reload, canServerPageable, canServerSearch, canCreate, canUpdate, canDelete })
57
+
58
+ const computedInitialData = computed(() => {
59
+ return Object.assign({}, props.initialData, props.modelBy)
60
+ })
61
+
56
62
  defineExpose({ reload })
57
63
  </script>
64
+
58
65
  <template>
59
66
  <v-card>
60
- <VToolbar :color="toolbarColor">
61
- <v-row
67
+ <slot
68
+ name="header"
69
+ :items="items"
70
+ :search="search"
71
+ :operation="operation"
72
+ >
73
+ <VToolbar :color="toolbarColor">
74
+ <v-row
62
75
  justify="end"
63
76
  class="ma-1"
64
77
  dense
65
78
  no-gutters
66
79
  align="center"
67
- >
68
- <v-col cols="7">
69
- <VToolbarTitle class="pl-3">
70
- <slot name="title">
71
- {{ title }}
72
- </slot>
73
- </VToolbarTitle>
74
- </v-col>
75
- <v-col cols="5">
76
- <slot name="search">
77
- <VTextField
80
+ >
81
+ <v-col cols="7">
82
+ <VToolbarTitle class="pl-3">
83
+ <slot
84
+ name="title"
85
+ :reload="reload"
86
+ >
87
+ {{ title }}
88
+ <v-icon
89
+ size="small"
90
+ @click="reload"
91
+ >
92
+ mdi mdi-refresh
93
+ </v-icon>
94
+ </slot>
95
+ </VToolbarTitle>
96
+ </v-col>
97
+ <v-col cols="5">
98
+ <slot name="search">
99
+ <VTextField
78
100
  v-model="search"
79
101
  class="justify-end w-100"
80
102
  density="compact"
@@ -82,136 +104,137 @@ defineExpose({ reload })
82
104
  placeholder="ค้นหา"
83
105
  clearable
84
106
  variant="solo"
85
- />
86
- </slot>
87
- </v-col>
88
- </v-row>
107
+ />
108
+ </slot>
109
+ </v-col>
110
+ </v-row>
89
111
 
90
- <VToolbarItems>
91
- <slot name="toolbarItems" />
92
- <ImportCSV
112
+ <VToolbarItems>
113
+ <slot name="toolbarItems" />
114
+ <ImportCSV
93
115
  v-if="props.importable"
94
116
  icon="mdi mdi-file-upload"
95
117
  variant="flat"
96
118
  @import="importItems"
97
- />
98
- <ExportCSV
119
+ />
120
+ <ExportCSV
99
121
  v-if="props.exportable && items.length"
100
122
  icon="mdi mdi-file-download"
101
123
  variant="flat"
102
124
  :file-name="title"
103
125
  :model-value="items"
104
- />
105
- <VBtn
126
+ />
127
+ <VBtn
128
+ v-if="canCreate"
106
129
  :color="toolbarColor"
107
130
  prepend-icon="mdi mdi-plus"
108
131
  variant="flat"
109
132
  @click="openDialog()"
110
- v-if="canCreate"
111
- >
112
- add
113
- </VBtn>
114
- </VToolbarItems>
115
- </VToolbar>
133
+ >
134
+ add
135
+ </VBtn>
136
+ </VToolbarItems>
137
+ </VToolbar>
138
+ </slot>
116
139
  <v-data-table-server
117
- v-if="canServerPageable"
118
- v-bind="plainAttrs"
119
- color="primary"
120
- :items="items"
121
- :items-length="itemsLength"
122
- :item-value="props.modelKey"
123
- :search="search"
124
- :loading="isLoading"
125
- @update:options="loadItems"
140
+ v-if="canServerPageable"
141
+ v-bind="plainAttrs"
142
+ color="primary"
143
+ :items="items"
144
+ :items-length="itemsLength"
145
+ :item-value="props.modelKey"
146
+ :search="search"
147
+ :loading="isLoading"
148
+ @update:options="loadItems"
126
149
  >
127
150
  <!-- @ts-ignore -->
128
151
  <template
129
- v-for="(_, name, index) in ($slots as {})"
130
- :key="index"
131
- #[name]="slotData"
152
+ v-for="(_, name, index) in ($slots as {})"
153
+ :key="index"
154
+ #[name]="slotData"
132
155
  >
133
156
  <slot
134
- :name="name"
135
- v-bind="(slotData as object)"
136
- :operation="operation"
157
+ :name="name"
158
+ v-bind="(slotData as object)"
159
+ :operation="operation"
137
160
  />
138
161
  </template>
139
162
  <template
140
- v-if="!$slots['item.action']"
141
- #item.action="{ item }"
163
+ v-if="!$slots['item.action']"
164
+ #item.action="{ item }"
142
165
  >
143
166
  <v-btn
144
- variant="flat"
145
- density="compact"
146
- icon="mdi mdi-note-edit"
147
- @click="openDialog(item)"
148
- v-if="canUpdate"
167
+ v-if="canUpdate"
168
+ variant="flat"
169
+ density="compact"
170
+ icon="mdi mdi-note-edit"
171
+ @click="openDialog(item)"
149
172
  />
150
173
  <v-btn
151
- variant="flat"
152
- density="compact"
153
- icon="mdi mdi-delete"
154
- @click="deleteItem(item)"
155
- v-if="canDelete"
174
+ v-if="canDelete"
175
+ variant="flat"
176
+ density="compact"
177
+ icon="mdi mdi-delete"
178
+ @click="deleteItem(item)"
156
179
  />
157
180
  </template>
158
181
  </v-data-table-server>
159
182
  <v-data-table
160
- v-else
161
- v-bind="plainAttrs"
162
- color="primary"
163
- :items="items"
164
- :item-value="props.modelKey"
165
- :search="search"
166
- :loading="isLoading"
183
+ v-else
184
+ v-bind="plainAttrs"
185
+ color="primary"
186
+ :items="items"
187
+ :item-value="props.modelKey"
188
+ :search="search"
189
+ :loading="isLoading"
167
190
  >
168
191
  <!-- @ts-ignore -->
169
192
  <template
170
- v-for="(_, name, index) in ($slots as {})"
171
- :key="index"
172
- #[name]="slotData"
193
+ v-for="(_, name, index) in ($slots as {})"
194
+ :key="index"
195
+ #[name]="slotData"
173
196
  >
174
197
  <slot
175
- :name="name"
176
- v-bind="(slotData as object)"
177
- :operation="operation"
198
+ :name="name"
199
+ v-bind="(slotData as object)"
200
+ :operation="operation"
178
201
  />
179
202
  </template>
180
203
  <template
181
- v-if="!$slots['item.action']"
182
- #item.action="{ item }"
204
+ v-if="!$slots['item.action']"
205
+ #item.action="{ item }"
183
206
  >
184
207
  <v-btn
185
- variant="flat"
186
- density="compact"
187
- icon="mdi mdi-note-edit"
188
- @click="openDialog(item)"
189
- v-if="canUpdate"
208
+ v-if="canUpdate"
209
+ variant="flat"
210
+ density="compact"
211
+ icon="mdi mdi-note-edit"
212
+ @click="openDialog(item)"
190
213
  />
191
214
  <v-btn
192
- variant="flat"
193
- density="compact"
194
- icon="mdi mdi-delete"
195
- @click="deleteItem(item)"
196
- v-if="canDelete"
215
+ v-if="canDelete"
216
+ variant="flat"
217
+ density="compact"
218
+ icon="mdi mdi-delete"
219
+ @click="deleteItem(item)"
197
220
  />
198
221
  </template>
199
222
  </v-data-table>
200
223
  <FormDialog
201
- v-model="isDialogOpen"
202
- :title="title"
203
- :fullscreen="dialogFullscreen"
204
- :initial-data="initialData"
205
- :form-data="currentItem"
206
- @create="createItem"
207
- @update="updateItem"
224
+ v-model="isDialogOpen"
225
+ :title="title"
226
+ :fullscreen="dialogFullscreen"
227
+ :initial-data="computedInitialData"
228
+ :form-data="currentItem"
229
+ @create="createItem"
230
+ @update="updateItem"
208
231
  >
209
232
  <template #default="slotData">
210
233
  <slot
211
- name="form"
212
- v-bind="slotData"
234
+ name="form"
235
+ v-bind="slotData"
213
236
  />
214
237
  </template>
215
238
  </FormDialog>
216
239
  </v-card>
217
- </template>
240
+ </template>