Skip to content

Commit 7e3be7b

Browse files
committed
fix: store directory
1 parent 827951a commit 7e3be7b

File tree

15 files changed

+135
-162
lines changed

15 files changed

+135
-162
lines changed

app/@layouts/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { OffsetOptions } from '@floating-ui/dom'
22
import type { RouteLocationRaw, RouteRecordNormalized } from 'vue-router'
33
import type { AppContentLayoutNav, ContentWidth, FooterType, HorizontalNavType, NavbarType } from '@base/@layouts/enums'
44
import type { Component } from 'vue'
5-
import type { Actions, Subjects } from '@base/utils/casl'
5+
import type { Actions, Subjects } from '~/stores/casl'
66

77
export interface LayoutConfig {
88
app: {

app/app.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const { global } = useTheme()
2121
if (isMobile)
2222
configStore.appContentLayoutNav = 'vertical'
2323
24-
const notificationStore = useNotificationStore()
24+
const notificationStore = useMessageStore()
2525
const layoutStore = useLayoutStore()
2626
2727
onBeforeMount(async () => {

app/components/AppPagination.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ defineProps<{
55
66
const limit = defineModel('limit', { type: Number, required: true })
77
const page = defineModel('page', { type: Number, required: true })
8+
9+
function paginationMeta<T extends { page: number, itemsPerPage: number }>(options: T, total: number) {
10+
const start = (options.page - 1) * options.itemsPerPage + 1
11+
const end = Math.min(options.page * options.itemsPerPage, total)
12+
13+
return `${total === 0 ? 0 : start} - ${end} of ${total}`
14+
}
815
</script>
916

1017
<template>

app/layouts/components/NavBarNotifications.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { formatDistanceToNow } from '#imports'
33
44
type Notification = any
55
6-
const systemNotificationStore = useSystemNotificationStore()
6+
const systemNotificationStore = useNotificationStore()
77
const emptyNotification = ref(false)
88
const location = ref('bottom end' as const)
99
const badgeProps = ref<object>({})
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { InferSelectModel } from 'drizzle-orm'
22
import type { sysPermissionTable } from '@base/server/db/schemas'
3-
import type { Actions, Rule, Subjects } from '@base/utils/casl'
3+
import type { Actions, Rule, Subjects } from '~/stores/casl'
44

55
type Permission = InferSelectModel<typeof sysPermissionTable>
66

File renamed without changes.

app/stores/message.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
export type NotificationLocation = 'top' | 'bottom'
2+
3+
export type NotificationType = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error'
4+
5+
export interface NotifyOptions {
6+
type?: NotificationType
7+
location?: NotificationLocation
8+
timeout?: number
9+
outline?: boolean
10+
link?: string
11+
}
12+
13+
export const useMessageStore = defineStore('message', () => {
14+
const notificationVisible = ref(false)
15+
const notificationLocation = ref<NotificationLocation>('bottom')
16+
const notificationMessage = ref('')
17+
const notificationType = ref<NotificationType>()
18+
const notificationTimeout = ref(3000)
19+
const notificationOutline = ref(false)
20+
const notificationLink = ref('')
21+
22+
const confirmationMessage = ref('')
23+
24+
const notificationProps = computed(() => ({
25+
modelValue: notificationVisible.value,
26+
location: notificationLocation.value,
27+
color: notificationType.value,
28+
timeout: notificationTimeout.value,
29+
outline: notificationOutline.value,
30+
multiline: true,
31+
link: notificationLink.value,
32+
}))
33+
34+
function showNotification(message: string, options?: NotifyOptions) {
35+
notificationVisible.value = true
36+
notificationMessage.value = message
37+
notificationType.value = options?.type
38+
notificationLocation.value = options?.location || 'bottom'
39+
notificationTimeout.value = options?.timeout || 10000
40+
notificationOutline.value = options?.outline || false
41+
notificationLink.value = options?.link || ''
42+
43+
setTimeout(hideNotification, options?.timeout || notificationTimeout.value)
44+
}
45+
46+
function hideNotification() {
47+
notificationVisible.value = false
48+
notificationMessage.value = ''
49+
notificationType.value = 'success'
50+
notificationLocation.value = 'bottom'
51+
notificationTimeout.value = 3000
52+
notificationLink.value = ''
53+
}
54+
55+
let confirmationResolver: (value: boolean) => void
56+
function showConfirmation(message: string) {
57+
confirmationMessage.value = message
58+
59+
return new Promise<boolean>((resolve) => {
60+
confirmationResolver = resolve
61+
})
62+
}
63+
64+
function resolveConfirmation(value: boolean) {
65+
if (confirmationResolver) {
66+
confirmationResolver(value)
67+
68+
confirmationMessage.value = ''
69+
}
70+
}
71+
72+
return {
73+
notificationProps,
74+
notificationMessage,
75+
confirmationMessage,
76+
showNotification,
77+
hideNotification,
78+
showConfirmation,
79+
resolveConfirmation,
80+
}
81+
})

app/stores/notification.ts

Lines changed: 41 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,57 @@
1-
export type NotificationLocation = 'top' | 'bottom'
1+
import type { InferSelectModel } from 'drizzle-orm'
2+
import type { sysNotificationTable } from '@base/server/db/schemas/sys_notifications.schema.js'
3+
import type { ParsedFilterQuery } from '@base/server/utils/filter'
24

3-
export type NotificationType = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error'
4-
5-
export interface NotifyOptions {
6-
type?: NotificationType
7-
location?: NotificationLocation
8-
timeout?: number
9-
outline?: boolean
10-
link?: string
11-
}
5+
type Notification = InferSelectModel<typeof sysNotificationTable>
126

137
export const useNotificationStore = defineStore('notification', () => {
14-
const notificationVisible = ref(false)
15-
const notificationLocation = ref<NotificationLocation>('bottom')
16-
const notificationMessage = ref('')
17-
const notificationType = ref<NotificationType>()
18-
const notificationTimeout = ref(3000)
19-
const notificationOutline = ref(false)
20-
const notificationLink = ref('')
21-
22-
const confirmationMessage = ref('')
23-
24-
const notificationProps = computed(() => ({
25-
modelValue: notificationVisible.value,
26-
location: notificationLocation.value,
27-
color: notificationType.value,
28-
timeout: notificationTimeout.value,
29-
outline: notificationOutline.value,
30-
multiline: true,
31-
link: notificationLink.value,
32-
}))
33-
34-
function showNotification(message: string, options?: NotifyOptions) {
35-
notificationVisible.value = true
36-
notificationMessage.value = message
37-
notificationType.value = options?.type
38-
notificationLocation.value = options?.location || 'bottom'
39-
notificationTimeout.value = options?.timeout || 10000
40-
notificationOutline.value = options?.outline || false
41-
notificationLink.value = options?.link || ''
42-
43-
setTimeout(hideNotification, options?.timeout || notificationTimeout.value)
8+
async function fetchNotifications(query: Partial<ParsedFilterQuery>) {
9+
return $api<Notification[]>('/notifications', {
10+
query,
11+
})
4412
}
4513

46-
function hideNotification() {
47-
notificationVisible.value = false
48-
notificationMessage.value = ''
49-
notificationType.value = 'success'
50-
notificationLocation.value = 'bottom'
51-
notificationTimeout.value = 3000
52-
notificationLink.value = ''
14+
async function markRead(id: string) {
15+
return $api<Notification>(`/notifications/${id}`, {
16+
method: 'PATCH',
17+
body: {
18+
read_at: new Date(),
19+
},
20+
})
5321
}
5422

55-
let confirmationResolver: (value: boolean) => void
56-
function showConfirmation(message: string) {
57-
confirmationMessage.value = message
58-
59-
return new Promise<boolean>((resolve) => {
60-
confirmationResolver = resolve
23+
async function markUnread(id: string) {
24+
return $api<Notification>(`/notifications/${id}`, {
25+
method: 'PATCH',
26+
body: {
27+
read_at: null,
28+
},
6129
})
6230
}
6331

64-
function resolveConfirmation(value: boolean) {
65-
if (confirmationResolver) {
66-
confirmationResolver(value)
32+
async function markAllRead() {
33+
return $api<Notification>('/notifications/mark-all-read', {
34+
method: 'PATCH',
35+
})
36+
}
6737

68-
confirmationMessage.value = ''
69-
}
38+
async function markAllUnread() {
39+
return $api<Notification>('/notifications/mark-all-unread', {
40+
method: 'PATCH',
41+
})
7042
}
7143

44+
async function deleteNotification(id: string) {
45+
return $api<Notification>(`/notifications/${id}`, {
46+
method: 'DELETE',
47+
})
48+
}
7249
return {
73-
notificationProps,
74-
notificationMessage,
75-
confirmationMessage,
76-
showNotification,
77-
hideNotification,
78-
showConfirmation,
79-
resolveConfirmation,
50+
fetchNotifications,
51+
markRead,
52+
markUnread,
53+
markAllRead,
54+
markAllUnread,
55+
deleteNotification,
8056
}
8157
})
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)