Skip to content

Commit

Permalink
N21-1767 configure synced course (#3421)
Browse files Browse the repository at this point in the history
add synced course restriction
add hidden fields
  • Loading branch information
MBergCap authored Mar 11, 2024
1 parent a476dd7 commit 88390be
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 34 deletions.
81 changes: 61 additions & 20 deletions controllers/courses.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,41 @@ const markSelected = (options, values = []) => options.map((option) => {
return option;
});

// checks for user's 'STUDENT_LIST' permission and filters checked students
const filterStudents = (ctx, s) => (
!ctx.locals.currentUser.permissions.includes('STUDENT_LIST')
? s.filter(({ selected }) => selected) : s
);

const selectedElementIdsToString = (arr = []) => {
const txt = arr.filter((obj) => obj.selected).map((obj) => (obj.id !== undefined ? obj.id : obj._id)).join(',');
return txt;
};

const getSyncedElementIds = (
course,
classesAndGroups,
classAndGroupIdsOfCourse,
teachers,
substitutions,
students,
res,
) => {
const startDate = course.startDate ? timesHelper.formatDate(course.startDate, 'DD.MM.YYYY') : undefined;
const untilDate = course.untilDate ? timesHelper.formatDate(course.untilDate, 'DD.MM.YYYY') : undefined;

const selectedElements = {
teachersSelected: selectedElementIdsToString(markSelected(teachers, course.teacherIds)),
substitutionSelected: selectedElementIdsToString(markSelected(substitutions, course.substitutionIds)),
classesAndGroupsSelected: selectedElementIdsToString(markSelected(classesAndGroups, classAndGroupIdsOfCourse)),
studentsSelected: selectedElementIdsToString(filterStudents(res, markSelected(students, course.userIds))),
startDate,
untilDate,
};

return selectedElements;
};

const getDefaultRedirectUrl = (courseId) => `/rooms/${courseId}`;

/**
Expand Down Expand Up @@ -241,14 +276,18 @@ const editCourseHandler = (req, res, next) => {
'#795548',
];

// checks for user's 'STUDENT_LIST' permission and filters checked students
const filterStudents = (ctx, s) => (
!ctx.locals.currentUser.permissions.includes('STUDENT_LIST')
? s.filter(({ selected }) => selected) : s
);

const classAndGroupIdsOfCourse = [...(course.classIds || []), ...(course.groupIds || [])];

const syncedElementIds = course.syncedWithGroup ? getSyncedElementIds(
course,
classesAndGroups,
classAndGroupIdsOfCourse,
teachers,
substitutions,
students,
res,
) : {};

if (req.params.courseId) {
if (!_scopePermissions.includes('COURSE_EDIT')) return next(new Error(res.$t('global.text.403')));
return res.render('courses/edit-course', {
Expand All @@ -260,17 +299,12 @@ const editCourseHandler = (req, res, next) => {
course,
colors,
classesAndGroups: markSelected(classesAndGroups, classAndGroupIdsOfCourse),
teachers: markSelected(
teachers,
course.teacherIds,
),
substitutions: markSelected(
substitutions,
course.substitutionIds,
),
teachers: markSelected(teachers, course.teacherIds),
substitutions: markSelected(substitutions, course.substitutionIds),
students: filterStudents(res, markSelected(students, course.userIds)),
scopePermissions: _scopePermissions,
schoolData: res.locals.currentSchoolData,
...syncedElementIds,
});
}
return res.render('courses/create-course', {
Expand Down Expand Up @@ -379,12 +413,6 @@ const copyCourseHandler = (req, res, next) => {

course.isArchived = false;

// checks for user's 'STUDENT_LIST' permission and filters checked students
const filterStudents = (ctx, s) => (
!ctx.locals.currentUser.permissions.includes('STUDENT_LIST')
? s.filter(({ selected }) => selected) : s
);

res.render('courses/edit-course', {
action,
method,
Expand Down Expand Up @@ -764,6 +792,19 @@ router.patch('/:courseId', async (req, res, next) => {
req.body.substitutionIds = [];
}

if (typeof req.body.teacherIds === 'string') {
req.body.teacherIds = req.body.teacherIds.split(',');
}
if (typeof req.body.substitutionIds === 'string') {
req.body.substitutionIds = req.body.substitutionIds.split(',');
}
if (typeof req.body.classIds === 'string') {
req.body.classIds = req.body.classIds.split(',');
}
if (typeof req.body.userIds === 'string') {
req.body.userIds = req.body.userIds.split(',');
}

const startDate = timesHelper.dateStringToMoment(req.body.startDate);
const untilDate = timesHelper.dateStringToMoment(req.body.untilDate);

Expand Down
45 changes: 31 additions & 14 deletions views/courses/edit-course.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -137,36 +137,41 @@

<div class="form-group">
<label for="teacherId">{{$t "administration.global.label.teachingTeacher"}}</label>

<select id="teacherId" name="teacherIds[]" required multiple data-placeholder="{{$t "courses.global.input.chooseTeacher"}}"
{{#if course.isArchived}}disabled{{/if}}>
{{#each teachers}}
<option value="{{this._id}}" {{#if this.selected}}selected{{/if}} {{#if this.isHidden}}hidden{{/if}}>
{{this.lastName}}, {{this.firstName}}{{#if this.outdatedSince}} ~~{{/if}}
</option>
{{/each}}
</select>
<select id="teacherId" name="teacherIds[]" required multiple data-placeholder="{{$t "courses.global.input.chooseTeacher"}}"
{{#ifCond course.isArchived '||' course.syncedWithGroup}}disabled{{/ifCond}}>
{{#each teachers}}
<option value="{{this._id}}" {{#if this.selected}}selected{{/if}} {{#if this.isHidden}}hidden{{/if}}>
{{this.lastName}}, {{this.firstName}}{{#if this.outdatedSince}} ~~{{/if}}
</option>
{{/each}}
</select>
{{#if course.syncedWithGroup}}
<input type="hidden" id="teacherIdSync" name="teacherIds" value="{{teachersSelected}}">
{{/if}}
<span class="small course-validation-error" id="courseTeacherErr">
{{$t "courses.global.input.noCourseTeacher"}}</span>
</div>

<div class="form-group">
<label for="substituteTeacher">{{$t "courses._course.edit.label.substitute"}}</label>
<select id="substituteTeacher" name="substitutionIds[]" multiple data-placeholder="{{$t "courses.global.input.chooseTeacher"}}"
{{#if course.isArchived}}disabled{{/if}}>
{{#ifCond course.isArchived '||' course.syncedWithGroup}}disabled{{/ifCond}}>
{{#each substitutions}}
<option value="{{this._id}}" {{#if this.selected}}selected{{/if}} {{#if this.isHidden}}hidden{{/if}}>
{{this.lastName}}, {{this.firstName}}{{#if this.outdatedSince}} ~~{{/if}}
</option>
{{/each}}
{{#if course.syncedWithGroup}}
<input type="hidden" id="substituteTeacherSync" name="substitutionIds" value="{{substitutionSelected}}">
{{/if}}
</select>
</div>

<div class="form-group">
<label for="classId">{{$t "global.headline.classes"}} <small>{{$t "administration.global.label.afterSavingAllStudentsAdded"}}</small></label>

<select id="classId" name="classIds[]" multiple data-placeholder="{{$t "courses.global.input.selectClasses"}}"
{{#if course.isArchived}}disabled{{/if}}>
{{#ifCond course.isArchived '||' course.syncedWithGroup}}disabled{{/ifCond}}>
{{#each classesAndGroups}}
<option value="{{#if this._id}}{{this._id}}{{else}}{{this.id}}{{/if}}" {{#if this.selected}}selected{{/if}}>
{{#if (getConfig "FEATURE_GROUPS_IN_COURSE_ENABLED")}}
Expand All @@ -193,31 +198,43 @@
</option>
{{/each}}
</select>
{{#if course.syncedWithGroup}}
<input type="hidden" id="classIdSync" name="classIds" value="{{classesAndGroupsSelected}}">
{{/if}}
</div>

<div class="form-group">
<label for="studentsId">{{$t "administration.global.label.studentParticipants"}}</label>
<select id="studentsId" name="userIds[]" multiple data-placeholder="{{$t "courses.global.input.selectStudents"}}"
{{#if course.isArchived}}disabled{{/if}}>
{{#ifCond course.isArchived '||' course.syncedWithGroup}}disabled{{/ifCond}}>
{{#each students}}
<option value="{{this._id}}" {{#if this.selected}}selected{{/if}} {{#if this.isHidden}}hidden{{/if}}>
{{this.lastName}}, {{this.firstName}}{{#if this.outdatedSince}} ~~{{/if}}
</option>
{{/each}}
</select>
{{#if course.syncedWithGroup}}
<input type="hidden" id="studentsIdSync" name="userIds" value="{{studentsSelected}}">
{{/if}}
</div>

<label>{{$t "administration.global.label.chooseDate"}}</label>
<div class="times" id="timesContainer">
<label>{{$t "administration.global.label.timeSpan"}}</label>
<div class="row">
<div class="form-group col-md-6">
{{> "lib/forms/form-date-input" label=($t "global.label.from") id="startDate" value=course.startDate disabled=@root.course.isArchived ariaLabel=($t "administration.global.label.chooseDate") }}
{{> "lib/forms/form-date-input" label=($t "global.label.from") id="startDate" value=course.startDate disabled=(isCond @root.course.isArchived '||' @root.course.syncedWithGroup) ariaLabel=($t "administration.global.label.chooseDate") }}
</div>
{{#if course.syncedWithGroup}}
<input type="hidden" id="startDateSync" name="startDate" value="{{startDate}}">
{{/if}}

<div class="form-group col-md-6">
{{> "lib/forms/form-date-input" label=($t "global.label.to") id="untilDate" value=course.untilDate disabled=@root.course.isArchived ariaLabel=($t "administration.global.label.chooseDate") }}
{{> "lib/forms/form-date-input" label=($t "global.label.to") id="untilDate" value=course.untilDate disabled=(isCond @root.course.isArchived '||' @root.course.syncedWithGroup) ariaLabel=($t "administration.global.label.chooseDate") }}
</div>
{{#if course.syncedWithGroup}}
<input type="hidden" id="untilDateSync" name="untilDate" value="{{untilDate}}">
{{/if}}
</div>

<table width="100%" cellpadding="5px">
Expand Down

0 comments on commit 88390be

Please sign in to comment.