From 66e7fa24a1478ba872b51680c497b0567870cbd7 Mon Sep 17 00:00:00 2001 From: Anthony Debucquoy Date: Mon, 25 Mar 2024 00:08:44 +0100 Subject: [PATCH] Adding the discussion architectures and creating new discussions --- backend/build.gradle.kts | 2 + .../EndPoints/Msg/MessagesController.java | 49 +++++++++++++++++++ .../Msg/DiscussionRepository.java | 14 ++++++ .../Clyde/Services/Msg/DiscussionService.java | 24 +++++++++ .../herisson/Clyde/Tables/Msg/Discussion.java | 44 +++++++++++++++++ .../java/ovh/herisson/Clyde/Tables/User.java | 7 +++ frontend/src/Apps/Msg.vue | 18 ++++++- frontend/src/rest/msg.js | 35 ++++++------- 8 files changed, 172 insertions(+), 21 deletions(-) create mode 100644 backend/src/main/java/ovh/herisson/Clyde/EndPoints/Msg/MessagesController.java create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Repositories/Msg/DiscussionRepository.java create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java create mode 100644 backend/src/main/java/ovh/herisson/Clyde/Tables/Msg/Discussion.java diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index b7cabcd..794631f 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -16,6 +16,8 @@ repositories { } dependencies { + compileOnly("org.projectlombok:lombok") + annotationProcessor("org.projectlombok:lombok") implementation("org.springframework.boot:spring-boot-starter-jdbc") implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-mail") diff --git a/backend/src/main/java/ovh/herisson/Clyde/EndPoints/Msg/MessagesController.java b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/Msg/MessagesController.java new file mode 100644 index 0000000..e5534f4 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/EndPoints/Msg/MessagesController.java @@ -0,0 +1,49 @@ +package ovh.herisson.Clyde.EndPoints.Msg; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +import lombok.AllArgsConstructor; +import ovh.herisson.Clyde.Responses.UnauthorizedResponse; +import ovh.herisson.Clyde.Services.AuthenticatorService; +import ovh.herisson.Clyde.Services.Msg.DiscussionService; +import ovh.herisson.Clyde.Tables.User; +import ovh.herisson.Clyde.Tables.Msg.Discussion; + +@RestController +@CrossOrigin(originPatterns = "*", allowCredentials = "true") +@AllArgsConstructor +public class MessagesController { + + private AuthenticatorService authServ; + private DiscussionService discServ; + + @GetMapping("/discussions") + public ResponseEntity> getDiscussions(@RequestHeader("Authorization") String token ){ + User user = authServ.getUserFromToken(token); + if(user == null){ + return new UnauthorizedResponse<>(null); + } + + Iterable mock = discServ.getOwned(authServ.getUserFromToken(token)); + + return new ResponseEntity<>(mock, HttpStatus.OK); + } + + @GetMapping("/discussion/{id}") + public ResponseEntity getDiscussion(@RequestHeader("Authorization") String token, @PathVariable long id){ + return null; // TODO + } + + @PostMapping("/discussion") + public ResponseEntity createDiscussion(@RequestHeader("Authorization") String token, @RequestBody Discussion data){ + return new ResponseEntity<>(discServ.create(data.getName(), authServ.getUserFromToken(token)), HttpStatus.OK); + } +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Repositories/Msg/DiscussionRepository.java b/backend/src/main/java/ovh/herisson/Clyde/Repositories/Msg/DiscussionRepository.java new file mode 100644 index 0000000..3e74cb4 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Repositories/Msg/DiscussionRepository.java @@ -0,0 +1,14 @@ +package ovh.herisson.Clyde.Repositories.Msg; + +import java.util.List; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; + +import ovh.herisson.Clyde.Tables.Msg.Discussion; + +public interface DiscussionRepository extends CrudRepository{ + + @Query("SELECT d FROM Discussion d INNER JOIN FETCH d.members dm WHERE dm.id = ?1") + List findByMembership(long userid); +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java b/backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java new file mode 100644 index 0000000..e1b36e5 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Services/Msg/DiscussionService.java @@ -0,0 +1,24 @@ +package ovh.herisson.Clyde.Services.Msg; + +import org.springframework.stereotype.Service; + +import lombok.AllArgsConstructor; +import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository; +import ovh.herisson.Clyde.Tables.User; +import ovh.herisson.Clyde.Tables.Msg.Discussion; + +@Service +@AllArgsConstructor +public class DiscussionService { + + private DiscussionRepository discRepo; + + public Discussion create(String name, User author){ + return discRepo.save(new Discussion(name, author)); + } + + public Iterable getOwned(User author){ + return discRepo.findByMembership(author.getRegNo()); + } + +} diff --git a/backend/src/main/java/ovh/herisson/Clyde/Tables/Msg/Discussion.java b/backend/src/main/java/ovh/herisson/Clyde/Tables/Msg/Discussion.java new file mode 100644 index 0000000..57e5958 --- /dev/null +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/Msg/Discussion.java @@ -0,0 +1,44 @@ +package ovh.herisson.Clyde.Tables.Msg; + +import java.util.List; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import ovh.herisson.Clyde.Tables.User; + +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Discussion{ + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + private String name; + + @ManyToMany + @JoinTable( + name = "discussion_members", + joinColumns = @JoinColumn(name = "discussion_id"), + inverseJoinColumns = @JoinColumn(name = "user_id") + ) + private List members; + + public Discussion(String name){ + this.name = name; + } + + public Discussion(String name, User user){ + this.name = name; + this.members = List.of(user); + } +} 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 de958df..300a58c 100644 --- a/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java +++ b/backend/src/main/java/ovh/herisson/Clyde/Tables/User.java @@ -1,7 +1,10 @@ package ovh.herisson.Clyde.Tables; import jakarta.persistence.*; +import ovh.herisson.Clyde.Tables.Msg.Discussion; + import java.util.Date; +import java.util.List; @Entity @@ -20,6 +23,10 @@ public class User { private String profilePictureUrl; private ovh.herisson.Clyde.Tables.Role role; private String password; + + @ManyToMany( mappedBy = "members" ) + 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/src/Apps/Msg.vue b/frontend/src/Apps/Msg.vue index 5a09e18..254df1d 100644 --- a/frontend/src/Apps/Msg.vue +++ b/frontend/src/Apps/Msg.vue @@ -7,9 +7,9 @@ @@ -17,6 +17,7 @@
{{ discussion.name }}
+

{{currentDiscussion.name}}

@@ -50,6 +51,8 @@ div#discList{ border-radius: 10px; overflow: hidden; padding: 10px; + display: flex; + flex-direction: column; } @@ -66,6 +69,17 @@ div#discList{ border: 1px solid darkorange; } +#createDiscussion{ + height: 4vh; + margin: 5px; + color: white; + background-color: green; + border-radius: 0 30px 30px 0; + border: none; + font-weight: 900; + font-size: 2em; +} + div#discussion{ display: flex; flex-direction: column; diff --git a/frontend/src/rest/msg.js b/frontend/src/rest/msg.js index 9f3bf3e..06c084c 100644 --- a/frontend/src/rest/msg.js +++ b/frontend/src/rest/msg.js @@ -5,30 +5,19 @@ * Description: Messages frontend api consumer *******************************************************/ -import { restGet } from './restConsumer.js' +import { restGet, restPost } from './restConsumer.js' import { ref } from 'vue' export const currentDiscussion = ref({}); +/** + * @return array of + * - id + * - name + * - members + */ export async function getDiscussions(){ - return [ - { - id: 1, - name: "Discussion#1", - members: [1, 2, 3, 4], - }, - { - id: 2, - name: "Discussion#2", - members: [1, 4], - }, - { - id: 3, - name: "Discussion#3", - members: [1, 3], - } - ] - // return restGet("/discussions"); + return restGet("/discussions"); } export async function fetchDiscussion(id){ @@ -83,3 +72,11 @@ export async function fetchDiscussion(id){ // currentDiscussion.value = restGet("/discussion/" + id); } +export async function createDiscussion(name){ + restPost("/discussion", {name: name}); +} + + +export async function invite(id, regNo){ + restPost("/discussion/"+ id+ "/invite", {user: regNo}); +}