Skip to content

Commit e5873ae

Browse files
committed
interceptors
1 parent a6141c6 commit e5873ae

File tree

7 files changed

+49
-37
lines changed

7 files changed

+49
-37
lines changed

src/apps/app/app.element.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ import {
1919
} from '@umbraco-cms/backoffice/extension-registry';
2020
import { filter, first, firstValueFrom } from '@umbraco-cms/backoffice/external/rxjs';
2121
import { hasOwnOpener, retrieveStoredPath } from '@umbraco-cms/backoffice/utils';
22+
import {
23+
extractUmbNotificationColor,
24+
isUmbNotifications,
25+
UMB_NOTIFICATION_CONTEXT,
26+
} from '@umbraco-cms/backoffice/notification';
2227

2328
@customElement('umb-app')
2429
export class UmbAppElement extends UmbLitElement {
@@ -146,6 +151,7 @@ export class UmbAppElement extends UmbLitElement {
146151
super();
147152

148153
OpenAPI.BASE = window.location.origin;
154+
this.#attachApiInterceptor();
149155

150156
new UmbBundleExtensionInitializer(this, umbExtensionsRegistry);
151157

@@ -211,6 +217,32 @@ export class UmbAppElement extends UmbLitElement {
211217
}
212218
}
213219

220+
#attachApiInterceptor() {
221+
OpenAPI.interceptors.response.use(async (response) => {
222+
const umbNotifications = response.headers.get('umb-notifications') as string | null;
223+
if (!umbNotifications) return response;
224+
225+
const notifications = JSON.parse(umbNotifications);
226+
if (!isUmbNotifications(notifications)) return response;
227+
228+
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
229+
for (const notification of notifications) {
230+
notificationContext.peek(extractUmbNotificationColor(notification.type), {
231+
data: { headline: notification.category, message: notification.message },
232+
});
233+
}
234+
235+
const newHeader = new Headers();
236+
for (const header of response.headers.entries()) {
237+
const [key, value] = header;
238+
if (key !== 'umb-notifications') newHeader.set(key, value);
239+
}
240+
241+
const newResponse = { ...response, headers: newHeader };
242+
return newResponse;
243+
});
244+
}
245+
214246
// TODO: move set initial auth state into auth context
215247
async #setAuthStatus() {
216248
if (this.bypassAuth) return;

src/packages/core/resources/extractUmbColorNotification.function.ts renamed to src/packages/core/notification/extractUmbNotificationColor.function.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { UmbNotificationColor } from '../notification/notification.context.js';
1+
import type { UmbNotificationColor } from './notification.context.js';
22
import { EventMessageTypeModel } from '@umbraco-cms/backoffice/external/backend-api';
33

4-
export function extractUmbColorNotification(type: EventMessageTypeModel): UmbNotificationColor {
4+
export function extractUmbNotificationColor(type: EventMessageTypeModel): UmbNotificationColor {
55
switch (type) {
66
case EventMessageTypeModel.ERROR:
77
return 'danger';

src/packages/core/notification/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ import './layouts/default/index.js';
22

33
export * from './notification.context.js';
44
export * from './notification-handler.js';
5+
6+
export * from './isUmbNotifications.function.js';
7+
export * from './extractUmbNotificationColor.function.js';

src/packages/core/resources/isUmbNotification.function.ts renamed to src/packages/core/notification/isUmbNotifications.function.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import type { UmbNotificationsEventModel } from './resource.controller.js';
21
import { EventMessageTypeModel } from '@umbraco-cms/backoffice/external/backend-api';
32

4-
export function isUmbNotification(notification: unknown): notification is UmbNotificationsEventModel {
3+
function objectIsUmbNotification(notification: unknown): notification is UmbNotificationsEventModel {
54
if (typeof notification !== 'object' || notification === null) {
65
return false;
76
}
@@ -13,3 +12,13 @@ export function isUmbNotification(notification: unknown): notification is UmbNot
1312
Object.values(EventMessageTypeModel).includes(object.type)
1413
);
1514
}
15+
16+
export interface UmbNotificationsEventModel {
17+
category: string;
18+
message: string;
19+
type: EventMessageTypeModel;
20+
}
21+
22+
export function isUmbNotifications(notifications: Array<unknown>): notifications is Array<UmbNotificationsEventModel> {
23+
return notifications.every(objectIsUmbNotification);
24+
}

src/packages/core/resources/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
export * from './resource.controller.js';
22
export * from './tryExecute.function.js';
33
export * from './tryExecuteAndNotify.function.js';
4-
export * from './extractUmbColorNotification.function.js';
54
export * from './extractUmbColorVariable.function.js';
6-
export * from './isUmbNotification.function.js';
7-
export * from './isUmbNotifications.function.js';
85
export * from './apiTypeValidators.function.js';

src/packages/core/resources/isUmbNotifications.function.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/packages/core/resources/resource.controller.ts

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import { UMB_AUTH_CONTEXT } from '../auth/index.js';
33
import { isApiError, isCancelError, isCancelablePromise } from './apiTypeValidators.function.js';
4-
import { extractUmbColorNotification } from './extractUmbColorNotification.function.js';
5-
import { isUmbNotifications } from './isUmbNotifications.function.js';
64
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
75
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
86
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
97
import { UMB_NOTIFICATION_CONTEXT, type UmbNotificationOptions } from '@umbraco-cms/backoffice/notification';
108
import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository';
11-
import type { EventMessageTypeModel } from '@umbraco-cms/backoffice/external/backend-api';
12-
13-
export interface UmbNotificationsEventModel {
14-
category: string;
15-
message: string;
16-
type: EventMessageTypeModel;
17-
}
189

1910
export class UmbResourceController extends UmbControllerBase {
2011
#promise: Promise<any>;
@@ -137,9 +128,7 @@ export class UmbResourceController extends UmbControllerBase {
137128
break;
138129
default:
139130
// Other errors
140-
if (error && error.body && Array.isArray(error.body) && isUmbNotifications(error.body)) {
141-
this.#peekUmbNotifications(error.body);
142-
} else if (this.#notificationContext) {
131+
if (this.#notificationContext) {
143132
this.#notificationContext.peek('danger', {
144133
data: {
145134
headline: error.body?.title ?? error.name ?? 'Server Error',
@@ -155,21 +144,9 @@ export class UmbResourceController extends UmbControllerBase {
155144
}
156145
}
157146

158-
if (Array.isArray(data) && isUmbNotifications(data)) {
159-
this.#peekUmbNotifications(data);
160-
}
161-
162147
return { data, error };
163148
}
164149

165-
#peekUmbNotifications(notifications: Array<UmbNotificationsEventModel>) {
166-
notifications.forEach((notification) => {
167-
this.#notificationContext?.peek(extractUmbColorNotification(notification.type), {
168-
data: { headline: notification.category, message: notification.message },
169-
});
170-
});
171-
}
172-
173150
/**
174151
* Cancel all resources that are currently being executed by this controller if they are cancelable.
175152
*

0 commit comments

Comments
 (0)