bootstrap style notification

This commit is contained in:
Andrea Chiapparelli - 4Science
2018-03-02 19:39:56 +01:00
parent cc615ac0bf
commit 2b8df1cc9d
10 changed files with 210 additions and 155 deletions

View File

@@ -14,6 +14,6 @@
<ng-template #example> <ng-template #example>
<p>Simple example</p> <p>Simple Error example</p>
<button [routerLink]="['/mydspace']">Go to mydspace</button> <button [routerLink]="['/mydspace']">Go to mydspace</button>
</ng-template> </ng-template>

View File

@@ -11,9 +11,10 @@ export class HomePageComponent {
public notificationOptions: Options = { public notificationOptions: Options = {
position: ['top', 'right'], position: ['top', 'right'],
timeOut: 0, timeOut: 0,
lastOnBottom: true, animate: 'fromLeft'
clickIconToClose: false, // lastOnBottom: true,
showProgressBar: true, // clickIconToClose: false,
// showProgressBar: true,
}; };
@ViewChild('example') example: TemplateRef<any>; @ViewChild('example') example: TemplateRef<any>;
@@ -24,11 +25,11 @@ export class HomePageComponent {
createNotification() { createNotification() {
const n1 = this.notificationsService.success('Welcome in DSpace', 'Good choice!', const n1 = this.notificationsService.success('Welcome in DSpace', 'Good choice!',
{ {
showProgressBar: false,
animate: 'rotate', animate: 'rotate',
timeout: 2000}); timeout: 2000});
const n2 = this.notificationsService.error('Error in DSpace', 'This is a fake error!'); const n2 = this.notificationsService.info('Info in DSpace', 'For your info...!');
const n3 = this.notificationsService.info(this.example); const n3 = this.notificationsService.warn('Warning in DSpace', 'This is a fake alert!');
const n4 = this.notificationsService.error(this.example);
console.log('Notifications pushed'); console.log('Notifications pushed');
console.log(n1); console.log(n1);
console.log(n2); console.log(n2);

View File

@@ -2,13 +2,11 @@
<div class="inner-wrapper"> <div class="inner-wrapper">
<ds-header></ds-header> <ds-header></ds-header>
<p>Inizio notifiche</p>
<ds-notifications-board <ds-notifications-board
[options]="notificationOptions" [options]="notificationOptions"
(onCreate)="notificationCreated($event)" (onCreate)="notificationCreated($event)"
(onDestroy)="notificationDestroyed($event)"> (onDestroy)="notificationDestroyed($event)">
</ds-notifications-board> </ds-notifications-board>
<p>Fine notifiche</p>
<main class="main-content"> <main class="main-content">
<router-outlet></router-outlet> <router-outlet></router-outlet>

View File

@@ -30,10 +30,11 @@ export class AppComponent implements OnInit {
public notificationOptions: Options = { public notificationOptions: Options = {
position: ['top', 'right'], position: ['top', 'right'],
timeOut: 5000, timeOut: 0,
lastOnBottom: true, animate: 'fromLeft'
clickIconToClose: true, // lastOnBottom: true,
showProgressBar: true // clickIconToClose: false,
// showProgressBar: true,
}; };
notificationCreated(event) { notificationCreated(event) {

View File

@@ -2,15 +2,15 @@ import {Icons} from './icons';
export interface Options { export interface Options {
timeOut?: number; timeOut?: number;
showProgressBar?: boolean; // showProgressBar?: boolean;
pauseOnHover?: boolean; // pauseOnHover?: boolean;
lastOnBottom?: boolean; // lastOnBottom?: boolean;
clickToClose?: boolean; // clickToClose?: boolean;
clickIconToClose?: boolean; // clickIconToClose?: boolean;
maxLength?: number; maxLength?: number;
maxStack?: number; maxStack?: number;
preventDuplicates?: boolean; // preventDuplicates?: boolean;
preventLastDuplicates?: boolean | string; // preventLastDuplicates?: boolean | string;
theClass?: string; theClass?: string;
rtl?: boolean; rtl?: boolean;
animate?: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale'; animate?: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale';

View File

@@ -1,13 +1,12 @@
<div class="simple-notification" <div class="alert" role="alert"
[@enterLeave]="item.state" [@enterLeave]="item.state"
(click)="onClick($event)" (click)="onClick($event)"
[class]="theClass" [class]="theClass"
[ngClass]="{ [ngClass]="{
'alert': item.type === 'alert', 'alert-info': item.type === 'info',
'error': item.type === 'error', 'alert-danger': item.type === 'error',
'warn': item.type === 'warn', 'alert-warning': item.type === 'warn',
'success': item.type === 'success', 'alert-success': item.type === 'success',
'info': item.type === 'info',
'bare': item.type === 'bare', 'bare': item.type === 'bare',
'rtl-mode': rtl, 'rtl-mode': rtl,
'has-icon': item.icon !== 'bare' 'has-icon': item.icon !== 'bare'
@@ -33,7 +32,16 @@
<div class="sn-content" [innerHTML]="content"></div> <div class="sn-content" [innerHTML]="content"></div>
</ng-template> </ng-template>
<div class="icon" *ngIf="item.icon !== 'bare'" [innerHTML]="safeSvg"></div> <!--<div class="icon" *ngIf="item.icon !== 'bare'" [innerHTML]="safeSvg"></div>-->
{{icon}}
<div class="icon"><i
[ngClass]="{'fa': true,
'fa-check': icon == 'success',
'fa-times-circle': icon == 'error',
'fa-exclamation-triangle': icon == 'warn',
'fa-info': icon == 'info'
}"></i></div>
</div> </div>
<div *ngIf="item.html"> <div *ngIf="item.html">
<div class="sn-html" *ngIf="htmlIsTemplate; else regularHtml"> <div class="sn-html" *ngIf="htmlIsTemplate; else regularHtml">
@@ -44,11 +52,21 @@
<div class="sn-content" [innerHTML]="item.html"></div> <div class="sn-content" [innerHTML]="item.html"></div>
</ng-template> </ng-template>
<div class="icon" [class.icon-hover]="clickIconToClose" *ngIf="item.icon" [innerHTML]="safeSvg" (click)="onClickIcon($event)"></div> <!--<div class="icon" [class.icon-hover]="clickIconToClose" *ngIf="item.icon" [innerHTML]="safeSvg" (click)="onClickIcon($event)"></div>-->
{{icon}}
<div class="icon"><i
[ngClass]="{'fa': true,
'fa-check': icon == 'success',
'fa-times-circle': icon == 'error',
'fa-exclamation-triangle': icon == 'warning',
'fa-info': icon == 'info'
}"></i></div>
</div> </div>
<div class="sn-progress-loader" *ngIf="showProgressBar"> <div class="sn-progress-loader" *ngIf="showProgressBar">
<span [ngStyle]="{'width': progressWidth + '%'}"></span> <span [ngStyle]="{'width': progressWidth + '%'}"></span>
</div> </div>
<div class="close"><i class="fa fa-times" (click)="remove()"></i></div>
</div> </div>

View File

@@ -1,80 +1,80 @@
.simple-notification { //.simple-notification {
width: 100%; // width: 100%;
padding: 10px 20px; // padding: 10px 20px;
box-sizing: border-box; // box-sizing: border-box;
position: relative; // position: relative;
float: left; // float: left;
margin-bottom: 10px; // margin-bottom: 10px;
color: #fff; // color: #fff;
cursor: pointer; // cursor: pointer;
transition: all 0.5s; // transition: all 0.5s;
min-height: 70px; // min-height: 70px;
} //}
//
.simple-notification .sn-title, //.simple-notification .sn-title,
.simple-notification .sn-content, //.simple-notification .sn-content,
.simple-notification .sn-html { //.simple-notification .sn-html {
margin: 0; // margin: 0;
} //}
//
.simple-notification .sn-title { //.simple-notification .sn-title {
line-height: 30px; // line-height: 30px;
font-size: 20px; // font-size: 20px;
} //}
//
.simple-notification .sn-content { //.simple-notification .sn-content {
font-size: 16px; // font-size: 16px;
line-height: 20px; // line-height: 20px;
} //}
//
.simple-notification.has-icon .sn-title, //.simple-notification.has-icon .sn-title,
.simple-notification.has-icon .sn-content, //.simple-notification.has-icon .sn-content,
.simple-notification.has-icon .sn-html { //.simple-notification.has-icon .sn-html {
padding: 0 50px 0 0; // padding: 0 50px 0 0;
} //}
//
.simple-notification .icon { //.simple-notification {
position: absolute; // position: absolute;
box-sizing: border-box; // box-sizing: border-box;
top: 0; // top: 0;
right: 0; // right: 0;
width: 70px; // width: 70px;
height: 70px; // height: 70px;
padding: 10px; // padding: 10px;
} //}
//
.simple-notification .icon.icon-hover:hover { //.simple-notification .icon.icon-hover:hover {
opacity: 0.5; // opacity: 0.5;
} //}
//
.simple-notification .icon svg { //.simple-notification .icon svg {
fill: #fff; // fill: #fff;
width: 100%; // width: 100%;
height: 100%; // height: 100%;
} //}
//
.simple-notification .icon svg g { //.simple-notification .icon svg g {
fill: #fff; // fill: #fff;
} //}
//
.simple-notification.rtl-mode.has-icon .sn-title, //.simple-notification.rtl-mode.has-icon .sn-title,
.simple-notification.rtl-mode.has-icon .sn-content, //.simple-notification.rtl-mode.has-icon .sn-content,
.simple-notification.rtl-mode.has-icon .sn-html { //.simple-notification.rtl-mode.has-icon .sn-html {
padding: 0 0 0 50px; // padding: 0 0 0 50px;
} //}
//
.simple-notification.rtl-mode { //.simple-notification.rtl-mode {
direction: rtl; // direction: rtl;
} //}
//
.simple-notification.rtl-mode .sn-content { //.simple-notification.rtl-mode .sn-content {
padding: 0 0 0 50px; // padding: 0 0 0 50px;
} //}
//
.simple-notification.rtl-mode svg { //.simple-notification.rtl-mode svg {
left: 0; // left: 0;
right: auto; // right: auto;
} //}
.simple-notification.error { background: #F44336; } .simple-notification.error { background: #F44336; }
.simple-notification.success { background: #8BC34A; } .simple-notification.success { background: #8BC34A; }
@@ -82,18 +82,18 @@
.simple-notification.info { background: #03A9F4; } .simple-notification.info { background: #03A9F4; }
.simple-notification.warn { background: #ffdb5b; } .simple-notification.warn { background: #ffdb5b; }
.simple-notification .sn-progress-loader { //.simple-notification .sn-progress-loader {
position: absolute; // position: absolute;
top: 0; // top: 0;
left: 0; // left: 0;
width: 100%; // width: 100%;
height: 5px; // height: 5px;
} //}
//
.simple-notification .sn-progress-loader span { //.simple-notification .sn-progress-loader span {
float: left; // float: left;
height: 100%; // height: 100%;
} //}
.simple-notification.success .sn-progress-loader span { background: #689F38; } .simple-notification.success .sn-progress-loader span { background: #689F38; }
.simple-notification.error .sn-progress-loader span { background: #D32F2F; } .simple-notification.error .sn-progress-loader span { background: #D32F2F; }
@@ -102,6 +102,42 @@
.simple-notification.warn .sn-progress-loader span { background: #edc242; } .simple-notification.warn .sn-progress-loader span { background: #edc242; }
.simple-notification.bare .sn-progress-loader span { background: #ccc; } .simple-notification.bare .sn-progress-loader span { background: #ccc; }
.simple-notification.warn div .sn-title, //.simple-notification.warn div .sn-title,
.simple-notification.warn div .sn-content, //.simple-notification.warn div .sn-content,
.simple-notification.warn div .sn-html { color: #444; } //.simple-notification.warn div .sn-html { color: #444; }
.close {
position: absolute;
top: 5px;
right: 5px;
}
.icon {
position: absolute;
top: 5px;
left: 5px;
color: black;
}
//
//.icon > fa-times-circle {
// color: red;
//}
//
//.icon > fa-exclamation-triangle {
// color: orange;
//}
//
//.icon > fa-info {
// color: white;
//}
//
//.icon > fa-check {
// color: forestgreen;
//}
.sn-title, .sn-content, .sn-html {
position: relative;
left: 20px;
}

View File

@@ -113,12 +113,12 @@ import { NotificationsService } from '../notifications.service';
export class NotificationComponent implements OnInit, OnDestroy { export class NotificationComponent implements OnInit, OnDestroy {
@Input() public timeOut: number; @Input() public timeOut: number;
@Input() public showProgressBar: boolean; // @Input() public showProgressBar: boolean;
@Input() public pauseOnHover: boolean; // @Input() public pauseOnHover: boolean;
@Input() public clickToClose: boolean; // @Input() public clickToClose: boolean;
@Input() public clickIconToClose: boolean; // @Input() public clickIconToClose: boolean;
@Input() public maxLength: number; // @Input() public maxLength: number;
@Input() public theClass: string; // @Input() public theClass: string;
@Input() public rtl: boolean; @Input() public rtl: boolean;
@Input() public animate: string; @Input() public animate: string;
@Input() public position: number; @Input() public position: number;
@@ -179,32 +179,32 @@ export class NotificationComponent implements OnInit, OnDestroy {
} }
onEnter(): void { onEnter(): void {
if (this.pauseOnHover) { // if (this.pauseOnHover) {
this.stopTime = true; // this.stopTime = true;
} // }
} }
onLeave(): void { onLeave(): void {
if (this.pauseOnHover) { // if (this.pauseOnHover) {
this.stopTime = false; // this.stopTime = false;
this.zone.runOutsideAngular(() => setTimeout(this.instance, (this.speed - this.diff))); // this.zone.runOutsideAngular(() => setTimeout(this.instance, (this.speed - this.diff)));
} // }
} }
onClick($e: MouseEvent): void { onClick($e: MouseEvent): void {
this.item.click!.emit($e); this.item.click!.emit($e);
if (this.clickToClose) { // if (this.clickToClose) {
this.remove(); // this.remove();
} // }
} }
onClickIcon($e: MouseEvent): void { onClickIcon($e: MouseEvent): void {
this.item.clickIcon!.emit($e); this.item.clickIcon!.emit($e);
if (this.clickIconToClose) { // if (this.clickIconToClose) {
this.remove(); // this.remove();
} // }
} }
// Attach all the overrides // Attach all the overrides
@@ -227,9 +227,9 @@ export class NotificationComponent implements OnInit, OnDestroy {
this.remove(); this.remove();
this.item.timeoutEnd!.emit(); this.item.timeoutEnd!.emit();
} else if (!this.stopTime) { } else if (!this.stopTime) {
if (this.showProgressBar) { // if (this.showProgressBar) {
this.progressWidth += 100 / this.steps; // this.progressWidth += 100 / this.steps;
} // }
this.timer = setTimeout(this.instance, (this.speed - this.diff)); this.timer = setTimeout(this.instance, (this.speed - this.diff));
} }

View File

@@ -3,14 +3,15 @@
*ngFor="let a of notifications; let i = index" *ngFor="let a of notifications; let i = index"
[item]="a" [item]="a"
[timeOut]="timeOut" [timeOut]="timeOut"
[clickToClose]="clickToClose"
[clickIconToClose]="clickIconToClose"
[maxLength]="maxLength"
[showProgressBar]="showProgressBar"
[pauseOnHover]="pauseOnHover"
[theClass]="theClass"
[rtl]="rtl" [rtl]="rtl"
[animate]="animate" [animate]="animate"
[position]="i"> [position]="i">
<!--[clickToClose]="clickToClose"-->
<!--[clickIconToClose]="clickIconToClose"-->
<!--[maxLength]="maxLength"-->
<!--[showProgressBar]="showProgressBar"-->
<!--[pauseOnHover]="pauseOnHover"-->
<!--[theClass]="theClass"-->
</ds-notification> </ds-notification>
</div> </div>

View File

@@ -37,12 +37,12 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy {
// Sent values // Sent values
public timeOut = 0; public timeOut = 0;
public maxLength = 0; // public maxLength = 0;
public clickToClose = true; // public clickToClose = true;
public clickIconToClose = false; // public clickIconToClose = false;
public showProgressBar = true; // public showProgressBar = true;
public pauseOnHover = true; // public pauseOnHover = true;
public theClass = ''; // public theClass = '';
public rtl = false; public rtl = false;
public animate: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale' = 'fromRight'; public animate: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale' = 'fromRight';
@@ -54,7 +54,7 @@ export class NotificationsBoardComponent implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
// Listen for changes in the service // Listen for changes in the service
this.listener = this.service.emitter this.listener = this.service.emitter
.subscribe((item) => { .subscribe((item) => { // Subscribe a stato di redux
switch (item.command) { switch (item.command) {
case 'cleanAll': case 'cleanAll':
this.notifications = []; this.notifications = [];