@finema/finework-layer 1.0.17 → 1.0.19

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.19](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/1.0.18...1.0.19) (2026-03-23)
4
+
5
+ ### Bug Fixes
6
+
7
+ * update main max-width and change title in PortalApp for better layout clarity ([f2390f3](https://gitlab.finema.co/finema/finework/finework-frontend-layer/commit/f2390f38bfdd71925467c82cbeb5d12eed7c808b))
8
+
9
+ ## [1.0.18](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/1.0.17...1.0.18) (2026-03-23)
10
+
11
+ ### Bug Fixes
12
+
13
+ * refactor PortalApp layout for improved structure and responsiveness ([ec69707](https://gitlab.finema.co/finema/finework/finework-frontend-layer/commit/ec697075d2125b87985d90474b26885073522202))
14
+
3
15
  ## [1.0.17](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/1.0.16...1.0.17) (2026-03-23)
4
16
 
5
17
  ### Bug Fixes
@@ -54,7 +54,7 @@
54
54
  </div>
55
55
  </div>
56
56
  </nav>
57
- <main class="mx-auto w-full flex-1 px-4 pb-20 md:px-10">
57
+ <main class="mx-auto w-full max-w-[1480px] flex-1 px-4 pb-20 md:px-10">
58
58
  <div
59
59
  v-if="app.pageMeta.title"
60
60
  class="mb-4 flex flex-col justify-between gap-1 md:mb-6 md:gap-4 lg:flex-row lg:items-center"
@@ -1,257 +1,276 @@
1
1
  <template>
2
- <Card
3
- v-if="dailyApps.length > 0 || managementApps.length > 0 || financeApps.length > 0 || peopleApps.length > 0 || legalApps.length > 0"
4
- :ui="{
5
- body: isNavbar ? 'max-h-[calc(100vh-95px)] md:max-h-[calc(100vh-115px)] overflow-auto' : 'h-full overflow-auto',
6
- }"
7
- >
8
- <div
9
- class="bg-white"
10
- >
11
- <div class="mb-5 flex items-center gap-2">
12
- <img
13
- src="/icon-finema.png"
14
- alt="icon-finema"
15
- class="h-8 w-8 -translate-y-1"
16
- />
17
- <div class="text-2xl font-bold">
18
- Finework Apps
2
+ <DefineTemplate>
3
+ <div class="space-y-6">
4
+ <div
5
+ v-if="dailyApps.length > 0"
6
+ class="space-y-5"
7
+ >
8
+ <div class="text-lg font-bold text-gray-600">
9
+ Daily work Apps
19
10
  </div>
20
- </div>
21
-
22
- <div class="space-y-6">
23
11
  <div
24
- v-if="dailyApps.length > 0"
25
- class="space-y-5"
12
+ class="grid"
13
+ :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
26
14
  >
27
- <div class="text-lg font-bold text-gray-600">
28
- Daily work Apps
29
- </div>
30
- <div
31
- class="grid"
32
- :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
15
+ <component
16
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
17
+ v-for="app in dailyApps"
18
+ :key="app.name"
19
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
20
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
21
+ :class="app.status === StatusPortal.DEVELOPING
22
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
23
+ : 'bg-gray-100 hover:bg-gray-200'"
24
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
33
25
  >
34
- <component
35
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
36
- v-for="app in dailyApps"
37
- :key="app.name"
38
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
39
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
40
- :class="app.status === StatusPortal.DEVELOPING
41
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
42
- : 'bg-gray-100 hover:bg-gray-200'"
43
- @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
26
+ <div
27
+ v-if="app.status === StatusPortal.DEVELOPING"
28
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
44
29
  >
45
- <div
46
- v-if="app.status === StatusPortal.DEVELOPING"
47
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
48
- >
49
- กำลังพัฒนา
30
+ กำลังพัฒนา
31
+ </div>
32
+ <img
33
+ :src="app.logo"
34
+ :alt="app.label"
35
+ class="h-[45px] w-[45px] bg-white"
36
+ />
37
+ <div>
38
+ <div class="text-lg font-bold">
39
+ {{ app.label }}
50
40
  </div>
51
- <img
52
- :src="app.logo"
53
- :alt="app.label"
54
- class="h-[45px] w-[45px] bg-white"
55
- />
56
- <div>
57
- <div class="text-lg font-bold">
58
- {{ app.label }}
59
- </div>
60
- <div class="text-sm text-gray-500">
61
- {{ app.description }}
62
- </div>
41
+ <div class="text-sm text-gray-500">
42
+ {{ app.description }}
63
43
  </div>
64
- </component>
65
- </div>
44
+ </div>
45
+ </component>
46
+ </div>
47
+ </div>
48
+ <div
49
+ v-if="managementApps.length > 0"
50
+ class="space-y-5"
51
+ >
52
+ <div class="text-lg font-bold text-gray-600">
53
+ Management
66
54
  </div>
67
55
  <div
68
- v-if="managementApps.length > 0"
69
- class="space-y-5"
56
+ class="grid"
57
+ :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
70
58
  >
71
- <div class="text-lg font-bold text-gray-600">
72
- Management
73
- </div>
74
- <div
75
- class="grid"
76
- :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
59
+ <component
60
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
61
+ v-for="app in managementApps"
62
+ :key="app.name"
63
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
64
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
65
+ :class="app.status === StatusPortal.DEVELOPING
66
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
67
+ : 'bg-gray-100 hover:bg-gray-200'"
68
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
77
69
  >
78
- <component
79
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
80
- v-for="app in managementApps"
81
- :key="app.name"
82
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
83
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
84
- :class="app.status === StatusPortal.DEVELOPING
85
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
86
- : 'bg-gray-100 hover:bg-gray-200'"
87
- @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
70
+ <div
71
+ v-if="app.status === StatusPortal.DEVELOPING"
72
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
88
73
  >
89
- <div
90
- v-if="app.status === StatusPortal.DEVELOPING"
91
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
92
- >
93
- กำลังพัฒนา
74
+ กำลังพัฒนา
75
+ </div>
76
+ <img
77
+ :src="app.logo"
78
+ :alt="app.label"
79
+ class="h-[45px] w-[45px] bg-white"
80
+ />
81
+ <div>
82
+ <div class="text-lg font-bold">
83
+ {{ app.label }}
94
84
  </div>
95
- <img
96
- :src="app.logo"
97
- :alt="app.label"
98
- class="h-[45px] w-[45px] bg-white"
99
- />
100
- <div>
101
- <div class="text-lg font-bold">
102
- {{ app.label }}
103
- </div>
104
- <div class="text-sm text-gray-500">
105
- {{ app.description }}
106
- </div>
85
+ <div class="text-sm text-gray-500">
86
+ {{ app.description }}
107
87
  </div>
108
- </component>
109
- </div>
88
+ </div>
89
+ </component>
110
90
  </div>
91
+ </div>
111
92
 
93
+ <div
94
+ v-if="financeApps.length > 0"
95
+ class="space-y-5"
96
+ >
97
+ <div class="text-lg font-bold text-gray-600">
98
+ Finance
99
+ </div>
112
100
  <div
113
- v-if="financeApps.length > 0"
114
- class="space-y-5"
101
+ class="grid"
102
+ :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
115
103
  >
116
- <div class="text-lg font-bold text-gray-600">
117
- Finance
118
- </div>
119
- <div
120
- class="grid"
121
- :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
104
+ <component
105
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
106
+ v-for="app in financeApps"
107
+ :key="app.name"
108
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
109
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
110
+ :class="app.status === StatusPortal.DEVELOPING
111
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
112
+ : 'bg-gray-100 hover:bg-gray-200'"
113
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
122
114
  >
123
- <component
124
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
125
- v-for="app in financeApps"
126
- :key="app.name"
127
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
128
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
129
- :class="app.status === StatusPortal.DEVELOPING
130
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
131
- : 'bg-gray-100 hover:bg-gray-200'"
132
- @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
115
+ <div
116
+ v-if="app.status === StatusPortal.DEVELOPING"
117
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
133
118
  >
134
- <div
135
- v-if="app.status === StatusPortal.DEVELOPING"
136
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
137
- >
138
- กำลังพัฒนา
139
- </div>
119
+ กำลังพัฒนา
120
+ </div>
140
121
 
141
- <img
142
- :src="app.logo"
143
- :alt="app.label"
144
- class="h-[45px] w-[45px] bg-white"
145
- />
122
+ <img
123
+ :src="app.logo"
124
+ :alt="app.label"
125
+ class="h-[45px] w-[45px] bg-white"
126
+ />
146
127
 
147
- <div>
148
- <div class="text-lg font-bold">
149
- {{ app.label }}
150
- </div>
151
- <div class="text-sm text-gray-500">
152
- {{ app.description }}
153
- </div>
128
+ <div>
129
+ <div class="text-lg font-bold">
130
+ {{ app.label }}
154
131
  </div>
155
- </component>
156
- </div>
132
+ <div class="text-sm text-gray-500">
133
+ {{ app.description }}
134
+ </div>
135
+ </div>
136
+ </component>
157
137
  </div>
138
+ </div>
158
139
 
140
+ <div
141
+ v-if="peopleApps.length >0"
142
+ class="space-y-5"
143
+ >
144
+ <div class="text-lg font-bold text-gray-600">
145
+ People
146
+ </div>
159
147
  <div
160
- v-if="peopleApps.length >0"
161
- class="space-y-5"
148
+ class="grid"
149
+ :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
162
150
  >
163
- <div class="text-lg font-bold text-gray-600">
164
- People
165
- </div>
166
- <div
167
- class="grid"
168
- :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
151
+ <component
152
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
153
+ v-for="app in peopleApps"
154
+ :key="app.name"
155
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
156
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
157
+ :class="app.status === StatusPortal.DEVELOPING
158
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
159
+ : 'bg-gray-100 hover:bg-gray-200'"
160
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
169
161
  >
170
- <component
171
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
172
- v-for="app in peopleApps"
173
- :key="app.name"
174
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
175
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
176
- :class="app.status === StatusPortal.DEVELOPING
177
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
178
- : 'bg-gray-100 hover:bg-gray-200'"
179
- @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
162
+ <div
163
+ v-if="app.status === StatusPortal.DEVELOPING"
164
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
180
165
  >
181
- <div
182
- v-if="app.status === StatusPortal.DEVELOPING"
183
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
184
- >
185
- กำลังพัฒนา
166
+ กำลังพัฒนา
167
+ </div>
168
+ <img
169
+ :src="app.logo"
170
+ :alt="app.label"
171
+ class="h-[45px] w-[45px] bg-white"
172
+ />
173
+ <div>
174
+ <div class="text-lg font-bold">
175
+ {{ app.label }}
186
176
  </div>
187
- <img
188
- :src="app.logo"
189
- :alt="app.label"
190
- class="h-[45px] w-[45px] bg-white"
191
- />
192
- <div>
193
- <div class="text-lg font-bold">
194
- {{ app.label }}
195
- </div>
196
- <div class="text-sm text-gray-500">
197
- {{ app.description }}
198
- </div>
177
+ <div class="text-sm text-gray-500">
178
+ {{ app.description }}
199
179
  </div>
200
- </component>
201
- </div>
180
+ </div>
181
+ </component>
202
182
  </div>
183
+ </div>
203
184
 
185
+ <div
186
+ v-if="legalApps.length > 0"
187
+ class="space-y-5"
188
+ >
189
+ <div class="text-lg font-bold text-gray-600">
190
+ Legal
191
+ </div>
204
192
  <div
205
- v-if="legalApps.length > 0"
206
- class="space-y-5"
193
+ class="grid"
194
+ :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
207
195
  >
208
- <div class="text-lg font-bold text-gray-600">
209
- Legal
210
- </div>
211
- <div
212
- class="grid"
213
- :class="[isNavbar ?`gap-5 md:grid-cols-2 xl:grid-cols-4` : `grid-cols-1 gap-2`]"
196
+ <component
197
+ :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
198
+ v-for="app in legalApps"
199
+ :key="app.name"
200
+ :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
201
+ class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
202
+ :class="app.status === StatusPortal.DEVELOPING
203
+ ? 'cursor-not-allowed bg-gray-200 opacity-60'
204
+ : 'bg-gray-100 hover:bg-gray-200'"
205
+ @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
214
206
  >
215
- <component
216
- :is="app.status === StatusPortal.DEVELOPING ? 'div' : NuxtLink"
217
- v-for="app in legalApps"
218
- :key="app.name"
219
- :to="app.status !== StatusPortal.DEVELOPING ? app.to : undefined"
220
- class="relative flex items-center gap-3 rounded-lg px-2.5 py-[15px]"
221
- :class="app.status === StatusPortal.DEVELOPING
222
- ? 'cursor-not-allowed bg-gray-200 opacity-60'
223
- : 'bg-gray-100 hover:bg-gray-200'"
224
- @click="app.status !== StatusPortal.DEVELOPING && handleLinkClick(app.to)"
207
+ <div
208
+ v-if="app.status === StatusPortal.DEVELOPING"
209
+ class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
225
210
  >
226
- <div
227
- v-if="app.status === StatusPortal.DEVELOPING"
228
- class="absolute top-2 right-2 rounded-full bg-orange-100 px-2 py-0.5 text-xs font-semibold text-orange-600"
229
- >
230
- กำลังพัฒนา
211
+ กำลังพัฒนา
212
+ </div>
213
+ <img
214
+ :src="app.logo"
215
+ :alt="app.label"
216
+ class="h-[45px] w-[45px] bg-white"
217
+ />
218
+ <div>
219
+ <div class="text-lg font-bold">
220
+ {{ app.label }}
231
221
  </div>
232
- <img
233
- :src="app.logo"
234
- :alt="app.label"
235
- class="h-[45px] w-[45px] bg-white"
236
- />
237
- <div>
238
- <div class="text-lg font-bold">
239
- {{ app.label }}
240
- </div>
241
- <div class="text-sm text-gray-500">
242
- {{ app.description }}
243
- </div>
222
+ <div class="text-sm text-gray-500">
223
+ {{ app.description }}
244
224
  </div>
245
- </component>
246
- </div>
225
+ </div>
226
+ </component>
247
227
  </div>
248
228
  </div>
249
229
  </div>
230
+ </DefineTemplate>
231
+ <Card
232
+ v-if="dailyApps.length > 0 || managementApps.length > 0 || financeApps.length > 0 || peopleApps.length > 0 || legalApps.length > 0"
233
+ :ui="{
234
+ body: isNavbar
235
+ ? 'max-h-[calc(100vh-95px)] md:max-h-[calc(100vh-115px)] overflow-auto'
236
+ : 'h-full overflow-auto p-4!',
237
+ }"
238
+ >
239
+ <div class="bg-white">
240
+ <Collapsible
241
+ default-open
242
+ >
243
+ <div class="flex items-center justify-between gap-4">
244
+ <div class="mb-5 flex items-center gap-2">
245
+ <img
246
+ src="/icon-finema.png"
247
+ alt="icon-finema"
248
+ class="h-8 w-8 -translate-y-1"
249
+ />
250
+ <div class="text-2xl font-bold">
251
+ My Apps
252
+ </div>
253
+ </div>
254
+
255
+ <Button
256
+ v-if="!isNavbar"
257
+ variant="outline"
258
+ color="neutral"
259
+ :icon="open ? 'i-lucide-chevron-up' : 'i-lucide-chevron-down'"
260
+ />
261
+ </div>
262
+ <template #content>
263
+ <ReuseTemplate />
264
+ </template>
265
+ </Collapsible>
266
+ <ReuseTemplate v-if="isNavbar" />
267
+ </div>
250
268
  </Card>
251
269
  </template>
252
270
 
253
271
  <script lang="ts" setup>
254
272
  import { resolveComponent } from 'vue'
273
+ import { createReusableTemplate } from '@vueuse/core'
255
274
 
256
275
  const emit = defineEmits<{
257
276
  (e: 'close'): void
@@ -268,6 +287,8 @@ const enum StatusPortal {
268
287
  const NuxtLink = resolveComponent('NuxtLink')
269
288
  const auth = useAuth()
270
289
  const route = useRoute()
290
+ const open = ref(true)
291
+ const [DefineTemplate, ReuseTemplate] = createReusableTemplate()
271
292
 
272
293
  const handleLinkClick = (to: string) => {
273
294
  if (route.path === to) {
@@ -381,7 +402,7 @@ const financeApps = computed(() => [
381
402
  logo: '/admin/cost-sheet.png',
382
403
  label: 'Cost Sheet',
383
404
  description: 'รายรับรายจ่ายงบประมาณโครงการ',
384
- to: routes.costSheet.docs.doc.to,
405
+ to: routes.costSheet.overview.to,
385
406
  status: StatusPortal.ACTIVE,
386
407
  },
387
408
  ]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@finema/finework-layer",
3
3
  "type": "module",
4
- "version": "1.0.17",
4
+ "version": "1.0.19",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "dev": "nuxi dev .playground -o",