@finema/finework-layer 0.2.77 → 0.2.79

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/.husky/pre-commit +1 -1
  2. package/.playground/app/assets/css/main.css +6 -6
  3. package/.playground/app/pages/layout-admin/[id]/index.vue +145 -145
  4. package/.playground/app/pages/layout-admin/test/[id]/index.vue +286 -286
  5. package/.playground/app/pages/layout-admin.vue +283 -285
  6. package/.playground/app/pages/layout-user.vue +284 -284
  7. package/.playground/app/pages/submenu/layout-admin.vue +210 -210
  8. package/.vscode/settings.json +5 -1
  9. package/CHANGELOG.md +382 -374
  10. package/app/app.config.ts +144 -144
  11. package/app/app.vue +10 -10
  12. package/app/assets/css/main.css +77 -77
  13. package/app/components/Button/ActionIcon.vue +29 -29
  14. package/app/components/Button/Back.vue +22 -22
  15. package/app/components/Format/Currency.vue +17 -17
  16. package/app/components/Format/Date.vue +24 -24
  17. package/app/components/Format/DateTime.vue +24 -24
  18. package/app/components/Format/Number.vue +17 -17
  19. package/app/components/Format/Percent.vue +38 -38
  20. package/app/components/Format/TimeFromNow.vue +38 -38
  21. package/app/components/InfoItemList.vue +196 -196
  22. package/app/components/Layout/Admin/Sidebar.vue +343 -329
  23. package/app/components/Layout/Admin/index.vue +240 -224
  24. package/app/components/Layout/Apps.vue +45 -45
  25. package/app/components/Layout/User/index.vue +102 -102
  26. package/app/components/Notifications/index.vue +162 -162
  27. package/app/components/StatusBox.vue +56 -56
  28. package/app/composables/useAuth.ts +207 -207
  29. package/app/composables/useNotification.ts +76 -76
  30. package/app/composables/useRequestOptions.ts +86 -86
  31. package/app/constants/routes.ts +86 -86
  32. package/app/error.vue +218 -218
  33. package/app/middleware/auth.ts +45 -45
  34. package/app/middleware/common.ts +12 -12
  35. package/app/middleware/guest.ts +7 -7
  36. package/app/middleware/permissions.ts +29 -29
  37. package/bun.lock +2758 -2758
  38. package/eslint.config.js +206 -2
  39. package/index.d.ts +16 -16
  40. package/nuxt.config.ts +41 -41
  41. package/package.json +38 -38
