@ramathibodi/nuxt-commons 0.1.44 → 0.1.46

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 (41) hide show
  1. package/dist/module.d.mts +2 -1
  2. package/dist/module.d.ts +2 -1
  3. package/dist/module.json +2 -2
  4. package/dist/runtime/components/ExportCSV.vue +3 -1
  5. package/dist/runtime/components/ImportCSV.vue +11 -1
  6. package/dist/runtime/components/form/CheckboxGroup.vue +0 -2
  7. package/dist/runtime/components/form/Date.vue +39 -45
  8. package/dist/runtime/components/form/DateTime.vue +35 -41
  9. package/dist/runtime/components/form/Dialog.vue +48 -22
  10. package/dist/runtime/components/form/Table.vue +21 -0
  11. package/dist/runtime/components/form/Time.vue +38 -43
  12. package/dist/runtime/components/label/Field.vue +13 -8
  13. package/dist/runtime/components/master/Autocomplete.vue +5 -0
  14. package/dist/runtime/components/master/Combobox.vue +11 -0
  15. package/dist/runtime/components/master/Select.vue +13 -1
  16. package/dist/runtime/components/master/label.vue +5 -0
  17. package/dist/runtime/components/model/Autocomplete.vue +1 -1
  18. package/dist/runtime/components/model/Table.vue +19 -0
  19. package/dist/runtime/components/model/label.vue +3 -3
  20. package/dist/runtime/composables/api.d.ts +5 -4
  21. package/dist/runtime/composables/api.js +38 -9
  22. package/dist/runtime/composables/document/template.js +2 -2
  23. package/dist/runtime/composables/graphql.d.ts +1 -1
  24. package/dist/runtime/composables/graphql.js +3 -3
  25. package/dist/runtime/composables/graphqlModel.d.ts +6 -6
  26. package/dist/runtime/composables/graphqlModel.js +2 -0
  27. package/dist/runtime/composables/graphqlModelItem.d.ts +4 -4
  28. package/dist/runtime/composables/graphqlModelOperation.d.ts +6 -6
  29. package/dist/runtime/composables/graphqlOperation.d.ts +1 -1
  30. package/dist/runtime/composables/menu.js +2 -2
  31. package/dist/runtime/types/formDialog.d.ts +1 -0
  32. package/dist/runtime/types/graphqlOperation.d.ts +1 -1
  33. package/dist/runtime/utils/datetime.d.ts +36 -161
  34. package/dist/runtime/utils/hash.d.ts +1 -0
  35. package/dist/runtime/utils/hash.js +7 -0
  36. package/dist/runtime/utils/object.d.ts +1 -0
  37. package/dist/runtime/utils/object.js +25 -0
  38. package/dist/types.d.mts +7 -1
  39. package/dist/types.d.ts +7 -1
  40. package/package.json +41 -39
  41. package/templates/.codegen/plugin-schema-object.js +2 -2
package/dist/module.d.mts CHANGED
@@ -4,4 +4,5 @@ interface ModuleOptions {
4
4
  }
5
5
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
6
6
 
7
- export { type ModuleOptions, _default as default };
7
+ export { _default as default };
8
+ export type { ModuleOptions };
package/dist/module.d.ts CHANGED
@@ -4,4 +4,5 @@ interface ModuleOptions {
4
4
  }
5
5
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
6
6
 
7
- export { type ModuleOptions, _default as default };
7
+ export { _default as default };
8
+ export type { ModuleOptions };
package/dist/module.json CHANGED
@@ -4,9 +4,9 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0"
6
6
  },
7
- "version": "0.1.44",
7
+ "version": "0.1.46",
8
8
  "builder": {
9
- "@nuxt/module-builder": "0.8.3",
9
+ "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "2.0.0"
11
11
  }
12
12
  }
@@ -8,11 +8,13 @@ interface ExportButtonProps extends /* @vue-ignore */ InstanceType<typeof VBtn['
8
8
  fileName?: string
9
9
  sheetName?: string
10
10
  modelValue?: object[]
11
+ stringFields?: Array<string>
11
12
  }
12
13
 
