@eclipse-scout/core
Version:
Eclipse Scout runtime
216 lines (187 loc) • 5.69 kB
text/typescript
/*
* 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
});
}
}