diff --git a/backend/src/main/java/ovh/herisson/Clyde/DTO/ScientificPublications/ResearchDTO.java b/backend/src/main/java/ovh/herisson/Clyde/DTO/ScientificPublications/ResearchDTO.java new file mode 100644 index 0000000..5c8f2b3 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/DTO/ScientificPublications/ResearchDTO.java @@ -0,0 +1,63 @@ +package ovh.herisson.Clyde.DTO.ScientificPublications; + +/****************************************************** + * @file ResearchDTO.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Research format to return to front (without author's password) + ******************************************************/ + +import lombok.Data; +import ovh.herisson.Clyde.Tables.ScientificPublications.Access; +import ovh.herisson.Clyde.Tables.ScientificPublications.PaperType; +import ovh.herisson.Clyde.Tables.ScientificPublications.Research; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +@Data +public class ResearchDTO { + + private long id; + private String title; + private ResearcherDTO researcher; + private final Set coAuthors; + private Date releaseDate; + private PaperType paperType; + private String pdfLocation; + private String bibTexLocation; + private String language; + private Access access; + private String domain; + private String summary; + private long views; + + private ResearchDTO(String title, ResearcherDTO researcherDTO, Date releaseDate, PaperType paperType, String pdfLocation, String language, Access access, String domain, String bibTexLocation, String summary, Set coAuthors, long id, long views) { + this.title = title; + this.researcher = researcherDTO; + this.releaseDate = releaseDate; + this.paperType = paperType; + this.pdfLocation = pdfLocation; + this.language = language; + this.access = access; + this.domain = domain; + this.summary = summary; + this.id = id; + this.bibTexLocation = bibTexLocation; + this.coAuthors = new HashSet<>(); + for (Researcher coAuthor: coAuthors) { + this.coAuthors.add(ResearcherDTO.construct(coAuthor)); + } + this.views = views; + } + + + public static ResearchDTO construct(Research research){ + return new ResearchDTO(research.getTitle(), ResearcherDTO.construct(research.getAuthor()), research.getReleaseDate(), + research.getPaperType(),research.getPdfLocation(),research.getLanguage(),research.getAccess(), + research.getDomain(),research.getBibTexLocation(), research.getSummary(), research.getCoAuthors(),research.getId(), research.getViews()); + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/DTO/ScientificPublications/ResearcherDTO.java b/backend/src/main/java/ovh/herisson/Clyde/DTO/ScientificPublications/ResearcherDTO.java new file mode 100644 index 0000000..4dffff0 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/DTO/ScientificPublications/ResearcherDTO.java @@ -0,0 +1,38 @@ +package ovh.herisson.Clyde.DTO.ScientificPublications; + +/****************************************************** + * @file ResearcherDTO.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Researcher Format to return to front (without user password) + ******************************************************/ +import lombok.Data; +import ovh.herisson.Clyde.Services.ProtectionService; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; + +import java.util.Map; + +@Data +public class ResearcherDTO { + + private long id; + private Map user; + private String site; + private String domain; + private String orcidId; + + + private ResearcherDTO(long id, Map user, String site,String domain,String orcidId){ + this.domain = domain; + this.orcidId = orcidId; + this.site = site; + this.user = user; + this.id = id; + } + + public static ResearcherDTO construct(Researcher researcher){ + return new ResearcherDTO(researcher.getId(), ProtectionService.userWithoutPassword(researcher.getUser()),researcher.getSite(), + researcher.getDomain(),researcher.getOrcidId()); + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ApplicationsController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ApplicationsController.java index 74f76fa..69edb71 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ApplicationsController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ApplicationsController.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import ovh.herisson.Clyde.Services.AuthenticatorService; +import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService; import ovh.herisson.Clyde.Tables.Applications; import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.User; @@ -20,7 +21,10 @@ public class ApplicationsController { AuthenticatorService authServ; - public ApplicationsController(AuthenticatorService authServ){ + ResearchesService researchesServ; + + public ApplicationsController(AuthenticatorService authServ, ResearchesService researchesServ){ + this.researchesServ = researchesServ; this.authServ = authServ; } @@ -47,6 +51,7 @@ public class ApplicationsController { //if unAuthed authorizedApps.add(Applications.Login); + authorizedApps.add(Applications.ListResearches); authorizedApps.add(Applications.Schedule); User user = authServ.getUserFromToken(token); @@ -71,10 +76,15 @@ public class ApplicationsController { authorizedApps.add(Applications.Requests); authorizedApps.add(Applications.StudentsList);} + if (researchesServ.getResearcherByUser(user) != null) + authorizedApps.add(Applications.ManageResearcherProfile); + if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){ authorizedApps.add(Applications.UsersList); authorizedApps.add(Applications.ManageSchedules); - authorizedApps.add(Applications.LessonRequests);} + authorizedApps.add(Applications.LessonRequests); + authorizedApps.add(Applications.CreateUser); + } if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin, Role.InscriptionService},token)){ authorizedApps.add(Applications.Payments);} diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java index 1e89142..10634d3 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java @@ -7,17 +7,23 @@ import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository; import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository; import ovh.herisson.Clyde.Repositories.Inscription.UnregisterRequestRepository; import ovh.herisson.Clyde.Services.*; -import ovh.herisson.Clyde.Services.Inscription.InscriptionService; +import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService; import ovh.herisson.Clyde.Tables.*; +import ovh.herisson.Clyde.Tables.ScientificPublications.Access; +import ovh.herisson.Clyde.Tables.ScientificPublications.PaperType; +import ovh.herisson.Clyde.Tables.ScientificPublications.Research; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; +import ovh.herisson.Clyde.Services.Inscription.InscriptionService; +import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum; +import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest; +import ovh.herisson.Clyde.Tables.Inscription.Minerval; +import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest; import ovh.herisson.Clyde.Tables.Inscription.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; +import java.util.*; @RestController @CrossOrigin(originPatterns = "*", allowCredentials = "true") - public class MockController { public final UserService userService; public final UserRepository userRepo; @@ -36,14 +42,13 @@ public class MockController { public final LessonRequestService lessonRequestService; ArrayList mockUsers; + public final ResearchesService researchesService; public final UserCurriculumRepository ucr; - public final MinervalRepository minervalRepository; - public final ScholarshipRequestRepository scholarshipRequestRepository; - + public final UnregisterRequestRepository uninscriptionRequestRepository; - public MockController(UserService userService, UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, ExternalCurriculumRepository externalCurriculumRepository, InscriptionService inscriptionService, UserCurriculumRepository ucr, MinervalRepository minervalRepository, ScholarshipRequestRepository scholarshipRequestRepository, UnregisterRequestRepository unregisterRequestRepository, LessonService lessonService, ScheduleService scheduleService, ScheduleLessonService scheduleLessonService, LessonRequestService lessonRequestService){ + public MockController(UserService userService, UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, ExternalCurriculumRepository externalCurriculumRepository, ResearchesService researchesService, InscriptionService inscriptionService, UserCurriculumRepository ucr, MinervalRepository minervalRepository, ScholarshipRequestRepository scholarshipRequestRepository, UnregisterRequestRepository unregisterRequestRepository, LessonService lessonService, ScheduleService scheduleService, ScheduleLessonService scheduleLessonService, LessonRequestService lessonRequestService){ this.userService = userService; this.tokenRepo = tokenRepo; this.userRepo = userRepo; @@ -53,6 +58,7 @@ public class MockController { this.courseService = courseService; this.externalCurriculumRepository = externalCurriculumRepository; this.inscriptionService = inscriptionService; + this.researchesService = researchesService; this.lessonService = lessonService; this.scheduleService = scheduleService; this.scheduleLessonService = scheduleLessonService; @@ -70,7 +76,8 @@ public class MockController { */ @PostMapping("/mock") - public void postMock(){ + public void postMock() { + // user part User herobrine = new User("brine","hero","admin@admin.com","behind","ShadowsLand",new Date(0), null,Role.Admin,"admin"); @@ -87,9 +94,9 @@ public class MockController { ExternalCurriculum externalCurriculum = new ExternalCurriculum(null, "HEH", "Bachelier en ingénieur", "completed", 2015, 2017, null, joe); externalCurriculumRepository.save(externalCurriculum); - Minerval minerval = new Minerval(joe.getRegNo(), 0, 852, 2023); - minervalRepository.save(minerval); - // Course / Curriculum part + Minerval minerval = new Minerval(joe.getRegNo(), 0, 852, 2023); + minervalRepository.save(minerval); + // Course / Curriculum part Curriculum infoBab1 = new Curriculum(1,"info", false); Curriculum chemistryBab1 = new Curriculum(1,"chemistry", false); @@ -121,13 +128,14 @@ public class MockController { Course psycho1 = new Course(21, "Neuroreaction of isolated brain cells",joke); Course commun = new Course(2, "cours commun",joke); - courseService.save(progra1); - courseService.save(chemistry1); - courseService.save(psycho1); - courseService.save(commun); + courseService.save(progra1); + courseService.save(chemistry1); + courseService.save(psycho1); + courseService.save(commun); + + ScholarshipRequest ssr1 = new ScholarshipRequest(joe, RequestState.Pending, 0, new Date(), "test", "test"); + scholarshipRequestRepository.save(ssr1); - ScholarshipRequest ssr1 = new ScholarshipRequest(joe, RequestState.Pending, 0, new Date(), "test", "test"); - scholarshipRequestRepository.save(ssr1); CurriculumCourseService.save(new CurriculumCourse(infoBab1,progra1)); CurriculumCourseService.save(new CurriculumCourse(infoBab1,commun)); @@ -136,12 +144,42 @@ public class MockController { CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,commun)); CurriculumCourseService.save(new CurriculumCourse(chemistryBab1, chemistry1)); - CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,commun)); - CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1)); + CurriculumCourseService.save(new CurriculumCourse(chemistryBab1, commun)); + CurriculumCourseService.save(new CurriculumCourse(chemistryBab1, chemistry1)); + InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 4,RequestState.Pending,"yes.png","password", null, new Date(), RequestState.Pending, null); - inscriptionService.save(inscriptionRequest); + inscriptionService.save(inscriptionRequest); + + /////////////////////////// + // extension Publications Scientifiques + Researcher jojoResearcherAccount = new Researcher(jojo, "3363-22555-AB33-T", null, "IT"); + + Researcher joResearchAccount = new Researcher(joe,"N555-321213-BED-DD",null, "Physics"); + + + Researcher output = researchesService.saveResearcher(jojoResearcherAccount); + Researcher joOutput = researchesService.saveResearcher(joResearchAccount); + + Set coAuthor = new HashSet<>(); + coAuthor.add(joOutput); + + Research jojoResearch = new Research("Graphs : Advanced Search Algorithms", output, new Date(0), + PaperType.Article, "test.pdf", null, "english", + Access.OpenSource, "IT", "This Article's title speaks for itself \n We'll discuss about advanced Graph search Algorithms",coAuthor); + Research restrictedResearch = new Research("just another Name", output, new Date(1111111111), + PaperType.Article, "restricted", null, "english", + Access.Restricted, "Restricted", "This Article's title speaks for itself\n We'll discuss about advanced Graph search Algorithms", new HashSet<>()); + + Research privateResearch = new Research("the great Potato War", output, new Date(), + PaperType.Article, "private", null, "english", + Access.Private, "private", "This Article's title speaks for itself\n We'll discuss about advanced Graph search Algorithms",null); + + + researchesService.saveResearch(restrictedResearch); + researchesService.saveResearch(privateResearch); + researchesService.saveResearch(jojoResearch); //Schedule part diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/ResearchController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/ResearchController.java new file mode 100644 index 0000000..518147f --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/ResearchController.java @@ -0,0 +1,167 @@ +package ovh.herisson.Clyde.EndPoints.ScientificPublications; + +/****************************************************** + * @file ResearchController.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * API class for the researches + ******************************************************/ + +import lombok.AllArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ovh.herisson.Clyde.DTO.ScientificPublications.ResearchDTO; +import ovh.herisson.Clyde.DTO.ScientificPublications.ResearcherDTO; +import ovh.herisson.Clyde.Responses.UnauthorizedResponse; +import ovh.herisson.Clyde.Services.AuthenticatorService; +import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService; +import ovh.herisson.Clyde.Tables.Role; +import ovh.herisson.Clyde.Tables.ScientificPublications.Research; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; + +import java.util.ArrayList; +import java.util.Map; + +@RestController +@CrossOrigin(originPatterns = "*", allowCredentials = "true") +@AllArgsConstructor +public class ResearchController { + + + + private final ResearchesService researchesServ; + + private final AuthenticatorService authServ; + + /** Is accessible by anyone + * but if the user doesn't have the permission to download the research + * the return Research Download URL will be null + */ + @GetMapping("/research/{id}") + public ResponseEntity getResearch(@RequestHeader(value = "Authorization", required = false) String token, @PathVariable long id){ + + Research research = researchesServ.getResearchById(id); + + if (research == null) + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + + if (researchesServ.hasNoAccessTo(research,authServ.getUserFromToken(token))){ + research.setPdfLocation(null); + }// If the user doesn't have access to the document he can't download the pdf + + return new ResponseEntity<>(ResearchDTO.construct(research), HttpStatus.OK); + } + + /** + * @param token used to know if the user can download or not the research pdf + * @return every research + */ + @GetMapping("/researches") + public ResponseEntity> getResearches(@RequestHeader(value = "Authorization",required = false) String token){ + Iterable researches = researchesServ.getAllResearches(); + + ArrayList toReturnResearches = new ArrayList<>(); + + for (Research research: researches){ + if (researchesServ.hasNoAccessTo(research,authServ.getUserFromToken(token))){ + research.setPdfLocation(null); + } + toReturnResearches.add(ResearchDTO.construct(research)); + } + return new ResponseEntity<>(toReturnResearches,HttpStatus.OK); + } + + + @GetMapping("/researches/{id}") + public ResponseEntity> getResearchesFromResearcher(@RequestHeader(value = "Authorization",required = false) String token, + @PathVariable Long id + ){ + Iterable researches = researchesServ.getResearchesByAuthor(id); + if (researches == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); + + ArrayList toReturnResearches = new ArrayList<>(); + + for (Research research: researches){ + if (researchesServ.hasNoAccessTo(research,authServ.getUserFromToken(token))){ + research.setPdfLocation(null); + } + toReturnResearches.add(ResearchDTO.construct(research)); + } + return new ResponseEntity<>(toReturnResearches,HttpStatus.OK); + } + + /** post a new research + * + * @return the research saved + */ + @PostMapping("/research") + public ResponseEntity postResearch(@RequestHeader("Authorization") String token, @RequestBody Research research){ + + if (authServ.isNotIn(new Role[]{Role.Admin},token) && + researchesServ.getResearcherByUser(authServ.getUserFromToken(token)) == null){ + return new UnauthorizedResponse<>(null); + } // if the poster isn't a researcher + + return new ResponseEntity<>(researchesServ.saveResearch(research), HttpStatus.OK); + } + + /** post updates to the research + * in the updates, the coAuthors have to be referenced by their ids + * + */ + @PatchMapping("/research/{id}") + public ResponseEntity patchResearch(@RequestHeader("Authorization") String token, + @RequestBody Map updates, + @PathVariable long id + ) + { + Research research = researchesServ.getResearchById(id); + Researcher researcher = researchesServ.getResearcherByUser(authServ.getUserFromToken(token)); + + if (research == null) + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + + if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token) && + researcher != research.getAuthor()) { + return new UnauthorizedResponse<>(null); + } + + researchesServ.modifyResearchData(research, updates); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** Only Admin, Secretary and author can delete a research + * + */ + @DeleteMapping("/research/{id}") + public ResponseEntity deleteResearch(@RequestHeader("Authorization") String token, @PathVariable long id){ + + Research research = researchesServ.getResearchById(id); + Researcher researcher = researchesServ.getResearcherByUser(authServ.getUserFromToken(token)); + + if (research == null) + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + + if (authServ.isNotIn(new Role[]{Role.Admin, Role.Secretary},token) && + researcher != research.getAuthor()){ + return new UnauthorizedResponse<>(null); + } + + researchesServ.deleteResearch(research); + return new ResponseEntity<>(HttpStatus.OK); + } + + /////// + //views part + @PostMapping("/addview/cdn/{url}") + public ResponseEntity addView(@PathVariable String url){ + System.out.println(url); + Research research = researchesServ.getResearchByUrl("cdn/" + url); + if (research ==null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + + return new ResponseEntity<>(ResearchDTO.construct(researchesServ.addView(research)), HttpStatus.OK); + } + +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/ResearcherController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/ResearcherController.java new file mode 100644 index 0000000..8c3f5cf --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/ResearcherController.java @@ -0,0 +1,102 @@ +package ovh.herisson.Clyde.EndPoints.ScientificPublications; + +/****************************************************** + * @file ResearcherController.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * API class for the researchers + ******************************************************/ +import lombok.AllArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ovh.herisson.Clyde.DTO.ScientificPublications.ResearcherDTO; +import ovh.herisson.Clyde.Responses.UnauthorizedResponse; +import ovh.herisson.Clyde.Services.AuthenticatorService; +import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService; +import ovh.herisson.Clyde.Tables.Role; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; + +import java.util.ArrayList; +import java.util.Map; + +@RestController +@CrossOrigin(originPatterns = "*", allowCredentials = "true") +@AllArgsConstructor +public class ResearcherController { + + ResearchesService researchesServ; + AuthenticatorService authServ; + + + @GetMapping("/researcher/{id}") + public ResponseEntity getResearcher(@PathVariable long id){ + Researcher researcher = researchesServ.getResearcherById(id); + return new ResponseEntity<>(ResearcherDTO.construct(researcher),HttpStatus.OK); + } + + /** + * Everyone can access every researcher Account + * @return all the researchers accounts + */ + @GetMapping("/researchers") + public ResponseEntity> getAllResearchers(){ + Iterable researchers = researchesServ.getAllResearchers(); + ArrayList toReturnResearchersDTO = new ArrayList<>(); + for (Researcher researcher: researchers){ + toReturnResearchersDTO.add(ResearcherDTO.construct(researcher)); + } + return new ResponseEntity<>(toReturnResearchersDTO, HttpStatus.OK); + } + + @GetMapping("/researcher") + public ResponseEntity getSelf(@RequestHeader("Authorization") String token){ + + Researcher self = researchesServ.getResearcherByUser(authServ.getUserFromToken(token)); + + if (self ==null) return new UnauthorizedResponse<>(null); + + return new ResponseEntity<>(ResearcherDTO.construct(self), HttpStatus.OK); + } + + @PostMapping("/researcher") + public ResponseEntity postResearcher(@RequestHeader("Authorization") String token, @RequestBody Researcher researcher){ + if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary}, token)){ + return new UnauthorizedResponse<>(null); + } + + Researcher posted = researchesServ.saveResearcher(researcher); + + if (posted == null) return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); + + return new ResponseEntity<>(ResearcherDTO.construct(posted), HttpStatus.CREATED); + } + + @PatchMapping("/researcher/{id}") + public ResponseEntity patchResearcher(@RequestHeader("Authorization") String token, + @PathVariable long id, + @RequestBody Map updates){ + + Researcher researcher = researchesServ.getResearcherById(id); + if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin}, token) + && researcher.getId() != researchesServ.getResearcherByUser(authServ.getUserFromToken(token)).getId()) + return new UnauthorizedResponse<>(null); + + + if (researcher == null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + + researchesServ.modifyResearcherData(researcher,updates); + + return new ResponseEntity<>(ResearcherDTO.construct(researcher),HttpStatus.OK); + } + + @DeleteMapping("/researcher/{id}") + public ResponseEntity deleteResearcher(@RequestHeader ("Authorization") String token, @PathVariable long id){ + if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token)) + return new UnauthorizedResponse<>(null); + + researchesServ.deleteResearcher(researchesServ.getResearcherById(id)); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/StatController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/StatController.java new file mode 100644 index 0000000..ef363ae --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/ScientificPublications/StatController.java @@ -0,0 +1,47 @@ +package ovh.herisson.Clyde.EndPoints.ScientificPublications; + +/****************************************************** + * @file StatController.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Api class for handling statistics + ******************************************************/ +import lombok.AllArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService; +import ovh.herisson.Clyde.Services.ScientificPublications.StatisticsService; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; + +import java.util.Map; + +@RestController +@CrossOrigin(originPatterns = "*", allowCredentials = "true") +@AllArgsConstructor +public class StatController { + + + private StatisticsService statServ; + private ResearchesService researchesServ; + + /** returns all the statistics in a 2D array + * + * @param id the researcher's id + * @return all the stats in a 2D array + */ + @GetMapping("/stats/{id}") + public ResponseEntity>>> getStat(@PathVariable Long id){ + + Researcher researcher = researchesServ.getResearcherById(id); + if (researcher == null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + + Iterable>> stats = statServ.generateStats(researcher); + + if (stats == null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + + return new ResponseEntity<>(stats,HttpStatus.OK); + + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java index 2835b60..1292ad1 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/UserController.java @@ -86,19 +86,20 @@ public class UserController { * @return a string clarifying the issue (if there is any) */ @PatchMapping("/user/{id}") - public ResponseEntity patchUser(@RequestHeader("Authorization") String token, + public ResponseEntity> patchUser(@RequestHeader("Authorization") String token, @RequestBody Map updates, @PathVariable Long id) { if (token == null) return new UnauthorizedResponse<>(null); User poster = authServ.getUserFromToken(token); - if (poster == null) {return new UnauthorizedResponse<>("bad token");} + if (poster == null) {return new UnauthorizedResponse<>(null);} - if (!userService.modifyData(id, updates, poster)) - return new UnauthorizedResponse<>("there was an issue with the updates requested"); + User modified = userService.modifyData(id,updates,poster); + if (modified ==null) + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - return new ResponseEntity<>(null, HttpStatus.OK); + return new ResponseEntity<>(ProtectionService.userWithoutPassword(modified), HttpStatus.OK); } @GetMapping("/teachers") diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/ResearchRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/ResearchRepository.java new file mode 100644 index 0000000..1aa7b51 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/ResearchRepository.java @@ -0,0 +1,26 @@ +package ovh.herisson.Clyde.Repositories.ScientificPublications; + +/****************************************************** + * @file ResearchRepository.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Repository handling communication with Reseach table + ******************************************************/ +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import ovh.herisson.Clyde.Tables.ScientificPublications.Research; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; + +import java.util.Map; + +public interface ResearchRepository extends CrudRepository { + + Research findById(long id); + + Iterable findByAuthor(Researcher author); + + @Query("select r from Research r where r.pdfLocation = ?1") + Research findByPdfLocation(String url); + +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/ResearcherRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/ResearcherRepository.java new file mode 100644 index 0000000..ba1e6e8 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/ResearcherRepository.java @@ -0,0 +1,23 @@ +package ovh.herisson.Clyde.Repositories.ScientificPublications; + +/****************************************************** + * @file ResearcherRepository.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Repository handling communication with Reseacher table + ******************************************************/ +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import ovh.herisson.Clyde.Tables.ScientificPublications.Research; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; +import ovh.herisson.Clyde.Tables.User; + +public interface ResearcherRepository extends CrudRepository { + Researcher findByUser(User user); + + Researcher findById(long id); + + @Query("select r from Research r where r.author = ?1") + Iterable findAllByAuthorId(Researcher author); +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/StatsRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/StatsRepository.java new file mode 100644 index 0000000..6dc1726 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/ScientificPublications/StatsRepository.java @@ -0,0 +1,47 @@ +package ovh.herisson.Clyde.Repositories.ScientificPublications; + +/****************************************************** + * @file StatsRepository.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Repository handling communication with Reseach table for making statistics + ******************************************************/ +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import ovh.herisson.Clyde.Tables.ScientificPublications.Research; + +import java.util.Map; + +public interface StatsRepository extends CrudRepository { + + @Query("select new map(to_char(r.releaseDate, 'month') as label, sum(r.views) as y) from Research r group by to_char(r.releaseDate, 'month')") + Iterable> viewsByMonths(); + + @Query("select new map(to_char(r.releaseDate,'YYYY') as label, sum (r.views) as y) from Research r group by to_char(r.releaseDate,'YYYY')") + Iterable> viewsByYears(); + + + @Query("select new map(r.domain as label, sum(r.views) as y) from Research r group by r.domain") + Iterable> viewsByTopics(); + + + @Query("select new map(r.domain as label, count(distinct r.language) as y) from Research r group by r.domain") + Iterable> languageByTopics(); + + @Query("select new map(to_char(r.releaseDate,'YYYY') as label, count(distinct r.language) as y) from Research r group by to_char(r.releaseDate,'YYYY')") + Iterable> languageByYears(); + + @Query("select new map(to_char(r.releaseDate, 'month') as label, count(distinct r.language) as y) from Research r group by to_char(r.releaseDate, 'month')") + Iterable> languageByMonths(); + + @Query("select new map(to_char(r.releaseDate,'YYYY') as label, count(distinct r) as y) from Research r group by to_char(r.releaseDate,'YYYY')") + Iterable> researchesByYears(); + + @Query("select new map(r.domain as label, count(distinct r) as y) from Research r group by r.domain") + Iterable> researchesByTopics(); + + @Query("select new map(to_char(r.releaseDate, 'month') as label, count(distinct r) as y) from Research r group by to_char(r.releaseDate, 'month')") + Iterable> researchesByMonth(); + +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/ScientificPublications/ResearchesService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/ScientificPublications/ResearchesService.java new file mode 100644 index 0000000..445cf41 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/ScientificPublications/ResearchesService.java @@ -0,0 +1,178 @@ +package ovh.herisson.Clyde.Services.ScientificPublications; + +/****************************************************** + * @file ResearchesService.java + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Service for managing researcher and researches + ******************************************************/ +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearchRepository; +import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearcherRepository; +import ovh.herisson.Clyde.Tables.Role; +import ovh.herisson.Clyde.Tables.ScientificPublications.*; +import ovh.herisson.Clyde.Tables.User; + +import java.util.*; + +@Service +@AllArgsConstructor +@SuppressWarnings("unchecked") +public class ResearchesService { + + private final ResearcherRepository researcherRepo; + private final ResearchRepository articleRepo; + + + // researches Part + public Research getResearchById(long id) { + return articleRepo.findById(id); + } + + public Research getResearchByUrl(String url) { + return articleRepo.findByPdfLocation(url); + } + + + public Iterable getResearchesByAuthor(long authorId){ + Researcher researcher = researcherRepo.findById(authorId); + if (researcher == null) return null; + + return researcherRepo.findAllByAuthorId(researcher); + } + + public Research saveResearch(Research research) { + return articleRepo.save(research); + } + + public void modifyResearchData(Research research, Map updates) { + for (Map.Entry entry : updates.entrySet()){ + switch (entry.getKey()){ + case "title": + research.setTitle((String) entry.getValue()); + break; + case "paperType": + research.setPaperType((PaperType) entry.getValue()); + break; + case "language": + research.setLanguage((String) entry.getValue()); + break; + case "domain": + research.setDomain((String) entry.getValue()); + break; + case "summary": + research.setSummary((String) entry.getValue()); + break; + case "access": + research.setAccess(Access.valueOf((String) entry.getValue())); + break; + case "coAuthors": + Set set = new HashSet<>(); + + for (int id : (List) entry.getValue()) { + + Researcher r = researcherRepo.findById(id); + if (r != null){ + set.add(r); + } + } + research.setCoAuthors(set); + break; + } + } + articleRepo.save(research); + } + + public void deleteResearch(Research research) { + articleRepo.delete(research); + } + + + // Researchers Part + public Researcher getResearcherByUser(User user){ + return researcherRepo.findByUser(user); + } + + public Iterable getAllResearches() { + return articleRepo.findAll(); + } + + public Researcher saveResearcher(Researcher researcher) { + + if (researcherRepo.findByUser(researcher.getUser()) != null) return null; + return researcherRepo.save(researcher); + } + + public Iterable getAllResearchers() { + return researcherRepo.findAll(); + } + + public Researcher getResearcherById(long id) { + return researcherRepo.findById(id); + } + + public void deleteResearcher(Researcher researcher) { + articleRepo.findAll(); + for (Research r: articleRepo.findAll()) + { + if (r.getCoAuthors().contains(researcher)){ + r.getCoAuthors().remove(researcher); + articleRepo.save(r); + } + } + researcherRepo.delete(researcher); + } + + public void modifyResearcherData(Researcher researcher, Map updates) { + + for (Map.Entry entry : updates.entrySet()){ + switch (entry.getKey()){ + case "orcidId": + if (entry.getValue() != null) + researcher.setOrcidId((String) entry.getValue()); + break; + case "domain": + if (entry.getValue() != null) + researcher.setDomain((String) entry.getValue()); + break; + case "site": + if (entry.getValue() != null) + researcher.setSite((String) entry.getValue()); + break; + } + } + researcherRepo.save(researcher); + } + // Other stuff + + public Research addView(Research research) { + research.setViews(research.getViews()+1); + return articleRepo.save(research); + } + + public boolean hasNoAccessTo(Research research, User user){ + if (research.getAccess() == Access.OpenSource) return false; // if the access is open source even non-users can see it + if (user == null) return true; // else you need at least to be a user + + if (user.getRole() == Role.Admin) return false; + + + Researcher researcher = getResearcherByUser(user); + if (researcher !=null ){ + if (research.getAuthor().getId() == researcher.getId()) + return false; + + for (Researcher coAuthor: research.getCoAuthors()){ + if (coAuthor.getId() == researcher.getId()) + return false; + } + } + + return research.getAccess() != Access.Restricted || (user.getRole() != Role.Secretary && + user.getRole() != Role.Teacher && user.getRole() != Role.InscriptionService); + // if the access is restricted only the staff member (above) can access the research + + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/ScientificPublications/StatisticsService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/ScientificPublications/StatisticsService.java new file mode 100644 index 0000000..350feca --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/ScientificPublications/StatisticsService.java @@ -0,0 +1,50 @@ +package ovh.herisson.Clyde.Services.ScientificPublications; + +/****************************************************** + * @file StatisticsService + * @author Bartha Maxime + * @scope Publications Scientifiques + * + * Service for managing statistics + ******************************************************/ +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearchRepository; +import ovh.herisson.Clyde.Repositories.ScientificPublications.StatsRepository; +import ovh.herisson.Clyde.Tables.ScientificPublications.Research; +import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; + +import java.util.*; + +@Service +@AllArgsConstructor +public class StatisticsService { + + + private ResearchRepository articleRepo; + private StatsRepository statsRepo; + + + public Iterable>> generateStats(Researcher researcher){ + + Iterable researches = articleRepo.findByAuthor(researcher); + + if (researches == null) return null; + + + ArrayList>> toReturn = new ArrayList<>(); + + toReturn.add(statsRepo.viewsByYears()); + toReturn.add(statsRepo.viewsByMonths()); + toReturn.add(statsRepo.viewsByTopics()); + + toReturn.add(statsRepo.researchesByYears()); + toReturn.add(statsRepo.researchesByMonth()); + toReturn.add(statsRepo.researchesByTopics()); + + toReturn.add(statsRepo.languageByYears()); + toReturn.add(statsRepo.languageByMonths()); + toReturn.add(statsRepo.languageByTopics()); + return toReturn; + } +} \ No newline at end of file diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java index 483d731..b4f5d99 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/UserService.java @@ -45,61 +45,55 @@ public class UserService { * @param targetId the id of the user to update * @return if the changes were done or not */ - public boolean modifyData(long targetId, Map updates, User poster){ + public User modifyData(long targetId, Map updates, User poster){ User target = userRepo.findById(targetId); if (target == null) - return false; + return null; - if (poster.getRegNo().equals(target.getRegNo())){ - for (Map.Entry entry : updates.entrySet()){ + if (!target.getRegNo().equals(poster.getRegNo()) && !(poster.getRole() == Role.Secretary) && + !(poster.getRole() == Role.Admin)) + return null; - switch (entry.getKey()){ - case "firstName": - target.setFirstName((String) entry.getValue()); - break; - case "lastName": - target.setLastName((String) entry.getValue()); - break; - case "email": - target.setEmail((String) entry.getValue()); - break; - case "address": - target.setAddress((String) entry.getValue()); - break; - case "country": - target.setCountry((String) entry.getValue()); - break; - case "birthDate": - target.setBirthDate((Date) entry.getValue()); - break; - case "profilePictureUrl": - target.setProfilePictureUrl((String) entry.getValue()); - break; - case "password": - target.setPassword((String) entry.getValue()); - break; - } - } - userRepo.save(target); - return true; - } - // the secretary can change roles (for example if a student becomes a teacher) - else if (poster.getRole() == Role.Secretary) - { - for (Map.Entry entry : updates.entrySet()){ - - if ( entry.getKey().equals("role")) { - - if (entry.getValue() == Role.Admin) {return false;} - - target.setRole((Role) entry.getValue()); - userRepo.save(target); - return true; - } + for (Map.Entry entry : updates.entrySet()){ + System.out.println(entry.getValue()); + switch (entry.getKey()){ + case "firstName": + target.setFirstName((String) entry.getValue()); + break; + case "lastName": + target.setLastName((String) entry.getValue()); + break; + case "email": + target.setEmail((String) entry.getValue()); + break; + case "address": + target.setAddress((String) entry.getValue()); + break; + case "country": + target.setCountry((String) entry.getValue()); + break; + case "birthDate": + target.setBirthDate((Date) entry.getValue()); + break; + case "profilePictureUrl": + target.setProfilePictureUrl((String) entry.getValue()); + break; + case "password": + target.setPassword((String) entry.getValue()); + break; + case "role": + //a user can't change his own role + if (poster.getRole()==Role.Secretary || poster.getRole() == Role.Admin){ + Role wanted = Role.valueOf((String) entry.getValue()); + if (wanted == Role.Admin && poster.getRole() != Role.Admin) + return null; + target.setRole(wanted); + } } } - return false; + userRepo.save(target); + return target; } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/Applications.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/Applications.java index 741de69..72c1a50 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/Applications.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/Applications.java @@ -8,7 +8,6 @@ public enum Applications { // with any token Profile, - // Students and higher authorization Msg, Forum, @@ -27,6 +26,13 @@ public enum Applications { // InscriptionService authorization Requests, - StudentsList, + // profile of a researcher + ResearcherProfile, + ManageResearcherProfile, + + //the list of all researches (filterable) + ListResearches, + CreateUser, + StudentsList, Payments } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/FileType.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/FileType.java index ad5eab4..63d156b 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/FileType.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/FileType.java @@ -3,6 +3,8 @@ package ovh.herisson.Clyde.Tables; public enum FileType { ProfilePicture, EducationCertificate, + Research, + ResearchBibTex, JustificationDocument, IdentityCard, } diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Access.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Access.java new file mode 100644 index 0000000..2e50622 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Access.java @@ -0,0 +1,15 @@ +package ovh.herisson.Clyde.Tables.ScientificPublications; + +/****************************************************** + * @file Access.java + * @author Maxime Bartha + * @scope Extension Publications scientifiques + * + * Access Type for the Articles + * + ******************************************************/ +public enum Access { + OpenSource, // everyone can see + Restricted, // only Researchers and Staff Members (secretary, teachers and Inscription Service) + Private, // only authors and co-authors +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/PaperType.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/PaperType.java new file mode 100644 index 0000000..713bd4e --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/PaperType.java @@ -0,0 +1,16 @@ +package ovh.herisson.Clyde.Tables.ScientificPublications; + +/****************************************************** + * @file PaperType.java + * @author Maxime Bartha + * @scope Extension Publications scientifiques + * + * Type of the scientific paper + * + ******************************************************/ +public enum PaperType { + Article, + Paper, + Book, + BookChapter, +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Research.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Research.java new file mode 100644 index 0000000..4c41d15 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Research.java @@ -0,0 +1,79 @@ +package ovh.herisson.Clyde.Tables.ScientificPublications; + +/****************************************************** + * @file Research.java + * @author Maxime Bartha + * @scope Extension Publications scientifiques + * + * Research entity + ******************************************************/ +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; +import java.util.Date; +import java.util.List; +import java.util.Set; + +@Getter +@Setter +@NoArgsConstructor +@Entity +@Table(name = "Research") +public class Research { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String title; + + @ManyToOne(fetch = FetchType.EAGER) + @OnDelete(action = OnDeleteAction.CASCADE) + @JoinColumn(name ="Researcher") + private Researcher author; + + @Column(nullable = false) + private Date releaseDate; + + private PaperType paperType; + + private String pdfLocation; + + private String bibTexLocation; + + private String language; + + private Access access; + + private String domain; + + private String summary; + + private int views; + + @ManyToMany(cascade = {CascadeType.MERGE}) + @JoinTable(name = "ResearchCoAuhors", + joinColumns = @JoinColumn(name = "research_id"), + inverseJoinColumns = @JoinColumn(name = "researcher_id") + ) + private Set coAuthors; + + public Research(String title, Researcher author, Date releaseDate, PaperType paperType, + String pdfLocation, String bibTexLocation, String language, Access access, String domain, String summary,Set coauthors){ + this.author = author; + this.title = title; + this.releaseDate = releaseDate; + this.paperType = paperType; + this.pdfLocation = pdfLocation; + this.bibTexLocation = bibTexLocation; + this.language = language; + this.access = access; + this.domain = domain; + this.summary = summary; + this.coAuthors = coauthors; + } +} + diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Researcher.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Researcher.java new file mode 100644 index 0000000..259452b --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/ScientificPublications/Researcher.java @@ -0,0 +1,40 @@ +package ovh.herisson.Clyde.Tables.ScientificPublications; + +/****************************************************** + * @file Researcher.java + * @author Maxime Bartha + * @scope Extension Publications scientifiques + * + * Researcher entity + ******************************************************/ +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.OnDelete; +import ovh.herisson.Clyde.Tables.User; + + +@Getter +@Setter +@NoArgsConstructor +@Entity +@Table(name = "Researcher") +public class Researcher { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + @OneToOne + private User user; + private String orcidId; + private String site; + private String domain; + + public Researcher(User user, String orcidId, String site, String domain){ + this.user = user; + this.orcidId = orcidId; + this.site = site; + this.domain = domain; + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java index 2cee1fc..a9c0b6c 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java @@ -54,6 +54,7 @@ public class User { private List discussions; ///////////////////////////////// + ///////////////////////////////// public User(String lastName, String firstName, String email, String address, String country, Date birthDate, String profilePictureUrl, Role role, String password) { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 809af17..8f48574 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,8 @@ "name": "clyde", "version": "0.0.0", "dependencies": { + "@canvasjs/vue-charts": "^1.0.4", + "@vueuse/core": "^10.9.0", "vite-plugin-top-level-await": "^1.4.1", "vue": "^3.4.15", "vue3-toastify": "^0.2.1" @@ -29,6 +31,20 @@ "node": ">=6.0.0" } }, + "node_modules/@canvasjs/charts": { + "version": "3.7.45", + "resolved": "https://registry.npmjs.org/@canvasjs/charts/-/charts-3.7.45.tgz", + "integrity": "sha512-FPMX8wn+PEHzAa/GLBsL5lWB81AzKZLw51t7SiSUjMbtUN5/OIrmDcwUTw+53/Bbdd9gm2LLmxAdZsQ75JI31g==" + }, + "node_modules/@canvasjs/vue-charts": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@canvasjs/vue-charts/-/vue-charts-1.0.4.tgz", + "integrity": "sha512-PzOA8xeb/f68a39uoFZNn843dGPU36bsqmbO5DWjP7k6FwkK5AeGkYa/H3RHC02Xc6mG68vg9aFNj2Fyqhu4UQ==", + "dependencies": { + "@canvasjs/charts": "^3.7.5", + "vue": ">=3.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.19.12", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", @@ -753,6 +769,11 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==" + }, "node_modules/@vitejs/plugin-vue": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz", @@ -866,6 +887,89 @@ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, + "node_modules/@vueuse/core": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", + "integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.9.0", + "@vueuse/shared": "10.9.0", + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz", + "integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz", + "integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==", + "dependencies": { + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/agent-base": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index c02c826..8edbabe 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,8 @@ "preview": "vite preview" }, "dependencies": { + "@canvasjs/vue-charts": "^1.0.4", + "@vueuse/core": "^10.9.0", "vite-plugin-top-level-await": "^1.4.1", "vue": "^3.4.15", "vue3-toastify": "^0.2.1" diff --git a/frontend/public/i18n/EN.txt b/frontend/public/i18n/EN.txt index 566386b..30a1a0c 100644 --- a/frontend/public/i18n/EN.txt +++ b/frontend/public/i18n/EN.txt @@ -36,6 +36,9 @@ app.language=Language app.manage.profile=Manage profile app.studentList=Students List app.users=Users +app.manage.researcherProfile=Manage researcher profile +app.list.researches=List researches +app.Create.User=Create User app.manageOwnLessons=Manage Owned Courses Schedule app.lessonRequests=Schedule Requests app.payments=Payments @@ -121,6 +124,81 @@ Curriculum=curriculum Credits=Credits InscriptionService=I.S. faculty=Faculty +Year=Year +Access=Access +Access.Restricted=Restricted +Access.OpenSource=OpenSource +Access.Private=Private +Language=Language +Month=Month +Month.01=january +Month.02=february +Month.03=march +Month.04=april +Month.05=may +Month.06=june +Month.07=july +Month.08=august +Month.09=september +Month.10=october +Month.11=november +Month.12=december +Domain=Domain +PaperType=PaperType +Submit=Submit +Search.Researches=Search For Researches +Search.Researchers=Search For Researchers +Filters=Filters +Toggle.Researcher=Toggle Researcher Search +Untoggle.Researcher=Toggle Research Search +MoreInfo=More Info +Modify.Research=Modify Research +To.Change.In.Options=To change in regular account options +Modify.Data=Modify Data +Confirm.Changes=Confirm Changes +Cancel.Changes=Cancel Changes +Post.Research=Post a new Research +Summary=Summary +Title=Title +Views=Number of Views +See.Research=See Research +SeeBibTex=See BibTex +Author=Author +CoAuthors=Co-Authors +ReleaseDate=ReleaseDate +Article.Id=Article Id +Delete.Research=Delete Research +Here=Here +Stat.Type=Stat Type +Researches=Researches +Please.Select.Option=Please Select an Option +Class.By=Class By +PaperType.Article=Article +PaperType.Book=Book +PaperType.Book.Chapter=Book Chapter +PaperType.Paper=Paper +Research.Pdf=Research Pdf +BibTex.Pdf=BibTex Pdf +CoAuthors.List=Co-Author List +Confirm.Publish=Confirm Publishing +Cancel.Publish=Cancel Publishing +Years=Years +Months=Months +By=By +RegNo=RegNo +Address=Address +Country=Country +BirthDate=Birth Date +Researcher.Delete=Delete Researcher Profile +Researcher.Add=Create Researcher Profile +Confirm=Confirm +Cancel=Cancel +LastName=Last Name +FirstName=First Name +Profile.Picture=Profile Picture +Role=Role +Password=Password +Create.User=Create User msg.notification.new=You have a new message forum.create=Create forum forum.create.name=New forum's name diff --git a/frontend/public/i18n/FR.txt b/frontend/public/i18n/FR.txt index b7c7458..0ca8ac4 100644 --- a/frontend/public/i18n/FR.txt +++ b/frontend/public/i18n/FR.txt @@ -36,6 +36,9 @@ app.language=Langue app.manage.profile=Gérer le profil app.studentList=Liste des étudiants app.users=Utilisateurs +app.manage.researcherProfile= gérer son profil de chercheur +app.list.researches=Lister les recherches +app.Create.User=créer un utilisateur app.manageOwnLessons=Gérer ses horaires de cours app.lessonRequests=Requêtes d'horaire app.payments=Payements @@ -121,6 +124,79 @@ Curriculum=Cursus Credits=Credits InscriptionService=S.I. faculty=Faculté +Year=Année +Access=Accès +Access.Restricted=Restreint +Access.OpenSource=Libre +Access.Private=Privé +Language=Langue +Month=Mois +Month.01=janvier +Month.02=fevrier +Month.03=mars +Month.04=avril +Month.05=mai +Month.06=juin +Month.07=juillet +Month.08=août +Month.09=septembre +Month.10=octobre +Month.11=novembre +Month.12=decembre +Domain=Domaine +PaperType=Type de recherche +Submit=Envoyer +Search.Researches=Chercher Par Recherche +Search.Researchers=Chercher Par Chercheur +Filters=Filtres +Toggle.Researcher=Activer la recherche par chercheur +Untoggle.Researcher=Désactiver la recherche par chercheur +MoreInfo=Plus d'info +Modify.Research=Modifer l'article +To.Change.In.Options=À changer dans les options +Modify.Data=Modifier +Confirm.Changes=Confirmer les Changements +Cancel.Changes=Abandonner les Changements +Post.Research=Poster un nouvel article +Summary=Résumé +Title=Titre +Views=Nombre de Vues +See.Research=Ouvrir l'article +SeeBibTex=Ouvrir le BibTex +Author=Autheur +CoAuthors=Co-Autheurs +ReleaseDate=Date de Parution +Article.Id=Id de l'article +Delete.Research=Supprimer l'article +Here=Ici +Stat.Type=Type de Stat +Researches=Recherches +Please.Select.Option=Selectionnez des Options +Class.By=Classifer Par +PaperType.Article=Article +PaperType.Book=Livre +PaperType.Book.Chapter=Chapitre de Livre +PaperType.Paper=Papier +Research.Pdf=Pdf de la Recherche +BibTex.Pdf=BibTex de la Recherche +CoAuthors.List=Liste des Co-Autheurs +Confirm.Publish=Confirmer la Publication +Cancel.Publish=Annuler la Publication +Years=Années +Months=Mois +By=par +RegNo=Matricule +Address=Adresse +Country=Pays +BirthDate=Date de Naissance +Confirm=Confirmer +Cancel=Annuler +LastName=Nom de Famille +FirstName=Prénom +Profile.Picture=Photo de Profil +Role=Role +Password=Mot de Passe +Create.User=Créer l'utilisateur msg.notification.new=Vous avez un nouveau message! forum.create=Créer un forum forum.create.name=Nom du forum diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 45bdeb2..cc62e8f 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -169,7 +169,7 @@ window.addEventListener('hashchange', () => { border-color:black; height: 100%; position: fixed; - overflow:; + overflow: scroll; transition-duration: .3s; } diff --git a/frontend/src/Apps/AboutUser.vue b/frontend/src/Apps/AboutUser.vue new file mode 100644 index 0000000..0a3cce1 --- /dev/null +++ b/frontend/src/Apps/AboutUser.vue @@ -0,0 +1,214 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/Apps/CreateUser.vue b/frontend/src/Apps/CreateUser.vue new file mode 100644 index 0000000..7332017 --- /dev/null +++ b/frontend/src/Apps/CreateUser.vue @@ -0,0 +1,117 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/Apps/ScientificPublications/FilterComponent.vue b/frontend/src/Apps/ScientificPublications/FilterComponent.vue new file mode 100644 index 0000000..27405b4 --- /dev/null +++ b/frontend/src/Apps/ScientificPublications/FilterComponent.vue @@ -0,0 +1,153 @@ + + + + + + diff --git a/frontend/src/Apps/ScientificPublications/ListResearches.vue b/frontend/src/Apps/ScientificPublications/ListResearches.vue new file mode 100644 index 0000000..d056f72 --- /dev/null +++ b/frontend/src/Apps/ScientificPublications/ListResearches.vue @@ -0,0 +1,226 @@ + + + + + + \ No newline at end of file diff --git a/frontend/src/Apps/ScientificPublications/ManageResearcherProfile.vue b/frontend/src/Apps/ScientificPublications/ManageResearcherProfile.vue new file mode 100644 index 0000000..7f0490e --- /dev/null +++ b/frontend/src/Apps/ScientificPublications/ManageResearcherProfile.vue @@ -0,0 +1,184 @@ + + + + + + \ No newline at end of file diff --git a/frontend/src/Apps/ScientificPublications/ResearchComponent.vue b/frontend/src/Apps/ScientificPublications/ResearchComponent.vue new file mode 100644 index 0000000..bdec01f --- /dev/null +++ b/frontend/src/Apps/ScientificPublications/ResearchComponent.vue @@ -0,0 +1,242 @@ + + + + + + + diff --git a/frontend/src/Apps/ScientificPublications/ResearchPostComponent.vue b/frontend/src/Apps/ScientificPublications/ResearchPostComponent.vue new file mode 100644 index 0000000..d055f00 --- /dev/null +++ b/frontend/src/Apps/ScientificPublications/ResearchPostComponent.vue @@ -0,0 +1,177 @@ + + + + + + diff --git a/frontend/src/Apps/ScientificPublications/ResearcherProfile.vue b/frontend/src/Apps/ScientificPublications/ResearcherProfile.vue new file mode 100644 index 0000000..9ae1d30 --- /dev/null +++ b/frontend/src/Apps/ScientificPublications/ResearcherProfile.vue @@ -0,0 +1,171 @@ + + + + + + + diff --git a/frontend/src/Apps/UsersList.vue b/frontend/src/Apps/UsersList.vue index 59e60c4..a000495 100644 --- a/frontend/src/Apps/UsersList.vue +++ b/frontend/src/Apps/UsersList.vue @@ -1,20 +1,30 @@