notification
This commit is contained in:
parent
b6a028c6d8
commit
481c602f61
|
@ -45,6 +45,7 @@ import HistoryReadAllByProbeReducer from '@overflow/history/redux/reducer/read_a
|
|||
import HistoryReadAllByProbeAndTypeReducer from '@overflow/history/redux/reducer/read_all_by_probe_and_type';
|
||||
import HistoryTypeReadAllReducer from '@overflow/meta/redux/reducer/history_type_read_all';
|
||||
import NotificationReadAllUnconfirmedReducer from '@overflow/notification/redux/reducer/read_all_unconfirmed';
|
||||
import NotificationReadAllReducer from '@overflow/notification/redux/reducer/read_all';
|
||||
|
||||
|
||||
import AsyncRequest from '@overflow/app/redux/saga/AsyncRequest';
|
||||
|
@ -115,6 +116,7 @@ const reduxConfig: ReduxConfig = {
|
|||
HistoryTypeReadAllReducer,
|
||||
SensorRegistSensorConfigReducer,
|
||||
NotificationReadAllUnconfirmedReducer,
|
||||
NotificationReadAllReducer,
|
||||
],
|
||||
sagaWatchers: [
|
||||
AsyncRequest,
|
||||
|
|
|
@ -14,6 +14,8 @@ import ProbeSetup from '../../views/monitoring/probe/Setup';
|
|||
import HistoryList from '../../views/history/List';
|
||||
import TitleBarContainer from '@overflow/app/views/layout/TitleBarContainer';
|
||||
import SensorSetup from '../../views/monitoring/sensor/Setup';
|
||||
import NotificationList from '../../views/notification/Notification';
|
||||
|
||||
|
||||
export interface Props extends RouteComponentProps<any> {
|
||||
}
|
||||
|
@ -47,6 +49,7 @@ export class AppLayout extends React.Component<Props, State> {
|
|||
<Route exact={true} path={`${this.props.match.url}histories`} component={HistoryList}/>
|
||||
<Route exact={true} path={`${this.props.match.url}sensor_setup`} component={SensorSetup}/>
|
||||
<Route exact={true} path={`${this.props.match.url}sensor_setup/:id`} component={SensorSetup}/>
|
||||
<Route exact={true} path={`${this.props.match.url}notifications`} component={NotificationList}/>
|
||||
<Redirect to='/error/404' />
|
||||
</Switch>
|
||||
</Segment>
|
||||
|
|
|
@ -5,6 +5,8 @@ import {
|
|||
Container,
|
||||
Popup,
|
||||
Image,
|
||||
Label,
|
||||
Button,
|
||||
} from 'semantic-ui-react';
|
||||
import Notification from '@overflow/notification/react/Notification';
|
||||
|
||||
|
@ -21,11 +23,16 @@ export class LogoBar extends React.Component<any, any> {
|
|||
alert('handleLogoClick');
|
||||
}
|
||||
|
||||
public handleNotiClick = () => {
|
||||
alert('handleNotiClick');
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
let icon =
|
||||
<Button
|
||||
color='red'
|
||||
content='Notifications'
|
||||
icon='bell'
|
||||
floated='right'
|
||||
label={{ basic: true, color: 'red', pointing: 'left', content: '3' }}
|
||||
/>;
|
||||
|
||||
return (
|
||||
<Container fluid style={{ background: '#f8f8f8', 'paddingRight': '7px' }}>
|
||||
<Menu borderless secondary >
|
||||
|
@ -33,11 +40,7 @@ export class LogoBar extends React.Component<any, any> {
|
|||
{/*<Image src='../asset/image/overFlow_CI_blue_180.png'
|
||||
style={{width:'120px'}} onClick={this.handleLogoClick} /> */}
|
||||
</Menu.Item>
|
||||
<Popup trigger={<Menu.Item
|
||||
position='right'
|
||||
icon='bell'
|
||||
/>}
|
||||
on='click' wide >
|
||||
<Popup trigger={icon} on='click' wide >
|
||||
<Notification />
|
||||
</Popup>
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import * as React from 'react';
|
||||
import { RouteComponentProps } from 'react-router';
|
||||
import NotificationListContainer from '@overflow/notification/react/NotificationList';
|
||||
|
||||
class NotificationList extends React.Component<RouteComponentProps<object>, object> {
|
||||
|
||||
public constructor(props?: RouteComponentProps<object>, context?: object) {
|
||||
super(props, context);
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
return (
|
||||
<div>
|
||||
<NotificationListContainer params={this.props.match.url}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default NotificationList;
|
|
@ -1,8 +1,8 @@
|
|||
interface PageParams {
|
||||
pageNo: string;
|
||||
countPerPage: string;
|
||||
sortCol: string;
|
||||
sortDirection: string;
|
||||
sortCol?: string;
|
||||
sortDirection?: string;
|
||||
}
|
||||
|
||||
export default PageParams;
|
||||
|
|
|
@ -8,8 +8,9 @@ import { push as routerPush } from 'react-router-redux';
|
|||
import * as asyncRequestActions from '@overflow/commons/redux/action/asyncRequest';
|
||||
import Member from '@overflow/member/api/model/Member';
|
||||
import * as readAllUnconfirmedActions from '../redux/action/read_all_unconfirmed';
|
||||
import PageParams from '@overflow/commons/api/model/PageParams';
|
||||
|
||||
export function mapStateToProps(state: any, props: StateProps): StateProps {
|
||||
export function mapStateToProps(state: any, props: any): StateProps {
|
||||
return {
|
||||
notifications: state.notifications,
|
||||
};
|
||||
|
@ -17,9 +18,12 @@ export function mapStateToProps(state: any, props: StateProps): StateProps {
|
|||
|
||||
export function mapDispatchToProps(dispatch: Dispatch<any>): DispatchProps {
|
||||
return {
|
||||
onReadAllUnconfirmed: (member: Member, pageNo: string, countPerPage: string) => {
|
||||
onReadTop5Unconfirmed: (member: Member, pageParams: PageParams) => {
|
||||
dispatch(asyncRequestActions.request('NotificationService', 'readAllUnconfirmedByMember',
|
||||
readAllUnconfirmedActions.REQUEST, JSON.stringify(member), pageNo, countPerPage));
|
||||
readAllUnconfirmedActions.REQUEST, JSON.stringify(member), JSON.stringify(pageParams)));
|
||||
},
|
||||
onRedirectAllNotifications: () => {
|
||||
dispatch(routerPush('/notifications/'));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
29
src/ts/@overflow/notification/react/NotificationList.tsx
Normal file
29
src/ts/@overflow/notification/react/NotificationList.tsx
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { connect, Dispatch } from 'react-redux';
|
||||
import {
|
||||
NotificationList,
|
||||
StateProps as StateProps,
|
||||
DispatchProps as DispatchProps,
|
||||
} from './components/NotificationList';
|
||||
import { push as routerPush } from 'react-router-redux';
|
||||
import * as asyncRequestActions from '@overflow/commons/redux/action/asyncRequest';
|
||||
import Member from '@overflow/member/api/model/Member';
|
||||
import * as readAllActions from '../redux/action/read_all';
|
||||
import PageParams from '@overflow/commons/api/model/PageParams';
|
||||
|
||||
export function mapStateToProps(state: any, props: any): StateProps {
|
||||
return {
|
||||
notiPage: state.allNotifications,
|
||||
};
|
||||
}
|
||||
|
||||
export function mapDispatchToProps(dispatch: Dispatch<any>): DispatchProps {
|
||||
return {
|
||||
onReadAll: (member: Member, pageParams: PageParams) => {
|
||||
dispatch(asyncRequestActions.request('NotificationService', 'readAllByMember',
|
||||
readAllActions.REQUEST, JSON.stringify(member), JSON.stringify(pageParams)));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(NotificationList);
|
||||
|
|
@ -7,18 +7,21 @@ import {
|
|||
import Page from '@overflow/commons/api/model/Page';
|
||||
import Member from '@overflow/member/api/model/Member';
|
||||
import Notification from '../../api/model/Notification';
|
||||
import PageParams from '@overflow/commons/api/model/PageParams';
|
||||
|
||||
export interface StateProps {
|
||||
notifications: Page;
|
||||
}
|
||||
|
||||
export interface DispatchProps {
|
||||
onReadAllUnconfirmed(member: Member, pageNo: string, countPerPage: string): void;
|
||||
onReadTop5Unconfirmed(member: Member, pageParams: PageParams): void;
|
||||
onRedirectAllNotifications(): void;
|
||||
}
|
||||
|
||||
export type Props = StateProps & DispatchProps;
|
||||
|
||||
export interface State {
|
||||
show: boolean;
|
||||
}
|
||||
|
||||
export class NotificationModal extends React.Component<Props, State> {
|
||||
|
@ -27,14 +30,20 @@ export class NotificationModal extends React.Component<Props, State> {
|
|||
constructor(props: Props, context: State) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
list: null,
|
||||
show: true,
|
||||
};
|
||||
}
|
||||
public componentWillMount(): void {
|
||||
const member = {
|
||||
const member: Member = {
|
||||
id: 1,
|
||||
};
|
||||
this.props.onReadAllUnconfirmed(member, String(0), String(this.countPerPage));
|
||||
const pageParams: PageParams = {
|
||||
sortCol: 'id',
|
||||
sortDirection: 'descending',
|
||||
countPerPage: String(this.countPerPage),
|
||||
pageNo: String(0),
|
||||
};
|
||||
this.props.onReadTop5Unconfirmed(member, pageParams);
|
||||
}
|
||||
|
||||
public renderItems(): (JSX.Element | JSX.Element[]) {
|
||||
|
@ -45,22 +54,37 @@ export class NotificationModal extends React.Component<Props, State> {
|
|||
<List.Item key={index}>
|
||||
<List.Icon name='bell outline' size='large' verticalAlign='middle' />
|
||||
<List.Content>
|
||||
<List.Header as='a'>{item.title}</List.Header>
|
||||
<List.Description as='a'>{item.message}</List.Description>
|
||||
<List.Header >{item.title}</List.Header>
|
||||
<List.Description >{item.message}</List.Description>
|
||||
</List.Content>
|
||||
</List.Item>
|
||||
));
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
if(!this.state.show) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Container fluid>
|
||||
<Header as='h4' content='User Notifications' />
|
||||
<List divided relaxed>
|
||||
{this.renderItems()}
|
||||
<List.Item onClick={this.handleViewAll}>
|
||||
<List.Content>
|
||||
<List.Description as='a'><b>View All</b></List.Description>
|
||||
</List.Content>
|
||||
</List.Item>
|
||||
</List>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
private handleViewAll = (): void => {
|
||||
this.setState({
|
||||
show: false,
|
||||
});
|
||||
this.props.onRedirectAllNotifications();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
import * as React from 'react';
|
||||
import {
|
||||
Container,
|
||||
Table,
|
||||
} from 'semantic-ui-react';
|
||||
import Page from '@overflow/commons/api/model/Page';
|
||||
import Member from '@overflow/member/api/model/Member';
|
||||
import Notification from '../../api/model/Notification';
|
||||
import { SortTableHeaderRow } from '@overflow/commons/react/component/SortTableHeaderRow';
|
||||
import { Pager } from '@overflow/commons/react/component/Pager';
|
||||
import PageParams from '@overflow/commons/api/model/PageParams';
|
||||
|
||||
export interface StateProps {
|
||||
notiPage: Page;
|
||||
}
|
||||
|
||||
export interface DispatchProps {
|
||||
onReadAll(member: Member, pageParams: PageParams): void;
|
||||
}
|
||||
|
||||
export type Props = StateProps & DispatchProps;
|
||||
|
||||
export interface State {
|
||||
}
|
||||
|
||||
export class NotificationList extends React.Component<Props, State> {
|
||||
|
||||
private countPerPage: number = 10;
|
||||
private sortCol: string = 'id';
|
||||
private sortDirection: string = 'descending';
|
||||
private pageNo: number = 0;
|
||||
|
||||
constructor(props: Props, context: State) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
};
|
||||
}
|
||||
public componentWillMount(): void {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
private getData(): void {
|
||||
const member = {
|
||||
id: 1,
|
||||
};
|
||||
const pageParams: PageParams = {
|
||||
sortCol: 'id',
|
||||
sortDirection: 'descending',
|
||||
countPerPage: String(this.countPerPage),
|
||||
pageNo: String(this.pageNo),
|
||||
};
|
||||
this.props.onReadAll(member, pageParams);
|
||||
}
|
||||
|
||||
public renderItems(): (JSX.Element | JSX.Element[]) {
|
||||
if (this.props.notiPage === undefined || this.props.notiPage.content.length === 0) {
|
||||
return <div>No user notifications found. </div>;
|
||||
}
|
||||
return this.props.notiPage.content.map((noti: Notification, index: number) => (
|
||||
<Table.Row key={index}>
|
||||
<Table.Cell textAlign={'center'}>{noti.id}</Table.Cell>
|
||||
<Table.Cell textAlign={'center'}>{noti.createDate}</Table.Cell>
|
||||
<Table.Cell textAlign={'center'}>{noti.title}</Table.Cell>
|
||||
<Table.Cell textAlign={'center'}>{noti.message}</Table.Cell>
|
||||
</Table.Row>
|
||||
));
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
let colsmap: Map<string, string> = new Map();
|
||||
colsmap.set('No.', 'id');
|
||||
colsmap.set('Created At', 'createDate');
|
||||
colsmap.set('Title', 'title');
|
||||
colsmap.set('Message', 'message');
|
||||
|
||||
return (
|
||||
<Container fluid>
|
||||
<Table celled striped sortable>
|
||||
<Table.Header>
|
||||
<SortTableHeaderRow columnMap={colsmap} onHeaderColumnClick={this.handleSort} />
|
||||
</Table.Header>
|
||||
|
||||
<Table.Body>
|
||||
{this.renderItems()}
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell colSpan='4'>
|
||||
<Pager page={this.props.notiPage} onPageChange={this.handlePaging} />
|
||||
</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
private handleSelect = (selected: Notification) => {
|
||||
console.log('handleSelect');
|
||||
}
|
||||
private handleSort = (col: string, direction: string) => {
|
||||
this.sortCol = col;
|
||||
this.sortDirection = direction;
|
||||
this.getData();
|
||||
}
|
||||
private handlePaging = (pageNo: number) => {
|
||||
this.pageNo = pageNo;
|
||||
this.getData();
|
||||
}
|
||||
}
|
7
src/ts/@overflow/notification/redux/action/read_all.ts
Normal file
7
src/ts/@overflow/notification/redux/action/read_all.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export type REQUEST = '@overflow/notification/read_all/REQUEST';
|
||||
export type REQUEST_SUCCESS = '@overflow/notification/read_all/REQUEST/SUCCESS';
|
||||
export type REQUEST_FAILURE = '@overflow/notification/read_all/REQUEST/FAILURE';
|
||||
|
||||
export const REQUEST: REQUEST = '@overflow/notification/read_all/REQUEST';
|
||||
export const REQUEST_SUCCESS: REQUEST_SUCCESS = '@overflow/notification/read_all/REQUEST/SUCCESS';
|
||||
export const REQUEST_FAILURE: REQUEST_FAILURE = '@overflow/notification/read_all/REQUEST/FAILURE';
|
24
src/ts/@overflow/notification/redux/reducer/read_all.ts
Normal file
24
src/ts/@overflow/notification/redux/reducer/read_all.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import Action from '@overflow/commons/redux/Action';
|
||||
import { ReducersMapObject } from 'redux';
|
||||
import Page from '@overflow/commons/api/model/Page';
|
||||
|
||||
import * as ReadAllActionTypes from '../action/read_all';
|
||||
import ReadAllState, { defaultState as ReadAllDefaultState } from '../state/ReadAll';
|
||||
|
||||
const reducer: ReducersMapObject = {
|
||||
[ReadAllActionTypes.REQUEST_SUCCESS]:
|
||||
(state: ReadAllState = ReadAllDefaultState, action: Action<Page>):
|
||||
ReadAllState => {
|
||||
return {
|
||||
...state,
|
||||
allNotifications: <Page>action.payload,
|
||||
};
|
||||
},
|
||||
[ReadAllActionTypes.REQUEST_FAILURE]:
|
||||
(state: ReadAllState = ReadAllDefaultState, action: Action<Error>):
|
||||
ReadAllState => {
|
||||
return state;
|
||||
},
|
||||
};
|
||||
|
||||
export default reducer;
|
13
src/ts/@overflow/notification/redux/state/ReadAll.ts
Normal file
13
src/ts/@overflow/notification/redux/state/ReadAll.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import Page from '@overflow/commons/api/model/Page';
|
||||
|
||||
export interface State {
|
||||
readonly allNotifications?: Page;
|
||||
readonly error?: Error;
|
||||
}
|
||||
|
||||
export const defaultState: State = {
|
||||
allNotifications: undefined,
|
||||
error: undefined,
|
||||
};
|
||||
|
||||
export default State;
|
Loading…
Reference in New Issue
Block a user