notification badge

This commit is contained in:
insanity 2018-04-20 18:49:20 +09:00
parent 99425e1466
commit 1547cce9c8
10 changed files with 128 additions and 70 deletions

View File

@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { trigger, state, style, transition, animate } from '@angular/animations'; import { trigger, state, style, transition, animate } from '@angular/animations';
import { MenuItem } from 'primeng/primeng'; import { MenuItem } from 'primeng/primeng';
import { AppComponent } from 'app/app.component'; import { AppComponent } from 'app/app.component';
import { PagesComponent } from '../../../../pages/pages.component'; import { PagesComponent } from 'app/pages/pages.component';
@Component({ @Component({
selector: 'of-menu', selector: 'of-menu',

View File

@ -0,0 +1,11 @@
<li role="menuitem" *ngFor="let noti of notifications; let i = index" >
<a *ngIf="i < 5" href="javascript:void(0)" class="topbar-message" (click)="onNotiClick(noti)" [ngStyle]="noti.confirmDate ? '' : {'background-color': 'lightblue'}">
<span>{{noti.title}}</span>
<span>{{noti.message}}</span>
</a>
</li>
<li role="menuitem">
<a href="javascript:void(0)" class="topbar-message" (click)="onViewAllClick(noti)">
<span>View All</span>
</a>
</li>

View File

@ -0,0 +1,81 @@
import { Component, Injectable, OnInit, AfterContentInit, Output, EventEmitter } from '@angular/core';
import * as ListStore from 'packages/notification/store/list';
import * as DetailStore from 'packages/notification/store/detail';
import { Store, select } from '@ngrx/store';
import { ReadAllByMemberSelector, ReadSelector } from 'packages/notification/store';
import { Page, PageParams } from '../../../model';
import { RPCClientError } from '@loafer/ng-rpc/protocol';
import { AuthSelector } from 'packages/member/store';
import { Member } from 'packages/member/model';
import { PagesComponent } from 'app/pages/pages.component';
import { Notification } from 'packages/notification/model';
import { Router } from '@angular/router';
@Component({
selector: 'of-notification-menu',
templateUrl: './app.notification.component.html'
})
export class AppNotificationComponent implements OnInit, AfterContentInit {
notification$ = this.listStore.pipe(select(ReadAllByMemberSelector.select('page')));
notifications: Notification[];
@Output() notificationLoaded = new EventEmitter<number>();
constructor(
private router: Router,
private app: PagesComponent,
private listStore: Store<ListStore.State>,
private detailStore: Store<DetailStore.State>,
) {
}
ngOnInit() {
this.notification$.subscribe(
(page: Page) => {
if (page !== null) {
this.notifications = page.content;
this.getUnconfirmedCount();
}
},
(error: RPCClientError) => {
console.log(error.response.message);
}
);
}
ngAfterContentInit() {
this.listStore.select(AuthSelector.select('member')).subscribe(
(member: Member) => {
const pageParams: PageParams = {
pageNo: '0',
countPerPage: '10',
sortCol: 'id',
sortDirection: 'descending'
};
this.listStore.dispatch(new ListStore.ReadAllByMember({ member, pageParams }));
},
(error) => {
console.log(error);
}
);
}
getUnconfirmedCount() {
let totalCnt = 0;
for (let i = 0; i < 5; i ++) {
if (!this.notifications[i].confirmDate) {
totalCnt += 1;
}
}
this.notificationLoaded.emit(totalCnt);
}
onViewAllClick() {
this.router.navigate(['notification']);
}
noNotiClick() {
}
}

View File

@ -129,50 +129,21 @@
<li #messages [ngClass]="{'active-top-menu':app.activeTopbarItem === messages}"> <li #messages [ngClass]="{'active-top-menu':app.activeTopbarItem === messages}">
<a href="#" (click)="app.onTopbarItemClick($event,messages)"> <a href="#" (click)="app.onTopbarItemClick($event,messages)">
<i class="topbar-icon material-icons animated swing">message</i> <i class="topbar-icon material-icons animated swing">message</i>
<span class="topbar-badge animated rubberBand">5</span> <span class="topbar-badge animated rubberBand" *ngIf="notificationCount > 0">
{{notificationCount}}
</span>
<span class="topbar-item-name">Messages</span> <span class="topbar-item-name">Messages</span>
</a> </a>
<ul class="ultima-menu animated fadeInDown"> <ul class="ultima-menu animated fadeInDown">
<li role="menuitem" *ngFor="let noti of notis"> <of-notification-menu (notificationLoaded)="onNotiLoaded($event)"></of-notification-menu>
<a href="#" class="topbar-message">
<!-- <img src="assets/layout/images/avatar1.png" width="35" /> -->
<span>{{noti.title}}</span>
<span>{{noti.content}}</span>
</a>
</li>
<!-- <li role="menuitem"> <!-- <li role="menuitem">
<a href="#" class="topbar-message"> <a href="#" class="topbar-message">
<img src="assets/layout/images/avatar1.png" width="35" />
<span>Give me a call</span> <span>Give me a call</span>
</a> </a>
</li>
<li role="menuitem">
<a href="#" class="topbar-message">
<img src="assets/layout/images/avatar2.png" width="35" />
<span>Sales reports attached</span>
</a>
</li>
<li role="menuitem">
<a href="#" class="topbar-message">
<img src="assets/layout/images/avatar3.png" width="35" />
<span>About your invoice</span>
</a>
</li>
<li role="menuitem">
<a href="#" class="topbar-message">
<img src="assets/layout/images/avatar2.png" width="35" />
<span>Meeting today at 10pm</span>
</a>
</li>
<li role="menuitem">
<a href="#" class="topbar-message">
<img src="assets/layout/images/avatar4.png" width="35" />
<span>Out of office</span>
</a>
</li> --> </li> -->
</ul> </ul>
</li> </li>
<li #notifications [ngClass]="{'active-top-menu':app.activeTopbarItem === notifications}"> <!-- <li #notifications [ngClass]="{'active-top-menu':app.activeTopbarItem === notifications}">
<a href="#" (click)="app.onTopbarItemClick($event,notifications)"> <a href="#" (click)="app.onTopbarItemClick($event,notifications)">
<i class="topbar-icon material-icons">timer</i> <i class="topbar-icon material-icons">timer</i>
<span class="topbar-badge animated rubberBand">4</span> <span class="topbar-badge animated rubberBand">4</span>
@ -204,7 +175,7 @@
</a> </a>
</li> </li>
</ul> </ul>
</li> </li> -->
<li #search class="search-item" [ngClass]="{'active-top-menu':app.activeTopbarItem === search}" (click)="app.onTopbarItemClick($event,search)"> <li #search class="search-item" [ngClass]="{'active-top-menu':app.activeTopbarItem === search}" (click)="app.onTopbarItemClick($event,search)">
<span class="md-inputfield"> <span class="md-inputfield">
<input type="text" pInputText> <input type="text" pInputText>

View File

@ -1,32 +1,24 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { AppComponent } from 'app/app.component'; import { AppComponent } from 'app/app.component';
import { PagesComponent } from '../../../../pages/pages.component'; import { PagesComponent } from 'app/pages/pages.component';
import { AppNotificationComponent } from '../notification/app.notification.component';
@Component({ @Component({
selector: 'of-topbar', selector: 'of-topbar',
templateUrl: './app.topbar.component.html' templateUrl: './app.topbar.component.html',
}) })
export class AppTopbarComponent implements OnInit { export class AppTopbarComponent implements OnInit {
notis; notificationCount;
constructor(
constructor(public app: PagesComponent) { } public app: PagesComponent,
) { }
ngOnInit() { ngOnInit() {
this.notis = [
{
title: 'Notification 1',
content: 'Noti content11111111111111111111111111111111111111111111',
},
{
title: 'Notification 2',
content: 'Noti content22222222222',
},
{
title: 'Notification 3',
content: 'content3',
}
];
} }
onNotiLoaded(count) {
console.log('count changed');
this.notificationCount = count;
}
} }

View File

@ -19,6 +19,8 @@ import { PagesRoutingModule } from './pages-routing.module';
import { LocationStrategy, HashLocationStrategy } from '@angular/common'; import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { PrimeNGModules } from 'packages/commons/prime-ng/prime-ng.module'; import { PrimeNGModules } from 'packages/commons/prime-ng/prime-ng.module';
import { TabbarModule } from 'app/commons/component/layout/tabbar/app.tabbar.module'; import { TabbarModule } from 'app/commons/component/layout/tabbar/app.tabbar.module';
import { AppNotificationComponent } from '../commons/component/layout/notification/app.notification.component';
import { NotificationModule } from 'packages/notification/notification.module';
@NgModule({ @NgModule({
imports: [ imports: [
@ -26,7 +28,8 @@ import { TabbarModule } from 'app/commons/component/layout/tabbar/app.tabbar.mod
PagesRoutingModule, PagesRoutingModule,
LocalizationModule, LocalizationModule,
PrimeNGModules, PrimeNGModules,
TabbarModule TabbarModule,
NotificationModule
], ],
declarations: [ declarations: [
PagesComponent, PagesComponent,
@ -37,6 +40,7 @@ import { TabbarModule } from 'app/commons/component/layout/tabbar/app.tabbar.mod
AppBreadcrumbComponent, AppBreadcrumbComponent,
AppRightpanelComponent, AppRightpanelComponent,
AppInlineProfileComponent, AppInlineProfileComponent,
AppNotificationComponent
], ],
providers: [ providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy }, { provide: LocationStrategy, useClass: HashLocationStrategy },

View File

@ -1,3 +1,4 @@
<!-- <div class="toolbar-notification-container"> <!-- <div class="toolbar-notification-container">
<button mat-icon-button (click)="isOpen = !isOpen;" [ngClass]="[cssPrefix+'-btn']" [class.open]="isOpen"> <button mat-icon-button (click)="isOpen = !isOpen;" [ngClass]="[cssPrefix+'-btn']" [class.open]="isOpen">
<mat-icon>notifications_none</mat-icon> <mat-icon>notifications_none</mat-icon>

View File

@ -23,6 +23,7 @@ export class NotificationBadgeComponent implements OnInit, AfterContentInit {
notifications: Notification[] = null; notifications: Notification[] = null;
badgeCount = 0; badgeCount = 0;
constructor( constructor(
private router: Router, private router: Router,
private listStore: Store<ListStore.State>, private listStore: Store<ListStore.State>,

View File

@ -1,7 +1,5 @@
import { NotificationComponent } from './notification/notification.component'; import { NotificationComponent } from './notification/notification.component';
import { NotificationBadgeComponent } from './badge/notification.component';
export const COMPONENTS = [ export const COMPONENTS = [
NotificationComponent, NotificationComponent,
NotificationBadgeComponent,
]; ];

View File

@ -20,7 +20,7 @@ export class NotificationComponent implements OnInit, AfterContentInit {
notifications: Notification[]; notifications: Notification[];
readSuccess$ = this.detailStore.pipe(select(ReadSelector.select('notification'))); readSuccess$ = this.detailStore.pipe(select(ReadSelector.select('notification')));
pageSize = '12'; pageSize = '10';
totalLength = 0; totalLength = 0;
currPage = 0; currPage = 0;
@ -46,7 +46,7 @@ export class NotificationComponent implements OnInit, AfterContentInit {
this.readSuccess$.subscribe( this.readSuccess$.subscribe(
(noti: Notification) => { (noti: Notification) => {
if (noti) { if (noti) {
this.updateData(noti); this.getNotifications(this.currPage);
} }
}, },
(error: RPCClientError) => { (error: RPCClientError) => {
@ -59,16 +59,15 @@ export class NotificationComponent implements OnInit, AfterContentInit {
this.getNotifications(this.currPage); this.getNotifications(this.currPage);
} }
updateData(noti: Notification) { // updateData(noti: Notification) {
for (let i = 0; i < this.notifications.length; i++) { // for (let i = 0; i < this.notifications.length; i++) {
const exist = this.notifications[i]; // const exist = this.notifications[i];
if (exist.id === noti.id) { // if (exist.id === noti.id) {
this.notifications[i] = noti; // this.notifications[i] = noti;
return; // return;
} // }
} // }
// }
}
getNotifications(pageIndex: number) { getNotifications(pageIndex: number) {
this.listStore.select(AuthSelector.select('member')).subscribe( this.listStore.select(AuthSelector.select('member')).subscribe(