From acbc4972002af95fda85475bb62577e2a59cf76c Mon Sep 17 00:00:00 2001
From: Lone Iversen <108085781+loivsen@users.noreply.github.com>
Date: Thu, 4 Jul 2024 11:17:32 +0200
Subject: [PATCH] make the notification layout handle structured list
---
.../notification-layout-default.element.ts | 47 ++++++++++++++++++-
.../core/notification/notification.context.ts | 1 +
.../core/resources/resource.controller.ts | 25 +++-------
3 files changed, 53 insertions(+), 20 deletions(-)
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/notification/layouts/default/notification-layout-default.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/notification/layouts/default/notification-layout-default.element.ts
index 91517a9e90..25f3e28a64 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/notification/layouts/default/notification-layout-default.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/notification/layouts/default/notification-layout-default.element.ts
@@ -1,4 +1,12 @@
-import { html, LitElement, customElement, property, ifDefined } from '@umbraco-cms/backoffice/external/lit';
+import {
+ html,
+ LitElement,
+ customElement,
+ property,
+ ifDefined,
+ nothing,
+ css,
+} from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbNotificationDefaultData, UmbNotificationHandler } from '@umbraco-cms/backoffice/notification';
@@ -16,11 +24,46 @@ export class UmbNotificationLayoutDefaultElement extends LitElement {
return html`
${this.data.message}
+ ${this.#renderStructuredList(this.data.structuredList)}
`;
}
- static override styles = [UmbTextStyles];
+ #renderStructuredList(list: unknown) {
+ if (!this.data.structuredList) return nothing;
+ if (typeof list !== 'object' || list === null) return nothing;
+
+ return html`${Object.entries(list).map(
+ ([property, errors]) =>
+ html`
+
${property}:
+
+ ${this.#renderListItem(errors)}
+
+
`,
+ )}`;
+ }
+
+ #renderListItem(items: unknown) {
+ if (Array.isArray(items)) {
+ return items.map((item) => html`${item}`);
+ } else {
+ return html`${items}`;
+ }
+ }
+
+ static override styles = [
+ UmbTextStyles,
+ css`
+ .structured-list ul {
+ margin: 0;
+ }
+ .structured-list span {
+ display: block;
+ padding: var(--uui-size-3) 0 var(--uui-size-1);
+ }
+ `,
+ ];
}
declare global {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/notification/notification.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/notification/notification.context.ts
index f332742a43..cf73a33857 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/notification/notification.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/notification/notification.context.ts
@@ -12,6 +12,7 @@ import { UmbBasicState } from '@umbraco-cms/backoffice/observable-api';
export interface UmbNotificationDefaultData {
message: string;
headline?: string;
+ structuredList?: Record>;
}
/**
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/resource.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/resource.controller.ts
index b7e20d1df3..550993365e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/resource.controller.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/resource.controller.ts
@@ -1,11 +1,14 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { UMB_AUTH_CONTEXT } from '../auth/index.js';
import { isApiError, isCancelError, isCancelablePromise } from './apiTypeValidators.function.js';
-import { html } from '@umbraco-cms/backoffice/external/lit';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api';
-import { UMB_NOTIFICATION_CONTEXT, type UmbNotificationOptions } from '@umbraco-cms/backoffice/notification';
+import {
+ UMB_NOTIFICATION_CONTEXT,
+ type UmbNotificationDefaultData,
+ type UmbNotificationOptions,
+} from '@umbraco-cms/backoffice/notification';
import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository';
export type ErrorMessageText = { property: string; messages: string[] };
@@ -39,20 +42,6 @@ export class UmbResourceController extends UmbControllerBase {
this.cancel();
}
- #buildApiErrorMessage(error: ErrorMessageText) {
- if (!error) return undefined;
- if (typeof error !== 'object') return undefined;
-
- const entries: Array = [];
- Object.entries(error).forEach(([property, message]) => {
- entries.push({ property, messages: Array.isArray(message) ? message : [message] });
- });
-
- const template = html` ${entries.map((e) => e.messages.map((msg: string) => html`${msg}
`))}`;
-
- return template;
- }
-
/**
* Base execute function with a try/catch block and return a tuple with the result and the error.
*/
@@ -146,11 +135,11 @@ export class UmbResourceController extends UmbControllerBase {
default:
// Other errors
if (this.#notificationContext) {
- const message = this.#buildApiErrorMessage(error?.body?.errors);
this.#notificationContext.peek('danger', {
data: {
headline: error.body?.title ?? error.name ?? 'Server Error',
- message: message ?? error.body?.detail ?? error.message ?? 'Something went wrong',
+ message: error.body?.detail ?? error.message ?? 'Something went wrong',
+ structuredList: error.body.errors,
},
...options,
});