Skip to content

Commit fddb772

Browse files
committed
Finishing archiving procedure on Groups Superadmin page.
1 parent 2b1c364 commit fddb772

File tree

4 files changed

+108
-10
lines changed

4 files changed

+108
-10
lines changed

src/locales/cs.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@
9393
"app.groupsSupervisor.archiveButton": "Archivovat vybrané skupiny",
9494
"app.groupsSupervisor.archivingGroupsHeading": "Archivace starých semestrálních skupin",
9595
"app.groupsSupervisor.archivingGroupsInfo": "Vybrané semestrální skupiny budou archivovány (včetně všech jejich podskupin). Tuto operaci lze v ReCodExu vrátit zpět individuálním vyjmutím skupin z archivu.",
96+
"app.groupsSupervisor.archivingResult": "Celkem {archivedGroups} {archivedGroups, plural, one {skupina byla archivována} =2 {skupiny byly archivovány} =3 {skupiny byly archivovány} =4 {skupiny byly archivovány} other {skupin bylo archivováno}} , ale u {archivedErrors} {archivedErrors, plural, one {skupiny} other {skupin}} se archivace nezdařila. Prosíme, zkuste operaci znovu nebo zkuste archivovat skupiny jednotlivě v ReCodExu.",
97+
"app.groupsSupervisor.archivingResultFailure": "Celkem {archivedErrors} {archivedErrors, plural, one {skupina selhala} =2 {skupiny selhaly} =3 {skupiny selhaly} =4 {skupiny selhaly} other {skupin selhalo}} při archivaci. Prosíme, zkuste operaci znovu nebo zkuste archivovat skupiny jednotlivě v ReCodExu.",
98+
"app.groupsSupervisor.archivingResultSuccess": "Celkem {archivedGroups} {archivedGroups, plural, one {skupina byla archivována} =2 {skupiny byly archivovány} =3 {skupiny byly archivovány} =4 {skupiny byly archivovány} other {skupin bylo archivováno}}.",
9699
"app.groupsSupervisor.cancelArchivingButton": "Zrušit archivaci",
97100
"app.groupsSupervisor.cancelPlantTermButton": "Zrušit osazování skupin",
98101
"app.groupsSupervisor.currentlyManagedGroups": "Skupiny",

src/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@
9393
"app.groupsSupervisor.archiveButton": "Archive Selected Groups",
9494
"app.groupsSupervisor.archivingGroupsHeading": "Archiving Old Term Groups",
9595
"app.groupsSupervisor.archivingGroupsInfo": "Selected term groups will be archived (with all their sub-groups). This operation may be reverted in ReCodEx by individually excavating the groups from the archive.",
96+
"app.groupsSupervisor.archivingResult": "Total {archivedGroups} {archivedGroups, plural, one {group} other {groups}} were successfully archived, but {archivedErrors} {archivedErrors, plural, one {group} other {groups}} failed. Please, try the operation again or try archiving the groups individually in ReCodEx.",
97+
"app.groupsSupervisor.archivingResultFailure": "Selected {archivedErrors} {archivedErrors, plural, one {group} other {groups}} failed to be archived. Please, try the operation again or try archiving the groups individually in ReCodEx.",
98+
"app.groupsSupervisor.archivingResultSuccess": "Total {archivedGroups} {archivedGroups, plural, one {group} other {groups}} were successfully archived.",
9699
"app.groupsSupervisor.cancelArchivingButton": "Cancel Archiving",
97100
"app.groupsSupervisor.cancelPlantTermButton": "Cancel Group Planting",
98101
"app.groupsSupervisor.currentlyManagedGroups": "Groups",

src/pages/GroupsSuperadmin/GroupsSuperadmin.js