package/app/app.config.ts CHANGED
@@ -1,144 +1,144 @@
1
- export default defineAppConfig({
2
- core: {
3
- is_thai_year: true,
4
- is_thai_month: true,
5
- date_format: 'dd MMM yyyy',
6
- month_format: 'MMM yyyy',
7
- date_time_format: 'dd MMM yyyy HH:mm',
8
- color: '#335AFF',
9
- limit_per_page: 10,
10
- locale: 'en',
11
- },
12
- ui: {
13
- dialog: {
14
- slots: {
15
- base: [
16
- 'bg-[url(/dialog-bg.png)] bg-no-repeat bg-top-left bg-size-[220px]',
17
- ],
18
- },
19
- },
20
- card: {
21
- variants: {
22
- variant: {
23
- soft: {
24
- root: 'bg-elevated/50 divide-y divide-default',
25
- },
26
- },
27
- },
28
- defaultVariants: {
29
- variant: 'soft',
30
- },
31
-
32
- },
33
- tabs: {
34
- slots: {
35
- list: 'p-0 ',
36
- label: ' font-bold ',
37
- leadingIcon: 'hover:!text-primary',
38
- },
39
- variants: {
40
- variant: {
41
- pill: {
42
- list: 'bg-white rounded-sm',
43
- trigger: 'grow',
44
- indicator: 'rounded-md shadow-xs',
45
- },
46
- link: {
47
- list: 'border-default',
48
- indicator: 'rounded-none',
49
- trigger: 'focus:outline-none',
50
- },
51
- },
52
- orientation: {
53
- horizontal: {
54
- root: 'flex-col',
55
- list: 'w-full ',
56
- indicator: 'left-0 w-(--reka-tabs-indicator-size) translate-x-(--reka-tabs-indicator-position) ',
57
- trigger: 'justify-center ',
58
- },
59
- vertical: {
60
- list: 'flex-col',
61
- trigger: '!px-3 py-2 text-sm gap-3',
62
- indicator: 'top-0 h-(--reka-tabs-indicator-size) translate-y-(--reka-tabs-indicator-position) ',
63
- },
64
- },
65
- size: {
66
- lg: {
67
- trigger: 'px-4 py-2 text-sm gap-3',
68
- leadingIcon: 'size-6',
69
- leadingAvatarSize: '2xs',
70
- },
71
- },
72
- },
73
- compoundVariants: [
74
- {
75
- orientation: 'horizontal',
76
- variant: 'pill',
77
- class: {
78
- root: ' px-4 py-2 bg-white rounded-xl',
79
- indicator: 'inset-y-5 ',
80
- label: 'text-[#344054]',
81
- trigger: 'data-[state=active]:bg-[#F9FAFB]',
82
- },
83
- },
84
- {
85
- orientation: 'vertical',
86
- variant: 'pill',
87
- class: {
88
- indicator: 'inset-x-1',
89
- list: 'items-center gap-3 xl:gap-5',
90
- root: 'p-4 bg-white rounded-xl',
91
- label: 'text-[#344054]',
92
- trigger: 'data-[state=active]:bg-[#F9FAFB]',
93
- },
94
- },
95
- {
96
- orientation: 'horizontal',
97
- variant: 'link',
98
- class: {
99
- list: 'border-b -mb-px',
100
- indicator: '-bottom-px h-px',
101
- trigger: 'data-[state=active]:text-primary ',
102
- },
103
- },
104
- {
105
- orientation: 'vertical',
106
- variant: 'link',
107
- class: {
108
- list: 'border-none -ms-px gap-1',
109
- indicator: '-start-px w-px !w-[2px] !left-[-2px]',
110
- },
111
- },
112
- {
113
- color: 'primary',
114
- variant: 'pill',
115
- class: {
116
- indicator: 'bg-[#F9FAFB]',
117
- trigger: 'data-[state=active]:text-primary',
118
- },
119
- },
120
-
121
- ],
122
- defaultVariants: {
123
- color: 'primary',
124
- variant: 'pill',
125
- size: 'lg',
126
- },
127
- },
128
- table: {
129
- slots: {
130
- th: 'text-[#222222] whitespace-nowrap border-r border-[#EAECF0] last:border-0 bg-[#F9FAFB]',
131
- td: 'text-[#222222] border-r border-[#EAECF0] last:border-0',
132
- },
133
- },
134
- button: {
135
- compoundVariants: [
136
- {
137
- color: 'error',
138
- variant: 'outline',
139
- class: 'ring ring-inset ring-[#FDA29B] text-[#B42318] hover:bg-error/10 active:bg-error/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-error',
140
- },
141
- ],
142
- },
143
- },
144
- })
1
+ export default defineAppConfig({
2
+ core: {
3
+ is_thai_year: true,
4
+ is_thai_month: true,
5
+ date_format: 'dd MMM yyyy',
6
+ month_format: 'MMM yyyy',
7
+ date_time_format: 'dd MMM yyyy HH:mm',
8
+ color: '#335AFF',
9
+ limit_per_page: 10,
10
+ locale: 'en',
11
+ },
12
+ ui: {
13
+ dialog: {
14
+ slots: {
15
+ base: [
16
+ 'bg-[url(/dialog-bg.png)] bg-no-repeat bg-top-left bg-size-[220px]',
17
+ ],
18
+ },
19
+ },
20
+ card: {
21
+ variants: {
22
+ variant: {
23
+ soft: {
24
+ root: 'bg-elevated/50 divide-y divide-default',
25
+ },
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ variant: 'soft',
30
+ },
31
+
32
+ },
33
+ tabs: {
34
+ slots: {
35
+ list: 'p-0 ',
36
+ label: ' font-bold ',
37
+ leadingIcon: 'hover:!text-primary',
38
+ },
39
+ variants: {
40
+ variant: {
41
+ pill: {
42
+ list: 'bg-white rounded-sm',
43
+ trigger: 'grow',
44
+ indicator: 'rounded-md shadow-xs',
45
+ },
46
+ link: {
47
+ list: 'border-default',
48
+ indicator: 'rounded-none',
49
+ trigger: 'focus:outline-none',
50
+ },
51
+ },
52
+ orientation: {
53
+ horizontal: {
54
+ root: 'flex-col',
55
+ list: 'w-full ',
56
+ indicator: 'left-0 w-(--reka-tabs-indicator-size) translate-x-(--reka-tabs-indicator-position) ',
57
+ trigger: 'justify-center ',
58
+ },
59
+ vertical: {
60
+ list: 'flex-col',
61
+ trigger: '!px-3 py-2 text-sm gap-3',
62
+ indicator: 'top-0 h-(--reka-tabs-indicator-size) translate-y-(--reka-tabs-indicator-position) ',
63
+ },
64
+ },
65
+ size: {
66
+ lg: {
67
+ trigger: 'px-4 py-2 text-sm gap-3',
68
+ leadingIcon: 'size-6',
69
+ leadingAvatarSize: '2xs',
70
+ },
71
+ },
72
+ },
73
+ compoundVariants: [
74
+ {
75
+ orientation: 'horizontal',
76
+ variant: 'pill',
77
+ class: {
78
+ root: ' px-4 py-2 bg-white rounded-xl',
79
+ indicator: 'inset-y-5 ',
80
+ label: 'text-[#344054]',
81
+ trigger: 'data-[state=active]:bg-[#F9FAFB]',
82
+ },
83
+ },
84
+ {
85
+ orientation: 'vertical',
86
+ variant: 'pill',
87
+ class: {
88
+ indicator: 'inset-x-1',
89
+ list: 'items-center gap-3 xl:gap-5',
90
+ root: 'p-4 bg-white rounded-xl',
91
+ label: 'text-[#344054]',
92
+ trigger: 'data-[state=active]:bg-[#F9FAFB]',
93
+ },
94
+ },
95
+ {
96
+ orientation: 'horizontal',
97
+ variant: 'link',
98
+ class: {
99
+ list: 'border-b -mb-px',
100
+ indicator: '-bottom-px h-px',
101
+ trigger: 'data-[state=active]:text-primary ',
102
+ },
103
+ },
104
+ {
105
+ orientation: 'vertical',
106
+ variant: 'link',
107
+ class: {
108
+ list: 'border-none -ms-px gap-1',
109
+ indicator: '-start-px w-px !w-[2px] !left-[-2px]',
110
+ },
111
+ },
112
+ {
113
+ color: 'primary',
114
+ variant: 'pill',
115
+ class: {
116
+ indicator: 'bg-[#F9FAFB]',
117
+ trigger: 'data-[state=active]:text-primary',
118
+ },
119
+ },
120
+
121
+ ],
122
+ defaultVariants: {
123
+ color: 'primary',
124
+ variant: 'pill',
125
+ size: 'lg',
126
+ },
127
+ },
128
+ table: {
129
+ slots: {
130
+ th: 'text-[#222222] whitespace-nowrap border-r border-[#EAECF0] last:border-0 bg-[#F9FAFB]',
131
+ td: 'text-[#222222] border-r border-[#EAECF0] last:border-0',
132
+ },
133
+ },
134
+ button: {
135
+ compoundVariants: [
136
+ {
137
+ color: 'error',
138
+ variant: 'outline',
139
+ class: 'ring ring-inset ring-[#FDA29B] text-[#B42318] hover:bg-error/10 active:bg-error/10 disabled:bg-transparent aria-disabled:bg-transparent dark:disabled:bg-transparent dark:aria-disabled:bg-transparent focus:outline-none focus-visible:ring-2 focus-visible:ring-error',
140
+ },
141
+ ],
142
+ },
143
+ },
144
+ })
package/app/app.vue CHANGED
@@ -1,10 +1,10 @@
1
- <template>
2
- <App
3
- :toaster="{
4
- position: 'top-right',
5
- progress: false,
6
- }"
7
- >
8
- <NuxtPage />
9
- </App>
10
- </template>
1
+ <template>
2
+ <App
3
+ :toaster="{
4
+ position: 'top-right',
5
+ progress: false,
6
+ }"
7
+ >
8
+ <NuxtPage />
9
+ </App>
10
+ </template>
@@ -1,78 +1,78 @@
1
- @import "tailwindcss";
2
-
3
- @theme static{
4
- --color-main: #1570EF;
5
- --color-main-50: #EFF8FF;
6
- --color-main-100: #D1E9FF;
7
- --color-main-200: #B2DDFF;
8
- --color-main-300: #84CAFF;
9
- --color-main-400: #53B1FD;
10
- --color-main-500: #2E90FA;
11
- --color-main-600: #1570EF;
12
- --color-main-700: #175CD3;
13
- --color-main-800: #1849A9;
14
- --color-main-900: #194185;
15
- --color-main-950: #102A56;
16
-
17
- --color-warning: #DC6803;
18
- --color-warning-50: #FFFAEB;
19
- --color-warning-100: #FEF0C7;
20
- --color-warning-200: #FEDF89;
21
- --color-warning-300: #FEC84B;
22
- --color-warning-400: #FDB022;
23
- --color-warning-500: #F79009;
24
- --color-warning-600: #DC6803;
25
- --color-warning-700: #B54708;
26
- --color-warning-800: #93370D;
27
- --color-warning-900: #7A2E0E;
28
- --color-warning-950: #4E1D09;
29
-
30
- --color-success: #079455;
31
- --color-success-50: #ECFDF3;
32
- --color-success-100: #DCFAE6;
33
- --color-success-200: #ABEFC6;
34
- --color-success-300: #75E0A7;
35
- --color-success-400: #47CD89;
36
- --color-success-500: #17B26A;
37
- --color-success-600: #079455;
38
- --color-success-700: #067647;
39
- --color-success-800: #085D3A;
40
- --color-success-900: #074D31;
41
- --color-success-950: #053321;
42
-
43
- --color-error: #D92D20 !important;
44
- --color-error-50: #FEF3F2;
45
- --color-error-100: #FEE4E2;
46
- --color-error-200: #FECDCA;
47
- --color-error-300: #FDA29B;
48
- --color-error-400: #F97066;
49
- --color-error-500: #F04438;
50
- --color-error-600: #D92D20 !important;
51
- --color-error-700: #B42318;
52
- --color-error-800: #912018;
53
- --color-error-900: #7A271A;
54
- --color-error-950: #55160C;
55
-
56
- --color-gray: #475467;
57
- --color-gray-50: #F9FAFB;
58
- --color-gray-100: #F2F4F7;
59
- --color-gray-200: #EAECF0;
60
- --color-gray-300: #D0D5DD;
61
- --color-gray-400: #98A2B3;
62
- --color-gray-500: #667085;
63
- --color-gray-600: #475467;
64
- --color-gray-700: #344054;
65
- --color-gray-800: #182230;
66
- --color-gray-900: #101828;
67
- --color-gray-950: #0C111D;
68
- }
69
- :root {
70
- --color-background: var(--color-gray-50);
71
- --ui-primary:#1570EF;
72
- --ui-error: #D92D20;
73
- --ui-success: #079455;
74
- }
75
-
76
- body {
77
- @apply bg-[var(--color-background)];
1
+ @import "tailwindcss";
2
+
3
+ @theme static{
4
+ --color-main: #1570EF;
5
+ --color-main-50: #EFF8FF;
6
+ --color-main-100: #D1E9FF;
7
+ --color-main-200: #B2DDFF;
8
+ --color-main-300: #84CAFF;
9
+ --color-main-400: #53B1FD;
10
+ --color-main-500: #2E90FA;
11
+ --color-main-600: #1570EF;
12
+ --color-main-700: #175CD3;
13
+ --color-main-800: #1849A9;
14
+ --color-main-900: #194185;
15
+ --color-main-950: #102A56;
16
+
17
+ --color-warning: #DC6803;
18
+ --color-warning-50: #FFFAEB;
19
+ --color-warning-100: #FEF0C7;
20
+ --color-warning-200: #FEDF89;
21
+ --color-warning-300: #FEC84B;
22
+ --color-warning-400: #FDB022;
23
+ --color-warning-500: #F79009;
24
+ --color-warning-600: #DC6803;
25
+ --color-warning-700: #B54708;
26
+ --color-warning-800: #93370D;
27
+ --color-warning-900: #7A2E0E;
28
+ --color-warning-950: #4E1D09;
29
+
30
+ --color-success: #079455;
31
+ --color-success-50: #ECFDF3;
32
+ --color-success-100: #DCFAE6;
33
+ --color-success-200: #ABEFC6;
34
+ --color-success-300: #75E0A7;
35
+ --color-success-400: #47CD89;
36
+ --color-success-500: #17B26A;
37
+ --color-success-600: #079455;
38
+ --color-success-700: #067647;
39
+ --color-success-800: #085D3A;
40
+ --color-success-900: #074D31;
41
+ --color-success-950: #053321;
42
+
43
+ --color-error: #D92D20 !important;
44
+ --color-error-50: #FEF3F2;
45
+ --color-error-100: #FEE4E2;
46
+ --color-error-200: #FECDCA;
47
+ --color-error-300: #FDA29B;
48
+ --color-error-400: #F97066;
49
+ --color-error-500: #F04438;
50
+ --color-error-600: #D92D20 !important;
51
+ --color-error-700: #B42318;
52
+ --color-error-800: #912018;
53
+ --color-error-900: #7A271A;
54
+ --color-error-950: #55160C;
55
+
56
+ --color-gray: #475467;
57
+ --color-gray-50: #F9FAFB;
58
+ --color-gray-100: #F2F4F7;
59
+ --color-gray-200: #EAECF0;
60
+ --color-gray-300: #D0D5DD;
61
+ --color-gray-400: #98A2B3;
62
+ --color-gray-500: #667085;
63
+ --color-gray-600: #475467;
64
+ --color-gray-700: #344054;
65
+ --color-gray-800: #182230;
66
+ --color-gray-900: #101828;
67
+ --color-gray-950: #0C111D;
68
+ }
69
+ :root {
70
+ --color-background: var(--color-gray-50);
71
+ --ui-primary:#1570EF;
72
+ --ui-error: #D92D20;
73
+ --ui-success: #079455;
74
+ }
75
+
76
+ body {
77
+ @apply bg-[var(--color-background)];
78
78
  }
@@ -1,29 +1,29 @@
1
- <template>
2
- <Button
3
- size="lg"
4
- variant="ghost"
5
- :icon="icon"
6
- :color="color"
7
- square
8
- :disabled="disabled"
9
- :loading="loading"
10
- :to="to"
11
- @click="$emit('click')"
12
- />
13
- </template>
14
-
15
- <script lang="ts" setup>
16
- defineEmits<{
17
- (e: 'click'): void
18
- }>()
19
-
20
- withDefaults(defineProps<{
21
- to?: string
22
- icon: string
23
- color?: 'neutral' | 'error' | 'primary' | 'success' | 'warning' | 'info'
24
- disabled?: boolean
25
- loading?: boolean
26
- }>(), {
27
- color: 'neutral',
28
- })
29
- </script>
1
+ <template>
2
+ <Button
3
+ size="lg"
4
+ variant="ghost"
5
+ :icon="icon"
6
+ :color="color"
7
+ square
8
+ :disabled="disabled"
9
+ :loading="loading"
10
+ :to="to"
11
+ @click="$emit('click')"
12
+ />
13
+ </template>
14
+
15
+ <script lang="ts" setup>
16
+ defineEmits<{
17
+ (e: 'click'): void
18
+ }>()
19
+
20
+ withDefaults(defineProps<{
21
+ to?: string
22
+ icon: string
23
+ color?: 'neutral' | 'error' | 'primary' | 'success' | 'warning' | 'info'
24
+ disabled?: boolean
25
+ loading?: boolean
26
+ }>(), {
27
+ color: 'neutral',
28
+ })
29
+ </script>
@@ -1,22 +1,22 @@
1
- <template>
2
- <Button
3
- icon="ph:caret-left"
4
- variant="outline"
5
- color="neutral"
6
- :to="to"
7
- @click="$emit('click')"
8
- >
9
- {{ label || 'กลับ' }}
10
- </Button>
11
- </template>
12
-
13
- <script lang="ts" setup>
14
- defineEmits<{
15
- (e: 'click'): void
16
- }>()
17
-
18
- defineProps<{
19
- to?: string
20
- label?: string
21
- }>()
22
- </script>
1
+ <template>
2
+ <Button
3
+ icon="ph:caret-left"
4
+ variant="outline"
5
+ color="neutral"
6
+ :to="to"
7
+ @click="$emit('click')"
8
+ >
9
+ {{ label || 'กลับ' }}
10
+ </Button>
11
+ </template>
12
+
13
+ <script lang="ts" setup>
14
+ defineEmits<{
15
+ (e: 'click'): void
16
+ }>()
17
+
18
+ defineProps<{
19
+ to?: string
20
+ label?: string
21
+ }>()
22
+ </script>
@@ -1,17 +1,17 @@
1
- <template>
2
- <component :is="props.as || 'span'">
3
- {{ getValue }} {{ unit ? unit : '' }}
4
- </component>
5
- </template>
6
-
7
- <script lang="ts" setup>
8
- const props = defineProps<{
9
- value: number | string | null | undefined
10
- as?: string
11
- unit?: string
12
- }>()
13
-
14
- const getValue = computed(() => {
15
- return NumberHelper.toCurrency(props.value)
16
- })
17
- </script>
1
+ <template>
2
+ <component :is="props.as || 'span'">
3
+ {{ getValue }} {{ unit ? unit : '' }}
4
+ </component>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ const props = defineProps<{
9
+ value: number | string | null | undefined
10
+ as?: string
11
+ unit?: string
12
+ }>()
13
+
14
+ const getValue = computed(() => {
15
+ return NumberHelper.toCurrency(props.value)
16
+ })
17
+ </script>
@@ -1,24 +1,24 @@
1
- <template>
2
- <component
3
- :is="props.as || 'span'"
4
- :title="getValue"
5
- >
6
- {{ getValue ?? '–' }}
7
- </component>
8
- </template>
9
-
10
- <script lang="ts" setup>
11
- const props = defineProps<{
12
- value: string | Date
13
- as?: string
14
- }>()
15
-
16
- const config = useAppConfig()
17
- const localeInject = inject('locale')
18
-
19
- const getValue = computed(() => {
20
- return (localeInject ?? config.core.locale) === 'th'
21
- ? TimeHelper.displayDateThai(props.value)
22
- : TimeHelper.displayDate(props.value)
23
- })
24
- </script>
1
+ <template>
2
+ <component
3
+ :is="props.as || 'span'"
4
+ :title="getValue"
5
+ >
6
+ {{ getValue ?? '–' }}
7
+ </component>
8
+ </template>
9
+
10
+ <script lang="ts" setup>
11
+ const props = defineProps<{
12
+ value: string | Date
13
+ as?: string
14
+ }>()
15
+
16
+ const config = useAppConfig()
17
+ const localeInject = inject('locale')
18
+
19
+ const getValue = computed(() => {
20
+ return (localeInject ?? config.core.locale) === 'th'
21
+ ? TimeHelper.displayDateThai(props.value)
22
+ : TimeHelper.displayDate(props.value)
23
+ })
24
+ </script>