UNPKG

@eclipse-scout/core

Version:
216 lines (187 loc) 5.69 kB
/* * Copyright (c) 2010, 2025 BSI Business Systems Integration AG * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 */ import {aria, HtmlComponent, Icon, icons, InitModelOf, NotificationEventMap, NotificationModel, scout, Status, StatusOrModel, strings, texts, Widget} from '../index'; import $ from 'jquery'; export class Notification extends Widget implements NotificationModel { declare model: NotificationModel; declare eventMap: NotificationEventMap; declare self: Notification; status: Status; closable: boolean; htmlEnabled: boolean; $content: JQuery; $messageText: JQuery; $closer: JQuery; protected _icon: Icon; constructor() { super(); this.status = Status.info(); this.closable = false; this.htmlEnabled = false; this._icon = null; } protected override _init(model: InitModelOf<this>) { super._init(model); // this allows to set the properties severity and message directly on the model object // without having a status object. because it's more convenient when you must create // a notification programmatically. if (model.severity || model.message || model.iconId) { this.status = new Status({ severity: scout.nvl(model.severity, this.status.severity), message: scout.nvl(model.message, this.status.message), iconId: scout.nvl(model.iconId, this.status.iconId) }); } this._resolveStatusTextKeys(['message']); this._resolveStatusIconIds(['iconId']); this._setStatus(this.status); } protected _resolveStatusTextKeys(properties: string[]) { texts.resolveTextProperties(this.status, properties, this.session); } protected _resolveStatusIconIds(properties: string[]) { icons.resolveIconProperties(this.status, properties); } protected override _render() { this.$container = this.$parent.appendDiv('notification alternative'); // Alternative is the new default. this.$content = this.$container.appendDiv('notification-content'); this.$messageText = this.$content.appendDiv('notification-message'); this.htmlComp = HtmlComponent.install(this.$container, this.session); } protected override _remove() { super._remove(); this._removeCloser(); this._removeIcon(); } protected override _renderProperties() { super._renderProperties(); this._renderStatus(); this._renderClosable(); } setStatus(status: StatusOrModel) { this.setProperty('status', status); } protected _setStatus(status: StatusOrModel) { if (this.rendered) { this._removeStatus(); } status = Status.ensure(status) || Status.info(); this._setProperty('status', status); } protected _removeStatus() { if (this.status) { this.$container.removeClass(this.status.cssClass()); } } protected _renderStatus() { if (this.status) { this.$container.addClass(this.status.cssClass()); this._renderIconId(); } this._renderMessage(); } protected _renderMessage() { let message = this.status.message || ''; if (this.htmlEnabled) { this.$messageText.html(message); // Add action to app-links this.$messageText.find('.app-link') .on('click', this._onAppLinkAction.bind(this)); } else { this.$messageText.html(strings.nl2br(message)); } this.invalidateLayoutTree(); } setIconId(iconId: string) { if (!this.status) { this.status = Status.info(); } this.status.iconId = iconId; if (this.rendered) { this._renderStatus(); } } protected _renderIconId() { let hasIcon = this.status && !!this.status.iconId; this.$container.toggleClass('has-icon', hasIcon); this.$container.toggleClass('no-icon', !hasIcon); if (hasIcon) { this._renderIcon(); } else { this._removeIcon(); } } protected _renderIcon() { if (this._icon) { this._icon.setIconDesc(this.status.iconId); return; } this._icon = scout.create(Icon, { parent: this, iconDesc: this.status.iconId, prepend: true }); this._icon.one('destroy', () => { this._icon = null; }); this._icon.render(); this._icon.$container.addClass('notification-icon'); } protected _removeIcon() { if (this._icon) { this._icon.destroy(); } } setClosable(closable: boolean) { this.setProperty('closable', closable); } protected _renderClosable() { this.$container.toggleClass('closable', this.closable); this.$content.toggleClass('closable', this.closable); if (!this.closable) { this._removeCloser(); } else { this._renderCloser(); } } protected _removeCloser() { if (!this.$closer) { return; } this.$closer.remove(); this.$closer = null; } protected _renderCloser() { if (this.$closer) { return; } this.$closer = this.$content .appendDiv('closer') .on('click', this._onCloseIconClick.bind(this)); aria.role(this.$closer, 'button'); aria.label(this.$closer, this.session.text('ui.Close')); } protected _onCloseIconClick(event: JQuery.ClickEvent) { if (this.removing) { return; } this.trigger('close'); } protected _onAppLinkAction(event: JQuery.ClickEvent) { let $target = $(event.delegateTarget); let ref = $target.data('ref') as string; this.triggerAppLinkAction(ref); } triggerAppLinkAction(ref: string) { this.trigger('appLinkAction', { ref: ref }); } }