@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.
- package/.husky/pre-commit +1 -1
- package/.playground/app/assets/css/main.css +6 -6
- package/.playground/app/pages/layout-admin/[id]/index.vue +145 -145
- package/.playground/app/pages/layout-admin/test/[id]/index.vue +286 -286
- package/.playground/app/pages/layout-admin.vue +283 -285
- package/.playground/app/pages/layout-user.vue +284 -284
- package/.playground/app/pages/submenu/layout-admin.vue +210 -210
- package/.vscode/settings.json +5 -1
- package/CHANGELOG.md +382 -374
- package/app/app.config.ts +144 -144
- package/app/app.vue +10 -10
- package/app/assets/css/main.css +77 -77
- package/app/components/Button/ActionIcon.vue +29 -29
- package/app/components/Button/Back.vue +22 -22
- package/app/components/Format/Currency.vue +17 -17
- package/app/components/Format/Date.vue +24 -24
- package/app/components/Format/DateTime.vue +24 -24
- package/app/components/Format/Number.vue +17 -17
- package/app/components/Format/Percent.vue +38 -38
- package/app/components/Format/TimeFromNow.vue +38 -38
- package/app/components/InfoItemList.vue +196 -196
- package/app/components/Layout/Admin/Sidebar.vue +343 -329
- package/app/components/Layout/Admin/index.vue +240 -224
- package/app/components/Layout/Apps.vue +45 -45
- package/app/components/Layout/User/index.vue +102 -102
- package/app/components/Notifications/index.vue +162 -162
- package/app/components/StatusBox.vue +56 -56
- package/app/composables/useAuth.ts +207 -207
- package/app/composables/useNotification.ts +76 -76
- package/app/composables/useRequestOptions.ts +86 -86
- package/app/constants/routes.ts +86 -86
- package/app/error.vue +218 -218
- package/app/middleware/auth.ts +45 -45
- package/app/middleware/common.ts +12 -12
- package/app/middleware/guest.ts +7 -7
- package/app/middleware/permissions.ts +29 -29
- package/bun.lock +2758 -2758
- package/eslint.config.js +206 -2
- package/index.d.ts +16 -16
- package/nuxt.config.ts +41 -41
- package/package.json +38 -38
|
@@ -1,207 +1,207 @@
|
|
|
1
|
-
export enum Permission {
|
|
2
|
-
USER = 'USER',
|
|
3
|
-
ADMIN = 'ADMIN',
|
|
4
|
-
SUPER = 'SUPER',
|
|
5
|
-
NONE = 'NONE',
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export const PERMISSION_LABEL = {
|
|
9
|
-
[Permission.ADMIN]: 'Admin',
|
|
10
|
-
[Permission.USER]: 'User',
|
|
11
|
-
[Permission.SUPER]: 'Settings',
|
|
12
|
-
[Permission.NONE]: 'No Access',
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface ITeam {
|
|
16
|
-
id: string
|
|
17
|
-
name: string
|
|
18
|
-
code: string
|
|
19
|
-
color: string
|
|
20
|
-
description?: string
|
|
21
|
-
working_start_at: string
|
|
22
|
-
working_end_at: string
|
|
23
|
-
users: IUser[] | null
|
|
24
|
-
created_at: string
|
|
25
|
-
updated_at: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface IUser {
|
|
29
|
-
id: string
|
|
30
|
-
email: string
|
|
31
|
-
full_name: string
|
|
32
|
-
display_name: string
|
|
33
|
-
position: string
|
|
34
|
-
team: ITeam
|
|
35
|
-
team_code: string
|
|
36
|
-
avatar_url: string
|
|
37
|
-
company: string
|
|
38
|
-
sig: string
|
|
39
|
-
access_level: IUserAccessLevel
|
|
40
|
-
is_active: boolean
|
|
41
|
-
joined_date: string
|
|
42
|
-
slack_id: string
|
|
43
|
-
created_at: string
|
|
44
|
-
updated_at: string
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export enum UserModule {
|
|
48
|
-
CHECKIN = 'clockin',
|
|
49
|
-
PMO = 'pmo',
|
|
50
|
-
TIMESHEET = 'timesheet',
|
|
51
|
-
SETTING = 'setting',
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface IUserAccessLevel {
|
|
55
|
-
used_id: string
|
|
56
|
-
pmo: Permission.USER | Permission.ADMIN | Permission.SUPER
|
|
57
|
-
clockin: Permission.USER | Permission.ADMIN
|
|
58
|
-
timesheet: Permission.USER | Permission.ADMIN
|
|
59
|
-
setting: Permission.USER | Permission.SUPER
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export const useAuth = () => {
|
|
63
|
-
const {
|
|
64
|
-
auth,
|
|
65
|
-
} = useRequestOptions()
|
|
66
|
-
|
|
67
|
-
const token = useCookie('token', {
|
|
68
|
-
path: '/',
|
|
69
|
-
maxAge: 60 * 60 * 24 * 365,
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
const isAuthenticated = computed(() => !!token.value)
|
|
73
|
-
const me = defineStore('auth.me', () => {
|
|
74
|
-
const value = ref<IUser | null>(null)
|
|
75
|
-
const timestamp = ref<number | null>(null)
|
|
76
|
-
|
|
77
|
-
const set = (user: IUser | null) => {
|
|
78
|
-
value.value = user
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const setTimestamp = (t: number | null) => {
|
|
82
|
-
timestamp.value = t
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const isShouldFetch = () => {
|
|
86
|
-
if (!value.value || !timestamp.value) return true
|
|
87
|
-
|
|
88
|
-
// expire after 1 min - fetch if timestamp is older than 1 minute ago
|
|
89
|
-
return Date.now() - timestamp.value > 1000 * 60 * 1
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
value,
|
|
94
|
-
set,
|
|
95
|
-
timestamp,
|
|
96
|
-
setTimestamp,
|
|
97
|
-
isShouldFetch,
|
|
98
|
-
}
|
|
99
|
-
})()
|
|
100
|
-
|
|
101
|
-
const fetchMe = (() => {
|
|
102
|
-
return useObjectLoader<IUser>({
|
|
103
|
-
method: 'GET',
|
|
104
|
-
url: '/me',
|
|
105
|
-
getRequestOptions: auth,
|
|
106
|
-
})
|
|
107
|
-
})()
|
|
108
|
-
|
|
109
|
-
const updateMe = (() => {
|
|
110
|
-
return useObjectLoader<IUser>({
|
|
111
|
-
method: 'PUT',
|
|
112
|
-
url: '/me',
|
|
113
|
-
getRequestOptions: auth,
|
|
114
|
-
})
|
|
115
|
-
})()
|
|
116
|
-
|
|
117
|
-
const loginSlack = async () => {
|
|
118
|
-
const config = useRuntimeConfig()
|
|
119
|
-
|
|
120
|
-
window.location.href = config.public.baseAPI + '/auth/slack-login'
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const loginMs = async () => {
|
|
124
|
-
const config = useRuntimeConfig()
|
|
125
|
-
|
|
126
|
-
window.location.href = config.public.baseAPI + '/auth/ms-login'
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
useWatchTrue(() => fetchMe.status.value.isSuccess, () => {
|
|
130
|
-
me.setTimestamp(Date.now())
|
|
131
|
-
me.set(fetchMe.data.value)
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
useWatchTrue(() => fetchMe.status.value.isError, () => {
|
|
135
|
-
token.value = undefined
|
|
136
|
-
me.setTimestamp(null)
|
|
137
|
-
me.set(null)
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
const hasPermission = (module: UserModule, ...permission: Permission[]) => {
|
|
141
|
-
if (!me.value?.access_level) {
|
|
142
|
-
return false
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return permission.includes(me.value.access_level[module])
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const isSuperAdmin = computed(() => {
|
|
149
|
-
return me.value?.access_level?.setting === Permission.SUPER
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
const menusNavbar = computed(() => [
|
|
153
|
-
{
|
|
154
|
-
label: 'Clock-In',
|
|
155
|
-
icon: '/admin/clock-in-logo.png',
|
|
156
|
-
to: routes.clockin.home.to,
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
label: 'Timesheet',
|
|
160
|
-
icon: '/admin/timesheet-logo.png',
|
|
161
|
-
to: routes.timesheet.home.to,
|
|
162
|
-
},
|
|
163
|
-
...(hasPermission(UserModule.PMO, Permission.ADMIN, Permission.USER, Permission.SUPER)
|
|
164
|
-
? [{
|
|
165
|
-
label: 'PMO',
|
|
166
|
-
icon: '/admin/pmo-logo.png',
|
|
167
|
-
to: routes.pmo.project.projects.to,
|
|
168
|
-
}]
|
|
169
|
-
: []),
|
|
170
|
-
...(hasPermission(UserModule.CHECKIN, Permission.ADMIN)
|
|
171
|
-
? [{
|
|
172
|
-
label: 'Clock-In Admin',
|
|
173
|
-
icon: '/admin/clock-in-admin-logo.png',
|
|
174
|
-
to: routes.adminClockin.checkinDashboard.to,
|
|
175
|
-
}]
|
|
176
|
-
: []),
|
|
177
|
-
...(hasPermission(UserModule.TIMESHEET, Permission.ADMIN)
|
|
178
|
-
? [{
|
|
179
|
-
label: 'Timesheet Admin',
|
|
180
|
-
icon: '/admin/timesheet-admin-logo.png',
|
|
181
|
-
to: routes.adminTimesheet.summaryReport.to,
|
|
182
|
-
}]
|
|
183
|
-
: []),
|
|
184
|
-
|
|
185
|
-
...(hasPermission(UserModule.SETTING, Permission.SUPER)
|
|
186
|
-
? [{
|
|
187
|
-
label: 'Settings',
|
|
188
|
-
icon: '/admin/super-admin-logo.png',
|
|
189
|
-
to: routes.admin.users.to,
|
|
190
|
-
}]
|
|
191
|
-
: []),
|
|
192
|
-
])
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
token,
|
|
196
|
-
loginSlack,
|
|
197
|
-
loginMs,
|
|
198
|
-
isAuthenticated,
|
|
199
|
-
me,
|
|
200
|
-
fetchMe,
|
|
201
|
-
updateMe,
|
|
202
|
-
hasPermission,
|
|
203
|
-
isSuperAdmin,
|
|
204
|
-
menusNavbar,
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
}
|
|
1
|
+
export enum Permission {
|
|
2
|
+
USER = 'USER',
|
|
3
|
+
ADMIN = 'ADMIN',
|
|
4
|
+
SUPER = 'SUPER',
|
|
5
|
+
NONE = 'NONE',
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const PERMISSION_LABEL = {
|
|
9
|
+
[Permission.ADMIN]: 'Admin',
|
|
10
|
+
[Permission.USER]: 'User',
|
|
11
|
+
[Permission.SUPER]: 'Settings',
|
|
12
|
+
[Permission.NONE]: 'No Access',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ITeam {
|
|
16
|
+
id: string
|
|
17
|
+
name: string
|
|
18
|
+
code: string
|
|
19
|
+
color: string
|
|
20
|
+
description?: string
|
|
21
|
+
working_start_at: string
|
|
22
|
+
working_end_at: string
|
|
23
|
+
users: IUser[] | null
|
|
24
|
+
created_at: string
|
|
25
|
+
updated_at: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface IUser {
|
|
29
|
+
id: string
|
|
30
|
+
email: string
|
|
31
|
+
full_name: string
|
|
32
|
+
display_name: string
|
|
33
|
+
position: string
|
|
34
|
+
team: ITeam
|
|
35
|
+
team_code: string
|
|
36
|
+
avatar_url: string
|
|
37
|
+
company: string
|
|
38
|
+
sig: string
|
|
39
|
+
access_level: IUserAccessLevel
|
|
40
|
+
is_active: boolean
|
|
41
|
+
joined_date: string
|
|
42
|
+
slack_id: string
|
|
43
|
+
created_at: string
|
|
44
|
+
updated_at: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export enum UserModule {
|
|
48
|
+
CHECKIN = 'clockin',
|
|
49
|
+
PMO = 'pmo',
|
|
50
|
+
TIMESHEET = 'timesheet',
|
|
51
|
+
SETTING = 'setting',
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface IUserAccessLevel {
|
|
55
|
+
used_id: string
|
|
56
|
+
pmo: Permission.USER | Permission.ADMIN | Permission.SUPER
|
|
57
|
+
clockin: Permission.USER | Permission.ADMIN
|
|
58
|
+
timesheet: Permission.USER | Permission.ADMIN
|
|
59
|
+
setting: Permission.USER | Permission.SUPER
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const useAuth = () => {
|
|
63
|
+
const {
|
|
64
|
+
auth,
|
|
65
|
+
} = useRequestOptions()
|
|
66
|
+
|
|
67
|
+
const token = useCookie('token', {
|
|
68
|
+
path: '/',
|
|
69
|
+
maxAge: 60 * 60 * 24 * 365,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const isAuthenticated = computed(() => !!token.value)
|
|
73
|
+
const me = defineStore('auth.me', () => {
|
|
74
|
+
const value = ref<IUser | null>(null)
|
|
75
|
+
const timestamp = ref<number | null>(null)
|
|
76
|
+
|
|
77
|
+
const set = (user: IUser | null) => {
|
|
78
|
+
value.value = user
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const setTimestamp = (t: number | null) => {
|
|
82
|
+
timestamp.value = t
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const isShouldFetch = () => {
|
|
86
|
+
if (!value.value || !timestamp.value) return true
|
|
87
|
+
|
|
88
|
+
// expire after 1 min - fetch if timestamp is older than 1 minute ago
|
|
89
|
+
return Date.now() - timestamp.value > 1000 * 60 * 1
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
value,
|
|
94
|
+
set,
|
|
95
|
+
timestamp,
|
|
96
|
+
setTimestamp,
|
|
97
|
+
isShouldFetch,
|
|
98
|
+
}
|
|
99
|
+
})()
|
|
100
|
+
|
|
101
|
+
const fetchMe = (() => {
|
|
102
|
+
return useObjectLoader<IUser>({
|
|
103
|
+
method: 'GET',
|
|
104
|
+
url: '/me',
|
|
105
|
+
getRequestOptions: auth,
|
|
106
|
+
})
|
|
107
|
+
})()
|
|
108
|
+
|
|
109
|
+
const updateMe = (() => {
|
|
110
|
+
return useObjectLoader<IUser>({
|
|
111
|
+
method: 'PUT',
|
|
112
|
+
url: '/me',
|
|
113
|
+
getRequestOptions: auth,
|
|
114
|
+
})
|
|
115
|
+
})()
|
|
116
|
+
|
|
117
|
+
const loginSlack = async () => {
|
|
118
|
+
const config = useRuntimeConfig()
|
|
119
|
+
|
|
120
|
+
window.location.href = config.public.baseAPI + '/auth/slack-login'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const loginMs = async () => {
|
|
124
|
+
const config = useRuntimeConfig()
|
|
125
|
+
|
|
126
|
+
window.location.href = config.public.baseAPI + '/auth/ms-login'
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
useWatchTrue(() => fetchMe.status.value.isSuccess, () => {
|
|
130
|
+
me.setTimestamp(Date.now())
|
|
131
|
+
me.set(fetchMe.data.value)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
useWatchTrue(() => fetchMe.status.value.isError, () => {
|
|
135
|
+
token.value = undefined
|
|
136
|
+
me.setTimestamp(null)
|
|
137
|
+
me.set(null)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
const hasPermission = (module: UserModule, ...permission: Permission[]) => {
|
|
141
|
+
if (!me.value?.access_level) {
|
|
142
|
+
return false
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return permission.includes(me.value.access_level[module])
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const isSuperAdmin = computed(() => {
|
|
149
|
+
return me.value?.access_level?.setting === Permission.SUPER
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const menusNavbar = computed(() => [
|
|
153
|
+
{
|
|
154
|
+
label: 'Clock-In',
|
|
155
|
+
icon: '/admin/clock-in-logo.png',
|
|
156
|
+
to: routes.clockin.home.to,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
label: 'Timesheet',
|
|
160
|
+
icon: '/admin/timesheet-logo.png',
|
|
161
|
+
to: routes.timesheet.home.to,
|
|
162
|
+
},
|
|
163
|
+
...(hasPermission(UserModule.PMO, Permission.ADMIN, Permission.USER, Permission.SUPER)
|
|
164
|
+
? [{
|
|
165
|
+
label: 'PMO',
|
|
166
|
+
icon: '/admin/pmo-logo.png',
|
|
167
|
+
to: routes.pmo.project.projects.to,
|
|
168
|
+
}]
|
|
169
|
+
: []),
|
|
170
|
+
...(hasPermission(UserModule.CHECKIN, Permission.ADMIN)
|
|
171
|
+
? [{
|
|
172
|
+
label: 'Clock-In Admin',
|
|
173
|
+
icon: '/admin/clock-in-admin-logo.png',
|
|
174
|
+
to: routes.adminClockin.checkinDashboard.to,
|
|
175
|
+
}]
|
|
176
|
+
: []),
|
|
177
|
+
...(hasPermission(UserModule.TIMESHEET, Permission.ADMIN)
|
|
178
|
+
? [{
|
|
179
|
+
label: 'Timesheet Admin',
|
|
180
|
+
icon: '/admin/timesheet-admin-logo.png',
|
|
181
|
+
to: routes.adminTimesheet.summaryReport.to,
|
|
182
|
+
}]
|
|
183
|
+
: []),
|
|
184
|
+
|
|
185
|
+
...(hasPermission(UserModule.SETTING, Permission.SUPER)
|
|
186
|
+
? [{
|
|
187
|
+
label: 'Settings',
|
|
188
|
+
icon: '/admin/super-admin-logo.png',
|
|
189
|
+
to: routes.admin.users.to,
|
|
190
|
+
}]
|
|
191
|
+
: []),
|
|
192
|
+
])
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
token,
|
|
196
|
+
loginSlack,
|
|
197
|
+
loginMs,
|
|
198
|
+
isAuthenticated,
|
|
199
|
+
me,
|
|
200
|
+
fetchMe,
|
|
201
|
+
updateMe,
|
|
202
|
+
hasPermission,
|
|
203
|
+
isSuperAdmin,
|
|
204
|
+
menusNavbar,
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
}
|
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
export const NotificationType = {
|
|
2
|
-
INFO: 'INFO',
|
|
3
|
-
SUCCESS: 'SUCCESS',
|
|
4
|
-
WARNING: 'WARNING',
|
|
5
|
-
ERROR: 'ERROR',
|
|
6
|
-
MENTION: 'MENTION',
|
|
7
|
-
COMMENT: 'COMMENT',
|
|
8
|
-
ASSIGNMENT: 'ASSIGNMENT',
|
|
9
|
-
DEADLINE: 'DEADLINE',
|
|
10
|
-
APPROVAL: 'APPROVAL',
|
|
11
|
-
REMINDER: 'REMINDER',
|
|
12
|
-
SYSTEM: 'SYSTEM',
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const NotificationPMOActionType = {
|
|
16
|
-
PROJECT_CREATE: 'PROJECT_CREATE',
|
|
17
|
-
PROJECT_STATUS_CHANGED: 'PROJECT_STATUS_CHANGED',
|
|
18
|
-
PROJECT_OWNER_CHANGED: 'PROJECT_OWNER_CHANGED',
|
|
19
|
-
PROJECT_UPDATE: 'PROJECT_UPDATE',
|
|
20
|
-
|
|
21
|
-
COLLABORATOR_ADD: 'COLLABORATOR_ADD',
|
|
22
|
-
COLLABORATOR_UPDATE: 'COLLABORATOR_UPDATE',
|
|
23
|
-
COLLABORATOR_REMOVE: 'COLLABORATOR_REMOVE',
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface INotificationItem {
|
|
27
|
-
id: string
|
|
28
|
-
created_at: string
|
|
29
|
-
updated_at: string
|
|
30
|
-
user_id: string
|
|
31
|
-
type: typeof NotificationType[keyof typeof NotificationType]
|
|
32
|
-
title: string
|
|
33
|
-
message: string
|
|
34
|
-
data?: Record<string, any>
|
|
35
|
-
source_type?: 'PMO_PROJECT' | string
|
|
36
|
-
source_id?: string
|
|
37
|
-
actor_id?: string
|
|
38
|
-
action_type?: typeof NotificationPMOActionType[keyof typeof NotificationPMOActionType] & string
|
|
39
|
-
is_read: boolean
|
|
40
|
-
read_at: string
|
|
41
|
-
channels: string[]
|
|
42
|
-
sent_at: string
|
|
43
|
-
user: IUser
|
|
44
|
-
actor?: IUser
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const useNotificationLoader = defineStore('notification', () => {
|
|
48
|
-
const options = useRequestOptions()
|
|
49
|
-
|
|
50
|
-
return usePageLoader<INotificationItem>({
|
|
51
|
-
baseURL: '/notifications?limit=30',
|
|
52
|
-
getBaseRequestOptions: options.auth,
|
|
53
|
-
})
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
export const useNotificationUnreadCount = defineStore('notification-unread-count', () => {
|
|
57
|
-
const options = useRequestOptions()
|
|
58
|
-
|
|
59
|
-
return useObjectLoader<{
|
|
60
|
-
count: number
|
|
61
|
-
}>({
|
|
62
|
-
url: '/notifications/unread-count',
|
|
63
|
-
method: 'get',
|
|
64
|
-
getRequestOptions: options.auth,
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
export const useNotificationMarkAllRead = () => {
|
|
69
|
-
const options = useRequestOptions()
|
|
70
|
-
|
|
71
|
-
return useObjectLoader({
|
|
72
|
-
url: '/notifications/mark-all-read',
|
|
73
|
-
method: 'post',
|
|
74
|
-
getRequestOptions: options.auth,
|
|
75
|
-
})
|
|
76
|
-
}
|
|
1
|
+
export const NotificationType = {
|
|
2
|
+
INFO: 'INFO',
|
|
3
|
+
SUCCESS: 'SUCCESS',
|
|
4
|
+
WARNING: 'WARNING',
|
|
5
|
+
ERROR: 'ERROR',
|
|
6
|
+
MENTION: 'MENTION',
|
|
7
|
+
COMMENT: 'COMMENT',
|
|
8
|
+
ASSIGNMENT: 'ASSIGNMENT',
|
|
9
|
+
DEADLINE: 'DEADLINE',
|
|
10
|
+
APPROVAL: 'APPROVAL',
|
|
11
|
+
REMINDER: 'REMINDER',
|
|
12
|
+
SYSTEM: 'SYSTEM',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const NotificationPMOActionType = {
|
|
16
|
+
PROJECT_CREATE: 'PROJECT_CREATE',
|
|
17
|
+
PROJECT_STATUS_CHANGED: 'PROJECT_STATUS_CHANGED',
|
|
18
|
+
PROJECT_OWNER_CHANGED: 'PROJECT_OWNER_CHANGED',
|
|
19
|
+
PROJECT_UPDATE: 'PROJECT_UPDATE',
|
|
20
|
+
|
|
21
|
+
COLLABORATOR_ADD: 'COLLABORATOR_ADD',
|
|
22
|
+
COLLABORATOR_UPDATE: 'COLLABORATOR_UPDATE',
|
|
23
|
+
COLLABORATOR_REMOVE: 'COLLABORATOR_REMOVE',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface INotificationItem {
|
|
27
|
+
id: string
|
|
28
|
+
created_at: string
|
|
29
|
+
updated_at: string
|
|
30
|
+
user_id: string
|
|
31
|
+
type: typeof NotificationType[keyof typeof NotificationType]
|
|
32
|
+
title: string
|
|
33
|
+
message: string
|
|
34
|
+
data?: Record<string, any>
|
|
35
|
+
source_type?: 'PMO_PROJECT' | string
|
|
36
|
+
source_id?: string
|
|
37
|
+
actor_id?: string
|
|
38
|
+
action_type?: typeof NotificationPMOActionType[keyof typeof NotificationPMOActionType] & string
|
|
39
|
+
is_read: boolean
|
|
40
|
+
read_at: string
|
|
41
|
+
channels: string[]
|
|
42
|
+
sent_at: string
|
|
43
|
+
user: IUser
|
|
44
|
+
actor?: IUser
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const useNotificationLoader = defineStore('notification', () => {
|
|
48
|
+
const options = useRequestOptions()
|
|
49
|
+
|
|
50
|
+
return usePageLoader<INotificationItem>({
|
|
51
|
+
baseURL: '/notifications?limit=30',
|
|
52
|
+
getBaseRequestOptions: options.auth,
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export const useNotificationUnreadCount = defineStore('notification-unread-count', () => {
|
|
57
|
+
const options = useRequestOptions()
|
|
58
|
+
|
|
59
|
+
return useObjectLoader<{
|
|
60
|
+
count: number
|
|
61
|
+
}>({
|
|
62
|
+
url: '/notifications/unread-count',
|
|
63
|
+
method: 'get',
|
|
64
|
+
getRequestOptions: options.auth,
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
export const useNotificationMarkAllRead = () => {
|
|
69
|
+
const options = useRequestOptions()
|
|
70
|
+
|
|
71
|
+
return useObjectLoader({
|
|
72
|
+
url: '/notifications/mark-all-read',
|
|
73
|
+
method: 'post',
|
|
74
|
+
getRequestOptions: options.auth,
|
|
75
|
+
})
|
|
76
|
+
}
|