Added notifications state

This commit is contained in:
Giuseppe Digilio
2018-03-02 19:26:24 +01:00
parent 8c555292ac
commit cc615ac0bf
8 changed files with 254 additions and 30 deletions

View File

@@ -1,8 +1,10 @@
import { HeaderEffects } from './header/header.effects'; import { HeaderEffects } from './header/header.effects';
import { StoreEffects } from './store.effects'; import { StoreEffects } from './store.effects';
import { NotificationsEffects } from './shared/notifications/notifications.effects';
export const appEffects = [ export const appEffects = [
StoreEffects, StoreEffects,
HeaderEffects HeaderEffects,
NotificationsEffects
]; ];

View File

@@ -11,11 +11,13 @@ import {
filterReducer, filterReducer,
SearchFiltersState SearchFiltersState
} from './+search-page/search-filters/search-filter/search-filter.reducer'; } from './+search-page/search-filters/search-filter/search-filter.reducer';
import { notificationsReducer, NotificationsState } from './shared/notifications/notifications.reducers';
export interface AppState { export interface AppState {
router: fromRouter.RouterReducerState; router: fromRouter.RouterReducerState;
hostWindow: HostWindowState; hostWindow: HostWindowState;
header: HeaderState; header: HeaderState;
notifications: NotificationsState;
searchSidebar: SearchSidebarState; searchSidebar: SearchSidebarState;
searchFilter: SearchFiltersState; searchFilter: SearchFiltersState;
} }
@@ -24,6 +26,7 @@ export const appReducers: ActionReducerMap<AppState> = {
router: fromRouter.routerReducer, router: fromRouter.routerReducer,
hostWindow: hostWindowReducer, hostWindow: hostWindowReducer,
header: headerReducer, header: headerReducer,
notifications: notificationsReducer,
searchSidebar: sidebarReducer, searchSidebar: sidebarReducer,
searchFilter: filterReducer searchFilter: filterReducer
}; };

View File

@@ -0,0 +1,28 @@
export interface INotificationOptions {
timeOut: number;
clickToClose: boolean;
rtl: boolean;
animate: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale';
position: ['top' | 'bottom' | 'middle', 'right' | 'left' | 'center'];
}
export class NotificationOptions implements INotificationOptions {
public timeOut: number;
public clickToClose: boolean;
public rtl: boolean;
public animate: any;
public position: any;
constructor(timeOut = 0,
clickToClose = true,
animate = 'scale',
position = ['top' , 'right'],
rtl = false) {
this.timeOut = timeOut;
this.clickToClose = clickToClose;
this.animate = animate;
this.position = position;
this.rtl = rtl;
}
}

View File

@@ -0,0 +1,8 @@
export enum NotificationType {
Success = 'success',
Error = 'error',
Alert = 'alert',
Info = 'info',
Warning = 'warn',
Bare = 'bare'
}

View File

@@ -0,0 +1,32 @@
import { INotificationOptions, NotificationOptions } from './notification-options.model';
import { NotificationType } from './notification-type';
import { isEmpty } from '../../empty.util';
export interface INotification {
id: string
type: NotificationType
title?: any
content?: any
options?: INotificationOptions
}
export class Notification implements INotification {
public id: string;
public type: NotificationType;
public title: any;
public content: any;
public options: INotificationOptions;
constructor(id: string,
type: NotificationType,
title?: any,
content?: any,
options?: INotificationOptions) {
this.id = id;
this.type = type;
this.title = title;
this.content = content;
this.options = isEmpty(options) ? new NotificationOptions() : options;
}
}

View File

@@ -0,0 +1,66 @@
// import @ngrx
import { Action } from '@ngrx/store';
// import type function
import { type } from '../../shared/ngrx/type';
// import models
import { Notification } from './models/notification.model';
export const NotificationsActionTypes = {
NEW_NOTIFICATION: type('dspace/notifications/NEW_NOTIFICATION'),
NEW_NOTIFICATION_WITH_TIMER: type('dspace/notifications/NEW_NOTIFICATION_WITH_TIMER'),
REMOVE_NOTIFICATION: type('dspace/notifications/REMOVE_NOTIFICATION'),
};
/* tslint:disable:max-classes-per-file */
/**
* New notification.
* @class NewNotificationAction
* @implements {Action}
*/
export class NewNotificationAction implements Action {
public type: string = NotificationsActionTypes.NEW_NOTIFICATION;
payload: Notification;
constructor(notification: Notification) {
this.payload = notification;
}
}
/**
* New notification.
* @class NewNotificationAction
* @implements {Action}
*/
export class NewNotificationWithTimerAction implements Action {
public type: string = NotificationsActionTypes.NEW_NOTIFICATION_WITH_TIMER;
payload: Notification;
constructor(notification: Notification) {
this.payload = notification;
}
}
/**
* New notification.
* @class NewNotificationAction
* @implements {Action}
*/
export class RemoveNotificationAction implements Action {
public type: string = NotificationsActionTypes.REMOVE_NOTIFICATION;
constructor(public payload?: any) { }
}
/* tslint:enable:max-classes-per-file */
/**
* Actions type.
* @type {NotificationsActions}
*/
export type NotificationsActions
= NewNotificationAction
| NewNotificationWithTimerAction
| RemoveNotificationAction;

View File

@@ -0,0 +1,46 @@
import { Injectable } from '@angular/core';
// import @ngrx
import { Effect, Actions } from '@ngrx/effects';
import { Action, Store } from '@ngrx/store';
// import rxjs
import { Observable } from 'rxjs/Observable';
// import services
// import actions
import { AppState } from '../../app.reducer';
import {
NewNotificationWithTimerAction, NotificationsActionTypes,
RemoveNotificationAction
} from './notifications.actions';
@Injectable()
export class NotificationsEffects {
/**
* Authenticate user.
* @method authenticate
*/
@Effect()
public timer: Observable<Action> = this.actions$
.ofType(NotificationsActionTypes.NEW_NOTIFICATION_WITH_TIMER)
.debounceTime((action) => action.payload.options.timeOut)
.map(() => new RemoveNotificationAction());
/* .switchMap((action: NewNotificationWithTimerAction) => Observable
.timer(30000)
.mapTo(() => new RemoveNotificationAction())
);*/
/**
* @constructor
* @param {Actions} actions$
* @param {AuthService} authService
* @param {Store} store
*/
constructor(private actions$: Actions,
private store: Store<AppState>) {
}
}

View File

@@ -0,0 +1,39 @@
// import actions
import { NotificationsActions, NotificationsActionTypes } from './notifications.actions';
// import models
import { INotification } from './models/notification.model';
/**
* The auth state.
* @interface State
*/
export interface NotificationsState {
[index: number]: INotification;
}
/**
* The initial state.
*/
const initialState: NotificationsState = [];
/**
* The reducer function.
* @function reducer
* @param {State} state Current state
* @param {NotificationsActions} action Incoming action
*/
export function notificationsReducer(state: any = initialState, action: NotificationsActions): NotificationsState {
switch (action.type) {
case NotificationsActionTypes.NEW_NOTIFICATION:
case NotificationsActionTypes.NEW_NOTIFICATION_WITH_TIMER:
return [...state, action.payload];
case NotificationsActionTypes.REMOVE_NOTIFICATION:
return [];
default:
return state;
}
}