Merge pull request #18172 from umbraco/v15/feature/reworking-error-notifications
Feature: reworking error toast notifications
This commit is contained in:
@@ -584,6 +584,8 @@ export default {
|
||||
deleteLayout: 'You are deleting the layout',
|
||||
deletingALayout:
|
||||
'Modifying layout will result in loss of data for any existing content that is based on this configuration.',
|
||||
seeErrorAction: 'Se fejlen',
|
||||
seeErrorDialogHeadline: 'Fejl detaljer',
|
||||
},
|
||||
dictionary: {
|
||||
noItems: 'Der er ingen ordbogselementer.',
|
||||
|
||||
@@ -614,6 +614,8 @@ export default {
|
||||
deleteLayout: 'You are deleting the layout',
|
||||
deletingALayout:
|
||||
'Modifying layout will result in loss of data for any existing content that is based on this configuration.',
|
||||
seeErrorAction: 'See error',
|
||||
seeErrorDialogHeadline: 'Error details',
|
||||
},
|
||||
dictionary: {
|
||||
importDictionaryItemHelp:
|
||||
|
||||
@@ -610,6 +610,8 @@ export default {
|
||||
deletingALayout:
|
||||
'Modifying layout will result in loss of data for any existing content that is based on this configuration.',
|
||||
selectEditorConfiguration: 'Select configuration',
|
||||
seeErrorAction: 'See error',
|
||||
seeErrorDialogHeadline: 'Error details',
|
||||
},
|
||||
dictionary: {
|
||||
importDictionaryItemHelp:
|
||||
|
||||
@@ -68,7 +68,6 @@ export class UmbCodeBlockElement extends LitElement {
|
||||
}
|
||||
|
||||
uui-scroll-container {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { manifests as iconRegistryManifests } from './icon-registry/manifests.js
|
||||
import { manifests as localizationManifests } from './localization/manifests.js';
|
||||
import { manifests as menuManifests } from './menu/manifests.js';
|
||||
import { manifests as modalManifests } from './modal/manifests.js';
|
||||
import { manifests as notificationManifests } from './notification/manifests.js';
|
||||
import { manifests as pickerManifests } from './picker/manifests.js';
|
||||
import { manifests as propertyActionManifests } from './property-action/manifests.js';
|
||||
import { manifests as propertyEditorManifests } from './property-editor/manifests.js';
|
||||
@@ -40,6 +41,7 @@ export const manifests: Array<UmbExtensionManifest | UmbExtensionManifestKind> =
|
||||
...localizationManifests,
|
||||
...menuManifests,
|
||||
...modalManifests,
|
||||
...notificationManifests,
|
||||
...pickerManifests,
|
||||
...propertyActionManifests,
|
||||
...propertyEditorManifests,
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './peek-error.controller.js';
|
||||
@@ -0,0 +1,43 @@
|
||||
import { customElement, html, ifDefined, nothing, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbNotificationHandler } from '../../notification-handler.js';
|
||||
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
import type { UmbPeekErrorArgs } from '../../types.js';
|
||||
import { UMB_ERROR_VIEWER_MODAL } from '../../index.js';
|
||||
|
||||
@customElement('umb-peek-error-notification')
|
||||
export class UmbPeekErrorNotificationElement extends UmbLitElement {
|
||||
@property({ attribute: false })
|
||||
public data?: UmbPeekErrorArgs;
|
||||
|
||||
public notificationHandler!: UmbNotificationHandler;
|
||||
|
||||
async #onClick() {
|
||||
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
|
||||
|
||||
modalManager.open(this, UMB_ERROR_VIEWER_MODAL, { data: this.data?.details });
|
||||
|
||||
this.notificationHandler.close();
|
||||
}
|
||||
|
||||
protected override render() {
|
||||
return this.data
|
||||
? html`<uui-toast-notification-layout headline=${ifDefined(this.data.headline)}
|
||||
>${this.data.message}${this.data.details
|
||||
? html`<uui-button
|
||||
slot="actions"
|
||||
look="primary"
|
||||
color="danger"
|
||||
label=${this.localize.term('defaultdialogs_seeErrorAction')}
|
||||
@click=${this.#onClick}></uui-button>`
|
||||
: nothing}</uui-toast-notification-layout
|
||||
>`
|
||||
: nothing;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-peek-error-notification': UmbPeekErrorNotificationElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { UMB_NOTIFICATION_CONTEXT } from '../../notification.context.js';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { UmbPeekErrorArgs } from '../../types.js';
|
||||
|
||||
import './peek-error-notification.element.js';
|
||||
|
||||
export class UmbPeekErrorController extends UmbControllerBase {
|
||||
async open(args: UmbPeekErrorArgs): Promise<void> {
|
||||
const context = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
|
||||
context.peek('danger', {
|
||||
elementName: 'umb-peek-error-notification',
|
||||
data: args,
|
||||
});
|
||||
|
||||
// This is a one time off, so we can destroy our selfs.
|
||||
this.destroy();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param host {UmbControllerHost} - The host controller
|
||||
* @param args {UmbPeekErrorArgs} - The data to pass to the notification
|
||||
* @returns {UmbPeekErrorController} The notification peek controller instance
|
||||
*/
|
||||
export function umbPeekError(host: UmbControllerHost, args: UmbPeekErrorArgs) {
|
||||
return new UmbPeekErrorController(host).open(args);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { UmbNotificationColor } from './notification.context.js';
|
||||
import { EventMessageTypeModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbNotificationColor } from './types.js';
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import './layouts/default/index.js';
|
||||
|
||||
export * from './notification.context.js';
|
||||
export * from './notification-handler.js';
|
||||
|
||||
export * from './isUmbNotifications.function.js';
|
||||
export * from './controllers/peek-error/index.js';
|
||||
export * from './extractUmbNotificationColor.function.js';
|
||||
export * from './isUmbNotifications.function.js';
|
||||
export * from './modals/error-viewer/index.js';
|
||||
export * from './notification-handler.js';
|
||||
export * from './notification.context.js';
|
||||
|
||||
export type * from './types.js';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import { manifest } from './modals/error-viewer/manifest.js';
|
||||
|
||||
export const manifests = [manifest];
|
||||
@@ -0,0 +1,77 @@
|
||||
import type { UmbErrorViewerModalData, UmbErrorViewerModalValue } from './error-viewer-modal.token.js';
|
||||
import { css, customElement, html, nothing, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
@customElement('umb-error-viewer-modal')
|
||||
export class UmbErrorViewerModalElement extends UmbModalBaseElement<UmbErrorViewerModalData, UmbErrorViewerModalValue> {
|
||||
@state()
|
||||
_displayError?: string;
|
||||
|
||||
@state()
|
||||
_displayLang?: string;
|
||||
|
||||
// Code adapted from https://stackoverflow.com/a/57668208/12787
|
||||
// Licensed under the permissions of the CC BY-SA 4.0 DEED
|
||||
#stringify(obj: any): string {
|
||||
let output = '{';
|
||||
for (const key in obj) {
|
||||
let value = obj[key];
|
||||
if (typeof value === 'function') {
|
||||
value = value.toString();
|
||||
} else if (value instanceof Array) {
|
||||
value = JSON.stringify(value);
|
||||
} else if (typeof value === 'object') {
|
||||
value = this.#stringify(value);
|
||||
} else {
|
||||
value = `"${value}"`;
|
||||
}
|
||||
output += `\n ${key}: ${value},`;
|
||||
}
|
||||
return output + '\n}';
|
||||
}
|
||||
|
||||
public override set data(value: UmbErrorViewerModalData | undefined) {
|
||||
super.data = value;
|
||||
// is JSON:
|
||||
if (typeof value === 'string') {
|
||||
this._displayLang = 'String';
|
||||
this._displayError = value;
|
||||
} else {
|
||||
this._displayLang = 'JSON';
|
||||
this._displayError = this.#stringify(value);
|
||||
}
|
||||
}
|
||||
public override get data(): UmbErrorViewerModalData | undefined {
|
||||
return super.data;
|
||||
}
|
||||
|
||||
override render() {
|
||||
return html`
|
||||
<umb-body-layout headline=${this.localize.term('defaultdialogs_seeErrorDialogHeadline')} main-no-padding>
|
||||
${this.data
|
||||
? html`<umb-code-block language=${this._displayLang ?? ''} copy>${this._displayError}</umb-code-block>`
|
||||
: nothing}
|
||||
<div slot="actions">
|
||||
<uui-button label=${this.localize.term('general_close')} @click=${this._rejectModal}></uui-button>
|
||||
</div>
|
||||
</umb-body-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static override styles = [
|
||||
css`
|
||||
umb-code-block {
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbErrorViewerModalElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-error-viewer-modal': UmbErrorViewerModalElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
|
||||
import type { UmbPeekErrorArgs } from '../../types.js';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
export interface UmbErrorViewerModalData extends UmbPeekErrorArgs {}
|
||||
|
||||
export type UmbErrorViewerModalValue = undefined;
|
||||
|
||||
export const UMB_ERROR_VIEWER_MODAL = new UmbModalToken<UmbErrorViewerModalData, UmbErrorViewerModalValue>(
|
||||
'Umb.Modal.ErrorViewer',
|
||||
{
|
||||
modal: {
|
||||
type: 'sidebar',
|
||||
size: 'medium',
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './error-viewer-modal.token.js';
|
||||
export * from './manifest.js';
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { ManifestModal } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export const manifest: ManifestModal = {
|
||||
type: 'modal',
|
||||
alias: 'Umb.Modal.ErrorViewer',
|
||||
name: 'Error Viewer Modal',
|
||||
element: () => import('./error-viewer-modal.element.js'),
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UmbNotificationHandler } from './notification-handler.js';
|
||||
import type { UmbNotificationOptions } from './notification.context.js';
|
||||
import type { UmbNotificationOptions } from './types.js';
|
||||
import { assert, expect } from '@open-wc/testing';
|
||||
import { UmbId } from '@umbraco-cms/backoffice/id';
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import type {
|
||||
UmbNotificationOptions,
|
||||
UmbNotificationColor,
|
||||
UmbNotificationDefaultData,
|
||||
} from './notification.context.js';
|
||||
import type { UmbNotificationOptions, UmbNotificationColor, UmbNotificationDefaultData } from './types.js';
|
||||
import type { UUIToastNotificationElement } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbId } from '@umbraco-cms/backoffice/id';
|
||||
|
||||
const DEFAULT_LAYOUT = 'umb-notification-layout-default';
|
||||
|
||||
/**
|
||||
* @class UmbNotificationHandler
|
||||
*/
|
||||
@@ -17,10 +15,9 @@ export class UmbNotificationHandler {
|
||||
|
||||
private _defaultColor: UmbNotificationColor = 'default';
|
||||
private _defaultDuration = 6000;
|
||||
private _defaultLayout = 'umb-notification-layout-default';
|
||||
|
||||
public key: string;
|
||||
public element: any;
|
||||
public element!: UUIToastNotificationElement;
|
||||
public color: UmbNotificationColor;
|
||||
public duration: number | null;
|
||||
|
||||
@@ -34,23 +31,13 @@ export class UmbNotificationHandler {
|
||||
this.color = options.color || this._defaultColor;
|
||||
this.duration = options.duration !== undefined ? options.duration : this._defaultDuration;
|
||||
|
||||
this._elementName = options.elementName || this._defaultLayout;
|
||||
this._elementName = options.elementName || DEFAULT_LAYOUT;
|
||||
this._data = options.data;
|
||||
|
||||
this._closePromise = new Promise((res) => {
|
||||
this._closeResolver = res;
|
||||
});
|
||||
|
||||
this._createElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @memberof UmbNotificationHandler
|
||||
*/
|
||||
private _createElement() {
|
||||
if (!this._elementName) return;
|
||||
|
||||
const notification: UUIToastNotificationElement = document.createElement('uui-toast-notification');
|
||||
|
||||
notification.color = this.color;
|
||||
|
||||
@@ -3,29 +3,7 @@ import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import { UmbBasicState } from '@umbraco-cms/backoffice/observable-api';
|
||||
|
||||
/**
|
||||
* The default data of notifications
|
||||
* @interface UmbNotificationDefaultData
|
||||
*/
|
||||
export interface UmbNotificationDefaultData {
|
||||
message: string;
|
||||
headline?: string;
|
||||
structuredList?: Record<string, Array<unknown>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface UmbNotificationOptions
|
||||
* @template UmbNotificationData
|
||||
*/
|
||||
export interface UmbNotificationOptions<UmbNotificationData = UmbNotificationDefaultData> {
|
||||
color?: UmbNotificationColor;
|
||||
duration?: number | null;
|
||||
elementName?: string;
|
||||
data?: UmbNotificationData;
|
||||
}
|
||||
|
||||
export type UmbNotificationColor = '' | 'default' | 'positive' | 'warning' | 'danger';
|
||||
import type { UmbNotificationColor, UmbNotificationOptions } from './types.js';
|
||||
|
||||
export class UmbNotificationContext extends UmbContextBase<UmbNotificationContext> {
|
||||
// Notice this cannot use UniqueBehaviorSubject as it holds a HTML Element. which cannot be Serialized to JSON (it has some circular references)
|
||||
@@ -42,9 +20,9 @@ export class UmbNotificationContext extends UmbContextBase<UmbNotificationContex
|
||||
* @returns {*} {UmbNotificationHandler}
|
||||
* @memberof UmbNotificationContext
|
||||
*/
|
||||
private _open(options: UmbNotificationOptions): UmbNotificationHandler {
|
||||
#open<T extends UmbNotificationOptions = UmbNotificationOptions>(options: T): UmbNotificationHandler {
|
||||
const notificationHandler = new UmbNotificationHandler(options);
|
||||
notificationHandler.element.addEventListener('closed', () => this._handleClosed(notificationHandler));
|
||||
notificationHandler.element?.addEventListener('closed', () => this._handleClosed(notificationHandler));
|
||||
|
||||
this._notifications.setValue([...this._notifications.getValue(), notificationHandler]);
|
||||
|
||||
@@ -78,8 +56,11 @@ export class UmbNotificationContext extends UmbContextBase<UmbNotificationContex
|
||||
* @returns {*}
|
||||
* @memberof UmbNotificationContext
|
||||
*/
|
||||
public peek(color: UmbNotificationColor, options: UmbNotificationOptions): UmbNotificationHandler {
|
||||
return this._open({ color, ...options });
|
||||
public peek<T extends UmbNotificationOptions = UmbNotificationOptions>(
|
||||
color: UmbNotificationColor,
|
||||
options: T,
|
||||
): UmbNotificationHandler {
|
||||
return this.#open({ color, ...options });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,8 +70,11 @@ export class UmbNotificationContext extends UmbContextBase<UmbNotificationContex
|
||||
* @returns {*}
|
||||
* @memberof UmbNotificationContext
|
||||
*/
|
||||
public stay(color: UmbNotificationColor, options: UmbNotificationOptions): UmbNotificationHandler {
|
||||
return this._open({ ...options, color, duration: null });
|
||||
public stay<T extends UmbNotificationOptions = UmbNotificationOptions>(
|
||||
color: UmbNotificationColor,
|
||||
options: T,
|
||||
): UmbNotificationHandler {
|
||||
return this.#open({ ...options, color, duration: null });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* The default data of notifications
|
||||
* @interface UmbNotificationDefaultData
|
||||
*/
|
||||
export interface UmbNotificationDefaultData {
|
||||
message: string;
|
||||
headline?: string;
|
||||
/**
|
||||
* @deprecated, do not use this. It will be removed in v.16 — Use UmbPeekError instead
|
||||
*/
|
||||
structuredList?: Record<string, Array<unknown>>;
|
||||
whitespace?: 'normal' | 'pre-line' | 'pre-wrap' | 'nowrap' | 'pre';
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface UmbNotificationOptions
|
||||
* @template UmbNotificationData
|
||||
*/
|
||||
export interface UmbNotificationOptions<UmbNotificationData = UmbNotificationDefaultData> {
|
||||
color?: UmbNotificationColor;
|
||||
duration?: number | null;
|
||||
elementName?: string;
|
||||
data?: UmbNotificationData;
|
||||
}
|
||||
|
||||
export type UmbNotificationColor = '' | 'default' | 'positive' | 'warning' | 'danger';
|
||||
|
||||
export interface UmbPeekErrorArgs extends UmbNotificationDefaultData {
|
||||
details?: any;
|
||||
}
|
||||
@@ -4,8 +4,7 @@ import { isApiError, isCancelError, isCancelablePromise } from './apiTypeValidat
|
||||
import type { XhrRequestOptions } from './types.js';
|
||||
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 { umbPeekError, type UmbNotificationOptions } from '@umbraco-cms/backoffice/notification';
|
||||
import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository';
|
||||
import {
|
||||
ApiError,
|
||||
@@ -13,33 +12,19 @@ import {
|
||||
CancelError,
|
||||
type ProblemDetails,
|
||||
} from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import { UmbDeprecation } from '../utils/deprecation/deprecation.js';
|
||||
|
||||
export class UmbResourceController extends UmbControllerBase {
|
||||
#promise: Promise<any>;
|
||||
|
||||
#notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE;
|
||||
|
||||
#authContext?: typeof UMB_AUTH_CONTEXT.TYPE;
|
||||
|
||||
constructor(host: UmbControllerHost, promise: Promise<any>, alias?: string) {
|
||||
super(host, alias);
|
||||
|
||||
this.#promise = promise;
|
||||
|
||||
new UmbContextConsumerController(host, UMB_NOTIFICATION_CONTEXT, (_instance) => {
|
||||
this.#notificationContext = _instance;
|
||||
});
|
||||
|
||||
new UmbContextConsumerController(host, UMB_AUTH_CONTEXT, (_instance) => {
|
||||
this.#authContext = _instance;
|
||||
});
|
||||
}
|
||||
|
||||
override hostConnected(): void {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
override hostDisconnected(): void {
|
||||
super.hostDisconnected();
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
@@ -48,6 +33,7 @@ export class UmbResourceController extends UmbControllerBase {
|
||||
* @param promise
|
||||
*/
|
||||
static async tryExecute<T>(promise: Promise<T>): Promise<UmbDataSourceResponse<T>> {
|
||||
// TODO: tryExecute should not take a promise as argument, but should utilize the class property `#promise` instead. (In this way the promise can be cancelled when disconnected)
|
||||
try {
|
||||
return { data: await promise };
|
||||
} catch (error) {
|
||||
@@ -63,11 +49,20 @@ export class UmbResourceController extends UmbControllerBase {
|
||||
/**
|
||||
* Wrap the {tryExecute} function in a try/catch block and return the result.
|
||||
* If the executor function throws an error, then show the details in a notification.
|
||||
* @param options
|
||||
* @param _options
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async tryExecuteAndNotify<T>(options?: UmbNotificationOptions): Promise<UmbDataSourceResponse<T>> {
|
||||
const { data, error } = await UmbResourceController.tryExecute<T>(this.#promise);
|
||||
|
||||
if (options) {
|
||||
new UmbDeprecation({
|
||||
deprecated: 'tryExecuteAndNotify `options` argument is deprecated.',
|
||||
removeInVersion: '17.0.0',
|
||||
solution: 'Use the method without arguments.',
|
||||
}).warn();
|
||||
}
|
||||
|
||||
if (error) {
|
||||
/**
|
||||
* Determine if we want to show a notification or just log the error to the console.
|
||||
@@ -82,6 +77,7 @@ export class UmbResourceController extends UmbControllerBase {
|
||||
console.error('Request failed', error.request);
|
||||
console.error('Request body', error.body);
|
||||
console.error('Error', error);
|
||||
console.groupEnd();
|
||||
|
||||
let problemDetails: ProblemDetails | null = null;
|
||||
|
||||
@@ -111,23 +107,14 @@ export class UmbResourceController extends UmbControllerBase {
|
||||
switch (error.status ?? 0) {
|
||||
case 401: {
|
||||
// See if we can get the UmbAuthContext and let it know the user is timed out
|
||||
if (this.#authContext) {
|
||||
this.#authContext.timeOut();
|
||||
} else {
|
||||
// If we can't get the auth context, show a notification
|
||||
this.#notificationContext?.peek('warning', {
|
||||
data: {
|
||||
headline: 'Session Expired',
|
||||
message: 'Your session has expired. Please refresh the page.',
|
||||
},
|
||||
});
|
||||
}
|
||||
const authContext = await this.getContext(UMB_AUTH_CONTEXT);
|
||||
authContext.timeOut();
|
||||
break;
|
||||
}
|
||||
case 500:
|
||||
// Server Error
|
||||
|
||||
if (!isCancelledByNotification && this.#notificationContext) {
|
||||
if (!isCancelledByNotification) {
|
||||
let headline = problemDetails?.title ?? error.name ?? 'Server Error';
|
||||
let message = 'A fatal server error occurred. If this continues, please reach out to your administrator.';
|
||||
|
||||
@@ -141,19 +128,19 @@ export class UmbResourceController extends UmbControllerBase {
|
||||
'The Umbraco object cache is corrupt, but your action may still have been executed. Please restart the server to reset the cache. This is a work in progress.';
|
||||
}
|
||||
|
||||
this.#notificationContext.peek('danger', {
|
||||
data: {
|
||||
headline,
|
||||
message,
|
||||
},
|
||||
...options,
|
||||
umbPeekError(this, {
|
||||
headline: headline,
|
||||
message: message,
|
||||
details: problemDetails?.errors ?? problemDetails?.detail,
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Other errors
|
||||
if (!isCancelledByNotification && this.#notificationContext) {
|
||||
this.#notificationContext.peek('danger', {
|
||||
if (!isCancelledByNotification) {
|
||||
/*
|
||||
const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT);
|
||||
notificationContext.peek('danger', {
|
||||
data: {
|
||||
headline: problemDetails?.title ?? error.name ?? 'Server Error',
|
||||
message: problemDetails?.detail ?? error.message ?? 'Something went wrong',
|
||||
@@ -163,10 +150,14 @@ export class UmbResourceController extends UmbControllerBase {
|
||||
},
|
||||
...options,
|
||||
});
|
||||
*/
|
||||
const headline = problemDetails?.title ?? error.name ?? 'Server Error';
|
||||
umbPeekError(this, {
|
||||
message: headline,
|
||||
details: problemDetails?.errors ?? problemDetails?.detail,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.groupEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase<
|
||||
this,
|
||||
umbExtensionsRegistry,
|
||||
repositoryAlias,
|
||||
[this._host],
|
||||
[],
|
||||
(permitted, ctrl) => {
|
||||
this._detailRepository = permitted ? ctrl.api : undefined;
|
||||
this.#checkIfInitialized();
|
||||
|
||||
@@ -95,7 +95,7 @@ export class UmbModelsBuilderDashboardElement extends UmbLitElement {
|
||||
</p>
|
||||
${this._modelsBuilder?.lastError
|
||||
? html`<p class="error">Last generation failed with the following error:</p>
|
||||
<umb-code-block>${this._modelsBuilder.lastError}</umb-code-block>`
|
||||
<umb-code-block style="max-height:500px;">${this._modelsBuilder.lastError}</umb-code-block>`
|
||||
: nothing}
|
||||
</uui-box>
|
||||
`;
|
||||
|
||||
@@ -94,7 +94,7 @@ export class UmbTemplatingPageFieldBuilderModalElement extends UmbModalBaseEleme
|
||||
?disabled=${this._field ? false : true}></uui-checkbox>
|
||||
|
||||
<uui-label><umb-localize key="templateEditor_outputSample">Output sample</umb-localize></uui-label>
|
||||
<umb-code-block language="C#" copy
|
||||
<umb-code-block style="max-height:500px;" language="C#" copy
|
||||
>${this._field ? getUmbracoFieldSnippet(this._field, this._default, this._recursive) : ''}</umb-code-block
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -254,7 +254,9 @@ export default class UmbTemplateQueryBuilderModalElement extends UmbModalBaseEle
|
||||
(sample) => html`<span><umb-icon name=${sample.icon}></umb-icon>${sample.name}</span>`,
|
||||
) ?? ''}
|
||||
</div>
|
||||
<umb-code-block language="C#" copy>${this._templateQuery?.queryExpression ?? ''}</umb-code-block>
|
||||
<umb-code-block style="max-height:500px;" language="C#" copy
|
||||
>${this._templateQuery?.queryExpression ?? ''}</umb-code-block
|
||||
>
|
||||
</uui-box>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user