Skip to content

Commit

Permalink
Replace fetcher in api/notifications.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
davelopez committed Jul 25, 2024
1 parent 7e8c298 commit 267ba03
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 78 deletions.
63 changes: 14 additions & 49 deletions client/src/api/notifications.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type components, fetcher } from "@/api/schema";
import { type components } from "@/api/schema";

export type BaseUserNotification = components["schemas"]["UserNotificationResponse"];
export type UserNotificationPreferences = components["schemas"]["UserNotificationPreferences"]["preferences"];
Expand All @@ -14,61 +14,26 @@ export interface SharedItemNotification extends BaseUserNotification {
content: components["schemas"]["NewSharedItemNotificationContent"];
}

export type UserNotification = MessageNotification | SharedItemNotification;

export type NotificationChanges = components["schemas"]["UserNotificationUpdateRequest"];

export type UserNotificationsBatchUpdateRequest = components["schemas"]["UserNotificationsBatchUpdateRequest"];

export type NotificationVariants = components["schemas"]["NotificationVariant"];

export type NewSharedItemNotificationContentItemType =
components["schemas"]["NewSharedItemNotificationContent"]["item_type"];

type UserNotificationUpdateRequest = components["schemas"]["UserNotificationUpdateRequest"];

export type NotificationCreateRequest = components["schemas"]["NotificationCreateRequest"];

type NotificationResponse = components["schemas"]["NotificationResponse"];
type NotificationCreateData = components["schemas"]["NotificationCreateData"];

const getNotification = fetcher.path("/api/notifications/{notification_id}").method("get").create();

export async function loadNotification(id: string): Promise<NotificationResponse> {
const { data } = await getNotification({ notification_id: id });
return data;
}

const postNotification = fetcher.path("/api/notifications").method("post").create();

