diff --git a/projects/common/src/fm/actions/app-common.actions.ts b/projects/common/src/fm/actions/app-common.actions.ts
index 2407bd0..b37ed99 100644
--- a/projects/common/src/fm/actions/app-common.actions.ts
+++ b/projects/common/src/fm/actions/app-common.actions.ts
@@ -39,6 +39,8 @@ export const TASKPROGRESSEVENT = '[AppCommon] TaskProgressEvent';
export const DEVICEUPDATEEVENT = '[AppCommon] DeviceUpdateEvent';
+export const NOTIFICATIONEVENT = '[AppCommon] NotificationEvent';
+
export const DELETEITEMS = '[AppCommon] DeleteItems';
export const DELETEITEMSSUCCESS = '[AppCommon] DeleteItemsSuccess';
@@ -62,6 +64,8 @@ export const TOGGLEACCOUNTMENU = '[AppCommon] ToggleAccountMenu';
export const TOGGLEAPPMENU = '[AppCommon] ToggleAppMenu';
+export const TOGGLENOTIFICATIONMENU = '[AppCommon] ToggleNotificationMenu';
+
export const SETMENUVISIBLE = '[AppCommon] SetMenuVisible';
export const ONLINE = '[AppCommon] Online';
@@ -232,6 +236,12 @@ export class DeviceUpdateEvent implements Action {
constructor(public itemCode: string, public attributes: any) { }
}
+export class NotificationEvent implements Action {
+ readonly type = NOTIFICATIONEVENT;
+
+ constructor(public attributes: any) { }
+}
+
export class DeleteItems implements Action {
readonly type = DELETEITEMS;
@@ -291,6 +301,12 @@ export class ToggleAppMenu implements Action {
constructor() { }
}
+export class ToggleNotificationMenu implements Action {
+ readonly type = TOGGLENOTIFICATIONMENU;
+
+ constructor() { }
+}
+
export class SetMenuVisible implements Action {
readonly type = SETMENUVISIBLE;
@@ -355,6 +371,8 @@ export type Actions = OpenModal
| Online
| Offline
| SetPageMode
- | ToggleAppMenu;
+ | ToggleAppMenu
+ | ToggleNotificationMenu
+ | NotificationEvent;
diff --git a/projects/common/src/fm/common.module.ts b/projects/common/src/fm/common.module.ts
index 9e8b720..6076215 100644
--- a/projects/common/src/fm/common.module.ts
+++ b/projects/common/src/fm/common.module.ts
@@ -56,6 +56,7 @@ import { SecureOAuthStorage} from './shared/secureOAuthStorage';
import { GradientComponent } from './components/gradient/gradient.component';
import { GradientSelectComponent } from './components/gradient-select/gradient-select.component';
import { AppMenuComponent } from './components/app-menu/app-menu.component';
+import { NotificationMenuComponent} from './components/notification-menu/notification-menu.component';
import { BackButtonComponent } from './components/back-button/back-button.component';
export {
@@ -131,6 +132,7 @@ export {
GradientComponent,
GradientSelectComponent,
AppMenuComponent,
+ NotificationMenuComponent,
BackButtonComponent
],
exports: [
diff --git a/projects/common/src/fm/components/app/app.component.html b/projects/common/src/fm/components/app/app.component.html
index 71c79e2..e9823ba 100644
--- a/projects/common/src/fm/components/app/app.component.html
+++ b/projects/common/src/fm/components/app/app.component.html
@@ -31,6 +31,7 @@
diff --git a/projects/common/src/fm/components/app/app.component.scss b/projects/common/src/fm/components/app/app.component.scss
index b3c08b2..3735e89 100644
--- a/projects/common/src/fm/components/app/app.component.scss
+++ b/projects/common/src/fm/components/app/app.component.scss
@@ -125,7 +125,7 @@ body { background: #f1f1f1; line-height: 18px; user-select:none;font-family: Lat
max-height:0em;
}
-fm-app-menu,fm-user-menu {
+fm-app-menu,fm-user-menu,fm-notification-menu {
display: inline-block;
margin-left: 1rem;
}
diff --git a/projects/common/src/fm/components/app/app.component.ts b/projects/common/src/fm/components/app/app.component.ts
index f11fbff..71dbb9d 100644
--- a/projects/common/src/fm/components/app/app.component.ts
+++ b/projects/common/src/fm/components/app/app.component.ts
@@ -43,6 +43,8 @@ export class AppComponent implements OnInit, OnDestroy {
public menuVisible: Observable = this.store$.select(appReducers.SelectGetMenuVisible);
public accountMenuVisible: Observable = this.store$.select(appReducers.SelectGetAccountMenuVisible);
public appMenuVisible: Observable = this.store$.select(appReducers.SelectGetAppMenuVisible);
+ public notificationMenuVisible: Observable = this.store$.select(appReducers.SelectGetNotificationMenuVisible);
+ public unreadNotifications: Observable = this.store$.select(appReducers.SelectgetUnreadNotifications);
public user: Observable = this.store$.select(appReducers.SelectGetUser);
public isPageMode: Observable = this.store$.select(appReducers.SelectGetIsPageMode);
@Input() showUploadProgress: boolean = true;
@@ -98,6 +100,10 @@ export class AppComponent implements OnInit, OnDestroy {
action = new commonActions.DeviceUpdateEvent(event.itemCode, event.attributes);
break;
}
+ case "notification": {
+ action = new commonActions.NotificationEvent(event.attributes);
+ break;
+ }
}
return action;
}
diff --git a/projects/common/src/fm/components/notification-menu/notification-menu.component.html b/projects/common/src/fm/components/notification-menu/notification-menu.component.html
new file mode 100644
index 0000000..fab5e66
--- /dev/null
+++ b/projects/common/src/fm/components/notification-menu/notification-menu.component.html
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/projects/common/src/fm/components/notification-menu/notification-menu.component.scss b/projects/common/src/fm/components/notification-menu/notification-menu.component.scss
new file mode 100644
index 0000000..6d4d098
--- /dev/null
+++ b/projects/common/src/fm/components/notification-menu/notification-menu.component.scss
@@ -0,0 +1,80 @@
+.menu-button {
+ background-color: gray;
+ display: inline-block;
+ width: 2.5em;
+ height: 2.5em;
+ line-height: 2.5em;
+ text-align: center;
+ font-size: 1rem;
+ position: relative;
+}
+
+div.menu-button > span {
+ color:white;
+}
+
+.menu {
+ max-height: calc( 100vh - 4rem);
+ //transition: max-height 0.2s;
+ overflow: hidden;
+ box-shadow: 0 0 20px rgba(0,0,0,.3);
+ position: fixed;
+ top: 3.4rem;
+ right:0.5rem;
+ left:0.5rem;
+ background-color: #fff;
+ border-radius: 0.25rem;
+ padding: 0.5rem;
+ z-index: 3;
+}
+
+:host-context(.fullscreen) .menu {
+ top:4em;
+}
+
+.card {
+ padding:0.5rem;
+ min-width: 10rem;
+}
+
+.card-body {
+ text-align: left;
+}
+
+.hidden {
+ max-height: 0;
+}
+
+.menu.hidden {
+ padding: 0;
+}
+
+.menu-button.hidden {
+ overflow: hidden;
+}
+
+
+@media screen and (min-width: 44rem) {
+ .menu {
+ position: absolute;
+ top: 3rem;
+ right:0;
+ left: unset;
+ max-width: 30em;
+ }
+
+ :host-context(.fullscreen) .menu {
+ top: 3rem;
+ }
+}
+
+.unread {
+ display: block;
+ position: absolute;
+ top:-0.5em;
+ right: -0.5em;
+}
+
+.unread.hidden {
+ display: none;
+}
\ No newline at end of file
diff --git a/projects/common/src/fm/components/notification-menu/notification-menu.component.spec.ts b/projects/common/src/fm/components/notification-menu/notification-menu.component.spec.ts
new file mode 100644
index 0000000..b12d608
--- /dev/null
+++ b/projects/common/src/fm/components/notification-menu/notification-menu.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NotificationMenuComponent } from './notification-menu.component';
+
+describe('NotificationMenuComponent', () => {
+ let component: NotificationMenuComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ NotificationMenuComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NotificationMenuComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/projects/common/src/fm/components/notification-menu/notification-menu.component.ts b/projects/common/src/fm/components/notification-menu/notification-menu.component.ts
new file mode 100644
index 0000000..c1b2ace
--- /dev/null
+++ b/projects/common/src/fm/components/notification-menu/notification-menu.component.ts
@@ -0,0 +1,30 @@
+import { Component, OnInit, Input } from '@angular/core';
+
+
+import { IUser } from '../../models/user';
+import {Store} from '@ngrx/store';
+import * as appReducers from '../../reducers/app-common.reducer';
+import * as appActions from '../../actions/app-common.actions';
+
+@Component({
+ selector: 'fm-notification-menu',
+ templateUrl: './notification-menu.component.html',
+ styleUrls: ['./notification-menu.component.scss']
+})
+export class NotificationMenuComponent implements OnInit {
+
+ @Input() unread:number;
+ @Input() user:IUser;
+ @Input() showMenu:boolean;
+
+ constructor(private store: Store) { }
+
+ ngOnInit(): void {
+ }
+
+ toggle(event:MouseEvent) {
+ event.stopPropagation();
+ this.store.dispatch(new appActions.ToggleNotificationMenu());
+ }
+
+}
diff --git a/projects/common/src/fm/reducers/app-common.reducer.ts b/projects/common/src/fm/reducers/app-common.reducer.ts
index b554b5c..5db7304 100644
--- a/projects/common/src/fm/reducers/app-common.reducer.ts
+++ b/projects/common/src/fm/reducers/app-common.reducer.ts
@@ -22,6 +22,8 @@ export interface State {
userSettingsRoot: IItem,
accountMenuVisible: boolean,
appMenuVisible: boolean,
+ notificationMenuVisible: boolean,
+ unreadNotifications: number,
isOnline: boolean,
isPageMode:boolean
}
@@ -39,6 +41,8 @@ export const initialState: State = {
userSettingsRoot: null,
accountMenuVisible: false,
appMenuVisible: false,
+ notificationMenuVisible: false,
+ unreadNotifications: 0,
isOnline: true,
isPageMode: true
}
@@ -98,20 +102,23 @@ export function reducer(state = initialState, action: appCommonActions.Actions )
});
}
case appCommonActions.TOGGLEMENU: {
- return tassign(state, { menuVisible: !state.menuVisible,accountMenuVisible:!state.menuVisible?false:state.accountMenuVisible,appMenuVisible:!state.menuVisible?false:state.appMenuVisible });
+ return tassign(state, { menuVisible: !state.menuVisible,accountMenuVisible:!state.menuVisible?false:state.accountMenuVisible,appMenuVisible:!state.menuVisible?false:state.appMenuVisible,notificationMenuVisible:!state.menuVisible?false:state.notificationMenuVisible });
}
case appCommonActions.TOGGLEACCOUNTMENU: {
- return tassign(state, { accountMenuVisible: !state.accountMenuVisible,appMenuVisible:false });
+ return tassign(state, { accountMenuVisible: !state.accountMenuVisible,appMenuVisible:false,notificationMenuVisible:false });
}
case appCommonActions.TOGGLEAPPMENU: {
- return tassign(state, { appMenuVisible: !state.appMenuVisible,accountMenuVisible:false });
+ return tassign(state, { appMenuVisible: !state.appMenuVisible,accountMenuVisible:false,notificationMenuVisible:false });
+ }
+ case appCommonActions.TOGGLENOTIFICATIONMENU: {
+ return tassign(state, { notificationMenuVisible : !state.notificationMenuVisible,accountMenuVisible:false,appMenuVisible:false });
}
case appCommonActions.ESCAPE: {
- return tassign(state, { menuVisible: false,accountMenuVisible:false,appMenuVisible: false });
+ return tassign(state, { menuVisible: false,accountMenuVisible:false,appMenuVisible: false,notificationMenuVisible:false });
}
case appCommonActions.SETMENUVISIBLE: {
let a = action as appCommonActions.SetMenuVisible;
- return tassign(state, { menuVisible: a.visible,accountMenuVisible:a.visible?false:state.accountMenuVisible,appMenuVisible:a.visible?false:state.appMenuVisible });
+ return tassign(state, { menuVisible: a.visible,accountMenuVisible:a.visible?false:state.accountMenuVisible,appMenuVisible:a.visible?false:state.appMenuVisible,notificationMenuVisible:a.visible?false:state.notificationMenuVisible });
}
case appCommonActions.INITUSERPACKAGESSUCCESS:{
let a = action as appCommonActions.InitUserPackagesSuccess;
@@ -144,6 +151,14 @@ export function reducer(state = initialState, action: appCommonActions.Actions )
let a = action as appCommonActions.SetPageMode;
return tassign(state,{isPageMode:a.pageMode});
}
+ case appCommonActions.NOTIFICATIONEVENT: {
+ let a = action as appCommonActions.NotificationEvent;
+ let unread = 0;
+ if(a.attributes["unread"]) {
+ unread = parseInt(a.attributes["unread"]);
+ }
+ return tassign(state,{unreadNotifications:unread});
+ }
default: {
return state;
}
@@ -162,6 +177,8 @@ export const getUserPackages = (state: State) => state.userPackages;
export const getUserSettingsRoot = (state: State) => state.userSettingsRoot;
export const getAccountMenuVisible = (state: State) => state.accountMenuVisible;
export const getAppMenuVisible = (state: State) => state.appMenuVisible;
+export const getNotificationMenuVisible = (state: State) => state.notificationMenuVisible;
+export const getUnreadNotifications = (state: State) => state.unreadNotifications;
export const getIsOnline = (state: State) => state.isOnline;
export const getIsPageMode = (state: State) => state.isPageMode;
@@ -179,6 +196,9 @@ export const SelectGetUserPackages = createSelector(selectAppCommonState,getUser
export const SelectGetUserSettingsRoot = createSelector(selectAppCommonState,getUserSettingsRoot);
export const SelectGetAccountMenuVisible = createSelector(selectAppCommonState,getAccountMenuVisible);
export const SelectGetAppMenuVisible = createSelector(selectAppCommonState,getAppMenuVisible);
+export const SelectGetNotificationMenuVisible = createSelector(selectAppCommonState,getNotificationMenuVisible);
+export const SelectgetUnreadNotifications = createSelector(selectAppCommonState,getUnreadNotifications);
+
export const SelectGetIsOnline = createSelector(selectAppCommonState,getIsOnline);
export const SelectGetIsPageMode = createSelector(selectAppCommonState,getIsPageMode);