Add Course to Curriculum #169

Merged
Wal merged 3 commits from AddBranchToCurriculum into master 2024-04-21 21:56:15 +02:00
10 changed files with 125 additions and 35 deletions

View File

@ -6,10 +6,7 @@ import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository; import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.*; import ovh.herisson.Clyde.Services.*;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.UserCurriculum;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -28,15 +25,18 @@ public class CourseController {
private final UserService userService; private final UserService userService;
private final CurriculumService curriculumService;
private final UserCurriculumService userCurriculumService; private final UserCurriculumService userCurriculumService;
private final CurriculumCourseRepository curriculumCourseRepository; private final CurriculumCourseRepository curriculumCourseRepository;
private final CurriculumCourseService curriculumCourseService; private final CurriculumCourseService curriculumCourseService;
public CourseController(CourseService courseServ, TeacherCourseService teacherCourseServ, AuthenticatorService authServ, UserService userService, UserCurriculumService userCurriculumService, CurriculumCourseRepository curriculumCourseRepository, CurriculumCourseService curriculumCourseService) { public CourseController(CourseService courseServ, TeacherCourseService teacherCourseServ, AuthenticatorService authServ, UserService userService, CurriculumService curriculumService, UserCurriculumService userCurriculumService, CurriculumCourseRepository curriculumCourseRepository, CurriculumCourseService curriculumCourseService) {
this.courseServ = courseServ; this.courseServ = courseServ;
this.teacherCourseServ = teacherCourseServ; this.teacherCourseServ = teacherCourseServ;
this.authServ = authServ; this.authServ = authServ;
this.userService = userService; this.userService = userService;
this.curriculumService = curriculumService;
this.userCurriculumService = userCurriculumService; this.userCurriculumService = userCurriculumService;
this.curriculumCourseRepository = curriculumCourseRepository; this.curriculumCourseRepository = curriculumCourseRepository;
this.curriculumCourseService = curriculumCourseService; this.curriculumCourseService = curriculumCourseService;
@ -82,16 +82,18 @@ public class CourseController {
} }
@PostMapping("/course") @PostMapping("/course/curriculum/{id}")
public ResponseEntity<Map<String ,Object>> postCourse(@RequestHeader("Authorization") String token, public ResponseEntity<Map<String ,Object>> postCourse(@RequestHeader("Authorization") String token,
@RequestBody Course course) @RequestBody Course course,@PathVariable long id)
{ {
if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)) if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
Course createdCourse = courseServ.save(course); Course createdCourse = courseServ.save(course);
if (createdCourse == null) Curriculum curriculum = curriculumService.findById(id);
if (createdCourse == null || curriculum == null)
return new ResponseEntity<>(null,HttpStatus.BAD_REQUEST); return new ResponseEntity<>(null,HttpStatus.BAD_REQUEST);
CurriculumCourse curriculumCourse = new CurriculumCourse(curriculum,course);
curriculumCourseService.save(curriculumCourse);
return new ResponseEntity<>(ProtectionService.courseWithoutPassword(createdCourse), HttpStatus.CREATED); return new ResponseEntity<>(ProtectionService.courseWithoutPassword(createdCourse), HttpStatus.CREATED);
} }

View File

