62 lines
1.4 KiB
TypeScript
62 lines
1.4 KiB
TypeScript
import { computed, ref } from 'vue'
|
|
import { defineStore } from 'pinia'
|
|
|
|
export type UiNotificationTone = 'info' | 'success' | 'warning' | 'error'
|
|
|
|
export interface UiNotification {
|
|
id: string
|
|
title: string
|
|
message?: string
|
|
tone?: UiNotificationTone
|
|
}
|
|
|
|
export const useUiStore = defineStore('ui', () => {
|
|
const activeRequests = ref(0)
|
|
const notifications = ref<UiNotification[]>([])
|
|
|
|
const isPageLoading = computed(() => activeRequests.value > 0)
|
|
|
|
function setLoading(value: boolean) {
|
|
activeRequests.value = value ? 1 : 0
|
|
}
|
|
|
|
function startLoading() {
|
|
activeRequests.value += 1
|
|
}
|
|
|
|
function stopLoading() {
|
|
activeRequests.value = Math.max(0, activeRequests.value - 1)
|
|
}
|
|
|
|
function pushNotification(notification: Omit<UiNotification, 'id'> & { id?: string }) {
|
|
const nextNotification = {
|
|
...notification,
|
|
id: notification.id ?? crypto.randomUUID(),
|
|
tone: notification.tone ?? 'info'
|
|
} satisfies UiNotification
|
|
|
|
notifications.value = [...notifications.value, nextNotification]
|
|
|
|
return nextNotification.id
|
|
}
|
|
|
|
function removeNotification(id: string) {
|
|
notifications.value = notifications.value.filter((notification) => notification.id !== id)
|
|
}
|
|
|
|
function clearNotifications() {
|
|
notifications.value = []
|
|
}
|
|
|
|
return {
|
|
clearNotifications,
|
|
isPageLoading,
|
|
notifications,
|
|
pushNotification,
|
|
removeNotification,
|
|
setLoading,
|
|
startLoading,
|
|
stopLoading
|
|
}
|
|
})
|