feat: add employee push test button
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { FastifyInstance } from "fastify"
|
||||
import { and, eq, isNull } from "drizzle-orm"
|
||||
import { authUsers, notificationMobilePushDevices } from "../../db/schema"
|
||||
import { authProfiles, authUsers, notificationMobilePushDevices } from "../../db/schema"
|
||||
import { NotificationService, UserDirectory } from "../modules/notification.service"
|
||||
import { pushServerClient } from "../modules/push-server.client"
|
||||
|
||||
@@ -174,6 +174,60 @@ export default async function notificationsRoutes(server: FastifyInstance) {
|
||||
})
|
||||
})
|
||||
|
||||
server.post("/notifications/test-push/profile/:profileId", async (req, reply) => {
|
||||
const tenantId = requireTenant(req.user.tenant_id)
|
||||
const { profileId } = req.params as { profileId: string }
|
||||
const [profile] = await server.db
|
||||
.select({
|
||||
userId: authProfiles.user_id,
|
||||
})
|
||||
.from(authProfiles)
|
||||
.where(and(
|
||||
eq(authProfiles.id, profileId),
|
||||
eq(authProfiles.tenant_id, tenantId)
|
||||
))
|
||||
.limit(1)
|
||||
|
||||
if (!profile) {
|
||||
return reply.code(404).send({ error: "Mitarbeiter nicht gefunden" })
|
||||
}
|
||||
|
||||
if (!profile.userId) {
|
||||
return reply.code(409).send({
|
||||
error: "Der Mitarbeiter ist noch nicht mit einem Benutzerkonto verknüpft",
|
||||
})
|
||||
}
|
||||
|
||||
const result = await svc.trigger({
|
||||
tenantId,
|
||||
userId: profile.userId,
|
||||
eventType: "system.test_push",
|
||||
title: "FEDEO Push ist aktiv",
|
||||
message: "Diese Testbenachrichtigung wurde einmalig über das Mitarbeiterprofil ausgelöst.",
|
||||
payload: {
|
||||
link: "/",
|
||||
icon: "/favicon.ico",
|
||||
},
|
||||
channels: ["push"],
|
||||
})
|
||||
|
||||
if (result.created === 0) {
|
||||
return reply.code(409).send({
|
||||
error: "Pushnachrichten sind für diesen Mitarbeiter deaktiviert",
|
||||
result,
|
||||
})
|
||||
}
|
||||
|
||||
if (!result.success || result.delivered === 0) {
|
||||
return reply.code(424).send({
|
||||
error: "Die Pushnachricht konnte an kein aktives Gerät zugestellt werden",
|
||||
result,
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
server.post("/notifications/trigger", async (req, reply) => {
|
||||
try {
|
||||
const body = req.body as any
|
||||
|
||||
@@ -76,6 +76,12 @@ export const useDesktopPush = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const sendTestPushToProfile = async (profileId) => {
|
||||
return await $api(`/api/notifications/test-push/profile/${encodeURIComponent(profileId)}`, {
|
||||
method: "POST",
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
supported,
|
||||
permission,
|
||||
@@ -85,5 +91,6 @@ export const useDesktopPush = () => {
|
||||
loadConfig,
|
||||
subscribe,
|
||||
sendTestPush,
|
||||
sendTestPushToProfile,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ const route = useRoute()
|
||||
const toast = useToast()
|
||||
const auth = useAuthStore()
|
||||
const admin = useAdmin()
|
||||
const desktopPush = useDesktopPush()
|
||||
const { $api } = useNuxtApp()
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
|
||||
@@ -17,6 +18,7 @@ const creatingLinkedUser = ref(false)
|
||||
const createLinkedUserModalOpen = ref(false)
|
||||
const createdLinkedUserPassword = ref("")
|
||||
const generatingCalendarSubscription = ref(false)
|
||||
const sendingTestPush = ref(false)
|
||||
const createLinkedUserForm = reactive({
|
||||
email: "",
|
||||
})
|
||||
@@ -270,6 +272,30 @@ async function copyCalendarSubscriptionUrl(value: string, successTitle: string)
|
||||
}
|
||||
}
|
||||
|
||||
async function sendTestPush() {
|
||||
if (!profile.value?.user_id || sendingTestPush.value) return
|
||||
|
||||
sendingTestPush.value = true
|
||||
|
||||
try {
|
||||
await desktopPush.sendTestPushToProfile(profile.value.id)
|
||||
toast.add({
|
||||
title: "Test-Push gesendet",
|
||||
description: `Die Nachricht wurde einmalig an ${profile.value.full_name || "den Mitarbeiter"} gesendet.`,
|
||||
color: "green"
|
||||
})
|
||||
} catch (err: any) {
|
||||
console.error("[sendTestPush]", err)
|
||||
toast.add({
|
||||
title: "Test-Push fehlgeschlagen",
|
||||
description: err?.data?.error || err?.message || "Die Testnachricht konnte nicht zugestellt werden.",
|
||||
color: "red"
|
||||
})
|
||||
} finally {
|
||||
sendingTestPush.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const weekdays = [
|
||||
{ key: '1', label: 'Montag' },
|
||||
{ key: '2', label: 'Dienstag' },
|
||||
@@ -456,6 +482,35 @@ onMounted(async () => {
|
||||
description="Lege fest, unter welcher Nebenstelle dieser Benutzer erreichbar ist."
|
||||
/>
|
||||
|
||||
<UCard v-if="!pending && profile" class="mt-3">
|
||||
<USeparator label="Push-Benachrichtigung" />
|
||||
|
||||
<div class="mt-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p class="text-sm font-medium text-gray-900 dark:text-white">Push-Zustellung testen</p>
|
||||
<p class="mt-1 text-sm text-gray-500">
|
||||
<template v-if="profile.user_id">
|
||||
Sendet einmalig eine Testnachricht an alle aktiven Push-Geräte dieses Mitarbeiters.
|
||||
</template>
|
||||
<template v-else>
|
||||
Für einen Push-Test muss der Mitarbeiter zuerst mit einem Benutzerkonto verknüpft werden.
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<UButton
|
||||
icon="i-heroicons-paper-airplane"
|
||||
color="neutral"
|
||||
variant="outline"
|
||||
:loading="sendingTestPush"
|
||||
:disabled="!profile.user_id"
|
||||
@click="sendTestPush"
|
||||
>
|
||||
Test-Push senden
|
||||
</UButton>
|
||||
</div>
|
||||
</UCard>
|
||||
|
||||
<UCard v-if="!pending && profile" class="mt-3">
|
||||
<USeparator label="Vertragsinformationen" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user