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}: + +
`, + )}`; + } + + #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, });