Skip to content
This repository was archived by the owner on Aug 31, 2022. It is now read-only.

Commit 0bf912e

Browse files
aquibbaigportante
authored andcommitted
Show favorite user records
add table for user favoriting User model to favorite controllers and results store favorite records in the localStorage Displaying favorite records in separate Table There will be two tables in Controllers and Results page, one reflecting all records and the other is for user-favorite records
1 parent 27606f5 commit 0bf912e

File tree

6 files changed

+179
-33
lines changed

6 files changed

+179
-33
lines changed

src/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const persistConfig = {
1414
throttle: 1000,
1515
key: getAppPath(),
1616
storage,
17-
whitelist: ['global'],
17+
whitelist: ['global', 'user'],
1818
};
1919

2020
const persistEnhancer = () => createStore => (reducer, initialState, enhancer) => {

src/models/user.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export default {
2+
namespace: 'user',
3+
4+
state: {
5+
favoriteControllers: [],
6+
favoriteResults: [],
7+
},
8+
9+
effects: {
10+
*favoriteController({ payload }, { put }) {
11+
yield put({
12+
type: 'modifyFavoritedControllers',
13+
payload,
14+
});
15+
},
16+
*favoriteResult({ payload }, { put }) {
17+
yield put({
18+
type: 'modifyFavoritedResults',
19+
payload,
20+
});
21+
},
22+
},
23+
24+
reducers: {
25+
modifyFavoritedControllers(state, { payload }) {
26+
return {
27+
...state,
28+
favoriteControllers: [...state.favoriteControllers, payload],
29+
};
30+
},
31+
modifyFavoritedResults(state, { payload }) {
32+
return {
33+
...state,
34+
favoriteResults: [...state.favoriteResults, payload],
35+
};
36+
},
37+
},
38+
};

src/pages/Controllers/index.js

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import React, { Component } from 'react';
22
import { connect } from 'dva';
33
import { routerRedux } from 'dva/router';
4-
import { Card, Form } from 'antd';
4+
import { Card, Form, Icon, Tabs } from 'antd';
55

66
import SearchBar from '@/components/SearchBar';
77
import MonthSelect from '@/components/MonthSelect';
88
import Table from '@/components/Table';
99
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
1010

11-
@connect(({ datastore, global, dashboard, loading }) => ({
11+
const { TabPane } = Tabs;
12+
13+
@connect(({ datastore, global, dashboard, loading, user }) => ({
1214
controllers: dashboard.controllers,
1315
indices: datastore.indices,
1416
selectedIndices: global.selectedIndices,
1517
datastoreConfig: datastore.datastoreConfig,
18+
favoriteControllers: user.favoriteControllers,
1619
loadingControllers:
1720
loading.effects['dashboard/fetchControllers'] ||
1821
loading.effects['datastore/fetchMonthIndices'] ||
@@ -133,9 +136,20 @@ class Controllers extends Component {
133136
});
134137
};
135138

139+
favoriteRecord = (event, value, controller) => {
140+
// Stop propagation from going to the next page
141+
event.stopPropagation();
142+
const { dispatch } = this.props;
143+
// dispatch an action to favorite controller
144+
dispatch({
145+
type: 'user/favoriteController',
146+
payload: controller,
147+
});
148+
};
149+
136150
render() {
137151
const { controllers } = this.state;
138-
const { loadingControllers, selectedIndices, indices } = this.props;
152+
const { loadingControllers, selectedIndices, indices, favoriteControllers } = this.props;
139153
const columns = [
140154
{
141155
title: 'Controller',
@@ -155,6 +169,29 @@ class Controllers extends Component {
155169
key: 'results',
156170
sorter: (a, b) => a.results - b.results,
157171
},
172+
{
173+
title: 'Actions',
174+
dataIndex: 'actions',
175+
key: 'actions',
176+
render: (value, row) => {
177+
// if already favorited return a filled star,
178+
// else allow user to favorite a record
179+
let isFavorite = false;
180+
favoriteControllers.forEach(item => {
181+
if (item.key === row.key) {
182+
isFavorite = true;
183+
}
184+
});
185+
if (isFavorite) {
186+
return <Icon type="star" theme="filled" />;
187+
}
188+
return (
189+
<a onClick={e => this.favoriteRecord(e, null, row)}>
190+
<Icon type="star" />
191+
</a>
192+
);
193+
},
194+
},
158195
];
159196

160197
return (
@@ -173,17 +210,34 @@ class Controllers extends Component {
173210
value={selectedIndices}
174211
/>
175212
</Form>
176-
<Table
177-
style={{ marginTop: 20 }}
178-
columns={columns}
179-
dataSource={controllers}
180-
onRow={record => ({
181-
onClick: () => {
182-
this.retrieveResults(record);
183-
},
184-
})}
185-
loading={loadingControllers}
186-
/>
213+
<Tabs type="card">
214+
<TabPane tab="Controllers" key="controllers">
215+
<Table
216+
style={{ marginTop: 20 }}
217+
columns={columns}
218+
dataSource={controllers}
219+
onRow={record => ({
220+
onClick: () => {
221+
this.retrieveResults(record);
222+
},
223+
})}
224+
loading={loadingControllers}
225+
/>
226+
</TabPane>
227+
<TabPane tab="Favorites" key="favorites">
228+
<Table
229+
style={{ marginTop: 20 }}
230+
columns={columns}
231+
dataSource={favoriteControllers}
232+
onRow={record => ({
233+
onClick: () => {
234+
this.retrieveResults(record);
235+
},
236+
})}
237+
loading={loadingControllers}
238+
/>
239+
</TabPane>
240+
</Tabs>
187241
</Card>
188242
</PageHeaderLayout>
189243
);

src/pages/Controllers/index.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('test Controllers page component', () => {
2525
});
2626

2727
it('render Table component', () => {
28-
expect(wrapper.find(Table).length).toBe(1);
28+
expect(wrapper.find(Table).length).toBe(2);
2929
});
3030

3131
it('render SearchBar component', () => {

src/pages/Results/index.js

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import React, { Component } from 'react';
22
import { connect } from 'dva';
33
import { routerRedux } from 'dva/router';
4-
import { Card, Form } from 'antd';
4+
import { Card, Form, Icon, Tabs } from 'antd';
55

66
import SearchBar from '@/components/SearchBar';
77
import RowSelection from '@/components/RowSelection';
88
import Table from '@/components/Table';
99
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
1010

11-
@connect(({ datastore, global, dashboard, loading }) => ({
11+
const { TabPane } = Tabs;
12+
13+
@connect(({ datastore, global, dashboard, loading, user }) => ({
1214
selectedIndices: global.selectedIndices,
1315
results: dashboard.results[global.selectedControllers[0]]
1416
? dashboard.results[global.selectedControllers[0]]
1517
: [],
1618
selectedControllers: global.selectedControllers,
1719
datastoreConfig: datastore.datastoreConfig,
20+
favoriteResults: user.favoriteResults,
1821
loading: loading.effects['dashboard/fetchResults'],
1922
}))
2023
class Results extends Component {
@@ -121,9 +124,20 @@ class Results extends Component {
121124
);
122125
};
123126

127+
favoriteRecord = (event, value, result) => {
128+
// Stop propagation from going to the next page
129+
event.stopPropagation();
130+
const { dispatch } = this.props;
131+
// dispatch an action to favorite result
132+
dispatch({
133+
type: 'user/favoriteResult',
134+
payload: result,
135+
});
136+
};
137+
124138
render() {
125139
const { results, selectedRows } = this.state;
126-
const { selectedControllers, loading } = this.props;
140+
const { selectedControllers, loading, favoriteResults } = this.props;
127141
const rowSelection = {
128142
// eslint-disable-next-line no-shadow
129143
onSelect: (record, selected, selectedRows) => this.onSelectChange(selectedRows),
@@ -152,6 +166,29 @@ class Results extends Component {
152166
dataIndex: 'run.end',
153167
key: 'run.end',
154168
},
169+
{
170+
title: 'Actions',
171+
dataIndex: 'actions',
172+
key: 'actions',
173+
render: (value, row) => {
174+
// if already favorited return a filled star,
175+
// else allow user to favorite a record
176+
let isFavorite = false;
177+
favoriteResults.forEach(item => {
178+
if (item.key === row.key) {
179+
isFavorite = true;
180+
}
181+
});
182+
if (isFavorite) {
183+
return <Icon type="star" theme="filled" />;
184+
}
185+
return (
186+
<a onClick={e => this.favoriteRecord(e, null, row)}>
187+
<Icon type="star" />
188+
</a>
189+
);
190+
},
191+
},
155192
];
156193

157194
return (
@@ -169,19 +206,36 @@ class Results extends Component {
169206
onCompare={this.compareResults}
170207
/>
171208
</Form>
172-
<Table
173-
style={{ marginTop: 16 }}
174-
rowSelection={rowSelection}
175-
columns={columns}
176-
dataSource={results}
177-
onRow={record => ({
178-
onClick: () => {
179-
this.retrieveResults([record]);
180-
},
181-
})}
182-
loading={loading}
183-
bordered
184-
/>
209+
<Tabs type="card" style={{ marginTop: 16 }}>
210+
<TabPane tab="Results" key="results">
211+
<Table
212+
rowSelection={rowSelection}
213+
columns={columns}
214+
dataSource={results}
215+
onRow={record => ({
216+
onClick: () => {
217+
this.retrieveResults([record]);
218+
},
219+
})}
220+
loading={loading}
221+
bordered
222+
/>
223+
</TabPane>
224+
<TabPane tab="Favorites" key="favorites">
225+
<Table
226+
rowSelection={rowSelection}
227+
columns={columns}
228+
dataSource={favoriteResults}
229+
onRow={record => ({
230+
onClick: () => {
231+
this.retrieveResults([record]);
232+
},
233+
})}
234+
loading={loading}
235+
bordered
236+
/>
237+
</TabPane>
238+
</Tabs>
185239
</Card>
186240
</PageHeaderLayout>
187241
);

src/pages/Results/index.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('test Results page component', () => {
2323
});
2424

2525
it('render Table component', () => {
26-
expect(wrapper.find(Table).length).toBe(1);
26+
expect(wrapper.find(Table).length).toBe(2);
2727
});
2828

2929
it('render RowSelection component', () => {

0 commit comments

Comments
 (0)