-
Notifications
You must be signed in to change notification settings - Fork 1
/
grid-saga.js
124 lines (110 loc) · 3.32 KB
/
grid-saga.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { call, put, takeEvery, select, fork, cancel } from 'redux-saga/effects';
import { delay } from 'redux-saga';
import {
GRID_LOAD,
GRID_PAGE_SIZE_CHANGE,
GRID_FILTERS_CHANGE,
GRID_STATE_CHANGE,
GRID_GROUPING_STATE_CHANGE,
gridDataLoaded,
gridStateChange,
gridLoad,
gridResetEditingState,
gridResetTempGrouping
} from './grid-reducer';
import { BATCH_SAVE, BATCH_DISCARD } from './toolbar-reducer';
import { fetchData, commitChanges } from './data-access';
function getLoadOptions(state) {
const {
sorting,
currentPage,
pageSize,
filters,
grouping,
expandedGroups
} = state.grid;
return {
sorting,
currentPage,
pageSize,
filters,
grouping,
expandedGroups
};
}
function loadData(loadOptions, force) {
if (force) loadOptions.force = true;
return fetchData(loadOptions).then(res => {
if (res.dataFetched) return res.data;
else {
console.error('Data not fetched: ', res.reason);
return undefined;
}
});
}
function* startLoadingTimer() {
const threshold = yield select(state => state.grid.loadingIndicatorThreshold);
yield delay(threshold);
const loading = yield select(state => state.grid.loading);
if (loading) yield put(gridStateChange('showLoadingIndicator', true));
}
function* gridLoadHandler(action) {
yield put(gridStateChange('loading', true));
const loadingTimer = yield fork(startLoadingTimer);
const loadOptions = yield select(getLoadOptions);
const data = yield call(loadData, loadOptions, action.force);
if (data) yield put(gridDataLoaded(data));
else {
yield put(gridStateChange('loading', false));
yield put(gridResetTempGrouping());
}
yield cancel(loadingTimer);
yield put(gridStateChange('showLoadingIndicator', false));
}
function getCommitParams(state) {
return {
added: state.grid.addedRows,
changed: state.grid.changedRows
};
}
function* batchSaveHandler(action) {
const commitParams = yield select(getCommitParams);
yield call(commitChanges, commitParams);
yield put(gridResetEditingState());
// Without the delay, the grid reacts so quickly that we won't
// see the change coming back from the service. Delaying may
// not be the most elegant option in reality, but then this
// part of the demo doesn't have change notifications.
yield delay(100);
yield put(gridLoad(true));
}
function* batchDiscardHandler(action) {
yield put(gridResetEditingState());
}
function* followWithGridLoad(action) {
yield put(gridLoad());
}
function selectiveFollowWithGridLoad(fields) {
const fieldList = new Set(fields);
return function*(action) {
if (fieldList.has(action.stateFieldName)) yield* followWithGridLoad(action);
};
}
const gridStateChangeHandler = selectiveFollowWithGridLoad([
'sorting',
'currentPage'
]);
const gridGroupingStateChangeHandler = selectiveFollowWithGridLoad([
'grouping',
'expandedGroups'
]);
function* gridSaga() {
yield takeEvery(GRID_LOAD, gridLoadHandler);
yield takeEvery(BATCH_SAVE, batchSaveHandler);
yield takeEvery(BATCH_DISCARD, batchDiscardHandler);
yield takeEvery(GRID_PAGE_SIZE_CHANGE, followWithGridLoad);
yield takeEvery(GRID_STATE_CHANGE, gridStateChangeHandler);
yield takeEvery(GRID_GROUPING_STATE_CHANGE, gridGroupingStateChangeHandler);
yield takeEvery(GRID_FILTERS_CHANGE, followWithGridLoad);
}
export default gridSaga;