@ramathibodi/nuxt-commons 0.1.13 → 0.1.15

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 (59) hide show
  1. package/README.md +96 -96
  2. package/dist/module.json +1 -1
  3. package/dist/runtime/components/Alert.vue +53 -53
  4. package/dist/runtime/components/BarcodeReader.vue +98 -98
  5. package/dist/runtime/components/ExportCSV.vue +55 -55
  6. package/dist/runtime/components/FileBtn.vue +62 -62
  7. package/dist/runtime/components/ImportCSV.vue +64 -64
  8. package/dist/runtime/components/SplitterPanel.vue +59 -59
  9. package/dist/runtime/components/TabsGroup.vue +32 -32
  10. package/dist/runtime/components/TextBarcode.vue +52 -52
  11. package/dist/runtime/components/dialog/Confirm.vue +100 -100
  12. package/dist/runtime/components/dialog/Index.vue +72 -72
  13. package/dist/runtime/components/dialog/Loading.vue +39 -39
  14. package/dist/runtime/components/document/TemplateBuilder.vue +203 -216
  15. package/dist/runtime/components/form/Birthdate.vue +216 -199
  16. package/dist/runtime/components/form/CodeEditor.vue +37 -37
  17. package/dist/runtime/components/form/Date.vue +163 -163
  18. package/dist/runtime/components/form/DateTime.vue +107 -107
  19. package/dist/runtime/components/form/Dialog.vue +138 -138
  20. package/dist/runtime/components/form/File.vue +187 -187
  21. package/dist/runtime/components/form/Hidden.vue +32 -32
  22. package/dist/runtime/components/form/Login.vue +131 -131
  23. package/dist/runtime/components/form/Pad.vue +217 -217
  24. package/dist/runtime/components/form/SignPad.vue +186 -186
  25. package/dist/runtime/components/form/Table.vue +266 -266
  26. package/dist/runtime/components/form/Time.vue +158 -158
  27. package/dist/runtime/components/form/images/Capture.vue +231 -0
  28. package/dist/runtime/components/form/images/Edit.vue +117 -143
  29. package/dist/runtime/components/label/Date.vue +29 -29
  30. package/dist/runtime/components/label/Field.vue +42 -29
  31. package/dist/runtime/components/label/FormatMoney.vue +29 -29
  32. package/dist/runtime/components/label/Mask.vue +38 -38
  33. package/dist/runtime/components/master/Autocomplete.vue +159 -159
  34. package/dist/runtime/components/master/Combobox.vue +84 -84
  35. package/dist/runtime/components/master/RadioGroup.vue +78 -78
  36. package/dist/runtime/components/master/Select.vue +82 -82
  37. package/dist/runtime/components/model/Pad.vue +122 -122
  38. package/dist/runtime/components/model/Table.vue +242 -240
  39. package/dist/runtime/components/model/iterator.vue +312 -312
  40. package/dist/runtime/components/pdf/Print.vue +63 -63
  41. package/dist/runtime/components/pdf/View.vue +104 -104
  42. package/dist/runtime/composables/graphqlModel.d.ts +4 -1
  43. package/dist/runtime/composables/graphqlModel.mjs +5 -5
  44. package/dist/runtime/composables/graphqlModelOperation.mjs +7 -4
  45. package/dist/runtime/labs/Calendar.vue +99 -99
  46. package/dist/runtime/labs/form/EditMobile.vue +152 -152
  47. package/dist/runtime/labs/form/TextFieldMask.vue +43 -43
  48. package/dist/runtime/types/alert.d.ts +11 -11
  49. package/dist/runtime/types/formDialog.d.ts +4 -4
  50. package/dist/runtime/types/graphqlOperation.d.ts +23 -23
  51. package/dist/runtime/types/menu.d.ts +25 -25
  52. package/dist/runtime/types/modules.d.ts +7 -7
  53. package/package.json +120 -118
  54. package/scripts/postInstall.cjs +70 -70
  55. package/templates/.codegen/codegen.ts +32 -32
  56. package/templates/.codegen/plugin-schema-object.js +154 -154
  57. package/dist/runtime/components/Camera.vue +0 -129
  58. package/dist/runtime/components/form/images/CameraCrop.vue +0 -58
  59. package/dist/runtime/components/form/images/Preview.vue +0 -48
