@finema/finework-layer 0.2.111 → 0.2.112

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.112](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.111...0.2.112) (2026-01-26)
4
+
5
+ ### Features
6
+
7
+ * enhance PortalApp layout and add Clock-In and Timesheet buttons ([e700e31](https://gitlab.finema.co/finema/finework/finework-frontend-layer/commit/e700e31875ce7b2bb82ef02bfb19fc800ef44378))
8
+ * update Apps and PortalApp components for improved layout and functionality ([6695a0c](https://gitlab.finema.co/finema/finework/finework-frontend-layer/commit/6695a0c57cfdf21676ef0efe050c9fffd8803db9))
9
+
3
10
  ## [0.2.111](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.110...0.2.111) (2026-01-23)
4
11
 
5
12
  ## [0.2.110](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.109...0.2.110) (2026-01-21)
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <div class="">
3
3
  <Slideover
4
+ v-model="isOpen"
4
5
  side="top"
5
6
  :portal="true"
6
7
  :modal="false"
@@ -14,12 +15,15 @@
14
15
  class="text-gray-500"
15
16
  />
16
17
  <template #content>
17
- <PortalApp is-navbar />
18
+ <PortalApp
19
+ is-navbar
20
+ @close="isOpen = false"
21
+ />
18
22
  </template>
19
23
  </Slideover>
20
24
  </div>
21
25
  </template>
22
26
 
23
27
  <script lang="ts" setup>
24
-
28
+ const isOpen = ref(false)
25
29
  </script>
@@ -16,170 +16,232 @@
16
16
  Finework Apps
17
17
  </div>
18
18
  </div>
19
- <div
20
- class="grid gap-5"
21
- :class="[isNavbar ?`md:grid-cols-2 xl:grid-cols-4` : `md:grid-cols-2 xl:grid-cols-3`]"
22
- >
19
+
20
+ <div class="space-y-6">
21
+ <div
22
+ v-if="dailyApps.length > 0"
23
+ class="space-y-5"
24
+ >
25
+ <div class="text-lg font-bold text-gray-600">
26
+ Daily work Apps
27
+ </div>
28
+ <div
29
+ class="grid gap-5"
30
+ :class="[isNavbar ?`md:grid-cols-2 xl:grid-cols-4` : `md:grid-cols-2 xl:grid-cols-3`]"
31
+ >
32
+ <component
33
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
34
+ v-for="app in dailyApps"
35
+ :key="app.name"
36
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
37
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
38
+ :class="app.status === StatusPortal.DEVELOPING
39
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
40
+ : 'bg-gray-100 hover:bg-gray-200'"
41
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
42
+ >
43
+ <div
44
+ v-if="app.status === StatusPortal.DEVELOPING"
45
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
46
+ >
47
+ กำลังพัฒนา
48
+ </div>
49
+ <img
50
+ :src="app.logo"
51
+ :alt="app.label"
52
+ class="h-[45px] w-[45px] bg-white"
53
+ />
54
+ <div>
55
+ <div class="text-lg font-bold">
56
+ {{ app.label }}
57
+ </div>
58
+ <div class="text-sm text-gray-500">
59
+ {{ app.description }}
60
+ </div>
61
+ </div>
62
+ </component>
63
+ </div>
64
+ </div>
23
65
  <div
24
66
  v-if="managementApps.length > 0"
25
- class="space-y-6"
67
+ class="space-y-5"
26
68
  >
27
69
  <div class="text-lg font-bold text-gray-600">
28
70
  Management
29
71
  </div>
30
-
31
- <component
32
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
33
- v-for="app in managementApps"
34
- :key="app.name"
35
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
36
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
37
- :class="app.status === StatusPortal.DEVELOPING
38
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
39
- : 'bg-gray-100 hover:bg-gray-200'"
72
+ <div
73
+ class="grid gap-5"
74
+ :class="[isNavbar ?`md:grid-cols-2 xl:grid-cols-4` : `md:grid-cols-2 xl:grid-cols-3`]"
40
75
  >
41
- <div
42
- v-if="app.status === StatusPortal.DEVELOPING"
43
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
76
+ <component
77
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
78
+ v-for="app in managementApps"
79
+ :key="app.name"
80
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
81
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
82
+ :class="app.status === StatusPortal.DEVELOPING
83
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
84
+ : 'bg-gray-100 hover:bg-gray-200'"
85
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
44
86
  >
45
- กำลังพัฒนา
46
- </div>
47
- <img
48
- :src="app.logo"
49
- :alt="app.label"
50
- class="h-[45px] w-[45px] bg-white"
51
- />
52
- <div>
53
- <div class="text-lg font-bold">
54
- {{ app.label }}
87
+ <div
88
+ v-if="app.status === StatusPortal.DEVELOPING"
89
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
90
+ >
91
+ กำลังพัฒนา
55
92
  </div>
56
- <div class="text-sm text-gray-500">
57
- {{ app.description }}
93
+ <img
94
+ :src="app.logo"
95
+ :alt="app.label"
96
+ class="h-[45px] w-[45px] bg-white"
97
+ />
98
+ <div>
99
+ <div class="text-lg font-bold">
100
+ {{ app.label }}
101
+ </div>
102
+ <div class="text-sm text-gray-500">
103
+ {{ app.description }}
104
+ </div>
58
105
  </div>
59
- </div>
60
- </component>
106
+ </component>
107
+ </div>
61
108
  </div>
62
109
 
63
110
  <div
64
111
  v-if="financeApps.length > 0"
65
- class="space-y-6"
112
+ class="space-y-5"
66
113
  >
67
114
  <div class="text-lg font-bold text-gray-600">
68
115
  Finance
69
116
  </div>
70
-
71
- <component
72
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
73
- v-for="app in financeApps"
74
- :key="app.name"
75
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
76
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
77
- :class="app.status === StatusPortal.DEVELOPING
78
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
79
- : 'bg-gray-100 hover:bg-gray-200'"
117
+ <div
118
+ class="grid gap-5"
119
+ :class="[isNavbar ?`md:grid-cols-2 xl:grid-cols-4` : `md:grid-cols-2 xl:grid-cols-3`]"
80
120
  >
81
- <div
82
- v-if="app.status === StatusPortal.DEVELOPING"
83
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
121
+ <component
122
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
123
+ v-for="app in financeApps"
124
+ :key="app.name"
125
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
126
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
127
+ :class="app.status === StatusPortal.DEVELOPING
128
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
129
+ : 'bg-gray-100 hover:bg-gray-200'"
130
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
84
131
  >
85
- กำลังพัฒนา
86
- </div>
132
+ <div
133
+ v-if="app.status === StatusPortal.DEVELOPING"
134
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
135
+ >
136
+ กำลังพัฒนา
137
+ </div>
87
138
 
88
- <img
89
- :src="app.logo"
90
- :alt="app.label"
91
- class="h-[45px] w-[45px] bg-white"
92
- />
139
+ <img
140
+ :src="app.logo"
141
+ :alt="app.label"
142
+ class="h-[45px] w-[45px] bg-white"
143
+ />
93
144
 
94
- <div>
95
- <div class="text-lg font-bold">
96
- {{ app.label }}
97
- </div>
98
- <div class="text-sm text-gray-500">
99
- {{ app.description }}
145
+ <div>
146
+ <div class="text-lg font-bold">
147
+ {{ app.label }}
148
+ </div>
149
+ <div class="text-sm text-gray-500">
150
+ {{ app.description }}
151
+ </div>
100
152
  </div>
101
- </div>
102
- </component>
153
+ </component>
154
+ </div>
103
155
  </div>
104
156
 
105
157
  <div
106
158
  v-if="peopleApps.length >0"
107
- class="space-y-6"
159
+ class="space-y-5"
108
160
  >
109
161
  <div class="text-lg font-bold text-gray-600">
110
162
  People
111
163
  </div>
112
-
113
- <component
114
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
115
- v-for="app in peopleApps"
116
- :key="app.name"
117
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
118
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
119
- :class="app.status === StatusPortal.DEVELOPING
120
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
121
- : 'bg-gray-100 hover:bg-gray-200'"
164
+ <div
165
+ class="grid gap-5"
166
+ :class="[isNavbar ?`md:grid-cols-2 xl:grid-cols-4` : `md:grid-cols-2 xl:grid-cols-3`]"
122
167
  >
123
- <div
124
- v-if="app.status === StatusPortal.DEVELOPING"
125
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
168
+ <component
169
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
170
+ v-for="app in peopleApps"
171
+ :key="app.name"
172
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
173
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
174
+ :class="app.status === StatusPortal.DEVELOPING
175
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
176
+ : 'bg-gray-100 hover:bg-gray-200'"
177
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
126
178
  >
127
- กำลังพัฒนา
128
- </div>
129
- <img
130
- :src="app.logo"
131
- :alt="app.label"
132
- class="h-[45px] w-[45px] bg-white"
133
- />
134
- <div>
135
- <div class="text-lg font-bold">
136
- {{ app.label }}
179
+ <div
180
+ v-if="app.status === StatusPortal.DEVELOPING"
181
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
182
+ >
183
+ กำลังพัฒนา
137
184
  </div>
138
- <div class="text-sm text-gray-500">
139
- {{ app.description }}
185
+ <img
186
+ :src="app.logo"
187
+ :alt="app.label"
188
+ class="h-[45px] w-[45px] bg-white"
189
+ />
190
+ <div>
191
+ <div class="text-lg font-bold">
192
+ {{ app.label }}
193
+ </div>
194
+ <div class="text-sm text-gray-500">
195
+ {{ app.description }}
196
+ </div>
140
197
  </div>
141
- </div>
142
- </component>
198
+ </component>
199
+ </div>
143
200
  </div>
144
201
 
145
202
  <div
146
203
  v-if="legalApps.length > 0"
147
- class="space-y-6"
204
+ class="space-y-5"
148
205
  >
149
206
  <div class="text-lg font-bold text-gray-600">
150
207
  Legal
151
208
  </div>
152
-
153
- <component
154
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
155
- v-for="app in legalApps"
156
- :key="app.name"
157
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
158
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
159
- :class="app.status === StatusPortal.DEVELOPING
160
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
161
- : 'bg-gray-100 hover:bg-gray-200'"
209
+ <div
210
+ class="grid gap-5"
211
+ :class="[isNavbar ?`md:grid-cols-2 xl:grid-cols-4` : `md:grid-cols-2 xl:grid-cols-3`]"
162
212
  >
163
- <div
164
- v-if="app.status === StatusPortal.DEVELOPING"
165
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
213
+ <component
214
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
215
+ v-for="app in legalApps"
216
+ :key="app.name"
217
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
218
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
219
+ :class="app.status === StatusPortal.DEVELOPING
220
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
221
+ : 'bg-gray-100 hover:bg-gray-200'"
222
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
166
223
  >
167
- กำลังพัฒนา
168
- </div>
169
- <img
170
- :src="app.logo"
171
- :alt="app.label"
172
- class="h-[45px] w-[45px] bg-white"
173
- />
174
- <div>
175
- <div class="text-lg font-bold">
176
- {{ app.label }}
224
+ <div
225
+ v-if="app.status === StatusPortal.DEVELOPING"
226
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
227
+ >
228
+ กำลังพัฒนา
177
229
  </div>
178
- <div class="text-sm text-gray-500">
179
- {{ app.description }}
230
+ <img
231
+ :src="app.logo"
232
+ :alt="app.label"
233
+ class="h-[45px] w-[45px] bg-white"
234
+ />
235
+ <div>
236
+ <div class="text-lg font-bold">
237
+ {{ app.label }}
238
+ </div>
239
+ <div class="text-sm text-gray-500">
240
+ {{ app.description }}
241
+ </div>
180
242
  </div>
181
- </div>
182
- </component>
243
+ </component>
244
+ </div>
183
245
  </div>
184
246
  </div>
185
247
  </div>
@@ -189,7 +251,11 @@
189
251
  <script lang="ts" setup>
190
252
  import { resolveComponent } from 'vue'
191
253
 
192
- defineProps<{
254
+ const emit = defineEmits<{
255
+ close: []
256
+ }>()
257
+
258
+ const props = defineProps<{
193
259
  isNavbar?: boolean
194
260
  }>()
195
261
 
@@ -199,6 +265,57 @@ const enum StatusPortal {
199
265
  }
200
266
  const NuxtLink = resolveComponent('NuxtLink')
201
267
  const auth = useAuth()
268
+ const route = useRoute()
269
+
270
+ const handleLinkClick = (to: string) => {
271
+ if (route.path === to) {
272
+ emit('close')
273
+ }
274
+ }
275
+
276
+ const dailyApps = computed(() => [
277
+ ...(auth.hasPermission(UserModule.CHECKIN, Permission.USER, Permission.ADMIN)
278
+ ? [
279
+ {
280
+ name: 'Clock-In',
281
+ logo: '/admin/clock-in-logo.png',
282
+ label: ' Clock-In',
283
+ description: 'เช็กอินเวลางาน และเลือกสถานที่ทำงานของวันนี้',
284
+ to: routes.clockin.home.to,
285
+ status: StatusPortal.ACTIVE,
286
+ },
287
+ ]
288
+ : []),
289
+ {
290
+ name: 'Timesheet',
291
+ logo: '/admin/timesheet-logo.png',
292
+ label: ' Timesheet',
293
+ description: 'บันทึกงานที่ทำในแต่ละวัน',
294
+ to: routes.timesheet.home.to,
295
+ status: StatusPortal.ACTIVE,
296
+ },
297
+ {
298
+ name: 'Requests',
299
+ logo: '/admin/request-admin.png',
300
+ label: 'Requests',
301
+ description: 'ระบบขอ ลา เบิก อนุมัติรายการต่างๆ',
302
+ to: '/',
303
+ status: StatusPortal.DEVELOPING,
304
+ },
305
+ ...(props.isNavbar
306
+ ? [
307
+ {
308
+ name: 'todo',
309
+ logo: '/admin/todo.png',
310
+ label: 'Todo',
311
+ description: 'ระบบจัดการงาน',
312
+ to: routes.todo.dashboard.to,
313
+ status: StatusPortal.ACTIVE,
314
+ },
315
+ ]
316
+ : []),
317
+ ])
318
+
202
319
  const managementApps = computed(() => [
203
320
  ...(auth.hasPermission(
204
321
  UserModule.PMO,
@@ -243,31 +360,6 @@ const managementApps = computed(() => [
243
360
  ]
244
361
  : []),
245
362
 
246
- ...(auth.hasPermission(UserModule.SETTING, Permission.SUPER)
247
- ? [
248
- {
249
- name: 'todo',
250
- logo: '/admin/todo.png',
251
- label: 'TODO',
252
- description: 'ระบบจัดการงานที่ต้องทำ',
253
- to: routes.todo.dashboard.to,
254
- status: StatusPortal.DEVELOPING,
255
- },
256
- ]
257
- : []),
258
- ...(auth.hasPermission(UserModule.SETTING, Permission.SUPER)
259
- ? [
260
- {
261
- name: 'Requests',
262
- logo: '/admin/request-admin.png',
263
- label: 'Requests',
264
- description: 'จัดการคำขอ',
265
- to: '/',
266
- status: StatusPortal.DEVELOPING,
267
- },
268
- ]
269
- : []),
270
-
271
363
  ])
272
364
 
273
365
  const financeApps = computed(() => [
@@ -326,7 +418,7 @@ const financeApps = computed(() => [
326
418
  {
327
419
  name: 'Purchase',
328
420
  logo: '/admin/purchase.png',
329
- label: 'purchase',
421
+ label: 'Purchase',
330
422
  description: 'จัดการเอกสารการจ่ายงวด',
331
423
  to: '/',
332
424
  status: StatusPortal.DEVELOPING,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@finema/finework-layer",
3
3
  "type": "module",
4
- "version": "0.2.111",
4
+ "version": "0.2.112",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "dev": "nuxi dev .playground -o",