diff --git a/frontend/api/class-interfaces/event-notifications.ts b/frontend/api/class-interfaces/event-notifications.ts index e69de29bb2d1..bbed21db6d05 100644 --- a/frontend/api/class-interfaces/event-notifications.ts +++ b/frontend/api/class-interfaces/event-notifications.ts @@ -0,0 +1,42 @@ +import { requests } from "../requests"; +import { BaseCRUDAPI } from "./_base"; + +export type EventCategory = "general" | "recipe" | "backup" | "scheduled" | "migration" | "group" | "user"; +export type DeclaredTypes = "General" | "Discord" | "Gotify" | "Pushover" | "Home Assistant"; +export type GotifyPriority = "low" | "moderate" | "normal" | "high"; + +export interface EventNotification { + id?: number; + name?: string; + type?: DeclaredTypes & string; + general?: boolean; + recipe?: boolean; + backup?: boolean; + scheduled?: boolean; + migration?: boolean; + group?: boolean; + user?: boolean; +} + +export interface CreateEventNotification extends EventNotification { + notificationUrl?: string; +} + +const prefix = "/api"; + +const routes = { + aboutEventsNotifications: `${prefix}/about/events/notifications`, + aboutEventsNotificationsTest: `${prefix}/about/events/notifications/test`, + + aboutEventsNotificationsId: (id: number) => `${prefix}/about/events/notifications/${id}`, +}; + +export class NotificationsAPI extends BaseCRUDAPI { + baseRoute = routes.aboutEventsNotifications; + itemRoute = routes.aboutEventsNotificationsId; + /** Returns the Group Data for the Current User + */ + async testNotification(id: number) { + return await requests.post(routes.aboutEventsNotificationsTest, { id }); + } +} diff --git a/frontend/api/index.ts b/frontend/api/index.ts index 598dc10733ba..e22ba4fc5796 100644 --- a/frontend/api/index.ts +++ b/frontend/api/index.ts @@ -8,6 +8,7 @@ import { UploadFile } from "./class-interfaces/upload"; import { CategoriesAPI } from "./class-interfaces/categories"; import { TagsAPI } from "./class-interfaces/tags"; import { UtilsAPI } from "./class-interfaces/utils"; +import { NotificationsAPI } from "./class-interfaces/event-notifications"; import { ApiRequestInstance } from "~/types/api"; class Api { @@ -21,6 +22,7 @@ class Api { public categories: CategoriesAPI; public tags: TagsAPI; public utils: UtilsAPI; + public notifications: NotificationsAPI; // Utils public upload: UploadFile; @@ -43,6 +45,7 @@ class Api { this.debug = new DebugAPI(requests); this.events = new EventsAPI(requests); this.backups = new BackupAPI(requests); + this.notifications = new NotificationsAPI(requests); // Utils this.upload = new UploadFile(requests); diff --git a/frontend/composables/use-notifications.ts b/frontend/composables/use-notifications.ts new file mode 100644 index 000000000000..0228a998f283 --- /dev/null +++ b/frontend/composables/use-notifications.ts @@ -0,0 +1,88 @@ +import { useAsync, ref } from "@nuxtjs/composition-api"; +import { CreateEventNotification } from "@/api/class-interfaces/event-notifications"; +import { useAsyncKey } from "./use-utils"; +import { useApiSingleton } from "~/composables/use-api"; + +const notificationTypes = ["General", "Discord", "Gotify", "Pushover", "Home Assistant"]; + + +export const useNotifications = function () { + const api = useApiSingleton(); + const loading = ref(false); + + const createNotificationData = ref({ + name: "", + type: "General", + general: true, + recipe: true, + backup: true, + scheduled: true, + migration: true, + group: true, + user: true, + notificationUrl: "", + }); + + const deleteTarget = ref(0) + + function getNotifications() { + loading.value = true; + const notifications = useAsync(async () => { + const { data } = await api.notifications.getAll(); + return data; + }, useAsyncKey()); + loading.value = false; + return notifications; + } + + async function refreshNotifications() { + loading.value = true; + const { data } = await api.notifications.getAll(); + if (data) { + notifications.value = data; + } + loading.value = false; + } + + async function createNotification() { + if (createNotificationData.value.name === "" || createNotificationData.value.notificationUrl === "") { + return; + } + const { response } = await api.notifications.createOne(createNotificationData.value); + + if (response?.status === 200) { + refreshNotifications(); + } + } + + async function deleteNotification() { + const { response } = await api.notifications.deleteOne(deleteTarget.value); + if (response?.status === 200) { + refreshNotifications(); + } + } + + async function testById() { + // TODO: Test by ID + } + + async function testByUrl() { + // TODO: Test by URL + } + + const notifications = getNotifications(); + + return { + createNotification, + deleteNotification, + refreshNotifications, + getNotifications, + testById, + testByUrl, + notifications, + loading, + createNotificationData, + notificationTypes, + deleteTarget, + }; +}; diff --git a/frontend/pages/admin/toolbox/notifications.vue b/frontend/pages/admin/toolbox/notifications.vue index e8dded771fda..1c9c0bbd405e 100644 --- a/frontend/pages/admin/toolbox/notifications.vue +++ b/frontend/pages/admin/toolbox/notifications.vue @@ -2,17 +2,213 @@ {{ $t("events.new-notification-form-description") }} + + + + + + {{ $t("general.confirm-delete-generic") }} + + + + + + + + + + + + + + + {{ $t("general.test") }} + + +

{{ $t("events.subscribed-events") }}

+
+ + + + + + + +
+
+
+
+ + + + +