@finema/core 1.4.121 → 1.4.123

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "1.4.121",
3
+ "version": "1.4.123",
4
4
  "configKey": "core",
5
5
  "compatibility": {
6
6
  "nuxt": "^3.7.4"
package/dist/module.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineNuxtModule, createResolver, installModule, addPlugin, addComponentsDir, addImportsDir } from '@nuxt/kit';
2
2
 
3
3
  const name = "@finema/core";
4
- const version = "1.4.121";
4
+ const version = "1.4.123";
5
5
 
6
6
  const colors = {
7
7
  black: "#20243E",
@@ -2,12 +2,36 @@
2
2
  <NuxtLoadingIndicator :color="color" />
3
3
  <Dialog />
4
4
  <UNotifications />
5
+ <div v-if="isDevEnv" class="fixed bottom-4 right-4 z-50">
6
+ <div class="flex flex-col items-end justify-end">
7
+ <div
8
+ v-show="isShowDevTools"
9
+ class="mb-4 size-[600px] overflow-auto rounded-lg border shadow-2xl"
10
+ >
11
+ <p class="p-3 text-lg font-semibold">Debug Tools</p>
12
+ <hr />
13
+ <div id="dev-logs" class="flex flex-col space-y-3 p-3" />
14
+ </div>
15
+ <Button
16
+ :icon="isShowDevTools ? 'heroicons:x-mark' : 'heroicons:information-circle'"
17
+ color="info"
18
+ square
19
+ :ui="{ rounded: 'rounded-full' }"
20
+ @click="isShowDevTools = !isShowDevTools"
21
+ />
22
+ </div>
23
+ </div>
5
24
  </template>
6
25
  <script lang="ts" setup>
26
+ import { defineProps, ref } from 'vue'
27
+
7
28
  defineProps({
8
29
  color: {
9
30
  type: String,
10
31
  default: '#3675FB',
11
32
  },
12
33
  })
34
+
35
+ const isShowDevTools = ref(false)
36
+ const isDevEnv = process.env.NODE_ENV === 'development'
13
37
  </script>
@@ -1,18 +1,31 @@
1
1
  <template>
2
- <slot v-if="status.isLoading" name="loading-state">
3
- <div class="flex h-60 items-center justify-center">
4
- <Icon name="i-svg-spinners:180-ring-with-bg" class="text-primary size-8" />
5
- </div>
6
- </slot>
7
2
  <slot v-if="!status.isLoading && rawData.length === 0" name="empty-state">
8
3
  <div class="min-h-60">
9
4
  <p class="text-center text-sm italic">ไม่พบข้อมูล!</p>
10
5
  </div>
11
6
  </slot>
12
- <div v-if="status.isSuccess" :class="containerClass">
13
- <slot v-for="(row, index) in rawData" :key="index" :row="row" />
7
+
8
+ <div
9
+ v-if="pageOptions && isEnableInfiniteScroll && !isHideTopPagination"
10
+ class="mb-4 flex items-center justify-end"
11
+ >
12
+ <p class="text-xs text-gray-500">
13
+ ผลลัพธ์ {{ totalInnerRawData }} ของ {{ totalCountWithComma }} รายการ
14
+ </p>
14
15
  </div>
15
- <div v-if="pageOptions" class="mt-4 flex justify-between px-3">
16
+
17
+ <div :class="containerClass">
18
+ <slot v-for="(row, index) in innerRawData" :key="index" :row="row" />
19
+ <div ref="bottomEdgeElement" />
20
+ </div>
21
+
22
+ <slot v-if="status.isLoading" name="loading-state">
23
+ <div class="flex h-60 items-center justify-center">
24
+ <Icon name="i-svg-spinners:180-ring-with-bg" class="text-primary size-8" />
25
+ </div>
26
+ </slot>
27
+
28
+ <div v-if="pageOptions && !isEnableInfiniteScroll" class="mt-4 flex justify-between px-3">
16
29
  <p class="text-xs text-gray-500">
17
30
  ผลลัพธ์ {{ pageBetween }} ของ {{ totalCountWithComma }} รายการ
18
31
  </p>
@@ -33,8 +46,9 @@
33
46
 
34
47
  <script lang="ts" setup>
35
48
  import { computed, type PropType } from 'vue'
49
+ import { useElementVisibility } from '@vueuse/core'
36
50
  import { StringHelper } from '#core/utils/StringHelper'
37
- import { ref, watch } from '#imports'
51
+ import { ref, useWatchTrue, watch } from '#imports'
38
52
  import type { IFlexDeckOptions } from '#core/components/FlexDeck/types'
39
53
 
40
54
  const emits = defineEmits(['pageChange'])
@@ -56,15 +70,29 @@ const props = defineProps({
56
70
  type: Boolean as PropType<IFlexDeckOptions['isSimplePagination']>,
57
71
  default: false,
58
72
  },
73
+ isHideTopPagination: {
74
+ type: Boolean as PropType<IFlexDeckOptions['isHideTopPagination']>,
75
+ default: false,
76
+ },
59
77
  isHideBottomPagination: {
60
78
  type: Boolean as PropType<IFlexDeckOptions['isHideBottomPagination']>,
61
79
  default: false,
62
80
  },
81
+ isEnableInfiniteScroll: {
82
+ type: Boolean as PropType<IFlexDeckOptions['isEnableInfiniteScroll']>,
83
+ default: false,
84
+ },
63
85
  containerClass: { type: [String, Array, Object] },
64
86
  })