@@ -1,63 +1,63 @@
1
- <script setup lang="ts">
2
- import printJS from 'print-js'
3
- import { ref, watch } from 'vue'
4
- import { useAlert } from '../../composables/alert'
5
-
6
- interface Props {
7
- base64String?: string
8
- fileName?: string
9
- print?: boolean
10
- title?: string
11
- disabled?: boolean
12
- }
13
-
14
- const props = withDefaults(defineProps<Props>(), {
15
- print: false,
16
- disabled: false,
17
- })
18
- const emit = defineEmits(['update:print'])
19
-
20
- const isMobile = ref(false)
21
- const alert = useAlert()
22
-
23
- const openPdf = () => {
24
- if (/Android|Mobi|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Macintosh/i.test(navigator.userAgent)) {
25
- isMobile.value = true
26
- }
27
- else {
28
- printJS({
29
- printable: props.base64String,
30
- type: 'pdf',
31
- base64: true,
32
- onPrintDialogClose: endLoadPdf,
33
- onError: (error: any) => {
34
- alert?.addAlert({ message: error, alertType: 'error' })
35
- },
36
- })
37
- }
38
- }
39
-
40
- const endLoadPdf = () => {
41
- emit('update:print', false)
42
- isMobile.value = false
43
- }
44
-
45
- watch(() => props.print, () => {
46
- if (props.print) openPdf()
47
- })
48
- </script>
49
-
50
- <template>
51
- <v-dialog
52
- v-model="isMobile"
53
- fullscreen
54
- >
55
- <PdfView
56
- :base64-string="props.base64String"
57
- :disabled="props.disabled"
58
- :title="props.title"
59
- :file-name="props.fileName"
60
- @close-dialog="endLoadPdf"
61
- />
62
- </v-dialog>
63
- </template>
1
+ <script setup lang="ts">
2
+ import printJS from 'print-js'
3
+ import { ref, watch } from 'vue'
4
+ import { useAlert } from '../../composables/alert'
5
+
6
+ interface Props {
7
+ base64String?: string
8
+ fileName?: string
9
+ print?: boolean
10
+ title?: string
11
+ disabled?: boolean
12
+ }
13
+
14
+ const props = withDefaults(defineProps<Props>(), {
15
+ print: false,
16
+ disabled: false,
17
+ })
18
+ const emit = defineEmits(['update:print'])
19
+
20
+ const isMobile = ref(false)
21
+ const alert = useAlert()
22
+
23
+ const openPdf = () => {
24
+ if (/Android|Mobi|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Macintosh/i.test(navigator.userAgent)) {
25
+ isMobile.value = true
26
+ }
27
+ else {
28
+ printJS({
29
+ printable: props.base64String,
30
+ type: 'pdf',
31
+ base64: true,
32
+ onPrintDialogClose: endLoadPdf,
33
+ onError: (error: any) => {
34
+ alert?.addAlert({ message: error, alertType: 'error' })
35
+ },
36
+ })
37
+ }
38
+ }
39
+
40
+ const endLoadPdf = () => {
41
+ emit('update:print', false)
42
+ isMobile.value = false
43
+ }
44
+
45
+ watch(() => props.print, () => {
46
+ if (props.print) openPdf()
47
+ })
48
+ </script>
49
+
50
+ <template>
51
+ <v-dialog
52
+ v-model="isMobile"
53
+ fullscreen
54
+ >
55
+ <PdfView
56
+ :base64-string="props.base64String"
57
+ :disabled="props.disabled"
58
+ :title="props.title"
59
+ :file-name="props.fileName"
60
+ @close-dialog="endLoadPdf"
61
+ />
62
+ </v-dialog>
63
+ </template>
@@ -1,104 +1,104 @@
1
- <script setup lang="ts">
2
- import PDF from 'pdf-vue3'
3
- import { uid } from 'uid'
4
- import printJS from 'print-js'
5
- import { ref, computed } from 'vue'
6
- import { useAlert } from '../../composables/alert'
7
-
8
- const props = defineProps<{
9
- base64String?: string
10
- title?: string
11
- fileName?: string
12
- disabled?: boolean
13
- }>()
14
-
15
- const emit = defineEmits(['closeDialog'])
16
- const base64 = ref(props.base64String)
17
- const alert = useAlert()
18
-
19
- const generateUniqueId = (): string => {
20
- const uniqueId: string = uid()
21
- return props.fileName ? `${props.fileName}` : uniqueId
22
- }
23
-
24
- const downloadPdf = (): void => {
25
- const byteString = atob(props.base64String || '')
26
- const byteArray = new Uint8Array(byteString.length)
27
-
28
- for (let i = 0; i < byteString.length; i++) {
29
- byteArray[i] = byteString.charCodeAt(i)
30
- }
31
-
32
- const blob = new Blob([byteArray], { type: 'application/pdf' })
33
- const link = URL.createObjectURL(blob)
34
- const anchorElement = document.createElement('a')
35
- anchorElement.style.display = 'none'
36
- anchorElement.href = link
37
- anchorElement.download = `${generateUniqueId()}.pdf`
38
-
39
- document.body.appendChild(anchorElement)
40
- anchorElement.click()
41
- URL.revokeObjectURL(link)
42
- document.body.removeChild(anchorElement)
43
- base64.value = ''
44
- }
45
-
46
- const printPdf = () => {
47
- printJS({
48
- printable: props.base64String,
49
- type: 'pdf',
50
- base64: true,
51
- onPrintDialogClose: endLoadPdf,
52
- onError: (error: any) => {
53
- alert?.addAlert({ message: error, alertType: 'error' })
54
- },
55
- })
56
- base64.value = ''
57
- }
58
-
59
- const endLoadPdf = () => {
60
- emit('closeDialog', false)
61
- base64.value = ''
62
- }
63
-
64
- const isMobile = computed(() => {
65
- if (/Android|Mobi|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Macintosh/i.test(navigator.userAgent)) {
66
- return true
67
- }
68
- })
69
- </script>
70
-
71
- <template>
72
- <v-card>
73
- <v-toolbar density="compact">
74
- <v-toolbar-title>{{ props.title }}</v-toolbar-title>
75
- <v-spacer />
76
- <v-btn
77
- v-if="!isMobile"
78
- icon="mdi mdi-printer"
79
- variant="plain"
80
- @click="printPdf"
81
- />
82
- <v-btn
83
- v-if="!props.disabled"
84
- icon="mdi mdi-download"
85
- variant="plain"
86
- @click="downloadPdf"
87
- />
88
- <v-btn
89
- icon="mdi mdi-close"
90
- variant="plain"
91
- @click="endLoadPdf"
92
- />
93
- </v-toolbar>
94
- <v-card-text class="justify-center">
95
- <PDF
96
- :show-progress="true"
97
- pdf-width="100%"
98
- :src="base64"
99
- :show-page-tooltip="false"
100
- :show-back-to-top-btn="false"
101
- />
102
- </v-card-text>
103
- </v-card>
104
- </template>
1
+ <script setup lang="ts">
2
+ import PDF from 'pdf-vue3'
3
+ import { uid } from 'uid'
4
+ import printJS from 'print-js'
5
+ import { ref, computed } from 'vue'
6
+ import { useAlert } from '../../composables/alert'
7
+
8
+ const props = defineProps<{
9
+ base64String?: string
10
+ title?: string
11
+ fileName?: string
12
+ disabled?: boolean
13
+ }>()
14
+
15
+ const emit = defineEmits(['closeDialog'])
16
+ const base64 = ref(props.base64String)
17
+ const alert = useAlert()
18
+
19
+ const generateUniqueId = (): string => {
20
+ const uniqueId: string = uid()
21
+ return props.fileName ? `${props.fileName}` : uniqueId
22
+ }
23
+
24
+ const downloadPdf = (): void => {
25
+ const byteString = atob(props.base64String || '')
26
+ const byteArray = new Uint8Array(byteString.length)
27
+
28
+ for (let i = 0; i < byteString.length; i++) {
29
+ byteArray[i] = byteString.charCodeAt(i)
30
+ }
31
+
32
+ const blob = new Blob([byteArray], { type: 'application/pdf' })
33
+ const link = URL.createObjectURL(blob)
34
+ const anchorElement = document.createElement('a')
35
+ anchorElement.style.display = 'none'
36
+ anchorElement.href = link
37
+ anchorElement.download = `${generateUniqueId()}.pdf`
38
+
39
+ document.body.appendChild(anchorElement)
40
+ anchorElement.click()
41
+ URL.revokeObjectURL(link)
42
+ document.body.removeChild(anchorElement)
43
+ base64.value = ''
44
+ }
45
+
46
+ const printPdf = () => {
47
+ printJS({
48
+ printable: props.base64String,
49
+ type: 'pdf',
50
+ base64: true,
51
+ onPrintDialogClose: endLoadPdf,
52
+ onError: (error: any) => {
53
+ alert?.addAlert({ message: error, alertType: 'error' })
54
+ },
55
+ })
56
+ base64.value = ''
57
+ }
58
+
59
+ const endLoadPdf = () => {
60
+ emit('closeDialog', false)
61
+ base64.value = ''
62
+ }
63
+
64
+ const isMobile = computed(() => {
65
+ if (/Android|Mobi|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|Macintosh/i.test(navigator.userAgent)) {
66
+ return true
67
+ }
68
+ })
69
+ </script>
70
+
71
+ <template>
72
+ <v-card>
73
+ <v-toolbar density="compact">
74
+ <v-toolbar-title>{{ props.title }}</v-toolbar-title>
75
+ <v-spacer />
76
+ <v-btn
77
+ v-if="!isMobile"
78
+ icon="mdi mdi-printer"
79
+ variant="plain"
80
+ @click="printPdf"
81
+ />
82
+ <v-btn
83
+ v-if="!props.disabled"
84
+ icon="mdi mdi-download"
85
+ variant="plain"
86
+ @click="downloadPdf"
87
+ />
88
+ <v-btn
89
+ icon="mdi mdi-close"
90
+ variant="plain"
91
+ @click="endLoadPdf"
92
+ />
93
+ </v-toolbar>
94
+ <v-card-text class="justify-center">
95
+ <PDF
96
+ :show-progress="true"
97
+ pdf-width="100%"
98
+ :src="base64"
99
+ :show-page-tooltip="false"
100
+ :show-back-to-top-btn="false"
101
+ />
102
+ </v-card-text>
103
+ </v-card>
104
+ </template>
@@ -3,7 +3,10 @@ import { type GraphqlModelConfigProps } from './graphqlModelOperation';
3
3
  export interface HeaderProps {
4
4
  headers?: any[];
5
5
  }