Lines changed: 92 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
addGroupAttribute,
3434
removeGroupAttribute,
3535
createTermGroup,
36+
setGroupArchived,
3637
} from '../../redux/modules/groups.js';
3738
import { fetchAllTerms } from '../../redux/modules/terms.js';
3839
import { fetchUserIfNeeded } from '../../redux/modules/users.js';
@@ -104,14 +105,16 @@ class GroupsSuperadmin extends Component {
104105
operationPending: false, // an async operation (adding attribute, planting groups, archiving groups) is pending
105106
selectedGroups: null, // groups with checkboxes (if checkboxes are shown)
106107
selectedGroupsCount: 0, // number of selected groups (for easy access without iterating over selectedGroups)
107-
modalGroup: null,
108-
modalGroupError: null,
109-
modalPlant: false,
110-
plantTerm: null,
111-
plantTexts: null,
112-
plantGroupsErrors: null,
113-
plantedGroups: 0,
114-
archiving: false,
108+
modalGroup: null, // group for which the "add attribute" modal is open (also controls whether the modal is open)
109+
modalGroupError: null, // error message to be displayed in the "add attribute" modal if the operation fails
110+
modalPlant: false, // whether the "plant term groups" modal is open
111+
plantTerm: null, // term selected for planting, if null, the first term in the list is used
112+
plantTexts: null, // texts for the groups to be planted (not null indicates that stage 2 of planting is active)
113+
plantGroupsErrors: null, // object groupId -> error message for groups that failed to be planted (only relevant in stage 2 of planting)
114+
plantedGroups: 0, // number of groups successfully planted in the last planting operation
115+
archiving: false, // whether the page is in "archiving mode" (selecting groups for archiving)
116+
archivedGroups: 0, // number of groups successfully archived in the last archiving operation
117+
archivedErrors: 0, // number of groups that failed to be archived in the last archiving operation
115118
};
116119

117120
pageInDefaultMode = () =>
@@ -135,7 +138,15 @@ class GroupsSuperadmin extends Component {
135138

136139
openModalGroup = modalGroup => {
137140
if (this.pageInDefaultMode() && !this.state.operationPending) {
138-
this.setState({ modalGroup, operationPending: false, modalGroupError: null, modalPlant: false });
141+
this.setState({
142+
modalGroup,
143+
operationPending: false,
144+
modalGroupError: null,
145+
modalPlant: false,
146+
plantedGroups: 0,
147+
archivedGroups: 0,
148+
archivedErrors: 0,
149+
});
139150
}
140151
};
141152

@@ -181,6 +192,8 @@ class GroupsSuperadmin extends Component {
181192
operationPending: false,
182193
plantGroupsErrors: null,
183194
plantedGroups: 0,
195+
archivedGroups: 0,
196+
archivedErrors: 0,
184197
});
185198
};
186199

@@ -269,18 +282,42 @@ class GroupsSuperadmin extends Component {
269282
selectedGroupsCount: Object.keys(selectedGroups).length,
270283
plantGroupsErrors: null,
271284
plantedGroups: 0,
285+
archivedGroups: 0,
286+
archivedErrors: 0,
272287
});
273288
}
274289
};
275290

276291
archiveSelectedGroups = async () => {
292+
const { setGroupArchived, reloadGroups } = this.props;
293+
277294
if (this.state.selectedGroupsCount === 0 || this.state.operationPending) {
278295
return;
279296
}
280297

281-
// TODO change the groups state in ReCodEx
298+
const promises = {};
299+
Object.keys(this.state.selectedGroups)
300+
.filter(id => this.state.selectedGroups[id])
301+
.forEach(id => {
302+
promises[id] = setGroupArchived(id, true);
303+
});
304+
305+
// wait for all promises and handle errors
306+
let archivedGroups = 0;
307+
let archivedErrors = 0;
308+
for (const id of Object.keys(promises)) {
309+
try {
310+
await promises[id];
311+
++archivedGroups;
312+
} catch (err) {
313+
++archivedErrors;
314+
}
315+
}
316+
317+
await reloadGroups();
282318

283319
this.cancelArchiving();
320+
this.setState({ archivedGroups, archivedErrors });
284321
};
285322

286323
cancelArchiving = () => this.setState({ archiving: false, selectedGroups: null, selectedGroupsCount: 0 });
@@ -460,6 +497,49 @@ class GroupsSuperadmin extends Component {
460497
</Callout>
461498
)}
462499

