@ramathibodi/nuxt-commons 0.1.20 → 0.1.22

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/dist/module.json CHANGED
@@ -4,5 +4,5 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "0.1.20"
7
+ "version": "0.1.22"
8
8
  }
@@ -29,9 +29,10 @@ const reset = () => {
29
29
  files.value = undefined
30
30
  }
31
31
 
32
- watch(files, () => {
32
+ const emitFiles = () => {
33
33
  emit('update:modelValue', files.value)
34
- }, { deep: true })
34
+ files.value = []
35
+ }
35
36
 
36
37
  defineExpose({ reset })
37
38
  </script>
@@ -55,6 +56,7 @@ defineExpose({ reset })
55
56
  <v-file-input
56
57
  ref="fileInput"
57
58
  v-model="files"
59
+ @update:modelValue="emitFiles"
58
60
  :accept="props.accept"
59
61
  :multiple="props.multiple"
60
62
  style="display: none"
@@ -1,22 +1,22 @@
1
1
  <script lang="ts" setup>
2
- import { VueSignaturePad } from 'vue-signature-pad'
3
- import { type Ref, ref, onMounted, onBeforeUnmount, withDefaults } from 'vue'
2
+ import { VueSignaturePad } from 'vue-signature-pad';
3
+ import { type Ref, ref, onMounted, onBeforeUnmount } from 'vue'
4
4
 
5
5
  interface SignatureOptions {
6
- penColor: string
7
- minWidth?: number
8
- maxWidth?: number
6
+ penColor: string
7
+ minWidth?: number
8
+ maxWidth?: number
9
9
  }
10
10
 
11
11
  interface SignatureProps {
12
- title?: string
13
- titleConfirm?: string
14
- modelValue: string
12
+ title?: string
13
+ titleConfirm?: string
14
+ modelValue?: string
15
15
  }
16
16
 
17
17
  const props = withDefaults(defineProps<SignatureProps>(), {
18
- title: 'Draw Your Signature',
19
- titleConfirm: 'I Accept My Signature',
18
+ title: 'Draw Your Signature',
19
+ titleConfirm: 'I Accept My Signature',
20
20
  })
21
21
 
22
22
  const signaturePadRef: Ref<any> = ref(null)