export async function sendNotification(notification: NotificationCreateRequest) {
const { data } = await postNotification(notification);
return data;
export interface MessageNotificationCreateData extends NotificationCreateData {
category: "message";
content: components["schemas"]["MessageNotificationContent"];
}

const putNotification = fetcher.path("/api/notifications/{notification_id}").method("put").create();
export type NotificationCreateRequest = components["schemas"]["NotificationCreateRequest"];

export async function updateNotification(id: string, notification: UserNotificationUpdateRequest) {
const { data } = await putNotification({ notification_id: id, ...notification });
return data;
export interface MessageNotificationCreateRequest extends NotificationCreateRequest {
notification: MessageNotificationCreateData;
}

const getNotifications = fetcher.path("/api/notifications").method("get").create();

export async function loadNotificationsFromServer(): Promise<UserNotification[]> {
const { data } = await getNotifications({});
return data as UserNotification[];
}
export type UserNotification = MessageNotification | SharedItemNotification;

const putBatchNotifications = fetcher.path("/api/notifications").method("put").create();
export type NotificationChanges = components["schemas"]["UserNotificationUpdateRequest"];

export async function updateBatchNotificationsOnServer(request: UserNotificationsBatchUpdateRequest) {
const { data } = await putBatchNotifications(request);
return data;
}
export type UserNotificationsBatchUpdateRequest = components["schemas"]["UserNotificationsBatchUpdateRequest"];

const getNotificationStatus = fetcher.path("/api/notifications/status").method("get").create();
export type NotificationVariants = components["schemas"]["NotificationVariant"];

export async function loadNotificationsStatus(since: Date) {
const { data } = await getNotificationStatus({ since: since.toISOString().replace("Z", "") });
return data;
}
export type NewSharedItemNotificationContentItemType =
components["schemas"]["NewSharedItemNotificationContent"]["item_type"];
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,21 @@ import { faInbox } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { computed } from "vue";
import { type MessageNotification } from "@/api/notifications";
import { type MessageNotification, type MessageNotificationCreateData } from "@/api/notifications";
import { useMarkdown } from "@/composables/markdown";
import NotificationActions from "@/components/Notifications/NotificationActions.vue";
library.add(faInbox);
type PartialNotification = Partial<MessageNotification> & { content: MessageNotification["content"] };
type Options =
| {
previewMode?: false;
notification: MessageNotification;
}
| {
previewMode: true;
notification: PartialNotification;
notification: MessageNotificationCreateData;
};
const props = defineProps<{
Expand All @@ -37,12 +35,16 @@ const notificationVariant = computed(() => {
return props.options.notification.variant;
}
});
const notificationSeen = computed(() => {
return "seen_time" in props.options.notification && !!props.options.notification.seen_time;
});
</script>

<template>
<div class="notification-container">
<div class="notification-header">
<div :class="!props.options.notification.seen_time ? 'font-weight-bold' : ''" class="notification-title">
<div :class="!notificationSeen ? 'font-weight-bold' : ''" class="notification-title">
<FontAwesomeIcon :class="`text-${notificationVariant}`" :icon="faInbox" fixed-width size="sm" />
{{ props.options.notification?.content?.subject }}
</div>
Expand Down
28 changes: 11 additions & 17 deletions client/src/components/admin/Notifications/NotificationForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { BAlert, BCard, BCol, BFormGroup, BRow } from "bootstrap-vue";
import { computed, type Ref, ref } from "vue";
import { useRouter } from "vue-router/composables";
import { type NotificationCreateRequest, sendNotification } from "@/api/notifications";
import { type MessageNotificationCreateRequest } from "@/api/notifications";
import { getAllRoles } from "@/api/roles";
import { client, type components } from "@/api/schema";
import { client } from "@/api/schema";
import { getAllUsers } from "@/api/users";
import { Toast } from "@/composables/toast";
import { errorMessageAsString } from "@/utils/simple-error";
Expand All @@ -23,16 +23,6 @@ import MessageNotification from "@/components/Notifications/Categories/MessageNo
library.add(faInfoCircle);
type SelectOption = [string, string];
type NotificationCreateData = components["schemas"]["NotificationCreateData"];
interface MessageNotificationCreateData extends NotificationCreateData {
category: "message";
content: components["schemas"]["MessageNotificationContent"];
}
interface MessageNotificationCreateRequest extends NotificationCreateRequest {
notification: MessageNotificationCreateData;
}
const router = useRouter();
Expand Down Expand Up @@ -125,13 +115,17 @@ loadData(getAllGroups, groups, (group) => {
});
async function sendNewNotification() {
try {
await sendNotification(notificationData.value);
Toast.success("Notification sent");
router.push("/admin/notifications");
} catch (error) {
const { error } = await client.POST("/api/notifications", {
body: notificationData.value,
});
if (error) {
Toast.error(errorMessageAsString(error));
return;
}
Toast.success("Notification sent");
router.push("/admin/notifications");
}
</script>

Expand Down
37 changes: 30 additions & 7 deletions client/src/stores/notificationsStore.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { defineStore } from "pinia";
import { computed, ref } from "vue";

import { client } from "@/api";
import {
loadNotificationsFromServer,
loadNotificationsStatus,
type NotificationChanges,
updateBatchNotificationsOnServer,
type UserNotification,
type UserNotificationsBatchUpdateRequest,
} from "@/api/notifications";
import { useResourceWatcher } from "@/composables/resourceWatcher";
import { rethrowSimple } from "@/utils/simple-error";
import { mergeObjectListsById } from "@/utils/utils";

import { useBroadcastsStore } from "./broadcastsStore";
Expand All @@ -33,8 +32,14 @@ export const useNotificationsStore = defineStore("notificationsStore", () => {
const unreadNotifications = computed(() => notifications.value.filter((n) => !n.seen_time));

async function loadNotifications() {
const data = await loadNotificationsFromServer();
notifications.value = mergeObjectListsById(data, [], "create_time", "desc");
const { data, error } = await client.GET("/api/notifications");

if (error) {
rethrowSimple(error);
}

const useNotifications = data as UserNotification[]; // We are sure this cannot be a broadcast
notifications.value = mergeObjectListsById(useNotifications, [], "create_time", "desc");
}

async function getNotificationStatus() {
Expand All @@ -45,7 +50,18 @@ export const useNotificationsStore = defineStore("notificationsStore", () => {
await loadNotifications();
updateUnreadCount();
} else {
const data = await loadNotificationsStatus(lastNotificationUpdate.value);
const { data, error } = await client.GET("/api/notifications/status", {
params: {
query: {
since: lastNotificationUpdate.value.toISOString().replace("Z", ""),
},
},
});

if (error) {
rethrowSimple(error);
}

totalUnreadCount.value = data.total_unread_count;
notifications.value = mergeObjectListsById(
notifications.value,
Expand All @@ -64,7 +80,14 @@ export const useNotificationsStore = defineStore("notificationsStore", () => {
}

async function updateBatchNotification(request: UserNotificationsBatchUpdateRequest) {
await updateBatchNotificationsOnServer(request);
const { error } = await client.PUT("/api/notifications", {
body: request,
});

if (error) {
rethrowSimple(error);
}

if (request.changes.deleted) {
notifications.value = notifications.value.filter((n) => !request.notification_ids.includes(n.id));
}
Expand Down

0 comments on commit 267ba03

Please sign in to comment.