13
14
  const props = withDefaults(defineProps<ExportButtonProps>(), {
14
15
  fileName: 'download',
15
16
  sheetName: 'Sheet1',
17
+ stringFields: ()=>[],
16
18
  })
17
19
 
18
20
  const alert = useAlert()
@@ -63,7 +65,7 @@ function flattenObject(obj: any, parentKey = '', separator = '.') {
63
65
  const newKey = parentKey ? `${parentKey}${separator}${key}` : key
64
66
  const value = obj[key]
65
67
 
66
- if (value && typeof value === 'object' && !Array.isArray(value)) {
68
+ if (value && typeof value === 'object' && !Array.isArray(value) && !props.stringFields.includes(newKey)) {
67
69
  Object.assign(acc, flattenObject(value, newKey, separator))
68
70
  } else {
69
71
  acc[newKey] = typeof value === 'object' ? JSON.stringify(value) : value
@@ -2,6 +2,15 @@
2
2
  import * as XLSX from 'xlsx'
3
3
  import { ref } from 'vue'
4
4
  import { useAlert } from '../composables/alert'
5
+ import { VBtn } from 'vuetify/components/VBtn'
6
+
7
+ interface ImportButtonProps extends /* @vue-ignore */ InstanceType<typeof VBtn['$props']> {
8
+ stringFields?: Array<string>
9
+ }
10
+
11
+ const props = withDefaults(defineProps<ImportButtonProps>(), {
12
+ stringFields: ()=>[],
13
+ })
5
14
 
6
15
  const alert = useAlert()
7
16
  const emit = defineEmits<{
@@ -59,7 +68,8 @@ const parseAndAggregateColumns = (items: any[]) => {
59
68
  assignNestedValue(aggregatedItem[rootKey], subKeys, parseIfJson(item[key]))
60
69
  } else {
61
70
  // Directly assign root-level properties
62
- aggregatedItem[key] = parseIfJson(item[key])
71
+ if (props.stringFields.includes(key)) aggregatedItem[key] = item[key]
72
+ else aggregatedItem[key] = parseIfJson(item[key])
63
73
  }
64
74
  }
65
75
 
@@ -59,7 +59,6 @@ watch(props.modelValue, () => {
59
59
  </script>
60
60
 
61
61
  <template>
62
- <v-container fluid>
63
62
  <label class="text-body-1 opacity-60">{{props.label}}</label>
64
63
  <div :class="`d-flex ${inline ? 'flex-row':'flex-column'}`">
65
64
  <v-checkbox v-for="item in computeItems"
@@ -83,7 +82,6 @@ watch(props.modelValue, () => {
83
82
  <label class="text-error text-subtitle-2 ml-1">
84
83
  {{computedRules}}
85
84
  </label>
86
- </v-container>
87
85
 
88
86
  </template>
89
87
 
@@ -6,7 +6,6 @@ import '@vuepic/vue-datepicker/dist/main.css'
6
6
  import {isArray, isString} from "lodash-es";
7
7
  import { type dateFormat, Datetime } from '../../utils/datetime'
8
8
  import { useRules } from "../../composables/utils/validation";
9
- import {VInput} from "vuetify/components/VInput";
10
9
 
11
10
  interface Props extends /* @vue-ignore */ InstanceType<typeof VTextField['$props']> {
12
11
  locale?: 'TH' | 'EN'
@@ -180,50 +179,45 @@ defineExpose({
180
179
  </script>
181
180
 
182
181
  <template>
183
- <v-input v-model="displayedDate" v-bind="$attrs" ref="inputRef">
184
- <template #default="{isReadonly,isDisabled}">
185
- <v-menu
186
- v-model="isMenuOpen"
187
- :open-on-click="false"
182
+ <v-menu
183
+ v-model="isMenuOpen"
184
+ :open-on-click="false"
185
+ >
186
+ <template #activator="{ props: activatorProps }">
187
+ <v-text-field
188
+ ref="textFieldRef"
189
+ v-model="displayedDate"
190
+ :rules="computedRules"
191
+ v-bind="$attrs"
192
+ @focus="handleTextFieldFocus"
193
+ @blur="handleTextFieldBlur"
194
+ @keydown="handleTextFieldInput"
195
+ @keyup.enter="handleTextFieldEnterKey"
196
+ @click:clear="handleTextFieldClear"
197
+ @click="toggleMenuOpen('textField')"
188
198
  >
189
- <template #activator="{ props: activatorProps }">
190
- <v-text-field
191
- ref="textFieldRef"
192
- v-model="displayedDate"
193
- :rules="computedRules"
194
- v-bind="$attrs"
195
- @focus="handleTextFieldFocus"
196
- @blur="handleTextFieldBlur"
197
- @keydown="handleTextFieldInput"
198
- @keyup.enter="handleTextFieldEnterKey"
199
- @click:clear="handleTextFieldClear"
200
- @click="toggleMenuOpen('textField')"
201
- >
202
- <template #append-inner>
203
- <v-icon v-if="!isReadonly.value"
204
- v-bind="activatorProps"
205
- @click="toggleMenuOpen('icon')"
206
- >
207
- fa:fa-regular fa-calendar
208
- </v-icon>
209
- </template>
210
- </v-text-field>
199
+ <template #append="{ isReadonly, isDisabled }">
200
+ <v-icon
201
+ :disabled="isReadonly.value || isDisabled.value"
202
+ v-bind="activatorProps"
203
+ @click="toggleMenuOpen('icon')"
204
+ >
205
+ fa:fa-regular fa-calendar
206
+ </v-icon>
211
207
  </template>
212
- <Datepicker
213
- v-model="selectedDate"
214
- model-type="yyyy-MM-dd"
215
- :enable-time-picker="false"
216
- :flow="flow"
217
- :min-date="props.minDate"
218
- :max-date="props.maxDate"
219
- auto-apply
220
- inline
221
- :locale="locale"
222
- @update:model-value="updateDatePicker"
223
- />
224
- </v-menu>
208
+ </v-text-field>
225
209
  </template>
226
-
227
- </v-input>
228
-
229
- </template>
210
+ <Datepicker
211
+ v-model="selectedDate"
212
+ model-type="yyyy-MM-dd"
213
+ :enable-time-picker="false"
214
+ :flow="flow"
215
+ :min-date="props.minDate"
216
+ :max-date="props.maxDate"
217
+ auto-apply
218
+ inline
219
+ :locale="locale"
220
+ @update:model-value="updateDatePicker"
221
+ />
222
+ </v-menu>
223
+ </template>
@@ -4,7 +4,6 @@ import { union,isBoolean,isArray,isString } from 'lodash-es'
4
4
  import { VTextField } from 'vuetify/components/VTextField'
5
5
  import { type dateFormat, Datetime } from '../../utils/datetime'
6
6
  import { useRules } from '../../composables/utils/validation'
7
- import {VInput} from "vuetify/components/VInput";
8
7
 
9
8
  interface Props {
10
9
  modelValue?: string | null
@@ -97,7 +96,7 @@ const computedTimeRules = computed(() => union(computedRules.value, props.timeRu
97
96
 
98
97
  const datePart = ref<string | null>(null)
99
98
  const timePart = ref<string | null>(null)
100
- const pauseEmit = ref(false)
99
+ const pauseEmit = ref(true)
101
100
 
102
101
  function reset() {
103
102
  datePart.value = null
@@ -159,43 +158,38 @@ watch(() => props.modelValue, () => {
159
158
  </script>
160
159
 
161
160
  <template>
162
- <v-input v-model="datePart" v-bind="$attrs" ref="inputRef">
163
- <template #default="{isReadonly,isDisabled}">
164
- <v-container
165
- :fluid="true"
166
- class="pa-0"
167
- >
168
- <v-row :dense="dense">
169
- <v-col cols="8">
170
- <FormDate
171
- v-model="datePart"
172
- ref="dateRef"
173
- :rules="computedDateRules"
174
- :label="label"
175
- :format="format"
176
- :picker-only="pickerOnly"
177
- :readonly="isReadonly.value"
178
- :disabled="fixedDate"
179
- :min-date="minDate"
180
- :max-date="maxDate"
181
- v-bind="$attrs"
182
- />
183
- </v-col>
184
- <v-col cols="4">
185
- <FormTime
186
- v-model="timePart"
187
- ref="timeRef"
188
- :rules="computedTimeRules"
189
- :label="label"
190
- :enable-seconds="enableSeconds"
191
- :picker-only="pickerOnly"
192
- :readonly="isReadonly.value"
193
- v-bind="$attrs"
194
- />
195
- </v-col>
196
- </v-row>
197
- </v-container>
198
- </template>
199
- </v-input>
200
-
161
+ <v-container
162
+ :fluid="true"
163
+ class="pa-0"
164
+ >
165
+ <v-row :dense="dense">
166
+ <v-col cols="8">
167
+ <FormDate
168
+ v-model="datePart"
169
+ ref="dateRef"
170
+ :rules="computedDateRules"
171
+ :label="label"
172
+ :format="format"
173
+ :picker-only="pickerOnly"
174
+ :readonly="readonly"
175
+ :disabled="fixedDate"
176
+ :min-date="minDate"
177
+ :max-date="maxDate"
178
+ v-bind="$attrs"
179
+ />
180
+ </v-col>
181
+ <v-col cols="4">
182
+ <FormTime
183
+ v-model="timePart"
184
+ ref="timeRef"
185
+ :rules="computedTimeRules"
186
+ :label="label"
187
+ :enable-seconds="enableSeconds"
188
+ :picker-only="pickerOnly"
189
+ :readonly="readonly"
190
+ v-bind="$attrs"
191
+ />
192
+ </v-col>
193
+ </v-row>
194
+ </v-container>
201
195
  </template>
@@ -11,24 +11,30 @@ interface Props {
11
11
  formData?: object
12
12
  saveCaption?: string
13
13
  cancelCaption?: string
14
+ closeCaption?: string
15
+ saveAndStay?: boolean
14
16
  }
15
17
 
16
18
  const props = withDefaults(defineProps<Props>(), {
17
19
  saveCaption: 'บันทึก',
18
20
  cancelCaption: 'ยกเลิก',
21
+ closeCaption: 'ปิด',
22
+ saveAndStay: false,
19
23
  })
20
24
 
21
25
  const isShowing = defineModel<boolean>({ default: false })
22
26
  const isSaving = ref<boolean>(false)
27
+ const isSavedAndStay = ref<boolean>(false)
23
28
  const formPadRef = ref()
24
29
  const formData = ref<object>({})
30
+ const formDataOriginalValue = ref<object>()
25
31
 
26
32
  const emit = defineEmits(['create', 'update'])
27
33
 
28
34
  function save() {
29
35
  if (formPadRef.value.isValid) {
30
36
  isSaving.value = true
31
- emit((isCreating.value) ? 'create' : 'update', cloneDeep(formData.value), callback)
37
+ emit((isCreating.value) ? 'create' : 'update', cloneDeep(formData.value), (props.saveAndStay) ? stayCallback : callback)
32
38
  }
33
39
  }
34
40
 
@@ -46,12 +52,26 @@ const callback: FormDialogCallback = {
46
52
  },
47
53
  }
48
54
 
55
+ const stayCallback: FormDialogCallback = {
56
+ done: function () {
57
+ isSaving.value = false
58
+ isSavedAndStay.value = true
59
+ },
60
+ error: function () {
61
+ isSaving.value = false
62
+ },
63
+ setData: function (item: object) {
64
+ formData.value = cloneDeep(item)
65
+ formDataOriginalValue.value = cloneDeep(item)
66
+ }
67
+ }
68
+
49
69
  const isDataChange = computed(() => {
50
- return !((isCreating.value) ? isEqual(formData.value, createOriginalValue.value) : isEqual(formData.value, props.formData))
70
+ return !((isCreating.value) ? isEqual(formData.value, createOriginalValue.value) : isEqual(formData.value, formDataOriginalValue.value))
51
71
  })
52
72
 
53
73
  const isCreating = computed(() => {
54
- return !props.formData
74
+ return !props.formData && !isSavedAndStay.value
55
75
  })
56
76
 
57
77
  const createOriginalValue = computed(() => {
@@ -61,12 +81,16 @@ const createOriginalValue = computed(() => {
61
81
  const loadFormData = () => {
62
82
  if (props.formData) {
63
83
  formData.value = cloneDeep(props.formData)
84
+ formDataOriginalValue.value = cloneDeep(props.formData)
64
85
  }
65
86
  else {
66
87
  formData.value = Object.assign({}, props.initialData)
67
88
  }
89
+ isSavedAndStay.value = false
68
90
  }
69
91
 
92
+ const operation = ref({ isDataChange, isCreating, isSaving, save, cancel })
93
+
70
94
  watchEffect(loadFormData)
71
95
 
72
96
  watch(() => isShowing.value, (newValue) => {
@@ -85,7 +109,7 @@ watch(() => isShowing.value, (newValue) => {
85
109
  <VCard>
86
110
  <VToolbar>
87
111
  <VToolbarTitle>
88
- <slot name="title">
112
+ <slot name="title" :operation="operation">
89
113
  {{ (isCreating) ? "New" : "Edit" }} {{ title }}
90
114
  </slot>
91
115
  </VToolbarTitle>
@@ -113,24 +137,26 @@ watch(() => isShowing.value, (newValue) => {
113
137
  </form-pad>
114
138
  </VCardText>
115
139
  <VCardActions>
116
- <VSpacer />
117
- <VBtn
118
- color="primary"
119
- variant="flat"
120
- :loading="isSaving"
121
- :disabled="!isDataChange"
122
- @click="save"
123
- >
124
- {{ saveCaption }}
125
- </VBtn>
126
- <VBtn
127
- color="error"
128
- variant="flat"
129
- :disabled="isSaving"
130
- @click="cancel"
131
- >
132
- {{ cancelCaption }}
133
- </VBtn>
140
+ <slot name="action" :operation="operation">
141
+ <VSpacer />
142
+ <VBtn
143
+ color="primary"
144
+ variant="flat"
145
+ :loading="isSaving"
146
+ :disabled="!isDataChange"
147
+ @click="save"
148
+ >
149
+ {{ saveCaption }}
150
+ </VBtn>
151
+ <VBtn
152
+ color="error"
153
+ variant="flat"
154
+ :disabled="isSaving"
155
+ @click="cancel"
156
+ >
157
+ {{ (!isDataChange) ? closeCaption : cancelCaption }}
158
+ </VBtn>
159
+ </slot>
134
160
  </VCardActions>
135
161
  </VCard>
136
162
  </v-dialog>
@@ -23,6 +23,8 @@ interface Props extends /* @vue-ignore */ InstanceType<typeof VDataTable['$props
23
23
  searchable?: boolean
24
24
  inputPad?: boolean
25
25
  inputPadOnly?: boolean
26
+ saveAndStay?: boolean
27
+ stringFields?: Array<string>
26
28
  }
27
29
 
28
30
  const props = withDefaults(defineProps<Props>(), {
@@ -36,6 +38,8 @@ const props = withDefaults(defineProps<Props>(), {
36
38
  searchable: true,
37
39
  inputPad: false,
38
40
  inputPadOnly: false,
41
+ saveAndStay: false,
42
+ stringFields: ()=>[],
39
43
  })
40
44
 
41
45
  const emit = defineEmits(['update:modelValue'])
@@ -85,6 +89,7 @@ function createItem(item: Record<string, any>, callback?: FormDialogCallback) {
85
89
 
86
90
  items.value.push(item)
87
91
 
92
+ if (callback && callback.setData) callback.setData(item)
88
93
  if (callback) callback.done()
89
94
  }
90
95
 
@@ -102,6 +107,7 @@ function updateItem(newItem: Record<string, any>, callback?: FormDialogCallback)
102
107
  items.value[index] = newItem
103
108
  }
104
109
 
110
+ if (callback && callback.setData) callback.setData(newItem)
105
111
  if (callback) callback.done()
106
112
  }
107
113
 
@@ -238,6 +244,7 @@ defineExpose({
238
244
  variant="flat"
239
245
  @import="importItems"
240
246
  :color="toolbarColor"
247
+ :stringFields="props.stringFields"
241
248
  />
242
249
  <ExportCSV
243
250
  v-if="props.exportable && items.length && !(isReadonly.value || isDisabled.value)"
@@ -246,6 +253,7 @@ defineExpose({
246
253
  :file-name="title"
247
254
  :model-value="items"
248
255
  :color="toolbarColor"
256
+ :stringFields="props.stringFields"
249
257
  />
250
258
  <VBtn
251
259
  v-if="props.insertable && !props.inputPadOnly && !(isReadonly.value || isDisabled.value)"
@@ -313,6 +321,7 @@ defineExpose({
313
321
  :form-data="currentItem"
314
322
  @create="createItem"
315
323
  @update="updateItem"
324
+ :saveAndStay="saveAndStay"
316
325
  v-if="!props.inputPadOnly"
317
326
  >
318
327
  <template #default="slotData">
@@ -321,6 +330,18 @@ defineExpose({
321
330
  v-bind="slotData"
322
331
  />
323
332
  </template>
333
+ <template #title="slotData">
334
+ <slot
335
+ name="formTitle"
336
+ v-bind="slotData"
337
+ />
338
+ </template>
339
+ <template #action="slotData">
340
+ <slot
341
+ name="formAction"
342
+ v-bind="slotData"
343
+ />
344
+ </template>
324
345
  </FormDialog>
325
346
  </v-card>
326
347
  <slot name="inputPad" :operation="operation" :isReadonly="isReadonly" :isDisabled="isDisabled">
@@ -4,7 +4,6 @@ import { VTextField } from 'vuetify/components/VTextField'
4
4
  import Datepicker from '@vuepic/vue-datepicker'
5
5
  import '@vuepic/vue-datepicker/dist/main.css'
6
6
  import { Datetime } from '../../utils/datetime'
7
- import {VInput} from "vuetify/components/VInput";
8
7
 
9
8
  interface Props extends /* @vue-ignore */ InstanceType<typeof VTextField['$props']> {
10
9
  enableSeconds?: boolean
@@ -123,49 +122,45 @@ defineExpose({
123
122
  </script>
124
123
 
125
124
  <template>
126
- <v-input v-model="displayedDate" v-bind="$attrs" ref="inputRef">
127
- <template #default="{isReadonly,isDisabled}">
128
- <v-menu
129
- v-model="isMenuOpen"
130
- :close-on-content-click="false"
131
- :open-on-click="false"
125
+ <v-menu
126
+ v-model="isMenuOpen"
127
+ :close-on-content-click="false"
128
+ :open-on-click="false"
129
+ >
130
+ <template #activator="{ props }">
131
+ <v-text-field
132
+ ref="textFieldRef"
133
+ v-model="tempTime"
134
+ v-bind="$attrs"
135
+ @focus="onTextFieldFocus"
136
+ @blur="onTextFieldBlur"
137
+ @keydown="onTextFieldTyped"
138
+ @keyup.enter="onTextFieldEnterKey"
139
+ @click:clear="onTextFieldClear"
140
+ @click="toggleMenuOpen('textField')"
132
141
  >
133
- <template #activator="{ props }">
134
- <v-text-field
135
- ref="textFieldRef"
136
- v-model="tempTime"
137
- v-bind="$attrs"
138
- @focus="onTextFieldFocus"
139
- @blur="onTextFieldBlur"
140
- @keydown="onTextFieldTyped"
141
- @keyup.enter="onTextFieldEnterKey"
142
- @click:clear="onTextFieldClear"
143
- @click="toggleMenuOpen('textField')"
142
+ <template #append="{ isReadonly, isDisabled }">
143
+ <v-icon
144
+ :disabled="isReadonly.value || isDisabled.value"
145
+ v-bind="props"
146
+ @click="toggleMenuOpen('icon')"
144
147
  >
145
- <template #append-inner>
146
- <v-icon v-if="!isReadonly.value"
147
- v-bind="props"
148
- @click="toggleMenuOpen('icon')"
149
- >
150
- fa:fa-regular fa-clock
151
- </v-icon>
152
- </template>
153
- </v-text-field>
148
+ fa:fa-regular fa-clock
149
+ </v-icon>
154
150
  </template>
155
- <Datepicker
156
- v-model="time"
157
- model-type="HH:mm:ss"
158
- :enable-seconds="enableSeconds"
159
- minutes-grid-increment="1"
160
- time-picker
161
- auto-apply
162
- :close-on-auto-apply="false"
163
- inline
164
- :locale="locale"
165
- @update:model-value="setDatePicker"
166
- />
167
- </v-menu>
151
+ </v-text-field>
168
152
  </template>
169
- </v-input>
170
-
171
- </template>
153
+ <Datepicker
154
+ v-model="time"
155
+ model-type="HH:mm:ss"
156
+ :enable-seconds="enableSeconds"
157
+ minutes-grid-increment="1"
158
+ time-picker
159
+ auto-apply
160
+ :close-on-auto-apply="false"
161
+ inline
162
+ :locale="locale"
163
+ @update:model-value="setDatePicker"
164
+ />
165
+ </v-menu>
166
+ </template>
@@ -7,6 +7,7 @@ interface Props {
7
7
  horizontal?: boolean;
8
8
  size?: 'large' | 'medium';
9
9
  truncate?: boolean;
10
+ notFoundText?: string
10
11
  }
11
12
 
12
13
  const props = withDefaults(defineProps<Props>(), {
@@ -15,6 +16,7 @@ const props = withDefaults(defineProps<Props>(), {
15
16
  horizontal: false,
16
17
  size: 'large',
17
18
  truncate: false,
19
+ notFoundText : '-'
18
20
  });
19
21
 
20
22
  const valueText = ref<HTMLElement | null>(null);
@@ -27,6 +29,9 @@ const setTruncate = (event: Event) => {
27
29
  const target = event.target as HTMLElement;
28
30
  isTooltip.value = target.offsetWidth < target.scrollWidth;
29
31
  };
32
+ const valueData = computed(()=>{
33
+ return (props.value) ? props.value : props.notFoundText
34
+ })
30
35
 
31
36
  </script>
32
37
 
@@ -41,8 +46,8 @@ const setTruncate = (event: Event) => {
41
46
  <slot name="label">{{ props.label }}:</slot>
42
47
  </div>
43
48
  <div :class="`ml-1 ${calTruncate}`" ref="valueText">
44
- <slot name="value">
45
- <div v-if="!props.truncate">{{ props.value }}</div>
49
+ <slot name="value" :value="valueData">
50
+ <div v-if="!props.truncate">{{ valueData }}</div>
46
51
  <div
47
52
  v-else
48
53
  @mouseover="setTruncate"
@@ -54,10 +59,10 @@ const setTruncate = (event: Event) => {
54
59
  class="text-truncate"
55
60
  v-bind="isTooltip ? props : ''"
56
61
  >
57
- {{ value }}
62
+ {{ valueData }}
58
63
  </div>
59
64
  </template>
60
- <span>{{ value }}</span>
65
+ <span>{{ valueData }}</span>
61
66
  </v-tooltip>
62
67
  </div>
63
68
  </slot>
@@ -70,8 +75,8 @@ const setTruncate = (event: Event) => {
70
75
  </VCardSubtitle>
71
76
  <VCardText :class="`pa-0 mb-2 ${calSize}`">
72
77
  <div :class="calTruncate" ref="valueText">
73
- <slot name="value">
74
- <div v-if="!props.truncate">{{ props.value }}</div>
78
+ <slot name="value" :value="valueData">
79
+ <div v-if="!props.truncate">{{ valueData }}</div>
75
80
  <div
76
81
  v-else
77
82
  @mouseover="setTruncate"
@@ -83,10 +88,10 @@ const setTruncate = (event: Event) => {
83
88
  class="text-truncate"
84
89
  v-bind="isTooltip ? props : ''"
85
90
  >
86
- {{ value }}
91
+ {{ valueData }}
87
92
  </div>
88
93
  </template>
89
- <span>{{ value }}</span>
94
+ <span>{{ valueData }}</span>
90
95
  </v-tooltip>
91
96
  </div>
92
97
  </slot>