[TASK] Cleanup TYPO3/CMS/Backend/Notification
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Private / TypeScript / Notification.ts
1 /*
2  * This file is part of the TYPO3 CMS project.
3  *
4  * It is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License, either version 2
6  * of the License, or any later version.
7  *
8  * For the full copyright and license information, please read the
9  * LICENSE.txt file that was distributed with this source code.
10  *
11  * The TYPO3 project - inspiring people to share!
12  */
13
14 import * as $ from 'jquery';
15 import {SeverityEnum} from './Enum/Severity';
16 import Severity = require('./Severity');
17
18 /**
19  * Module: TYPO3/CMS/Backend/Notification
20  * Notification API for the TYPO3 backend
21  */
22 class Notification {
23   private static duration: number = 5;
24   private static messageContainer: JQuery = null;
25
26   /**
27    * Show a notice notification
28    *
29    * @param {string} title
30    * @param {string} message
31    * @param {number} duration
32    */
33   public static notice(title: string, message?: string, duration?: number): void {
34     Notification.showMessage(title, message, SeverityEnum.notice, duration);
35   }
36
37   /**
38    * Show a info notification
39    *
40    * @param {string} title
41    * @param {string} message
42    * @param {number} duration
43    */
44   public static info(title: string, message?: string, duration?: number): void {
45     Notification.showMessage(title, message, SeverityEnum.info, duration);
46   }
47
48   /**
49    * Show a success notification
50    *
51    * @param {string} title
52    * @param {string} message
53    * @param {number} duration
54    */
55   public static success(title: string, message?: string, duration?: number): void {
56     Notification.showMessage(title, message, SeverityEnum.ok, duration);
57   }
58
59   /**
60    * Show a warning notification
61    *
62    * @param {string} title
63    * @param {string} message
64    * @param {number} duration
65    */
66   public static warning(title: string, message?: string, duration?: number): void {
67     Notification.showMessage(title, message, SeverityEnum.warning, duration);
68   }
69
70   /**
71    * Show a error notification
72    *
73    * @param {string} title
74    * @param {string} message
75    * @param {number} duration
76    */
77   public static error(title: string, message?: string, duration: number = 0): void {
78     Notification.showMessage(title, message, SeverityEnum.error, duration);
79   }
80
81   /**
82    * @param {string} title
83    * @param {string} message
84    * @param {SeverityEnum} severity
85    * @param {number} duration
86    */
87   public static showMessage(title: string,
88                             message?: string,
89                             severity: SeverityEnum = SeverityEnum.info,
90                             duration: number | string = this.duration): void {
91     const className = Severity.getCssClass(severity);
92     let icon = '';
93     switch (severity) {
94       case SeverityEnum.notice:
95         icon = 'lightbulb-o';
96         break;
97       case SeverityEnum.ok:
98         icon = 'check';
99         break;
100       case SeverityEnum.warning:
101         icon = 'exclamation';
102         break;
103       case SeverityEnum.error:
104         icon = 'times';
105         break;
106       case SeverityEnum.info:
107       default:
108         icon = 'info';
109     }
110
111     duration = (typeof duration === 'undefined')
112       ? this.duration
113       : (
114         typeof duration === 'string'
115           ? parseFloat(duration)
116           : duration
117       );
118
119     if (this.messageContainer === null) {
120       this.messageContainer = $('<div>', {'id': 'alert-container'}).appendTo('body');
121     }
122     const $box = $(
123       '<div class="alert alert-' + className + ' alert-dismissible fade" role="alert">' +
124         '<button type="button" class="close" data-dismiss="alert">' +
125           '<span aria-hidden="true"><i class="fa fa-times-circle"></i></span>' +
126           '<span class="sr-only">Close</span>' +
127         '</button>' +
128         '<div class="media">' +
129           '<div class="media-left">' +
130             '<span class="fa-stack fa-lg">' +
131               '<i class="fa fa-circle fa-stack-2x"></i>' +
132               '<i class="fa fa-' + icon + ' fa-stack-1x"></i>' +
133             '</span>' +
134           '</div>' +
135           '<div class="media-body">' +
136             '<h4 class="alert-title"></h4>' +
137             '<p class="alert-message text-pre-wrap"></p>' +
138           '</div>' +
139         '</div>' +
140       '</div>',
141     );
142     $box.find('.alert-title').text(title);
143     $box.find('.alert-message').text(message);
144     $box.on('close.bs.alert', (e: Event) => {
145       e.preventDefault();
146       const $me = $(e.currentTarget);
147       $me
148         .clearQueue()
149         .queue((next: any): void => {
150           $me.removeClass('in');
151           next();
152         })
153         .slideUp(() => {
154           $me.remove();
155         });
156     });
157     $box.appendTo(this.messageContainer);
158     $box.delay(200)
159       .queue((next: any): void => {
160         $box.addClass('in');
161         next();
162       });
163
164     if (duration > 0) {
165       // if duration > 0 dismiss alert
166       $box.delay(duration * 1000)
167         .queue((next: any): void => {
168           $box.alert('close');
169           next();
170         });
171     }
172   }
173 }
174
175 let notificationObject;
176
177 try {
178   // fetch from parent
179   if (parent && parent.window.TYPO3 && parent.window.TYPO3.Notification) {
180     notificationObject = parent.window.TYPO3.Notification;
181   }
182
183   // fetch object from outer frame
184   if (top && top.TYPO3.Notification) {
185     notificationObject = top.TYPO3.Notification;
186   }
187 } catch (e) {
188   // This only happens if the opener, parent or top is some other url (eg a local file)
189   // which loaded the current window. Then the browser's cross domain policy jumps in
190   // and raises an exception.
191   // For this case we are safe and we can create our global object below.
192 }
193
194 if (!notificationObject) {
195   notificationObject = Notification;
196
197   // attach to global frame
198   if (typeof TYPO3 !== 'undefined') {
199     TYPO3.Notification = notificationObject;
200   }
201 }
202 export = notificationObject;