500+
{this.state.archivedGroups + this.state.archivedErrors > 0 && (
501+
<Callout
502+
variant={
503+
this.state.archivedErrors === 0
504+
? 'success'
505+
: this.state.archivedGroups === 0
506+
? 'danger'
507+
: 'warning'
508+
}>
509+
<CloseIcon
510+
onClick={() => this.setState({ archivedGroups: 0, archivedErrors: 0 })}
511+
className="float-end clickable pt-1"
512+
/>
513+
514+
{this.state.archivedErrors === 0 ? (
515+
<FormattedMessage
516+
id="app.groupsSupervisor.archivingResultSuccess"
517+
defaultMessage="Total {archivedGroups} {archivedGroups, plural, one {group} other {groups}} were successfully archived."
518+
values={{
519+
archivedGroups: this.state.archivedGroups,
520+
}}
521+
/>
522+
) : this.state.archivedGroups === 0 ? (
523+
<FormattedMessage
524+
id="app.groupsSupervisor.archivingResultFailure"
525+
defaultMessage="Selected {archivedErrors} {archivedErrors, plural, one {group} other {groups}} failed to be archived. Please, try the operation again or try archiving the groups individually in ReCodEx."
526+
values={{
527+
archivedErrors: this.state.archivedErrors,
528+
}}
529+
/>
530+
) : (
531+
<FormattedMessage
532+
id="app.groupsSupervisor.archivingResult"
533+
defaultMessage="Total {archivedGroups} {archivedGroups, plural, one {group} other {groups}} were successfully archived, but {archivedErrors} {archivedErrors, plural, one {group} other {groups}} failed. Please, try the operation again or try archiving the groups individually in ReCodEx."
534+
values={{
535+
archivedGroups: this.state.archivedGroups,
536+
archivedErrors: this.state.archivedErrors,
537+
}}
538+
/>
539+
)}
540+
</Callout>
541+
)}
542+
463543
<GroupsTreeView
464544
groups={groups}
465545
errors={this.state.plantTexts ? this.state.plantGroupsErrors : null}
@@ -694,6 +774,7 @@ GroupsSuperadmin.propTypes = {
694774
removeAttribute: PropTypes.func.isRequired,
695775
createTermGroup: PropTypes.func.isRequired,
696776
reloadGroups: PropTypes.func.isRequired,
777+
setGroupArchived: PropTypes.func.isRequired,
697778
intl: PropTypes.object,
698779
};
699780

@@ -714,5 +795,6 @@ export default connect(
714795
),
715796
createTermGroup: (parentId, term, texts) => dispatch(createTermGroup(parentId, term, texts)),
716797
reloadGroups: () => dispatch(fetchAllGroups()),
798+
setGroupArchived: (groupId, value) => dispatch(setGroupArchived(groupId, value)),
717799
})
718800
)(injectIntl(GroupsSuperadmin));

src/redux/modules/groups.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const additionalActionTypes = {
1313
...createActionsWithPostfixes('JOIN', 'siscodex/groups'),
1414
...createActionsWithPostfixes('ADD_ATTRIBUTE', 'siscodex/groups'),
1515
...createActionsWithPostfixes('REMOVE_ATTRIBUTE', 'siscodex/groups'),
16+
...createActionsWithPostfixes('SET_ARCHIVED', 'siscodex/groups'),
1617
};
1718

1819
/**
@@ -91,6 +92,15 @@ export const removeGroupAttribute = (groupId, key, value) =>
9192
body: { key, value },
9293
});
9394

95+
export const setGroupArchived = (groupId, value) =>
96+
createApiAction({
97+
type: additionalActionTypes.SET_ARCHIVED,
98+
endpoint: `/groups/${groupId}/archived`,
99+
method: 'POST',
100+
meta: { groupId, value },
101+
body: { value },
102+
});
103+
94104
/**
95105
* Reducer
96106
*/

0 commit comments

Comments
 (0)