@@ -28,54 +28,54 @@ const signatureOptions: Ref<SignatureOptions> = ref({ penColor: defaultColor, mi
28
28
  const isDialogOpen: Ref<boolean> = ref(false)
29
29
 
30
30
  const undoSignature = (): void => {
31
- signaturePadRef.value.undoSignature()
31
+ signaturePadRef.value.undoSignature()
32
32
  }
33
33
 
34
34
  const clearSignature = (): void => {
35
- signaturePadRef.value.clearSignature()
35
+ signaturePadRef.value.clearSignature()
36
36
  }
37
37
 
38
38
  const closeDialog = (): void => {
39
- isDialogOpen.value = false
40
- signaturePadRef.value.clearSignature()
41
- signaturePadRef.value.clearCacheImages()
39
+ isDialogOpen.value = false
40
+ signaturePadRef.value.clearSignature()
41
+ signaturePadRef.value.clearCacheImages()
42
42
  }
43
43
 
44
44
  const emit = defineEmits<{
45
- (event: 'update:modelValue', value: string): void
45
+ (event: 'update:modelValue', value: string): void
46
46
  }>()
47
47
 
48
48
  const saveSignature = (): void => {
49
- isDialogOpen.value = false
50
- const { isEmpty, data } = signaturePadRef.value.saveSignature()
51
- signatureData.value = isEmpty ? '' : data
52
- emit('update:modelValue', signatureData.value)
49
+ isDialogOpen.value = false
50
+ const { isEmpty, data } = signaturePadRef.value.saveSignature()
51
+ signatureData.value = isEmpty ? '' : data
52
+ emit('update:modelValue', signatureData.value)
53
53
  }
54
54
 
55
55
  const changePenColor = (color: string): void => {
56
- selectedColor.value = color
57
- signatureOptions.value = { penColor: color }
56
+ selectedColor.value = color
57
+ signatureOptions.value = { penColor: color }
58
58
  }
59
59
 
60
60
  const openSignatureDialog = (): void => {
61
- selectedColor.value = defaultColor
62
- signatureOptions.value = { penColor: defaultColor }
63
- isDialogOpen.value = true
61
+ selectedColor.value = defaultColor
62
+ signatureOptions.value = { penColor: defaultColor }
63
+ isDialogOpen.value = true
64
64
  }
65
65
 
66
66
  const signaturePadHeight: Ref<string> = ref('')
67
67
  const updateSignaturePadHeight = () => {
68
- const screenHeight = window.innerHeight
69
- signaturePadHeight.value = `${screenHeight * 0.4}px`
68
+ const screenHeight = window.innerHeight
69
+ signaturePadHeight.value = `${screenHeight * 0.4}px`
70
70
  }
71
71
 
72
72
  onMounted(() => {
73
- updateSignaturePadHeight()
74
- window.addEventListener('resize', updateSignaturePadHeight)
73
+ updateSignaturePadHeight()
74
+ window.addEventListener('resize', updateSignaturePadHeight)
75
75
  })
76
76
 
77
77
  onBeforeUnmount(() => {
78
- window.removeEventListener('resize', updateSignaturePadHeight)
78
+ window.removeEventListener('resize', updateSignaturePadHeight)
79
79
  })
80
80
  </script>
81
81
 
@@ -0,0 +1,187 @@
1
+ <script lang="ts" setup>
2
+ import { type Ref, ref, watch} from 'vue'
3
+ import {useAlert} from '../../../composables/alert'
4
+ import { isEqual } from 'lodash-es'
5
+ interface Props {
6
+ modelValue?: any;
7
+ readonly?: boolean;
8
+ label?: string;
9
+ }
10
+
11
+ const props = defineProps<Props>();
12
+ const emit = defineEmits<{
13
+ (e: "update:modelValue", value: {}): void;
14
+ }>();
15
+
16
+ const alert = useAlert()
17
+
18
+ interface Image {
19
+ title: string;
20
+ data: string;
21
+ props: {};
22
+ }
23
+
24
+ const images = ref<Image[]>([]);
25
+ const dialog: Ref<boolean> = ref(false);
26
+ const dialogUpdate: Ref<boolean> = ref(false);
27
+ const dataUpdate: Ref<Image> = ref({
28
+ title: "",
29
+ data: "",
30
+ props: {},
31
+ });
32
+ const remove = (index: number) => {
33
+ images.value.splice(index, 1);
34
+ };
35
+
36
+ const setDataUpdate = (data: Image) => {
37
+ dataUpdate.value = data;
38
+ dialogUpdate.value = true;
39
+ };
40
+
41
+
42
+ interface FileBase64 {
43
+ base64string: string;
44
+ mineType: string;
45
+ filename: string;
46
+ }
47
+
48
+
49
+ const uploadImages: Ref<any[]> = ref([]);
50
+ const checkDuplicationName = async (currentImageName: string) => {
51
+ for (const {title} of images.value) {
52
+ if(isEqual(title, currentImageName)) return true
53
+ }
54
+ }
55
+
56
+ const update = async () => {
57
+ const duplicatedFileName = ref("")
58
+ for (const image of uploadImages.value) {
59
+ if(await checkDuplicationName(image.name)){
60
+ duplicatedFileName.value += `${image.name},`
61
+ }else{
62
+ const fileBase64: any = await convertFileToBase64(image);
63
+ if (isImage(fileBase64)) {
64
+ addImage(fileBase64);
65
+ } else {
66
+ alert?.addAlert({message: `ไฟล์ "${fileBase64.filename}" ไม่ใช่ไฟล์นามสกุล .jpg หรือ .jpeg`, alertType: 'error'})
67
+ }
68
+ }
69
+ }
70
+ uploadImages.value = []
71
+ if(duplicatedFileName.value !== ""){
72
+ alert?.addAlert({message: `ไม่สามารถอัพโหลดไฟล์ ${duplicatedFileName.value}`, alertType: 'error'})
73
+ duplicatedFileName.value = ""
74
+ }
75
+ };
76
+ const convertFileToBase64 = async (file: any) => {
77
+ try {
78
+ const readPromise: any = new Promise((resolve, reject) => {
79
+ const reader = new FileReader();
80
+ reader.onload = () => {
81
+ let result: any = reader.result;
82
+ const mineType = result.split(",")[0];
83
+ const base64 = result.split(",")[1];
84
+ resolve({
85
+ base64string: base64,
86
+ mineType: mineType,
87
+ filename: file.name,
88
+ });
89
+ };
90
+ reader.onerror = (error) => {
91
+ reject(error);
92
+ };
93
+ reader.readAsDataURL(file);
94
+ });
95
+ return await readPromise;
96
+ } catch (error: any) {
97
+ alert?.addAlert({message: error, alertType: 'error'})
98
+ }
99
+ };
100
+ const isImage = (fileBase64: any) => {
101
+ const typeFile: string = fileBase64.mineType.substring(5, 10);
102
+ return typeFile === "image" ? true : false;
103
+ };
104
+
105
+ const addImage = (data: FileBase64) => {
106
+ images.value.push({
107
+ title: data.filename,
108
+ data: `${data.mineType},${data.base64string}`,
109
+ props: {},
110
+ });
111
+ dialog.value = false;
112
+ };
113
+ watch(images, () => {
114
+ emit("update:modelValue", images);
115
+ }, { deep: true });
116
+ </script>
117
+
118
+ <template>
119
+ <VCard>
120
+ <VToolbar density="compact">
121
+ <VToolbarTitle>{{ label }}</VToolbarTitle>
122
+ <v-spacer></v-spacer>
123
+ <VToolbarItems v-if="!readonly">
124
+ <FileBtn
125
+ ref="fileBtn"
126
+ v-model="uploadImages"
127
+ accept=".jpg, .jpeg"
128
+ color="primary"
129
+ icon="mdi:mdi-image-plus"
130
+ iconOnly
131
+ multiple
132
+ variant="text"
133
+ @update:model-value="update"
134
+ />
135
+ <v-btn color="primary" icon @click="dialog = true">
136
+ <v-icon>mdi mdi-camera-plus</v-icon>
137
+ </v-btn>
138
+ </VToolbarItems>
139
+ </VToolbar>
140
+ <VCardText>
141
+ <VRow dense justify="center">
142
+ <VCol v-for="(image, index) in images" :key="index" cols="4">
143
+ <VCard max-height="250">
144
+ <VToolbar density="compact">
145
+ <VToolbarTitle>
146
+ {{ image.title }}
147
+ </VToolbarTitle>
148
+ <VSpacer></VSpacer>
149
+ <VToolbarItems v-if="!readonly">
150
+ <v-btn icon @click="remove(index)">
151
+ <v-icon>mdi mdi-delete-outline</v-icon>
152
+ </v-btn>
153
+ <v-btn
154
+ color="primary"
155
+ icon
156
+ @click="setDataUpdate(image)"
157
+ >
158
+ <v-icon>mdi mdi-image-edit-outline</v-icon>
159
+ </v-btn>
160
+ </VToolbarItems>
161
+ </VToolbar>
162
+ <v-img
163
+ :src="image.data"
164
+ @click="setDataUpdate(image)"
165
+ ></v-img>
166
+ </VCard>
167
+ </VCol>
168
+ </VRow>
169
+ </VCardText>
170
+ </VCard>
171
+ <VDialog
172
+ v-model="dialogUpdate"
173
+ fullscreen
174
+ transition="dialog-bottom-transition"
175
+ >
176
+ <FormImagesPad
177
+ v-model="dataUpdate.data"
178
+ @closedDialog="dialogUpdate = false"
179
+ ></FormImagesPad>
180
+ </VDialog>
181
+ <VDialog v-model="dialog">
182
+ <FormImagesCapture
183
+
184
+ @close-dialog="dialog = false"
185
+ ></FormImagesCapture>
186
+ </VDialog>
187
+ </template>
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, nextTick } from 'vue';
3
+ import Painterro from 'painterro';
4
+
5
+ const props = defineProps({
6
+ modelValue: String
7
+ })
8
+
9
+ const emit = defineEmits(['update:modelValue', 'closedDialog'])
10
+
11
+ const setting = {
12
+ id: "painterroContainer",
13
+ defaultTool: 'brush',
14
+ toolbarPosition: 'top',
15
+ toolbarHeightPx: '50',
16
+ pixelizePixelSize: '5%',
17
+ hiddenTools: [
18
+ 'resize',
19
+ 'redo',
20
+ 'bucket',
21
+ 'clear',
22
+ 'settings',
23
+ ],
24
+ saveHandler: function (image:any, done:any) {
25
+ emit('update:modelValue', image.asDataURL())
26
+ emit('closedDialog', false)
27
+ done(true)
28
+ },
29
+ onClose: function () {
30
+ emit('closedDialog', false)
31
+ }
32
+ }
33
+
34
+ onMounted(async () => {
35
+ await nextTick();
36
+ props.modelValue != "" ? Painterro(setting).show(props.modelValue) : Painterro(setting).show()
37
+ });
38
+
39
+ </script>
40
+
41
+ <template>
42
+ <div id="painterroContainer" style="width: 100%; height: 100dvh;"></div>
43
+ </template>
@@ -1,9 +1,9 @@
1
1
  <script lang="ts" setup>
2
- import {computed, nextTick, ref, useAttrs} from 'vue'
3
- import {VDataTable} from 'vuetify/components/VDataTable'
4
- import {omit} from 'lodash-es'
5
- import type {GraphqlModelProps} from '../../composables/graphqlModel'
6
- import {useGraphqlModel} from '../../composables/graphqlModel'
2
+ import { computed,watch, nextTick, ref, useAttrs } from 'vue'
3
+ import { VDataTable } from 'vuetify/components/VDataTable'
4
+ import { omit } from 'lodash-es'
5
+ import type { GraphqlModelProps } from '../../composables/graphqlModel'
6
+ import { useGraphqlModel } from '../../composables/graphqlModel'
7
7
 
8
8
  defineOptions({
9
9
  inheritAttrs: false,
@@ -17,6 +17,9 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VDataTable['$props
17
17
  toolbarColor?: string
18
18
  importable?: boolean
19
19
  exportable?: boolean
20
+ insertable?: boolean
21
+ searchable?: boolean
22
+ search?: string
20
23
  }
21
24
 
22
25
  const props = withDefaults(defineProps<Props & GraphqlModelProps>(), {
@@ -25,6 +28,8 @@ const props = withDefaults(defineProps<Props & GraphqlModelProps>(), {
25
28
  toolbarColor: 'primary',
26
29
  importable: true,
27
30
  exportable: true,
31
+ insertable: true,
32
+ searchable: true,
28
33
  modelKey: 'id',
29
34
  modelBy: undefined,
30
35
  fields: () => [],
@@ -40,7 +45,7 @@ const currentItem = ref<Record<string, any> | undefined>(undefined)
40
45
  const isDialogOpen = ref<boolean>(false)
41
46
 
42
47
  const { items, itemsLength,
43
- search,
48
+ search,setSearch,
44
49
  canServerPageable, canServerSearch, canCreate, canUpdate, canDelete,
45
50
  createItem, importItems, updateItem, deleteItem,
46
51
  loadItems, reload,
@@ -53,12 +58,16 @@ function openDialog(item?: object) {
53
58
  })
54
59
  }
55
60
 
56
- const operation = ref({ openDialog, createItem, importItems, updateItem, deleteItem, reload, canServerPageable, canServerSearch, canCreate, canUpdate, canDelete })
61
+ const operation = ref({ openDialog, createItem, importItems, updateItem, deleteItem, reload, setSearch, canServerPageable, canServerSearch, canCreate, canUpdate, canDelete })
57
62
 
58
63
  const computedInitialData = computed(() => {
59
64
  return Object.assign({}, props.initialData, props.modelBy)
60
65
  })
61
66
 
67
+ watch(()=>props.search,()=>{
68
+ search.value = props.search
69
+ },{immediate:true})
70
+
62
71
  defineExpose({ reload })
63
72
  </script>
64
73
 
@@ -67,7 +76,6 @@ defineExpose({ reload })
67
76
  <slot
68
77
  name="header"
69
78
  :items="items"
70
- :search="search"
71
79
  :operation="operation"
72
80
  >
73
81
  <VToolbar :color="toolbarColor">
@@ -94,7 +102,7 @@ defineExpose({ reload })
94
102
  </slot>
95
103
  </VToolbarTitle>
96
104
  </v-col>
97
- <v-col cols="5">
105
+ <v-col cols="5" v-if="props.searchable">
98
106
  <slot name="search">
99
107
  <VTextField
100
108
  v-model="search"
@@ -112,11 +120,11 @@ defineExpose({ reload })
112
120
  <VToolbarItems>
113
121
  <slot name="toolbarItems" />
114
122
  <ImportCSV
115
- v-if="props.importable"
123
+ v-if="props.importable && canCreate && props.insertable"
116
124
  icon="mdi mdi-file-upload"
117
125
  variant="flat"
118
- @import="importItems"
119
126
  :color="toolbarColor"
127
+ @import="importItems"
120
128
  />
121
129
  <ExportCSV
122
130
  v-if="props.exportable && items.length"
@@ -127,7 +135,7 @@ defineExpose({ reload })
127
135
  :color="toolbarColor"
128
136
  />
129
137
  <VBtn
130
- v-if="canCreate"
138
+ v-if="canCreate && props.insertable"
131
139
  :color="toolbarColor"
132
140
  prepend-icon="mdi mdi-plus"
133
141
  variant="flat"
@@ -17,6 +17,9 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VDataIterator['$pr
17
17
  toolbarColor?: string
18
18
  importable?: boolean
19
19
  exportable?: boolean
20
+ insertable?: boolean
21
+ searchable?: boolean
22
+ search?: string
20
23
  cols?: string | number | boolean
21
24
  xxl?: string | number | boolean
22
25
  xl?: string | number | boolean
@@ -32,6 +35,8 @@ const props = withDefaults(defineProps<Props & GraphqlModelProps>(), {
32
35
  toolbarColor: 'primary',
33
36
  importable: false,
34
37
  exportable: false,
38
+ insertable: true,
39
+ searchable: true,
35
40
  modelKey: 'id',
36
41
  modelBy: undefined,
37
42
  fields: () => [],
@@ -54,7 +59,7 @@ const currentItem = ref<Record<string, any> | undefined>(undefined)
54
59
  const isDialogOpen = ref<boolean>(false)
55
60
 
56
61
  const { items, itemsLength,
57
- search, currentOptions,
62
+ search, setSearch, currentOptions,
58
63
  canServerPageable, canServerSearch, canCreate, canUpdate, canDelete,
59
64
  createItem, importItems, updateItem, deleteItem,
60
65
  loadItems, reload,
@@ -92,7 +97,7 @@ watch([currentPage, itemsPerPageInternal, sortBy], () => {
92
97
  }
93
98
  }, { immediate: true })
94
99
 
95
- const operation = ref({ openDialog, createItem, importItems, updateItem, deleteItem, reload, canServerPageable, canServerSearch, canCreate, canUpdate, canDelete })
100
+ const operation = ref({ openDialog, createItem, importItems, updateItem, deleteItem, reload, setSearch, canServerPageable, canServerSearch, canCreate, canUpdate, canDelete })
96
101
 
97
102
  const computedInitialData = computed(() => {
98
103
  return Object.assign({}, props.initialData, props.modelBy)
@@ -103,6 +108,10 @@ const computedSkeletonPerPage = computed(() => {
103
108
  else return Number(itemsPerPageInternal.value)
104
109
  })
105
110
 
111
+ watch(()=>props.search,()=>{
112
+ search.value = props.search
113
+ },{immediate:true})
114
+
106
115
  defineExpose({ reload })
107
116
  </script>
108
117
 
@@ -176,7 +185,6 @@ defineExpose({ reload })
176
185
  name="header"
177
186
  v-bind="headerProps"
178
187
  :items="items"
179
- :search="search"
180
188
  :operation="operation"
181
189
  >
182
190
  <VToolbar :color="toolbarColor">
@@ -203,7 +211,7 @@ defineExpose({ reload })
203
211
  </slot>
204
212
  </VToolbarTitle>
205
213
  </v-col>
206
- <v-col cols="5">
214
+ <v-col cols="5" v-if="props.searchable">
207
215
  <slot name="search">
208
216
  <VTextField
209
217
  v-model="search"
@@ -221,20 +229,22 @@ defineExpose({ reload })
221
229
  <VToolbarItems>
222
230
  <slot name="toolbarItems" />
223
231
  <ImportCSV
224
- v-if="props.importable"
225
- icon="mdi mdi-file-upload"
226
- variant="flat"
227
- @import="importItems"
232
+ v-if="props.importable && canCreate && props.insertable"
233
+ icon="mdi mdi-file-upload"
234
+ variant="flat"
235
+ :color="toolbarColor"
236
+ @import="importItems"
228
237
  />
229
238
  <ExportCSV
230
- v-if="props.exportable && items.length"
231
- icon="mdi mdi-file-download"
232
- variant="flat"
233
- :file-name="title"
234
- :model-value="items"
239
+ v-if="props.exportable && items.length"
240
+ icon="mdi mdi-file-download"
241
+ variant="flat"
242
+ :file-name="title"
243
+ :model-value="items"
244
+ :color="toolbarColor"
235
245
  />
236
246
  <VBtn
237
- v-if="canCreate"
247
+ v-if="canCreate && props.insertable"
238
248
  :color="toolbarColor"
239
249
  prepend-icon="mdi mdi-plus"
240
250
  variant="flat"
@@ -11,6 +11,7 @@ export declare function useGraphqlModel<T extends GraphqlModelProps>(props: T):
11
11
  items: import("vue").Ref<Record<string, any>[]>;
12
12
  itemsLength: import("vue").Ref<number>;
13
13
  search: import("vue").Ref<string | undefined>;
14
+ setSearch: (keyword: string) => void;
14
15
  currentOptions: import("vue").Ref<any>;
15
16
  operationCreate: import("vue").ComputedRef<any>;
16
17
  operationUpdate: import("vue").ComputedRef<any>;
@@ -1,4 +1,5 @@
1
- import { computed, onMounted, ref, watch } from "vue";
1
+ import { computed, onMounted, ref } from "vue";
2
+ import { watchDebounced } from "@vueuse/core";
2
3
  import { useAlert } from "./alert.mjs";
3
4
  import { buildRequiredInputFields } from "./graphqlOperation.mjs";
4
5
  import { useGraphqlModelOperation } from "./graphqlModelOperation.mjs";
@@ -8,6 +9,9 @@ export function useGraphqlModel(props) {
8
9
  const itemsLength = ref(0);
9
10
  const search = ref();
10
11
  const currentOptions = ref();
12
+ function setSearch(keyword) {
13
+ search.value = keyword;
14
+ }
11
15
  const isLoading = ref(false);
12
16
  const { operationCreate, operationUpdate, operationDelete, operationRead, operationReadPageable, operationSearch } = useGraphqlModelOperation(props);
13
17
  function keyToField(key) {
@@ -150,9 +154,9 @@ export function useGraphqlModel(props) {
150
154
  });
151
155
  }
152
156
  }
153
- watch([() => props.modelName, () => props.modelBy, () => props.modelKey, canServerPageable], () => {
157
+ watchDebounced([() => props.modelName, () => props.modelBy, () => props.modelKey, canServerPageable], () => {
154
158
  reload();
155
- }, { deep: true });
159
+ }, { deep: true, debounce: 500, maxWait: 500 });
156
160
  onMounted(() => {
157
161
  if (!canServerPageable.value)
158
162
  reload();
@@ -161,6 +165,7 @@ export function useGraphqlModel(props) {
161
165
  items,
162
166
  itemsLength,
163
167
  search,
168
+ setSearch,
164
169
  currentOptions,
165
170
  operationCreate,
166
171
  operationUpdate,
@@ -11,11 +11,12 @@ export function routeToMenuItem(route) {
11
11
  icon: menuMeta.icon,
12
12
  role: menuMeta.role,
13
13
  name: route.name,
14
+ image: menuMeta.image,
14
15
  menuItems: [],
15
16
  link: {
16
17
  name: route.name
17
18
  },
18
- active: true
19
+ active: menuMeta.active != void 0 ? menuMeta.active : true
19
20
  };
20
21
  if (route.children) {
21
22
  const menuItems = new Array();
@@ -9,6 +9,8 @@ declare global {
9
9
  title: string
10
10
  icon: string
11
11
  role: string
12
+ image? : string
13
+ active? : boolean
12
14
  }
13
15
 
14
16
  interface MenuItem {
@@ -19,6 +21,7 @@ declare global {
19
21
  menuItems: Array<MenuItem>
20
22
  active: boolean
21
23
  name: string
24
+ image? : string
22
25
  }
23
26
  }
24
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramathibodi/nuxt-commons",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "Ramathibodi Nuxt modules for common components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -86,6 +86,7 @@
86
86
  "lodash": "^4.17.21",
87
87
  "luxon": "^3.4.4",
88
88
  "maska": "^2.1.11",
89
+ "painterro": "^1.2.87",
89
90
  "pdf-vue3": "^1.0.12",
90
91
  "prettier": "3.3.2",
91
92
  "print-js": "^1.6.0",
@@ -116,5 +117,5 @@
116
117
  "vitest": "^1.5.1",
117
118
  "vue-tsc": "^1.8.27"
118
119
  },
119
- "packageManager": "pnpm@9.8.0+sha512.8e4c3550fb500e808dbc30bb0ce4dd1eb614e30b1c55245f211591ec2cdf9c611cabd34e1364b42f564bd54b3945ed0f49d61d1bbf2ec9bd74b866fcdc723276"
120
+ "packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1"
120
121
  }
@@ -110,7 +110,7 @@ module.exports = {
110
110
  }
111
111
 
112
112
  function createGraphQLOperation${'<' + 'T,U>'}(operationType: "Query" | "Mutation",name: string,variables?: graphqlVariable[],fields?: graphqlTypeObject): graphqlOperationObject${'<' + 'T,U>'} {
113
- let returnGraphqlOperation = {
113
+ let returnGraphqlOperation : ${'Record' + '<string,any>'} = {
114
114
  operationType,
115
115
  name,
116
116
  variables,
@@ -125,7 +125,7 @@ module.exports = {
125
125
  return operationCall(operationType,name, fields, variables,cache);
126
126
  }
127
127
  }
128
- return returnGraphqlOperation
128
+ return returnGraphqlOperation as graphqlOperationObject${'<' + 'T,U>'}
129
129
  }
130
130
 
131
131
  interface graphqlTypeObjects extends ${'Record<string,' + 'graphqlTypeObject>'} {
@@ -1,2 +0,0 @@
1
- declare const _default: import("nuxt/app").Plugin<Record<string, unknown>> & import("nuxt/app").ObjectPlugin<Record<string, unknown>>;
2
- export default _default;
@@ -1,5 +0,0 @@
1
- import { defineNuxtPlugin } from "nuxt/app";
2
- import VueSignaturePad from "vue-signature-pad";
3
- export default defineNuxtPlugin((nuxtApp) => {
4
- nuxtApp.vueApp.use(VueSignaturePad);
5
- });