6
- export type GraphqlModelProps = GraphqlModelConfigProps & Partial<HeaderProps>;
6
+ export interface InitialDataProps {
7
+ initialData?: Record<string, any>;
8
+ }
9
+ export type GraphqlModelProps = GraphqlModelConfigProps & Partial<HeaderProps> & Partial<InitialDataProps>;
7
10
  export declare function useGraphqlModel<T extends GraphqlModelProps>(props: T): {
8
11
  items: import("vue").Ref<Record<string, any>[]>;
9
12
  itemsLength: import("vue").Ref<number>;
@@ -63,7 +63,7 @@ export function useGraphqlModel(props) {
63
63
  function createItem(item, callback, importing = false) {
64
64
  isLoading.value = true;
65
65
  return operationCreate.value?.call(fields.value, { input: item }).then((result) => {
66
- if (canServerPageable) {
66
+ if (canServerPageable.value) {
67
67
  if (!importing)
68
68
  loadItems(currentOptions.value);
69
69
  } else
@@ -81,7 +81,7 @@ export function useGraphqlModel(props) {
81
81
  isLoading.value = true;
82
82
  const importPromise = [];
83
83
  importItems2.forEach((item) => {
84
- const eachPromise = createItem(item, void 0, true);
84
+ const eachPromise = createItem(Object.assign({}, props.initialData, item), void 0, true);
85
85
  if (eachPromise)
86
86
  importPromise.push(eachPromise);
87
87
  });
@@ -95,7 +95,7 @@ export function useGraphqlModel(props) {
95
95
  function updateItem(item, callback) {
96
96
  isLoading.value = true;
97
97
  return operationUpdate.value?.call(fields.value, { input: item }).then((result) => {
98
- if (canServerPageable)
98
+ if (canServerPageable.value)
99
99
  loadItems(currentOptions.value);
100
100
  else {
101
101
  const index = items.value.findIndex((item2) => item2[props.modelKey || "id"] === result[props.modelKey || "id"]);
@@ -124,14 +124,14 @@ export function useGraphqlModel(props) {
124
124
  }
125
125
  function loadItems(options) {
126
126
  currentOptions.value = options;
127
- if (canServerPageable) {
127
+ if (canServerPageable.value) {
128
128
  const pageableVariable = {
129
129
  page: options.page,
130
130
  perPage: options.itemsPerPage,
131
131
  sortBy: options.sortBy
132
132
  };
133
133
  isLoading.value = true;
134
- operationReadPageable.value?.call([{ data: fields.value }, "meta"], Object.assign(props.modelBy || {}, { pageable: pageableVariable })).then((result) => {
134
+ operationReadPageable.value?.call([{ data: fields.value }, "meta"], Object.assign({}, props.modelBy, { pageable: pageableVariable })).then((result) => {
135
135
  items.value = result.data;
136
136
  itemsLength.value = result.meta.totalItems;
137
137
  }).catch((error) => {
@@ -7,6 +7,9 @@ export function useGraphqlModelOperation(props) {
7
7
  function lowercaseFirstLetter(string) {
8
8
  return string?.charAt(0).toLowerCase() + string?.slice(1);
9
9
  }
10
+ const computedModelName = computed(() => {
11
+ return props.modelName.split("By")[0].trim();
12
+ });
10
13
  const operationCreate = computed(() => {
11
14
  if (props.operationCreate) {
12
15
  if (typeof props.operationCreate === "string") {
@@ -16,7 +19,7 @@ export function useGraphqlModelOperation(props) {
16
19
  return props.operationCreate;
17
20
  }
18
21
  }
19
- return graphqlOperation["create" + capitalizeFirstLetter(props.modelName)];
22
+ return graphqlOperation["create" + capitalizeFirstLetter(computedModelName.value)];
20
23
  });
21
24
  const operationUpdate = computed(() => {
22
25
  if (props.operationUpdate) {
@@ -27,7 +30,7 @@ export function useGraphqlModelOperation(props) {
27
30
  return props.operationUpdate;
28
31
  }
29
32
  }
30
- return graphqlOperation["update" + capitalizeFirstLetter(props.modelName)];
33
+ return graphqlOperation["update" + capitalizeFirstLetter(computedModelName.value)];
31
34
  });
32
35
  const operationDelete = computed(() => {
33
36
  if (props.operationDelete) {
@@ -38,7 +41,7 @@ export function useGraphqlModelOperation(props) {
38
41
  return props.operationDelete;
39
42
  }
40
43
  }
41
- return graphqlOperation["delete" + capitalizeFirstLetter(props.modelName)];
44
+ return graphqlOperation["delete" + capitalizeFirstLetter(computedModelName.value)];
42
45
  });
43
46
  const operationRead = computed(() => {
44
47
  if (props.operationRead) {
@@ -71,7 +74,7 @@ export function useGraphqlModelOperation(props) {
71
74
  return props.operationSearch;
72
75
  }
73
76
  }
74
- return graphqlOperation["search" + capitalizeFirstLetter(props.modelName)];
77
+ return graphqlOperation["search" + capitalizeFirstLetter(computedModelName.value)];
75
78
  });
76
79
  return { operationCreate, operationUpdate, operationDelete, operationRead, operationReadPageable, operationSearch };
77
80
  }
@@ -1,99 +1,99 @@
1
- <script lang="ts" setup>
2
- import FullCalendar from '@fullcalendar/vue3'
3
- import dayGridPlugin from '@fullcalendar/daygrid'
4
- import timeGridPlugin from '@fullcalendar/timegrid'
5
- import listPlugin from '@fullcalendar/list'
6
- import interactionPlugin from '@fullcalendar/interaction'
7
- import { ref, computed, withDefaults } from 'vue'
8
- import { type CalendarOptions } from '@fullcalendar/core'
9
-
10
- type Event = {
11
- id: string | undefined
12
- title: string
13
- start: string // YYYY-MM-DD | YYYY-MM-DD HH:mm:ss
14
- end: string // YYYY-MM-DD
15
- color: string
16
- detail?: string
17
- props: Record<string, any> | any[]
18
- }
19
-
20
- interface CalendarProps {
21
- modelValue: Event[]
22
- locale?: 'th' | 'en'
23
- toolBarLeft?: string
24
- toolBarCenter?: string
25
- toolBarRight?: string
26
- height?: string | number
27
- selectViewDay?: string
28
- mode: 'dayGridMonth' | 'timeGridDay'
29
- }
30
-
31
- const props = withDefaults(defineProps<CalendarProps>(), {
32
- locale: 'th',
33
- height: 1200,
34
- toolBarLeft: 'today prev,next',
35
- toolBarCenter: 'title',
36
- toolBarRight: 'timeGridDay,timeGridWeek,dayGridMonth',
37
- mode: 'dayGridMonth',
38
- })
39
-
40
- const emit = defineEmits(['select', 'dialog'])
41
-
42
- const buttonText = computed(() => {
43
- return {
44
- today: props.locale === 'th' ? 'วันนี้' : 'today',
45
- month: props.locale === 'th' ? 'เดือน' : 'month',
46
- week: props.locale === 'th' ? 'สัปดาห์' : 'week',
47
- day: props.locale === 'th' ? 'วัน' : 'day',
48
- list: props.locale === 'th' ? 'รายการ' : 'list',
49
- year: props.locale === 'th' ? 'ปี' : 'year',
50
- }
51
- })
52
-
53
- const calendarRef = ref<InstanceType<typeof FullCalendar>>()
54
- const dateViewDay = ref({ date: '', props: {} })
55
-
56
- const handleDateClick = (info: any) => {
57
- emit('select', info.event)
58
- }
59
-
60
- const handleEventClick = (info: any) => {
61
- emit('dialog', true)
62
- emit('select', info.event)
63
- }
64
-
65
- const eventContentDay = (arg: any) => {
66
- const list = document.createElement('div')
67
- list.innerHTML = document.getElementById(arg.event.id.toString())?.innerHTML || ''
68
- return { domNodes: [list] }
69
- }
70
-
71
- // @ts-expect-error
72
- const calendarOptions = ref<CalendarOptions>({
73
- plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
74
- initialView: props.mode,
75
- locale: props.locale,
76
- dayMaxEvents: true,
77
- timeZone: 'UTC',
78
- headerToolbar: {
79
- left: props.toolBarLeft,
80
- center: props.toolBarCenter,
81
- right: props.toolBarRight,
82
- },
83
- buttonText: buttonText.value,
84
- events: props.modelValue,
85
- initialDate: props.selectViewDay,
86
- dateClick: handleDateClick,
87
- eventClick: handleEventClick,
88
- nowIndicator: true,
89
- height: props.height,
90
- eventColor: '#378006',
91
- })
92
- </script>
93
-
94
- <template>
95
- <FullCalendar
96
- ref="calendarRef"
97
- :options="calendarOptions as CalendarOptions"
98
- />
99
- </template>
1
+ <script lang="ts" setup>
2
+ import FullCalendar from '@fullcalendar/vue3'
3
+ import dayGridPlugin from '@fullcalendar/daygrid'
4
+ import timeGridPlugin from '@fullcalendar/timegrid'
5
+ import listPlugin from '@fullcalendar/list'
6
+ import interactionPlugin from '@fullcalendar/interaction'
7
+ import { ref, computed, withDefaults } from 'vue'
8
+ import { type CalendarOptions } from '@fullcalendar/core'
9
+
10
+ type Event = {
11
+ id: string | undefined
12
+ title: string
13
+ start: string // YYYY-MM-DD | YYYY-MM-DD HH:mm:ss
14
+ end: string // YYYY-MM-DD
15
+ color: string
16
+ detail?: string
17
+ props: Record<string, any> | any[]
18
+ }
19
+
20
+ interface CalendarProps {
21
+ modelValue: Event[]
22
+ locale?: 'th' | 'en'
23
+ toolBarLeft?: string
24
+ toolBarCenter?: string
25
+ toolBarRight?: string
26
+ height?: string | number
27
+ selectViewDay?: string
28
+ mode: 'dayGridMonth' | 'timeGridDay'
29
+ }
30
+
31
+ const props = withDefaults(defineProps<CalendarProps>(), {
32
+ locale: 'th',
33
+ height: 1200,
34
+ toolBarLeft: 'today prev,next',
35
+ toolBarCenter: 'title',
36
+ toolBarRight: 'timeGridDay,timeGridWeek,dayGridMonth',
37
+ mode: 'dayGridMonth',
38
+ })
39
+
40
+ const emit = defineEmits(['select', 'dialog'])
41
+
42
+ const buttonText = computed(() => {
43
+ return {
44
+ today: props.locale === 'th' ? 'วันนี้' : 'today',
45
+ month: props.locale === 'th' ? 'เดือน' : 'month',
46
+ week: props.locale === 'th' ? 'สัปดาห์' : 'week',
47
+ day: props.locale === 'th' ? 'วัน' : 'day',
48
+ list: props.locale === 'th' ? 'รายการ' : 'list',
49
+ year: props.locale === 'th' ? 'ปี' : 'year',
50
+ }
51
+ })
52
+
53
+ const calendarRef = ref<InstanceType<typeof FullCalendar>>()
54
+ const dateViewDay = ref({ date: '', props: {} })
55
+
56
+ const handleDateClick = (info: any) => {
57
+ emit('select', info.event)
58
+ }
59
+
60
+ const handleEventClick = (info: any) => {
61
+ emit('dialog', true)
62
+ emit('select', info.event)
63
+ }
64
+
65
+ const eventContentDay = (arg: any) => {
66
+ const list = document.createElement('div')
67
+ list.innerHTML = document.getElementById(arg.event.id.toString())?.innerHTML || ''
68
+ return { domNodes: [list] }
69
+ }
70
+
71
+ // @ts-expect-error
72
+ const calendarOptions = ref<CalendarOptions>({
73
+ plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
74
+ initialView: props.mode,
75
+ locale: props.locale,
76
+ dayMaxEvents: true,
77
+ timeZone: 'UTC',
78
+ headerToolbar: {
79
+ left: props.toolBarLeft,
80
+ center: props.toolBarCenter,
81
+ right: props.toolBarRight,
82
+ },
83
+ buttonText: buttonText.value,
84
+ events: props.modelValue,
85
+ initialDate: props.selectViewDay,
86
+ dateClick: handleDateClick,
87
+ eventClick: handleEventClick,
88
+ nowIndicator: true,
89
+ height: props.height,
90
+ eventColor: '#378006',
91
+ })
92
+ </script>
93
+
94
+ <template>
95
+ <FullCalendar
96
+ ref="calendarRef"
97
+ :options="calendarOptions as CalendarOptions"
98
+ />
99
+ </template>