65
87
 
88
+ const bottomEdgeElement = ref<HTMLElement | null>(null)
89
+
66
90
  const page = ref(props.pageOptions?.currentPage || 1)
67
91
 
92
+ const innerRawData = ref<object[]>([])
93
+
94
+ const targetElement = useElementVisibility(bottomEdgeElement)
95
+
68
96
  const pageBetween = computed((): string => {
69
97
  const length = props.rawData?.length
70
98
 
@@ -84,7 +112,32 @@ const totalCountWithComma = computed((): string => {
84
112
  : StringHelper.withComma(props.pageOptions!.totalCount)
85
113
  })
86
114
 
115
+ const totalInnerRawData = computed((): number => {
116
+ return innerRawData.value?.length || 0
117
+ })
118
+
119
+ useWatchTrue(
120
+ () => props.status.isSuccess,
121
+ () => {
122
+ if (props.isEnableInfiniteScroll) {
123
+ innerRawData.value = [...(innerRawData.value || []), ...props.rawData]
124
+
125
+ return
126
+ }
127
+
128
+ innerRawData.value = props.rawData
129
+ }
130
+ )
131
+
87
132
  watch(page, () => {
88
133
  emits('pageChange', page.value)
89
134
  })
135
+
136
+ watch(targetElement, (value) => {
137
+ if (props.status.isLoading || !props.isEnableInfiniteScroll) return
138
+
139
+ if (page.value < props.pageOptions!.totalPage && value) {
140
+ page.value++
141
+ }
142
+ })
90
143
  </script>
@@ -12,7 +12,9 @@
12
12
  :status="options.status"
13
13
  :page-options="options.pageOptions"
14
14
  :is-simple-pagination="isShowSimplePagination"
15
+ :is-hide-top-pagination="options.isHideTopPagination"
15
16
  :is-hide-bottom-pagination="options.isHideBottomPagination"
17
+ :is-enable-infinite-scroll="options.isEnableInfiniteScroll"
16
18
  :container-class="containerClass"
17
19
  @page-change="onPageChange"
18
20
  >
@@ -11,4 +11,5 @@ export interface IFlexDeckOptions<T = object> {
11
11
  isHideBottomPagination?: boolean;
12
12
  isHideTopPagination?: boolean;
13
13
  isSimplePagination?: boolean;
14
+ isEnableInfiniteScroll?: boolean;
14
15
  }
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <TeleportSafe v-if="isDevEnv" to="#dev-logs">
3
+ <VCodeBlock
4
+ v-if="data"
5
+ :code="JSON.stringify(data)"
6
+ max-height="400"
7
+ :browser-window="true"
8
+ :indent="2"
9
+ lang="json"
10
+ highlightjs
11
+ >
12
+ <template #label>
13
+ <span v-if="title" class="font-semibold">{{ title }}</span>
14
+ </template>
15
+ </VCodeBlock>
16
+
17
+ <VCodeBlock
18
+ v-for="(item, index) in dataItems"
19
+ :key="index"
20
+ :code="JSON.stringify(item)"
21
+ max-height="400"
22
+ :browser-window="true"
23
+ :indent="2"
24
+ lang="json"
25
+ highlightjs
26
+ >
27
+ <template #label>
28
+ <span v-if="title" class="font-semibold">{{ title }} #{{ index + 1 }} </span>
29
+ </template>
30
+ </VCodeBlock>
31
+ </TeleportSafe>
32
+ </template>
33
+ <script lang="ts" setup>
34
+ import { defineProps } from 'vue'
35
+ import { VCodeBlock } from '@wdns/vue-code-block'
36
+
37
+ defineProps<{
38
+ data?: any
39
+ dataItems?: any[]
40
+ title?: string
41
+ }>()
42
+
43
+ const isDevEnv = process.env.NODE_ENV === 'development'
44
+ </script>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <Teleport v-if="isShow" :to="target" :disabled="!target || disabled">
3
+ <slot />
4
+ </Teleport>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { onBeforeUnmount, onMounted, ref } from 'vue'
9
+
10
+ const props = defineProps<{ to: string; disabled?: boolean }>()
11
+
12
+ const target = ref<Element | null>(null)
13
+ const isShow = ref(false)
14
+
15
+ onBeforeUnmount(() => {
16
+ isShow.value = false
17
+ })
18
+
19
+ onMounted(() => {
20
+ isShow.value = true
21
+
22
+ const observer = new MutationObserver((mutationList, observer) => {
23
+ for (const mutation of mutationList) {
24
+ if (mutation.type !== 'childList') continue
25
+ const el = document.querySelector(props.to)
26
+ if (!el) continue
27
+ target.value = el
28
+ observer.disconnect()
29
+
30
+ break
31
+ }
32
+ })
33
+
34
+ observer.observe(document, { childList: true, subtree: true })
35
+
36
+ return () => {
37
+ observer.disconnect()
38
+ }
39
+ })
40
+ </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "1.4.121",
3
+ "version": "1.4.123",
4
4
  "repository": "https://gitlab.finema.co/finema/ui-kit",
5
5
  "license": "MIT",
6
6
  "author": "Finema Dev Core Team",
@@ -42,6 +42,7 @@
42
42
  "@vee-validate/zod": "^4.12.6",
43
43
  "@vuepic/vue-datepicker": "^8.2.0",
44
44
  "@vueup/vue-quill": "^1.2.0",
45
+ "@wdns/vue-code-block": "^2.3.2",
45
46
  "axios": "^1.6.8",
46
47
  "date-fns": "^3.3.1",
47
48
  "i18next": "^23.10.1",
@@ -49,6 +50,7 @@
49
50
  "nuxt-lodash": "^2.5.3",
50
51
  "nuxt-security": "^1.2.2",
51
52
  "pinia": "^2.1.7",
53
+ "prismjs": "^1.29.0",
52
54
  "qrcode.vue": "^3.4.1",
53
55
  "url-join": "^5.0.0",
54
56
  "zod": "^3.22.4",
@@ -63,6 +65,7 @@
63
65
  "@nuxt/test-utils": "^3.12.0",
64
66
  "@release-it/conventional-changelog": "^8.0.1",
65
67
  "@types/node": "^20.10.17",
68
+ "@types/prismjs": "^1",
66
69
  "@types/quill": "^2",
67
70
  "@vue/test-utils": "^2.4.3",
68
71
  "changelogen": "^0.5.5",
@@ -88,5 +91,5 @@
88
91
  "workspaces": [
89
92
  "./*"
90
93
  ],
91
- "packageManager": "yarn@4.1.1"
94
+ "packageManager": "yarn@4.2.2"
92
95
  }