@ -19,6 +19,7 @@ public class CurriculumController {
private final CurriculumService curriculumServ; private final CurriculumService curriculumServ;
private final CourseService courseServ;
private final AuthenticatorService authServ; private final AuthenticatorService authServ;
private final UserCurriculumService userCurriculumServ; private final UserCurriculumService userCurriculumServ;
@ -27,8 +28,9 @@ public class CurriculumController {
private final UserService userServ; private final UserService userServ;
private final ExternalCurriculumRepository ecr; private final ExternalCurriculumRepository ecr;
public CurriculumController(CurriculumService curriculumServ, AuthenticatorService authServ, UserCurriculumService userCurriculumServ, CurriculumCourseService curriculumCourseServ, InscriptionRepository ir, UserService userServ, ExternalCurriculumRepository ecr){ public CurriculumController(CurriculumService curriculumServ, CourseService courseServ, AuthenticatorService authServ, UserCurriculumService userCurriculumServ, CurriculumCourseService curriculumCourseServ, InscriptionRepository ir, UserService userServ, ExternalCurriculumRepository ecr){
this.curriculumServ = curriculumServ; this.curriculumServ = curriculumServ;
this.courseServ = courseServ;
this.authServ = authServ; this.authServ = authServ;
this.userCurriculumServ = userCurriculumServ; this.userCurriculumServ = userCurriculumServ;
this.curriculumCourseServ = curriculumCourseServ; this.curriculumCourseServ = curriculumCourseServ;
@ -60,6 +62,18 @@ public class CurriculumController {
return new ResponseEntity<>(curriculumCourseServ.getDepthCurriculum(curriculum),HttpStatus.OK); return new ResponseEntity<>(curriculumCourseServ.getDepthCurriculum(curriculum),HttpStatus.OK);
} }
@GetMapping("/course/curriculum/{id}")
public ResponseEntity<Iterable<Curriculum>> getCurriculumsByCourse(@RequestHeader("Authorization") String token, @PathVariable long id){
if(authServ.isNotIn(new Role[]{Role.Admin, Role.Secretary},token))
return new UnauthorizedResponse<>(null);
Course course = courseServ.findById(id);
if(course == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
Iterable<Curriculum> curriculum = curriculumCourseServ.findCurriculumByCourses(course);
return new ResponseEntity<>(curriculum, HttpStatus.OK);
}
//Return the list of all curicullums of an user //Return the list of all curicullums of an user
@GetMapping("/onescurriculum/{userId}") @GetMapping("/onescurriculum/{userId}")
@ -91,17 +105,20 @@ public class CurriculumController {
} }
@PostMapping("/curriculum/{id}") @PostMapping("/curriculum/{id}")
public ResponseEntity<String> postCoursesToCurriculum(@RequestHeader("Authorization") String token, public ResponseEntity<String> postCourseToCurriculum(@RequestHeader("Authorization") String token,
@RequestBody Iterable<Long> coursesIds, @RequestBody long coursesId,
@PathVariable long id) @PathVariable long id){
{
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
if (!curriculumCourseServ.saveAll(coursesIds, curriculumServ.findById(id))) CurriculumCourse curriculumCourse = new CurriculumCourse(curriculumServ.findById(id), courseServ.findById(coursesId));
if(curriculumCourse.getCourse() == null || curriculumCourse.getCurriculum() == null)
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
curriculumCourseServ.save(curriculumCourse);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }

View File

@ -1,5 +1,7 @@
package ovh.herisson.Clyde.Repositories; package ovh.herisson.Clyde.Repositories;
import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;
@ -11,7 +13,15 @@ public interface CurriculumCourseRepository extends CrudRepository<CurriculumCou
@Query("select distinct cc.course from CurriculumCourse cc where cc.curriculum = ?1") @Query("select distinct cc.course from CurriculumCourse cc where cc.curriculum = ?1")
Iterable<Course> findCoursesByCurriculum(Curriculum curriculum); Iterable<Course> findCoursesByCurriculum(Curriculum curriculum);
@Query("select distinct cc.curriculum from CurriculumCourse cc where cc.course = ?1")
Iterable<Curriculum> findCurriculumByCourses(Course course);
@Query("select distinct cc.curriculum from CurriculumCourse cc") @Query("select distinct cc.curriculum from CurriculumCourse cc")
Iterable<Curriculum> findDistinctCurriculums(); Iterable<Curriculum> findDistinctCurriculums();
@Modifying
@Transactional
@Query("delete from CurriculumCourse cc where cc.course =?1")
void delete(Course course);
} }

View File

@ -51,6 +51,10 @@ public class CurriculumCourseService {
return toReturn; return toReturn;
} }
public Iterable<Curriculum> findCurriculumByCourses(Course course){
return curriculumCourseRepo.findCurriculumByCourses(course);
}
public Iterable<Map<String, Object>> getAllDepthCurriculum(){ public Iterable<Map<String, Object>> getAllDepthCurriculum(){
ArrayList<Map<String,Object>> toReturn = new ArrayList<>(); ArrayList<Map<String,Object>> toReturn = new ArrayList<>();

View File

@ -105,6 +105,7 @@ courses.modify=Modify
courses.toDelete=Course to Delete courses.toDelete=Course to Delete
courses.confirm=Confirm courses.confirm=Confirm
courses.back=Back courses.back=Back
courses.AddToCurriculum=Add to a new Curriculum
profile.modify.data=Modify personnal data profile.modify.data=Modify personnal data
profile.reRegister=Re-register profile.reRegister=Re-register
profile.unRegister=Unregister profile.unRegister=Unregister

View File

@ -105,6 +105,7 @@ courses.modify=Modifier
courses.toDelete=Cours à supprimer courses.toDelete=Cours à supprimer
courses.confirm=Confirmer courses.confirm=Confirmer
courses.back=Retour courses.back=Retour
courses.AddToCurriculum=Ajouter à un cursus
profile.modify.data=Modifier données personnelles profile.modify.data=Modifier données personnelles
profile.reRegister=Réinsciption profile.reRegister=Réinsciption
profile.unRegister=Désinscription profile.unRegister=Désinscription

View File

@ -3,26 +3,27 @@
import {reactive , ref} from 'vue' import {reactive , ref} from 'vue'
import { getCourses,deleteCourse,alterCourse,createCourse } from "@/rest/courses.js" import { getCourses,deleteCourse,alterCourse,createCourse } from "@/rest/courses.js"
import {getUser, getSelf, getTeachers } from "@/rest/Users.js" import {getUser, getSelf, getTeachers } from "@/rest/Users.js"
import {addCourseToCurriculum, getAllCurriculums, getCurriculumsByCourse} from "@/rest/curriculum.js";
const self = await getSelf(); const self = await getSelf();
const curriculum = ref(await getCourses(self.role)); const curriculum = ref(await getCourses(self.role));
const profList = await getTeachers(); const profList = await getTeachers();
const allCurriculums = ref(await getAllCurriculums());
const curriculumToAdd = ref();
const createMod = ref(false) const createMod = ref(false)
const deleteMod = ref(false) const deleteMod = ref(false)
const editElementID = ref("") const editElementID = ref("")
const editAddCourse = ref("");
function editItem(id){
editElementID.value = id;
}
//Juste pour montrer le Create Mode const curriculumToAddId = ref()
const pattern = { const pattern = {
"id":null,
"title":null, "title":null,
"credits":null, "credits":null,
"owner":null, "owner":null,
@ -41,14 +42,40 @@
} }
if (!isnull){ if (!isnull){
await createCourse(toAdd.title,toAdd.credits,toAdd.owner); await createCourse(toAdd.id,toAdd.title,toAdd.credits,toAdd.owner);
toAdd= Object.assign({},pattern); toAdd= Object.assign({},pattern);
curriculum.value = await getCourses(self.role); curriculum.value = await getCourses(self.role);
}} }}
async function setAddToCurriculum(item){
let temp = [];
let courseCurriculum = await getCurriculumsByCourse(item.courseID);
let isIn = false;
for (let element in allCurriculums.value){
for (let item in courseCurriculum){
if((courseCurriculum[item].option == allCurriculums.value[element].option) && (courseCurriculum[item].year == allCurriculums.value[element].year) ){
isIn = true;
break;
}
}
if(!isIn){
temp.push(allCurriculums.value[element])
}
isIn = false;
}
curriculumToAdd.value = temp.slice();
}
async function addToCurriculum(item){
await addCourseToCurriculum(curriculumToAddId.value,item.courseID);
curriculumToAddId.value = null;
curriculumToAdd.value = null;
allCurriculums.value = await getAllCurriculums();
}
function setModify(item){ function setModify(item){
for(const el in profList){ for(const el in profList){
@ -96,13 +123,18 @@
<button class="create" @click="editElementID= '';createMod = true;"> <button class="create" @click="editElementID= '';createMod = true;">
{{i18n("courses.createCourse")}} {{i18n("courses.createCourse")}}
</button> </button>
<button class="delete" @click="deleteMod=true" > <button class="delete" @click="deleteMod=true">
{{i18n("courses.deleteCourse")}} {{i18n("courses.deleteCourse")}}
</button> </button>
</div> </div>
<div v-if="createMod"> <div v-if="createMod">
<form class="listElement" style="width:40%;margin-right:auto;margin-left:auto;"> <form class="listElement" style="width:40%;margin-right:auto;margin-left:auto;">
<div style="margin-bottom: 20px">
{{i18n("Curriculum")}}
<select v-model="toAdd.id">
<option v-for="element in allCurriculums" :value="element.curriculumId">{{element.option}}-{{element.year}}</option>
</select>
</div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("name")}} : {{i18n("name")}} :
<input v-model="toAdd.title"> <input v-model="toAdd.title">
@ -136,24 +168,39 @@
</div> </div>
<div v-if="!createMod && !deleteMod" v-for="item in curriculum" :key="item.title" style="width:50%;margin-left:auto; margin-right:auto;"> <div v-if="!createMod && !deleteMod" v-for="item in curriculum" :key="item.title" style="width:50%;margin-left:auto; margin-right:auto;">
<div v-if="editElementID !== item.title" style ="padding:15px 15px 15px 15px;"> <div v-if="editElementID !== item.title && editAddCourse !== item.title" style ="padding:15px 15px 15px 15px;">
<button @click="editElementID = item.title; setModify(item); "> <button @click="editElementID = item.title; editAddCourse = ''; setModify(item); ">
{{i18n("courses.modify")}} {{i18n("courses.modify")}}
</button> </button>
<button v-if="self.role !== 'Teacher'"@click="editAddCourse = item.title; editElementID ='';setAddToCurriculum(item)">Add to a new Curriculum</button>
</div> </div>
<div v-else> <div v-if="editElementID == item.title">
<button @click="editElementID= '';patchCourse(item)"> {{i18n("courses.confirm")}} </button> <button @click="editElementID= '';patchCourse(item)"> {{i18n("courses.confirm")}} </button>
<button @click="editElementID= '';"> {{i18n("courses.back")}} </button> <button @click="editElementID= '';"> {{i18n("courses.back")}} </button>
</div> </div>
<div class="listElement" > <div v-if="editAddCourse == item.title">
<button @click="editAddCourse= '';addToCurriculum(item)"> {{i18n("courses.confirm")}} </button>
<button @click="editAddCourse= '';"> {{i18n("courses.back")}} </button>
</div>
<div class="listElement">
<div class="containerElement" v-if="editElementID !== item.title" > <div class="containerElement" v-if="editElementID !== item.title && editAddCourse !== item.title" >
<div class="name"> {{item.title}} </div> <div class="name"> {{item.title}} </div>
<div class="teacher">{{item.owner.lastName}}</div> <div class="teacher">{{item.owner.lastName}}</div>
<div class="credits">{{i18n("Credits")}}:{{item.credits}}</div> <div class="credits">{{i18n("Credits")}}:{{item.credits}}</div>
</div> </div>
<div class="containerElement"v-else>
<div class="containerElement" v-if="editAddCourse == item.title" >
{{i18n("Curriculum")}}:
<select v-model="curriculumToAddId">
<option v-for="element in curriculumToAdd" :value="element.curriculumId">
{{element.option}}-{{element.year}}
</option>
</select>
</div>
<div class="containerElement" v-if="editElementID == item.title">
<input style="max-width:200px;" class="name" v-model="toModify.title"> <input style="max-width:200px;" class="name" v-model="toModify.title">
<select v-if="self.role != 'Secretary'" style="max-width:200px;" class="teacher" v-model="toModify.owner"> <select v-if="self.role != 'Secretary'" style="max-width:200px;" class="teacher" v-model="toModify.owner">
<option v-for="(item,index) in profList" :value='item'>{{item.lastName}}</option> <option v-for="(item,index) in profList" :value='item'>{{item.lastName}}</option>
@ -162,6 +209,8 @@
<input v-if="self.role !='Secretary'"style="max-width:100px;"class="credits" v-model="toModify.credits"> <input v-if="self.role !='Secretary'"style="max-width:100px;"class="credits" v-model="toModify.credits">
<div v-else class="credits">{{i18n("Credits")}}:{{item.credits}}</div> <div v-else class="credits">{{i18n("Credits")}}:{{item.credits}}</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -136,7 +136,7 @@ async function askChanges(i){
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("schedule")}} : {{i18n("schedule")}} :
<select @change="setCourses()"v-model="curriculum"> <select @change="setCourses()"v-model="curriculum">
<option v-for="item in allSchedules" :value='item.curriculum'>{{item.curriculum.option}}</option> <option v-for="item in allSchedules" :value='item.curriculum'>{{item.curriculum.option}}-{{item.curriculum.year}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">

View File

@ -7,8 +7,8 @@ import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
/** /**
* Create a new course * Create a new course
*/ */
export async function createCourse(name, credits, owner){ export async function createCourse(id,name, credits, owner){
return restPost("/course", {title: name, credits: credits, owner} ) return restPost("/course/curriculum/" + id, {title: name, credits: credits, owner} )
} }
/** /**
@ -19,7 +19,7 @@ export async function deleteCourse(id){
} }
/** /**
* Get informations on a particular course * Get information on a particular course
* *
* @param id identification of the course * @param id identification of the course
* *

View File

@ -23,6 +23,9 @@ export async function getAllCurriculums(){
return restGet("/curriculums"); return restGet("/curriculums");
} }
export async function getCurriculumsByCourse(id){
return restGet("/course/curriculum/"+ id);
}
/** /**
* Get informations on a particular curriculum * Get informations on a particular curriculum
* *
@ -53,4 +56,7 @@ export async function getSomeonesCurriculumList(user){
return restGet("/onescurriculum/"+user) return restGet("/onescurriculum/"+user)
} }
export async function addCourseToCurriculum(id,courseID){
return restPost("/curriculum/"+id, courseID);
}