-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreducer.js
84 lines (75 loc) · 2.3 KB
/
reducer.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
import * as types from'./constants';
import { compact_full, autoincrement } from'./utils';
const initialState = {
layout: [],
selected: null
};
//create item with modifying state
function createItem(state, next, settings) {
const { id, x, y, w, h, ...rest } = settings;
const next_id = id || next(state);
return [next_id, {
i: next_id.toString(),
x: x || 0,
y: y || state.layout.reduce((max_y, item) => Math.max(max_y, item.y + item.h), 0),
w: w || 1,
h: h || 1,
... rest
}];
}
//return updated state with added item/items
function add(state, next, settings) {
let inserts;
let next_id;
if(Array.isArray(settings)) {
const tempoState = {...state};
inserts = [];
settings.forEach(item => {
let [id, insert] = createItem(tempoState, next, item);
tempoState.next = id;
inserts.push(insert);
});
next_id = tempoState.next;
} else {
[next_id, inserts] = createItem(state, next, settings)
}
return {
next: next_id,
layout: state.layout.concat(inserts)
};
}
function removeItem(state, id) {
return state.layout.filter(item => (item.i !== id) );
}
function updateItem(state, newItem) {
return state.layout.map(item => (newItem.i == item.i ? Object.assign({}, item, newItem) : item))
}
export function createGridReducer({ name, next = autoincrement, compactor = compact_full }) {
return (state = initialState, action) => {
//TODO: think about testing for action type in case if 'grid' property of action is using by other reducer
if(action.grid != name) {
return state;
}
switch (action.type) {
case types.ADD:
return Object.assign({}, state, add(state, next, action.settings));
case types.REMOVE:
return Object.assign({}, state, {
selected: (state.selected != action.id ? state.selected : null),
layout: compactor(removeItem(state, action.id))
});
case types.UPDATE:
return Object.assign({}, state, { layout: compactor(updateItem(state, action.item)) });
case types.LAYOUT_CHANGE:
return Object.assign({}, state, { layout: compactor(action.layout) });
case types.COMPACT:
return Object.assign({}, state, { layout: compactor(state.layout) });
case types.SELECT:
return Object.assign({}, state, { selected: action.id });
case types.DESELECT:
return Object.assign({}, state, { selected: null });
default:
return state;
}
}
}