forked from code-dot-org/code-dot-org
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhiddenStageRedux.js
More file actions
137 lines (119 loc) · 3.72 KB
/
hiddenStageRedux.js
File metadata and controls
137 lines (119 loc) · 3.72 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* Reducer and actions for stage lock info. This includes the teacher panel on
* the course overview page, and the stage locking dialog.
*/
import $ from 'jquery';
import experiments from '@cdo/apps/experiments';
import Immutable from 'immutable';
export const UPDATE_HIDDEN_STAGE = 'hiddenStage/UPDATE_HIDDEN_STAGE';
export const ALLOW_HIDEABLE = 'hiddenStage/ALLOW_HIDEABLE';
const STUDENT_SECTION_ID = 'STUDENT';
export const hiddenStagesEnabled = () => experiments.isEnabled('hiddenStages');
const initialState = Immutable.fromJS({
initialized: false,
// mapping of section id to hidden stages for that section
// Teachers will potentially have a number of section ids. For students we
// use a sectionId of STUDENT_SECTION_ID, which represents the hidden state
// for the student based on the sections they are in.
bySection: {
// [sectionId]: {
// [stageId]: true
// }
}
});
/**
* hidden stage reducer
* Mapping of stage ids to bools indicating whether it's locked or not
*/
export default function reducer(state = initialState, action) {
if (action.type === UPDATE_HIDDEN_STAGE) {
const { sectionId, stageId, hidden } = action;
const nextState = state.setIn(['bySection', sectionId, stageId.toString()], hidden);
if (state.getIn(['bySection', STUDENT_SECTION_ID]) &&
state.get('bySection').size > 1) {
throw new Error('Should never have STUDENT_SECTION_ID alongside other sectionIds');
}
return nextState;
}
if (action.type === ALLOW_HIDEABLE) {
return state.set('initialized', true);
}
return state;
}
// action creators
function updateHiddenStage(sectionId, stageId, hidden) {
return {
type: UPDATE_HIDDEN_STAGE,
sectionId,
stageId,
hidden
};
}
export function toggleHidden(scriptName, sectionId, stageId, hidden) {
return (dispatch, getState) => {
// update local state
dispatch(updateHiddenStage(sectionId, stageId, hidden));
// update the server. note: we don't do anything differently if it succeeds
// or fails
$.ajax({
type: 'POST',
url: `/s/${scriptName}/toggle_hidden`,
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({
section_id: sectionId,
stage_id: stageId,
hidden
})
});
};
}
export function allowHideable() {
return {
type: ALLOW_HIDEABLE
};
}
export function getHiddenStages(scriptName) {
return dispatch => {
if (!hiddenStagesEnabled()) {
return;
}
$.ajax({
type: 'GET',
url: `/s/${scriptName}/hidden_stages`,
dataType: 'json',
contentType: 'application/json'
}).done(response => {
dispatch(allowHideable());
// For a teacher, we get back a map of section id to hidden stage ids
// For a student, we just get back a list of hidden stage ids. Turn that
// into an object, under the 'sectionId' of STUDENT_SECTION_ID
if (Array.isArray(response)) {
response = { [STUDENT_SECTION_ID]: response };
}
Object.keys(response).forEach(sectionId => {
const hiddenStageIds = response[sectionId];
hiddenStageIds.forEach(stageId => {
dispatch(updateHiddenStage(sectionId, stageId, true));
});
});
}).fail(err => {
console.error(err);
});
};
}
// utils
/**
* Helper to determine whether a stage is hidden for a given section. If no
* section is given, we assume this is a student and use STUDENT_SECTION_ID
*/
export function isHiddenFromState(bySection, sectionId, stageId) {
if (!stageId) {
return false;
}
// if we don't have a sectionId, we must be a student
if (sectionId === null){
sectionId = STUDENT_SECTION_ID;
}
return !!bySection.getIn([sectionId, stageId.toString()]);
}