@finema/finework-layer 0.2.140 → 0.2.142

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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.142](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.141...0.2.142) (2026-02-19)
4
+
5
+ ## [0.2.141](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.140...0.2.141) (2026-02-19)
6
+
7
+ ### Bug Fixes
8
+
9
+ * improve noti ([cb22978](https://gitlab.finema.co/finema/finework/finework-frontend-layer/commit/cb22978810ab73bdabb21bf0f49c35aaa19ed282))
10
+
3
11
  ## [0.2.140](https://gitlab.finema.co/finema/finework/finework-frontend-layer/compare/0.2.139...0.2.140) (2026-02-17)
4
12
 
5
13
  ### Features
@@ -31,53 +31,54 @@
31
31
  v-else
32
32
  :loading="notification.fetch.status.isLoading"
33
33
  >
34
- <div class="space-y-2 divide-y-1 divide-gray-200">
35
- <div
36
- v-for="item in notification.fetch.items"
37
- :key="item.id"
34
+ <div
35
+ v-for="item in notification.fetch.items"
36
+ :key="item.id"
37
+ >
38
+ <Separator />
39
+ <NuxtLink
40
+ :to="getLink(item)"
41
+ :target="getLink(item) === '#' ? '_self' : '_blank'"
42
+ :class="['flex cursor-pointer items-start gap-2 rounded-lg p-4 hover:bg-gray-100']"
38
43
  >
39
- <NuxtLink
40
- :to="getLink(item)"
41
- :target="getLink(item) === '#' ? '_self' : '_blank'"
42
- :class="['mb-2 flex cursor-pointer items-start gap-2 rounded-lg p-4 hover:bg-gray-100']"
43
- >
44
- <Chip
45
- v-if="getImage(item)"
44
+ <!-- <Chip
46
45
  position="bottom-right"
47
46
  size="3xl"
48
47
  inset
49
48
  :color="getNotificationColor(item)"
50
- >
51
- <img
52
-
53
- :src="getImage(item)!"
54
- class="w-12"
55
- />
56
- </Chip>
57
-
58
- <div class="flex-1">
59
- <div class="flex items-start justify-between gap-2">
60
- <p
61
- class="line-clamp-1 text-sm font-medium text-gray-700"
62
- :title="item.title"
63
- >
64
- {{ item.title }}
65
- </p>
66
- <FormatTimeFromNow
67
- class="text-muted flex-1 text-right text-xs whitespace-nowrap"
68
- :value="item.sent_at"
69
- />
70
- </div>
71
-
72
- <p
73
- class="text-sm text-neutral-500"
74
- :title="getMessage(item)"
75
- >
76
- {{ getMessage(item) }}
77
- </p>
78
- </div>
79
- </NuxtLink>
80
- </div>
49
+ > -->
50
+ <div
51
+ v-if="item.actor?.avatar_url"
52
+ class="relative"
53
+ >
54
+ <Avatar
55
+ class="min-h-12 min-w-12"
56
+ :src="item.actor?.avatar_url"
57
+ :alt="item.actor?.display_name"
58
+ />
59
+ <img
60
+ :src="getImage(item)!"
61
+ class="absolute -right-1 -bottom-1 w-5 rounded-full bg-white p-0.25"
62
+ />
63
+ </div>
64
+ <img
65
+ v-else
66
+ :src="getImage(item)!"
67
+ class="h-12 min-h-12 w-12 min-w-12"
68
+ />
69
+ <!-- </Chip> -->
70
+
71
+ <div class="flex flex-1 flex-col gap-0">
72
+ <p
73
+ class="text-gray line-clamp-2 text-sm"
74
+ v-html="getMessage(item)"
75
+ />
76
+ <FormatTimeFromNow
77
+ class="text-xs font-medium whitespace-nowrap text-gray-600"
78
+ :value="item.sent_at"
79
+ />
80
+ </div>
81
+ </NuxtLink>
81
82
  </div>
82
83
  </Loader>
83
84
  </template>
@@ -101,24 +102,41 @@ onMounted(() => {
101
102
  })
102
103
 
103
104
  const getLink = (item: INotificationItem) => {
104
- if (item.data?.url) {
105
- return item.data.url
106
- }
105
+ if (item.data?.url) return item.data.url
107
106
 
108
- if (item.source_type === 'PMO_PROJECT') {
109
- return `/pmo/projects/${item.source_id}`
110
- } else if (item.source_type === 'NEWSLETTER') {
111
- return `/announcement/${item.source_id}`
112
- } else if (item.source_type === 'TODO' && (item.action_type === 'TODO_ASSIGN_CARD' || item.action_type === 'TODO_COMMENT_ADD' || item.action_type === 'TODO_DUE_DATE_CHANGE' || item.action_type === 'TODO_STATUS_CHANGE')) {
113
- return `/todo/boards/${item.data?.todo_board_slug}/cards/${item.data?.todo_slug}`
114
- } else if (item.source_type === 'TODO' && (item.action_type === 'TODO_REMOVE_CARD' || item.action_type === 'TODO_ASSIGN_BOARD')) {
115
- return `/todo/boards/${item.data?.todo_board_slug}`
116
- } else if (item.source_type === 'TODO' && item.action_type === 'TODO_REMOVE_BOARD') {
117
- return `/todo/cards`
118
- }
107
+ switch (item.source_type) {
108
+ case 'PMO_PROJECT':
109
+ return `/pmo/projects/${item.source_id}`
110
+
111
+ case 'NEWSLETTER':
112
+ return `/announcement/${item.source_id}`
113
+
114
+ case 'TODO': {
115
+ const boardSlug = item.data?.todo_board_slug
116
+ const cardSlug = item.data?.todo_slug
117
+
118
+ switch (item.action_type) {
119
+ case 'TODO_ASSIGN_CARD':
120
+ case 'TODO_COMMENT_ADD':
121
+ case 'TODO_DUE_DATE_CHANGE':
122
+ case 'TODO_STATUS_CHANGE':
123
+ return `/todo/boards/${boardSlug}/cards/${cardSlug}`
124
+
125
+ case 'TODO_REMOVE_CARD':
126
+ case 'TODO_ASSIGN_BOARD':
127
+ return `/todo/boards/${boardSlug}`
119
128
 
120
- // todo/boards/MEE/cards/MEE-1
121
- return '#'
129
+ case 'TODO_REMOVE_BOARD':
130
+ return `/todo/cards`
131
+
132
+ default:
133
+ return '#'
134
+ }
135
+ }
136
+
137
+ default:
138
+ return '#'
139
+ }
122
140
  }
123
141
 
124
142
  const getImage = (item: INotificationItem): string | null => {
@@ -159,7 +177,42 @@ const getNotificationColor = (item: INotificationItem): string => {
159
177
  }
160
178
 
161
179
  const getMessage = (item: INotificationItem): string => {
162
- return item.message
180
+ let message = item.message
181
+
182
+ // ตรวจหาวันที่ในรูปแบบ yyyy-mm-dd และแปลงเป็น text
183
+ const datePattern = /\b(\d{4})-(\d{2})-(\d{2})\b/g
184
+
185
+ message = message.replace(datePattern, (match) => {
186
+ try {
187
+ const date = new Date(match)
188
+
189
+ return TimeHelper.displayDate(date)
190
+ ? `<span class="text-primary font-medium"> ${TimeHelper.displayDate(date)}</span>`
191
+ : match
192
+ } catch {
193
+ return match
194
+ }
195
+ })
196
+
197
+ if (item.data) {
198
+ Object.entries(item.data).forEach(([key, value]) => {
199
+ if (key.endsWith('_slug') && typeof value === 'string' && value) {
200
+ // หา slug ในข้อความและครอบด้วย <strong>
201
+ const slugPattern = new RegExp(`\\b${value}\\b`, 'g')
202
+
203
+ message = message.replace(slugPattern, `<span class="text-primary font-medium">${value}</span>`)
204
+ }
205
+ })
206
+ }
207
+
208
+ // ตรวจหาคำที่อยู่ระหว่าง "from" และ "to" และทำให้เป็น bold + text-primary font-semibold
209
+ const fromToPattern = /\bfrom\s+(\S+)\s+to\s+(\S+)/gi
210
+
211
+ message = message.replace(fromToPattern, (_match, from, to) => {
212
+ return `from <span class="text-primary font-medium">${from}</span> to <span class="text-primary font-semibold">${to}</span>`
213
+ })
214
+
215
+ return message
163
216
  }
164
217
 
165
218
  useWatchTrue(() => markAllRead.status.value.isSuccess, () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@finema/finework-layer",
3
3
  "type": "module",
4
- "version": "0.2.140",
4
+ "version": "0.2.142",
5
5
  "main": "./nuxt.config.ts",
6
6
  "scripts": {
7
7
  "dev": "nuxi dev .playground -o",