1
0
forked from PGL/Clyde

49 Commits

Author SHA1 Message Date
c1b8c39e92 adding to readme 2024-04-22 23:18:55 +02:00
3825565b16 Merge pull request 'fixed views update' (#188) from Maxime/Clyde:master into master
Reviewed-on: PGL/Clyde#188
2024-04-22 22:37:26 +02:00
48640dfa8b fixed views update 2024-04-22 22:36:12 +02:00
3acfd02bfb fixup! fixup! fixup! fix ci 2024-04-22 22:27:44 +02:00
a3fe6ce6bd fixup! fixup! fix ci 2024-04-22 22:26:31 +02:00
96965bde97 Merge pull request 'master' (#187) from Maxime/Clyde:master into master
Reviewed-on: PGL/Clyde#187
2024-04-22 22:13:49 +02:00
302e0b555c Merge remote-tracking branch 'origin/master' 2024-04-22 22:12:57 +02:00
Wal
84a408298d Merge pull request 'Last Correction Schedule' (#186) from miniCorrectionFinal into master
Reviewed-on: PGL/Clyde#186
2024-04-22 22:11:51 +02:00
3b48e5adfb Last Correction Schedule 2024-04-22 22:08:17 +02:00
78da7b23d2 fixup! fix ci 2024-04-22 21:38:50 +02:00
1831cc7eb2 fix ci 2024-04-22 21:05:51 +02:00
Wal
cc51510dac Merge pull request 'Little Correction in schedules' (#185) from origin/littleCorrections into master
Reviewed-on: PGL/Clyde#185
2024-04-22 20:53:53 +02:00
44bb04f21b Little Correction in schedules 2024-04-22 20:49:39 +02:00
1ed61c8c7b Merge pull request 'Fixing tests and tokenService' (#184) from f into master
Reviewed-on: PGL/Clyde#184
2024-04-22 20:44:53 +02:00
59c82d7482 Merge branch 'master' into f 2024-04-22 20:37:59 +02:00
772fa09e28 Fixing tests and tokenService 2024-04-22 20:35:30 +02:00
672fcd099f Merge pull request 'Fixing stuffs' (#183) from e into master
Reviewed-on: PGL/Clyde#183
2024-04-22 18:50:33 +02:00
3198a7ade0 Merge branch 'master' into e 2024-04-22 18:27:51 +02:00
5516f75346 Fixing stuffs 2024-04-22 18:27:06 +02:00
1f66ac5a4d Merge remote-tracking branch 'origin/master' 2024-04-22 18:26:31 +02:00
Wal
59b82abf71 Merge pull request 'Post mock when arrives on the app' (#182) from PostMockAndCorrections into master
Reviewed-on: PGL/Clyde#182
2024-04-22 13:35:10 +02:00
cf0c465248 Merge remote-tracking branch 'origin/master' into PostMockAndCorrections 2024-04-22 13:31:31 +02:00
2917d645fa post Mock and corrections 2024-04-22 13:29:59 +02:00
730a72dba3 added profile picture handling 2024-04-22 13:19:08 +02:00
47eb98da57 Merge pull request 'Cleaning backend' (#181) from e into master
Reviewed-on: PGL/Clyde#181
2024-04-22 13:08:35 +02:00
eafcf6b265 Cleaning backend 2024-04-22 13:06:33 +02:00
34e537ff02 fixed push of researcher 2024-04-22 12:19:21 +02:00
364f39c4bc put the about user in the middle 2024-04-22 11:58:42 +02:00
f2675ed764 Merge remote-tracking branch 'origin/master' 2024-04-22 11:42:48 +02:00
85c1282f48 Merge pull request 'master' (#180) from Maxime/Clyde:master into master
Reviewed-on: PGL/Clyde#180
2024-04-22 11:31:25 +02:00
490bf403f0 Merge pull request 'Add the regNo in profile and aboutStudent' (#178) from regNoFix into master
Reviewed-on: PGL/Clyde#178
2024-04-22 09:52:56 +02:00
c61a092809 Add the regNo in profile and aboutStudent 2024-04-22 09:39:48 +02:00
2cffe28720 show regno on options 2024-04-22 09:22:19 +02:00
060526c20d timer on notifications 2024-04-22 09:09:53 +02:00
af8bc8872d Merge pull request 'fix with the stats and translations' (#177) from Maxime/Clyde:master into master
Reviewed-on: PGL/Clyde#177
2024-04-22 02:28:41 +02:00
82cf7cbfaf removing apps spacing 2024-04-22 01:46:46 +02:00
3b63896439 Merge pull request 'tonitch/front/bar' (#176) from tonitch/front/bar into master
Reviewed-on: PGL/Clyde#176
2024-04-22 01:39:48 +02:00
bd3b03dfea Merge pull request 'ok last one I promise' (#175) from prank into master
Reviewed-on: PGL/Clyde#175
2024-04-22 00:55:40 +02:00
b38b1ab6b8 Merge branch 'master' into prank 2024-04-22 00:51:58 +02:00
6e0a9a46e5 ok last one I promise 2024-04-22 00:50:44 +02:00
2d8fcb4712 Merge pull request 'Fixing some little bugs and details' (#174) from last into master
Reviewed-on: PGL/Clyde#174
2024-04-22 00:42:56 +02:00
fcb48ac71a Fixing some little bugs and details 2024-04-22 00:39:17 +02:00
043f5c87d2 fixup! fix bar height 2024-04-22 00:12:59 +02:00
a03983d625 fix bar height 2024-04-22 00:09:39 +02:00
b382bf957f Merge pull request 'master' (#173) from Maxime/Clyde:master into master
Reviewed-on: PGL/Clyde#173
2024-04-22 00:06:59 +02:00
bbddcb26ad fixup! Merge pull request 'Notifications on Schedule' (#172) from NotificationSchedule into master 2024-04-22 00:03:45 +02:00
Wal
71c2af7fcb Merge pull request 'Notifications on Schedule' (#172) from NotificationSchedule into master
Reviewed-on: PGL/Clyde#172
2024-04-21 23:39:29 +02:00
c717205764 Notifications Schedule 2024-04-21 23:36:25 +02:00
8ac1f7ed8b notifications forum 2024-04-21 23:25:03 +02:00
38 changed files with 204 additions and 118 deletions

View File

@ -14,26 +14,26 @@ on:
workflow_dispatch:
jobs:
deploy-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
working-directory: ./frontend
- run: npm ci
name: clean install
working-directory: ./frontend
- name: building
working-directory: ./frontend
run: npm run build
- name: pushing to the server
working-directory: ./frontend
run: |
echo "${{ secrets.SSH_KEY }}" > key
chmod 0600 key
scp -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key -r dist/ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:
- run: echo "The website has been deployed. visit https://clyde.herisson.ovh/"
# deploy-frontend:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - name: Use Node.js ${{ matrix.node-version }}
# uses: actions/setup-node@v3
# working-directory: ./frontend
# - run: npm ci
# name: clean install
# working-directory: ./frontend
# - name: building
# working-directory: ./frontend
# run: npm run build
# - name: pushing to the server
# working-directory: ./frontend
# run: |
# echo "${{ secrets.SSH_KEY }}" > key
# chmod 0600 key
# scp -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key -r dist/ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:
# - run: echo "The website has been deployed. visit https://clyde.herisson.ovh/"
deploy-backend:
runs-on: ubuntu-latest
@ -46,5 +46,5 @@ jobs:
scp -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key -r * ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:api/
- name: restarting the backend
run: |
ssh -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 'cd api/ && sed -i compose.yaml -e "s/8080:8080/4001:8080/" -e "s/8000:8080/4000:8080/" && docker-compose up --force-recreate --build -d'
ssh -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 'cd api/ && sed -i compose.yaml -e "s/8080:8080/4001:8080/" -e "s/8000:8080/4000:8080/" && sed -e "8d" -i frontend/Dockerfile && docker-compose up --force-recreate --build -d'
- run: echo "The backend has been deployed. running at https://clyde.herisson.ovh/api"

View File

@ -1,5 +1,7 @@
# Clyde project
Système de gestion d'universitée (dévelopé dans le cadre du cours de projet de génie logiciel de l'Umons 2024)
## Signature
Projet du groupe 01:
@ -11,21 +13,28 @@ Projet du groupe 01:
## Running
**Attention**: Vous devez avoir installé docker-compose pour lancer ce projet.
Le projet peut être lancé grace à docker compose.
```sh
$ docker compose up
```
Dans le cas ou vous modifiers des fichiers, pour éviter que les images de docker soient recrées avec les changement
Dans le cas ou vous modifiez des fichiers, pour éviter que les images de docker ne soient réutilisés sans les
changements.
```sh
$ docker compose up --force-recreate --build
```
Vous pouvez alors accéder au frontend à l'adresse [http://localhost:5173](http://localhost:5173)
Une version finie du site construite automatiquement à l'aide de gitea actions tourne à l'adresse
[https://clyde.herisson.ovh/](https://clyde.herisson.ovh/)
## Dévelopement
Dans le cas ou vous êtes dans une phase de développement, il est plus simple d'utiliser gradle pour lancer le backend et frontend dans un mode de développement.
Dans le cas ou vous êtes dans une phase de développement, il est plus simple d'utiliser gradle pour lancer le backend et frontend.
**Attention**: Ce mode n'est pas fait pour être utilisé en production!
```sh
@ -38,4 +47,3 @@ Ceci requière également docker pour lancer une instance de postgresql pris en
Il est possible de se passer entièrement de docker en supprimant la dépendance dans le fichier `backend/build.gradle.kts`: ~~`developmentOnly("org.springframework.boot:spring-boot-docker-compose")`~~
Il est alors nécéssaire d'avoir une instance de postgresql tournant sur `localhost:5432` avec une table `clyde`, utilisateur: `devel` et password: `devel`
(cette configuration peut également être changée dans le fichier resources/application.properties de spring)

View File

@ -13,10 +13,7 @@ import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.TokenService;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
import ovh.herisson.Clyde.Tables.Inscription.Minerval;
import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest;
import ovh.herisson.Clyde.Tables.Inscription.UnregisterRequest;
import ovh.herisson.Clyde.Tables.Inscription.*;
import java.util.ArrayList;
import java.util.Calendar;
@ -328,7 +325,7 @@ public class RequestsController {
return new ResponseEntity<>(HttpStatus.OK);
}
toEdit.setState(newteacherstate);
toEdit.setTeacherApprovalState(newteacherstate);
changeCurriculumRequestRepository.save(toEdit);
if (newteacherstate == RequestState.Accepted && toEdit.getState() == RequestState.Accepted){

View File

@ -12,14 +12,8 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.LessonRequestService;
import ovh.herisson.Clyde.Services.LessonService;
import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Tables.LessonChangesRequest;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Services.*;
import ovh.herisson.Clyde.Tables.*;
import java.util.Map;
@ -28,11 +22,13 @@ import java.util.Map;
public class LessonRequestsController {
private final LessonRequestService lessonRequestServ;
private final AuthenticatorService authServ;
private final UserService userServ;
private final LessonService lessonServ;
public LessonRequestsController(LessonRequestService lessonRequestServer, AuthenticatorService authServ, LessonService lessonServ) {
public LessonRequestsController(LessonRequestService lessonRequestServer, AuthenticatorService authServ, UserService userServ, LessonService lessonServ) {
this.lessonRequestServ = lessonRequestServer;
this.authServ = authServ;
this.userServ = userServ;
this.lessonServ = lessonServ;
}
/**
@ -113,6 +109,7 @@ public class LessonRequestsController {
if(lessonRequest.getRequestType() == 0 ) {
if (!lessonRequestServ.modifyCreateRequestState(lessonRequest, state, local))
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
userServ.Notify(lessonRequest.getUser(), new Notification("Request took in charge","Request"+ state + ":" + lessonRequest.getCourse().getTitle(), "#/manage-owned-lessons"));
}
else if(lessonRequest.getRequestType() == 1){
@ -122,12 +119,14 @@ public class LessonRequestsController {
if(!lessonRequestServ.modifyChangeRequestState(infos,lessonRequest.getLessonId(),state))
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
lessonRequest.setState(state);
userServ.Notify(lessonRequest.getUser(), new Notification("Request took in charge","Request"+ state + ":" + lessonServ.findById(lessonRequest.getLessonId()).getCourse().getTitle(), "#/manage-owned-lessons"));
}
else{
userServ.Notify(lessonRequest.getUser(), new Notification("Request took in charge","Request"+ state + ":" + lessonServ.findById(lessonRequest.getLessonId()).getCourse().getTitle(), "#/manage-owned-lessons"));
lessonRequestServ.modifyDeleteRequest(lessonRequest, state);
lessonRequest.setState(state);
}
lessonRequestServ.save(lessonRequest);
return new ResponseEntity<>(HttpStatus.OK);

View File

@ -42,6 +42,7 @@ public class MockController {
public final LessonRequestService lessonRequestService;
ArrayList<User> mockUsers;
public static boolean isMocked = false;
public final ResearchesService researchesService;
public final UserCurriculumRepository ucr;
public final MinervalRepository minervalRepository;
@ -78,7 +79,7 @@ public class MockController {
@PostMapping("/mock")
public void postMock() {
if(!isMocked){
// user part
User herobrine = new User("brine","hero","admin@admin.com","behind","ShadowsLand",new Date(0), null,Role.Admin,"admin");
User joe = new User("Piplo","Joe","student@student.com","roundabout","England",new Date(0), null,Role.Student,"student");
@ -184,11 +185,11 @@ public class MockController {
//Schedule part
Lesson lesson_0_progra1 = new Lesson(progra1, "Mon Apr 22 2024 08:15", "Mon Apr 22 2024 10:15","rgb(0,50,100)","A0B2","Course");
Lesson lesson_0_chemistry1 = new Lesson(chemistry1, "Wed Mar 27 2024 08:15", "Wed Mar 27 2024 09:15","rgb(100,50,0)","A0B2","TP");
Lesson lesson_0_psycho1 = new Lesson(psycho1, "Sun Mar 24 2024 10:30 ","Sun Mar 24 2024 12:30 ","rgb(100,50,100)", "A0B2","TD");
Lesson lesson_1_progra1 = new Lesson(progra1, "Mon Apr 02 2024 13:30", "Mon Apr 02 2024 15:30","rgb(0,50,100)","A0B2","TP");
Lesson lesson_0_commun = new Lesson(commun, "Mon Apr 01 2024 10:30", "Mon Apr 01 2024 12:30","rgb(0,50,100)","A0B2","Course");
Lesson lesson_0_progra1 = new Lesson(progra1, "Mon Apr 22 2024 08:15", "Mon Apr 22 2024 10:15","rgb(255,36,175)","A0B2","Course");
Lesson lesson_0_chemistry1 = new Lesson(chemistry1, "Wed Mar 27 2024 08:15", "Wed Mar 27 2024 09:15","rgb(36,175,255)","A0B2","TP");
Lesson lesson_0_psycho1 = new Lesson(psycho1, "Sun Mar 24 2024 10:30 ","Sun Mar 24 2024 12:30 ","rgb(255,36,175)", "A0B2","TD");
Lesson lesson_1_progra1 = new Lesson(progra1, "Mon Apr 02 2024 13:30", "Mon Apr 02 2024 15:30","rgb(36,175,255)","A0B2","TP");
Lesson lesson_0_commun = new Lesson(commun, "Mon Apr 01 2024 10:30", "Mon Apr 01 2024 12:30","rgb(255,36,175)","A0B2","Course");
LessonChangesRequest request1 = new LessonChangesRequest(joke,RequestState.Pending,null,null,null,null,2,null,1);
LessonChangesRequest request2 = new LessonChangesRequest(joke,RequestState.Pending,"Fri Apr 19 2024 10:30 ","Fri Apr 19 2024 12:30 ",null,null,1,null,2);
@ -230,6 +231,9 @@ public class MockController {
externalCurriculum = new ExternalCurriculum(inscriptionRequest, "HEH", "Bachelier en informatique", "Completed", 2015, 2018, null, null);
externalCurriculumRepository.save(externalCurriculum);
isMocked = true;
}
}
}

View File

@ -44,7 +44,7 @@ public class UserController {
@GetMapping("/user/{id}")
public ResponseEntity<HashMap<String ,Object>> getUserById(@RequestHeader("Authorization") String token, @PathVariable Long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService, Role.Teacher},token))
return new UnauthorizedResponse<>(null);
return new ResponseEntity<>(ProtectionService.userWithoutPassword(userService.getUserById(id)), HttpStatus.OK);

View File

@ -1,7 +1,7 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.ChangeCurriculumRequest;
import ovh.herisson.Clyde.Tables.Inscription.ChangeCurriculumRequest;
public interface ChangeCurriculumRequestRepository extends CrudRepository<ChangeCurriculumRequest, Long> {
ChangeCurriculumRequest findById(long id);

View File

@ -22,6 +22,9 @@ public interface ScheduleLessonRepository extends CrudRepository<ScheduleLesson,
@Query("select distinct sl.schedule from ScheduleLesson sl where sl.schedule.curriculum = ?1")
Schedule findScheduleByCurriculum(Curriculum curriculum);
@Query("select distinct sl from ScheduleLesson sl where sl.lesson = ?1")
ScheduleLesson findByLesson(Lesson lesson);
@Modifying
@Transactional
@Query("delete from ScheduleLesson sl where sl.lesson =?1")

View File

@ -13,9 +13,11 @@ public interface UserCurriculumRepository extends CrudRepository<UserCurriculum,
@Query("select uc.curriculum from UserCurriculum uc where uc.user = ?1")
Curriculum findByUser(User student);
@Query("select distinct uc.user from UserCurriculum uc where uc.curriculum = ?1")
Iterable<User> findUsersByCurriculum(Curriculum curriculum);
ArrayList<UserCurriculum> findByUserOrderByCurriculum(User student);
UserCurriculum findByUserAndCurriculumAndActual(User user, Curriculum curriculum, boolean actual);
ArrayList<UserCurriculum> findByUserAndActual(User user, boolean actual);
}

View File

@ -7,10 +7,7 @@ package ovh.herisson.Clyde.Services;
* @scope Extension Horaire
******************************************************/
import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository;
import ovh.herisson.Clyde.Repositories.LessonRepository;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Repositories.*;
import ovh.herisson.Clyde.Tables.*;
import java.util.ArrayList;
@ -19,12 +16,17 @@ import java.util.Map;
@Service
public class LessonService {
private final LessonRepository lessonRepo;
private final ScheduleLessonRepository scheduleLessonRepo;
private final UserCurriculumRepository userCurriculumRepo;
private final UserService userServ;
private final CourseRepository courseRepo;
private final CurriculumCourseRepository curriculumCourseRepo;
public LessonService(LessonRepository lessonRepo, UserCurriculumRepository userCurriculumRepo, CourseRepository courseRepo, CurriculumCourseRepository curriculumCourseRepo){
public LessonService(LessonRepository lessonRepo, ScheduleLessonRepository scheduleLessonRepo, UserCurriculumRepository userCurriculumRepo, UserService userServ, CourseRepository courseRepo, CurriculumCourseRepository curriculumCourseRepo){
this.lessonRepo = lessonRepo;
this.scheduleLessonRepo = scheduleLessonRepo;
this.userCurriculumRepo = userCurriculumRepo;
this.userServ = userServ;
this.courseRepo = courseRepo;
this.curriculumCourseRepo = curriculumCourseRepo;
}
@ -136,7 +138,12 @@ public class LessonService {
break;
}
}
lessonRepo.save(target);
Lesson lesson = lessonRepo.save(target);
ScheduleLesson scheduleLesson = scheduleLessonRepo.findByLesson(lesson);
Iterable<User> users = userCurriculumRepo.findUsersByCurriculum(scheduleLesson.getSchedule().getCurriculum());
for(User user: users){
userServ.Notify(user, new Notification("Course modified in the schedule", "Course Modified " + lesson.getCourse().getTitle() , "/#/schedule"));
}
return true;
}
/**

View File

@ -6,7 +6,9 @@ import lombok.AllArgsConstructor;
import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.Msg.ForumRepository;
import ovh.herisson.Clyde.Repositories.Msg.TopicRepository;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Notification;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Answer;
import ovh.herisson.Clyde.Tables.Msg.Forum;
@ -16,17 +18,24 @@ import ovh.herisson.Clyde.Tables.Msg.Topic;
@AllArgsConstructor
public class ForumService {
private UserService userServ;
private CourseRepository courseRepo;
private ForumRepository forumRepo;
private TopicRepository topicRepo;
public void createForum(Course c, Forum f){
c.addForum(f);
for (User u: f.getRegister()) {
userServ.Notify(u, new Notification("forum.notification.forum.new", f.getName(), "/#/Forum"));
}
courseRepo.save(c);
}
public void createTopic(Forum f, Topic data) {
f.addTopic(data);
for (User u: f.getRegister()) {
userServ.Notify(u, new Notification("forum.notification.topic.new", data.getSubject(), "/#/Forum"));
}
forumRepo.save(f);
}

View File

@ -9,22 +9,26 @@ import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Repositories.LessonRepository;
import ovh.herisson.Clyde.Repositories.ScheduleLessonRepository;
import ovh.herisson.Clyde.Repositories.ScheduleRepository;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Tables.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@Service
public class ScheduleLessonService {
private final ScheduleLessonRepository scheduleLessonRepo;
private final UserCurriculumRepository userCurriculumRepo;
private final UserService userServ;
private final LessonRepository lessonRepo;
private final ScheduleRepository scheduleRepo;
public ScheduleLessonService(ScheduleLessonRepository scheduleLessonRepo, LessonRepository lessonRepo, ScheduleRepository scheduleRepo) {
public ScheduleLessonService(ScheduleLessonRepository scheduleLessonRepo, UserCurriculumRepository userCurriculumRepo, UserService userServ, LessonRepository lessonRepo, ScheduleRepository scheduleRepo) {
this.scheduleLessonRepo = scheduleLessonRepo;
this.userCurriculumRepo = userCurriculumRepo;
this.userServ = userServ;
this.lessonRepo = lessonRepo;
this.scheduleRepo = scheduleRepo;
}
@ -32,19 +36,22 @@ public class ScheduleLessonService {
if(scheduleLesson == null)
return false;
scheduleLessonRepo.save(scheduleLesson);
Iterable<User> users = userCurriculumRepo.findUsersByCurriculum(scheduleLesson.getSchedule().getCurriculum());
for(User user: users){
userServ.Notify(user, new Notification("New course in the schedule", "Course added " + scheduleLesson.getLesson().getCourse().getTitle(), "/#/schedule"));
}
return true;
}
/**
* Save a lesson to all the schedule it is linked
*/
public boolean saveToAllSchedule(Lesson lesson){
public void saveToAllSchedule(Lesson lesson){
Iterable<Schedule> schedules = scheduleRepo.findAllLessonSchedule(lesson.getCourse());
if(schedules == null)
return false;
return;
for (Schedule schedule : schedules){
save(new ScheduleLesson(schedule, lesson));
}
return true;
}
/**
* Delete a scheduleLesson via its lesson
@ -52,6 +59,11 @@ public class ScheduleLessonService {
public boolean delete(long lessonId){
if(lessonId == 0)
return false;
ScheduleLesson scheduleLesson = scheduleLessonRepo.findByLesson(lessonRepo.findById(lessonId));
Iterable<User> users = userCurriculumRepo.findUsersByCurriculum(scheduleLesson.getSchedule().getCurriculum());
for(User user: users){
userServ.Notify(user, new Notification("Course deleted in the schedule","Course deleted " + scheduleLesson.getLesson().getCourse().getTitle(), "/#/schedule"));
}
scheduleLessonRepo.delete(lessonRepo.findById(lessonId));
return true;
}

View File

@ -51,8 +51,8 @@ public class TokenService {
ArrayList<Token> tokenList = tokenRepo.getByUserOrderByExpirationDate(token.getUser());
while(tokenList.size() >= 5){
tokenRepo.delete(tokenList.getFirst());
tokenList.remove(tokenList.getFirst());
tokenRepo.delete(tokenList.get(0));
tokenList.remove(tokenList.get(0));
}
tokenRepo.save(token);
}

View File

@ -1,6 +1,9 @@
package ovh.herisson.Clyde.Tables;
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;

View File

@ -2,8 +2,6 @@ package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;

View File

@ -7,7 +7,6 @@ import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;
import java.util.Map;
@Entity
public class ScholarshipRequest {

View File

@ -3,7 +3,6 @@ package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;

View File

@ -12,6 +12,7 @@ import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.Tables.Msg.Message;
import ovh.herisson.Clyde.Tables.Notification.Status;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -41,7 +42,7 @@ public class User {
@JsonIgnore
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Notification> notifications;
private List<Notification> notifications = new ArrayList<>();
////// Extension Messagerie /////
@JsonIgnore

View File

@ -23,6 +23,7 @@ import ovh.herisson.Clyde.Repositories.TokenRepository;
import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.TokenService;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.Token;
import ovh.herisson.Clyde.Tables.User;
@ -46,7 +47,8 @@ public class UserControllerTest {
@Autowired
private TokenService tokenService;
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@Autowired
@ -72,6 +74,7 @@ public class UserControllerTest {
@BeforeEach
void setup(){
RestAssured.baseURI = "http://localhost:" + port;
userRepository.deleteAll();
}
@AfterEach
@ -84,7 +87,7 @@ public class UserControllerTest {
public void userPostTest(){
User god = new User("god","god","admin@admin.com","everywhere","every",new Date(0), null, Role.Admin,"goddoesntneedpassword");
Token godToken = new Token(god, tokenService.generateNewToken(), new Date());
userRepository.save(god);
userService.save(god);
tokenService.saveToken(godToken);
//Can god post herobrine himself ?

View File

@ -70,7 +70,7 @@ class TokenServiceTest {
ArrayList<Token> tokenList = new ArrayList<>();
GregorianCalendar gc = new GregorianCalendar();
User malveillant = new User("Cargo", "John", "CargoJ@mail.com", "secret", "secret", null, null, null, "secret");
User malveillant = new User("Cargo", "John", "CargoJ@mail.com", "secret", "secret", new Date(), null, "secret", null);
userRepository.save(malveillant);
for (int i = 0; i < 20; i++){

View File

@ -50,6 +50,7 @@ Delete=Delete
Modify=Modify
Create=Créer
requestType=Request Type
lessonType=Course Type
day=Day
start=Start
end=End
@ -203,6 +204,8 @@ msg.notification.new=You have a new message
forum.create=Create forum
forum.create.name=New forum's name
forum.post.create.name=New post's title
forum.notification.topic.new=New topic created
forum.notification.forum.new=New Forum created
firstname/name=Firstname/Name
regNo=regNo
From=From
@ -282,7 +285,7 @@ rereg=Reregister in the next year of one of my cursus
reregsup=Register in a supplementary cursus
chcur=Change from a cursus to another
iwouldlike=I would like to :
newcurr=New curriculum
newcurr=Actual curriculums
cursusprereq=The cursus you selected has some prerequisites ensure that your external curriculum data is updated in your profile
imposecurriculum=Impose a curriculum
impose=Impose

View File

@ -50,6 +50,7 @@ Delete=Supprimer
Modify=Modifier
Create=Créer
requestType=Type de Requête
lessonType=Type de cours
day=Jour
start=Début
end=Fin
@ -201,6 +202,8 @@ msg.notification.new=Vous avez un nouveau message!
forum.create=Créer un forum
forum.create.name=Nom du forum
forum.post.create.name=Titre du post
forum.notification.topic.new=Nouveau Topic crée
forum.notification.forum.new=Nouveau forum crée
firstname/name=Prénom/Nom
regNo=Matricule
From=De
@ -280,9 +283,9 @@ rereg=Me réinscrire dans l'année supérieure
reregsup=M'inscrire dans un cursus supplémentaire
chcur=Changer d'un cursus vers un autre
iwouldlike=Je voudrais :
newcurr=Nouveau cursus
newcurr=Cursus actuels
cursusprereq=Le cursus que vous avez selectionné a des prérequis assurez vous que votre dossier de parcours est a jour dans votre profil
imposecurriculum=Imposer un cursusgotimposed
impose=Imposer
gotimposed=Le cursus selectionné a été imposé
DifferentLanguage=Langues différentes
DifferentLanguage=Langues différentes

View File

@ -1,22 +1,23 @@
<script setup>
import { toast } from 'vue3-toastify';
import { ref } from 'vue'
import i18n, { setLang } from './i18n.js'
import { isLogged } from '@/rest/Users.js'
import { isLogged, getSelf } from '@/rest/Users.js'
import { notifications, fetchNotifications, archiveNotification } from '@/rest/notifications.js'
import {postMock} from "@/rest/restConsumer.js";
import { appList, currentView } from '@/rest/apps.js'
var prevURL;
var currentURL = window.location.hash;
postMock()
window.onhashchange = function() {
prevURL = currentURL;
currentURL = window.location.hash;
}
const Logged = ref(isLogged());
const user = ref();
if(Logged.value){
fetchNotifications();
getSelf().then(e => user.value = e);
}
window.addEventListener('hashchange', () => {
@ -40,7 +41,7 @@ window.addEventListener('hashchange', () => {
<div class="topBar">
<ul class="horizontal">
<li title=home>
<a class="icon" href="#home">
<a class="icon" href="#home">
<img class="clyde" src="/Clyde.png" style="width: 40px; height: auto; margin-top:4px">
</a></li>
<li title=home>
@ -49,7 +50,7 @@ window.addEventListener('hashchange', () => {
</a></li>
<li style="float: right;" title=login>
<a class="icon" href="#/login">
<div class="fa-solid fa-user" :style="Logged ? 'color: red' : ''" style="margin-top: 7px; margin-bottom: 3px; "></div>
<div class="fa-solid fa-user" :style="Logged ? 'color: red' : ''" style="margin-top: 7px; margin-bottom: 3px; "></div>
</a></li>
<li style="float: right;" title=notifications @click="notification = !notification">
<a class="icon">
@ -75,6 +76,7 @@ window.addEventListener('hashchange', () => {
{{i18n("app.manage.profile")}}
</a>
</div>
<span v-if=Logged>RegNo - {{ user.regNo }}</span>
</div>
</a></li>
</ul>
@ -133,10 +135,12 @@ window.addEventListener('hashchange', () => {
.dropdown {
color:black;
margin-top:55px;
width:160px;
display: inline-block;
height:110px;
/* height:110px; */
text-align: center;
font-size: 13px;
position: absolute;
z-index: 1;
@ -162,12 +166,12 @@ window.addEventListener('hashchange', () => {
margin-top: var(--header-size);
top:0;
left:0;
padding: 25px 0 0;
padding: 25px 0;
width: 70px ;
background-color: rgb(53, 53, 53);
border-right:5px;
border-color:black;
height: 100%;
height: calc( 95% - var(--header-size) ) ;
position: fixed;
overflow: scroll;
transition-duration: .3s;
@ -237,8 +241,7 @@ window.addEventListener('hashchange', () => {
.text {
right: 0%;
width: 0%;
visibility: collapse;
opacity: 0;
display:none;
color: white;
font-size: 1.2em;
font-weight: 600;
@ -247,7 +250,7 @@ window.addEventListener('hashchange', () => {
ul.vertical:hover .text {
opacity:1;
visibility:visible;
display: inline;
width: 60%;
transition-duration: .3s;
padding-left: 15px;

View File

@ -32,6 +32,7 @@ async function createResearcher(){
toCreate.user = user.value
await postResearcher(toCreate)
creating.value = false
allResearcher.value = await fetchAllResearchers()
for (let i = 0; i < allResearcher.value.length; i++) {
if (user.value.regNo === allResearcher.value[i].user.regNo){
researcher.value = allResearcher.value[i]
@ -147,8 +148,7 @@ async function modify(){
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
"profilPic globalInfos";
}
.profilPic{
@ -167,7 +167,8 @@ async function modify(){
display:flex;
align-items:center;
justify-content:center;
margin-top:5%;
margin-right: auto;
margin-left: auto;
}
.subContainer{

View File

@ -51,12 +51,12 @@ async function editChangeCurrReqTeacherApproval(state){
<div>
<button @click="localwindowstate++"> {{ i18n("seeprofile") }} </button>
</div>
<div>
<div v-if="user.role === 'InscriptionService' || user.role==='Admin'">
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">{{ i18n("request.accept") }}</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">{{i18n("request.refuse")}}</button>
</div>
<div v-if="user.role === 'Teacher' || user.role === 'Admin'">
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')">{{i18n("acceptequiv")}}</button>
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')" style="margin-right: 2%">{{i18n("acceptequiv")}}</button>
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Refused';editChangeCurrReqTeacherApproval('Refused')">{{i18n("refuseequiv")}}</button>
</div>
</div>

View File

@ -32,6 +32,9 @@
<div>
{{ i18n("firstname/name") }} : {{user.firstName}} {{user.lastName}}
</div>
<div>
{{ i18n("regNo") }} : {{user.regNo}}
</div>
<div>
{{ i18n("login.guest.email") }}: {{user.email}}
</div>

View File

@ -80,7 +80,7 @@ function isExempted(course){
</div>
</div>
<div v-if="list === false">
<button @click="list=!list;submitted=!submitted">{{ i18n("courses.back") }}</button>
<button @click="list=!list;submitted=false">{{ i18n("courses.back") }}</button>
</div>
</template>

View File

@ -115,7 +115,7 @@
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="reqState">{{ i18n("approval")}}{{item.state}}</div>
<div class="teacherApproval">{{ i18n("teacherapproval") }} : {{item.teacherApprovalState}}</div>
<div class="teacherApproval">{{ i18n("teacherapproval") }} {{item.teacherApprovalState}}</div>
<div class="infos"><button @click="windowsState=5;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
</div>
</div>

View File

@ -18,7 +18,7 @@ const AcceptMod = ref(false);
const moreInfosMod = ref(false);
const requestTypes = ["Create", "Modify", "Delete"]
const editElementID = ref('');
const chosenLocal = ref("");
const chosenLocal = ref();
const locals = ["A0B1","A1B1","A2B1","A0B2"];
const moreInfos = ref({});
@ -30,6 +30,7 @@ const moreInfos = ref({});
async function upPage(id,review){
await changeRequestState(id, review) ;
requests.value = await getAllRequests();
chosenLocal.value = null;
}
/*

View File

@ -168,11 +168,9 @@
</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="editElementID !== item.title && editAddCourse !== item.title" style ="padding:15px 15px 15px 15px;">
<button @click="editElementID = item.title; editAddCourse = ''; setModify(item); ">
{{i18n("courses.modify")}}
</button>
<button v-if="self.role !== 'Teacher'"@click="editAddCourse = item.title; editElementID ='';setAddToCurriculum(item)">Add to a new Curriculum</button>
<div v-if="editElementID !== item.title && editAddCourse !== item.title" style="display:flex;">
<button @click="editElementID = item.title; editAddCourse = ''; setModify(item);">{{i18n("courses.modify")}}</button>
<button v-if="self.role !== 'Teacher'"@click="editAddCourse = item.title; editElementID ='';setAddToCurriculum(item)">{{i18n("courses.AddToCurriculum")}}</button>
</div>
<div v-if="editElementID == item.title">
<button @click="editElementID= '';patchCourse(item)"> {{i18n("courses.confirm")}} </button>

View File

@ -221,6 +221,8 @@ async function setCourses(){
lessonBuffer.value = Object.assign({}, pattern);
lessonFinder.value = null;
lessonCreatorBuffer.value = Object.assign({},lessonCreator)
allSchedules.value = await getAllSchedule();
schedule.value = null;
trueSchedule.value = null;
}

View File

@ -93,12 +93,14 @@
async function ChangeInfos(){
for (let element in toModify){
console.log(element)
console.log(toModify[element])
if (element ==="email" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{email : toModify[element]});
}
if (element ==="profilPictureUrl" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{ profilPictureUrl : toModify[element]});
if (element ==="profilePictureUrl" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{ profilePictureUrl : toModify[element]});
}
else if(element === "address" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{address : toModify[element]});
@ -116,7 +118,7 @@
toModify.address = item.address;
toModify.profilPictureUrl = item.profilPictureUrl;
toModify.email= item.email;
toModify.password= item.password;
toModify.password= item.password
}
function getPP(){
@ -176,6 +178,13 @@
}
}
async function getProfilePic(data){
const pp= await uploadProfilePicture(data)
toModify.profilePictureUrl = pp.url
}
</script>
<template>
@ -192,10 +201,10 @@
<div>
{{ i18n("login.guest.email") }}: {{user.email}}
</div>
<div v-if="user.role==='Student'">
<div>
{{ i18n("regNo") }} : {{user.regNo}}
</div>
<div v-else>
<div>
{{ i18n("role") }}: {{i18n((user.role))}}
</div>
<div>
@ -253,7 +262,7 @@
{{ i18n("alreadypaid") }}
</div>
<div>
<button @click="windowState=7" v-if="minerv.value.toPay <= 0">{{ i18n("askscholarship") }}</button>
<button @click="windowState=7" v-if="minerv.value.toPay >= 0">{{ i18n("askscholarship") }}</button>
</div>
</div>
<div v-if="windowState === 5">
@ -306,7 +315,7 @@
<div v-else-if="windowState === 1" class="infosContainer">
<div>
{{i18n("profile.picture")}}:
<input type="file" @change="user.profilPicture = uploadProfilePicture($event.target.files);" accept="image/*">
<input type="file" @change="getProfilePic($event.target.files)" accept="image/*">
</div>
<div>
{{ i18n("login.guest.email")}}
@ -343,19 +352,19 @@
<select v-model="changecurrdata.actualcursus" style="margin-right: 3%">
<option v-for="item in getActualCurriculumList()" style="font-size:20px;" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
{{ i18n("newcurr") }} :
{{ i18n("newcursus") }} :
<select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div style="height:40px;" v-if="reRegState === 2">
{{ i18n("newcurr") }} :
{{ i18n("newcursus") }} :
<select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div style="height:40px;" v-if="reRegState === 1">
{{ i18n("newcurr") }} :
{{ i18n("newcursus") }} :
<select v-model="changecurrdata.newcursus" @change="getActualCurr(changecurrdata.newcursus);">
<option v-for="item in getCurriculumsNextYear()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
@ -369,7 +378,7 @@
</div>
</div>
</div>
<div v-if="windowState === 0" class="moreInfos">
<div v-if="windowState === 0 && user.role==='Student'" class="moreInfos">
<div class = "oldcursus">
<div class="listTitle">
{{ i18n("oldcursus") }}

View File

@ -8,7 +8,7 @@
<script setup>
import { ref } from 'vue'
import {getDifferenceTime,lastDateOfMonth,formatDate,getFirstDay,sortByDate,weekFromList,sundayToTheEnd,getMarginTop,getHoursMinutes, monthFromList, durationCourse} from '../scheduleFunctions.js'
import {getDifferenceTime,lastDateOfMonth,formatDate,getFirstDay,sortByDate,weekFromList,sundayToTheEnd,getMarginTop,getHoursMinutes, monthFromList} from '../scheduleFunctions.js'
import {getAllSchedule} from "@/rest/scheduleRest.js";
import {getOnesLessons, getOwnedLessons } from "@/rest/lessonSchedule.js"
import {isLogged, getSelf,getTeachers} from "@/rest/Users.js"
@ -76,8 +76,6 @@
}
const days = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"];
const months = ["january","february","march","april",'may',"june","july","august","september","october","november","december"]
const firstDayOfMonth = ref(getFirstDay(new Date()))
const monthDone = ref(false);
function getMonday(d) {
d = new Date(d);
d.setHours(0,0,0);
@ -534,7 +532,7 @@
<option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}}-{{item.curriculum.year}}</option>
</select>
<button v-if="display=='Week'" @click="display='Month'">{{i18n("Week")}}</button>
<button v-if="display=='Month'" @click="display='Week'; value=1;">{{i18("Month")}}</button>
<button v-if="display=='Month'" @click="display='Week'; value=1;">{{i18n("Month")}}</button>
<button v-if="format == 'Grid'" @click="format ='List'">{{i18n("Grid")}}</button>
<button v-if="format == 'List'" @click ="format = 'Grid'">{{i18n("List")}}</button>
<button v-if="verifUser()" @click="jsonMod=false ;displayOwnSchedule();">{{i18n("OwnSchedule")}}</button>
@ -577,6 +575,7 @@
</div>
<div class="body" style="background-color:rgb(50,50,50);">{{i18n("schedule.courses")}}</div>
<div class="body" style="background-color:#484848;"v-for="lesson in focusLessons">
{{formatDate(lesson.lessonStart)}}
{{ getHoursMinutes(lesson.lessonStart)}}-{{getHoursMinutes(lesson.lessonEnd)}}
{{ lesson.local}}
{{i18n(lesson.lessonType.toString())}}

View File

@ -35,6 +35,14 @@ watch(
}
);
async function modified(){
if (typeof props.researchList === 'undefined'){
researchList.value = await fetchAllResearches()
}
else {
emit('modified')
}
}
const openFilter = () => {
isFilterOpened.value = true;
@ -112,7 +120,7 @@ const emit = defineEmits(["modified"]);
<template>
<div id="researches">
<FilterComponent :isOpen="isFilterOpened" :allArticles="researchList" @modal-close="closeFilter" @submit="submitFilters"></FilterComponent>
<ArticleComponent :allResearcher="allResearcher" :article="articleToDisplay" :isOpen="isResearchOpened" :manage="props.manage" @modal-close="closeResearch" @modified="emit('modified')"></ArticleComponent>
<ArticleComponent :allResearcher="allResearcher" :article="articleToDisplay" :isOpen="isResearchOpened" :manage="props.manage" @modal-close="closeResearch" @modified="modified"></ArticleComponent>
<div id="search">
<input v-if="!isResearcher" type="text" id="search-input" :placeholder="i18n('Search.Researches')" v-model="input"/>
<input v-else type="text" id="search-input" :placeholder="i18n('Search.Researchers')" v-model="input"/>

View File

@ -50,8 +50,8 @@ function getPP(){
<template> <div class="body"><div id="main">
<ResearchPostComponent :allResearcher="allResearcher" :researcher="researcher" :isOpen="isPostResearchOpened" @modal-close="isPostResearchOpened = false" @posted="modifiedResearch"></ResearchPostComponent>
<div id="profilePicture">
<img :src=getPP() />
<div id="profilePicture" >
<img :src=getPP() style="border-radius: 20%"/>
</div>
<div id="researcherInfos">
<div class="surrounded" v-if="!changing">{{researcher.user.lastName}} {{researcher.user.firstName}}</div>

View File

@ -73,12 +73,16 @@ function update(){
}
}
async function modifiedResearch(){
researchList.value = await fetchResearches(researcher.value.id)
}
</script>
<template>
<div id="main">
<div id="profilePicture">
<img :src=getPP() />
<img :src=getPP() style="border-radius: 20%"/>
</div>
<div id="researcherInfos">
<div class="surrounded">{{researcher.user.lastName}} {{researcher.user.firstName}}</div>
@ -111,7 +115,7 @@ function update(){
<CanvasJSChart :options="options" id=chart @chart-ref="c => chart = c "/>
</div>
</div>
<div id="researches" style="margin-top: -15px"><list-researches :researchList="researchList"></list-researches></div>
<div id="researches" style="margin-top: -15px"><list-researches :researchList="researchList" @modified="modifiedResearch"></list-researches></div>
</div>
</template>

View File

@ -2,9 +2,14 @@ import { ref } from 'vue'
import { restGet, restPost } from '@/rest/restConsumer.js'
export const notifications = ref([]);
let timerSet = false
export function fetchNotifications(){
restGet("/notifications").then( e => notifications.value = e );
if(!timerSet){
timerSet = true;
setTimeout(() => {timerSet = false; fetchNotifications()}, 5000);
}
}
export function archiveNotification(id){

View File

@ -27,6 +27,9 @@ export function restPatch(endPoint, data) {
return _rest(endPoint, {method: "PATCH", credentials: 'include', body: JSON.stringify(data)});
}
export function postMock(){
return restPost("/mock")
}
/**
* backbone for the request made by the frontend
*