1
0
forked from PGL/Clyde

responses and general modifications

This commit is contained in:
Debucquoy Anthony 2024-04-09 23:41:24 +02:00
parent 7b0d76dae8
commit 106bf96a98
Signed by: tonitch
GPG Key ID: A78D6421F083D42E
8 changed files with 105 additions and 57 deletions

View File

@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
import jakarta.websocket.server.PathParam;
import lombok.AllArgsConstructor;
import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.Msg.AnswerRepository;
import ovh.herisson.Clyde.Repositories.Msg.ForumRepository;
import ovh.herisson.Clyde.Repositories.Msg.TopicRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
@ -27,6 +28,7 @@ import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.Token;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Answer;
import ovh.herisson.Clyde.Tables.Msg.Forum;
import ovh.herisson.Clyde.Tables.Msg.Topic;
@ -36,7 +38,6 @@ import ovh.herisson.Clyde.Tables.Msg.Topic;
public class ForumController {
private CourseRepository courseRepo;
private CourseService courseServ;
private AuthenticatorService authServ;
private ForumService forumServ;
private ForumRepository forumRepo;
@ -69,7 +70,7 @@ public class ForumController {
@GetMapping("/forum/{id}")
public ResponseEntity<List<Topic>> getTopicsFromForumId(@RequestHeader("Authorization") String token, @PathVariable long id){
User u = authServ.getUserFromToken(token);
if(u != null){
if(u == null){
return new UnauthorizedResponse<>(null);
}
return new ResponseEntity<>(forumRepo.findById(id).orElse(null).getTopics(), HttpStatus.OK);
@ -79,7 +80,7 @@ public class ForumController {
public ResponseEntity<Topic> postTopicToForum(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Topic data){
User u = authServ.getUserFromToken(token);
Forum f = forumRepo.findById(id).orElse(null);
if(!f.getWriters().contains(u)){
if(!(f.getWriters().contains(u) || u.getRole() == Role.Admin)){
return new UnauthorizedResponse<>(null);
}
forumServ.createTopic(f, data);
@ -91,13 +92,25 @@ public class ForumController {
@GetMapping("/forum/post/{id}")
public ResponseEntity<Topic> getPost(@RequestHeader("Authorization") String token, @PathVariable long id){
User u = authServ.getUserFromToken(token);
if(u != null){
if(u == null){
return new UnauthorizedResponse<>(null);
}
Topic t = topicRepo.findById(id).orElse(null);
return new ResponseEntity<>(t, HttpStatus.OK);
}
@PostMapping("/forum/post/{id}")
public ResponseEntity<Topic> postTopicToForum(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Answer data){
User u = authServ.getUserFromToken(token);
Topic t = topicRepo.findById(id).orElse(null);
if(t.isLocked() && u.getRole() != Role.Admin){
return new UnauthorizedResponse<>(null);
}
System.out.println(data);
forumServ.answerTopic(t, data, u);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
// TODO: <tonitch> Create a new post/topic and response to a topic
// TODO: <tonitch> Check if authorization to view a post/forum/...
}

View File

@ -0,0 +1,10 @@
package ovh.herisson.Clyde.Repositories.Msg;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Msg.Answer;
public interface AnswerRepository extends CrudRepository<Answer, Long> {
}

View File

@ -5,7 +5,10 @@ import org.springframework.stereotype.Service;
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.Tables.Course;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Answer;
import ovh.herisson.Clyde.Tables.Msg.Forum;
import ovh.herisson.Clyde.Tables.Msg.Topic;
@ -15,6 +18,7 @@ public class ForumService {
private CourseRepository courseRepo;
private ForumRepository forumRepo;
private TopicRepository topicRepo;
public void createForum(Course c, Forum f){
c.addForum(f);
@ -25,4 +29,10 @@ public class ForumService {
f.addTopic(data);
forumRepo.save(f);
}
public void answerTopic(Topic t, Answer data, User u) {
data.setAuthor(u);
t.addAnswer(data);
topicRepo.save(t);
}
}

View File

@ -11,7 +11,7 @@ import ovh.herisson.Clyde.Tables.User;
@Entity
@Data
public class Answers {
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ -19,12 +19,9 @@ public class Answers {
@CreationTimestamp
private Date creation;
@ManyToOne
private Topic topic;
private String content;
@OneToOne
@ManyToOne(cascade=CascadeType.ALL)
private User author;
private boolean anonymous;

View File

@ -20,7 +20,7 @@ public class Forum {
private String name;
@OneToMany
@OneToMany(cascade = CascadeType.ALL)
private List<Topic> topics;
public void addTopic(Topic t) {

View File

@ -16,11 +16,16 @@ public class Topic {
private String subject, content;
@OneToOne
@ManyToOne
private User author;
@OneToMany(mappedBy = "topic", cascade = CascadeType.ALL)
private List<Answers> answers;
@OneToMany(cascade = CascadeType.ALL)
private List<Answer> answers;
public void addAnswer(Answer a){
answers.add(a);
}
private boolean locked; // true if new messages can be posted
}

View File

@ -9,8 +9,8 @@
import { ref, reactive } from 'vue'
import { getCourses } from '@/rest/courses.js'
import { ForumsOfCurrentCourse, getForumsOfCourse, createForum } from '@/rest/forum.js'
import { PostsOfCurrentForum, getPostsOfForum } from '@/rest/forum.js'
import { fetchedPost, fetchPost } from '@/rest/forum.js'
import { PostsOfCurrentForum, getPostsOfForum, createPost } from '@/rest/forum.js'
import { fetchedPost, fetchPost, sendAnswer } from '@/rest/forum.js'
import { getSelf } from '@/rest/Users.js'
const courses = await reactive(getCourses());
@ -20,6 +20,9 @@ const Role = (await getSelf()).role;
const addForum = ref(false);
const addForumName = ref("");
const addPost = ref(false);
const addPostSubject = ref("");
const addPostContent = ref("");
</script>
@ -36,8 +39,8 @@ const addForumName = ref("");
<button v-if="(Role === 'Admin' || Role === 'Teacher') && ForumsOfCurrentCourse != null " id="createPost" @click="addForum = true">+</button>
</div>
<div id="PostSelector" v-if="PostsOfCurrentForum != null">
<div @click="fetchPost(post.id)" class="postItem" v-for="post in PostsOfCurrentForum" :key="post.id">{{ post.name }}</div>
<button v-if="Role === 'Admin' || Role === 'Teacher' " id="createPost" @click="createPost()">+</button>
<div @click="fetchPost(post.id)" class="postItem" v-for="post in PostsOfCurrentForum" :key="post.id">{{ post.subject }}</div>
<button v-if="Role === 'Admin' || Role === 'Teacher' " id="createPost" @click="addPost = true">+</button>
</div>
<div id="PostViewer" v-if="fetchedPost != null">
<div id="Post">
@ -45,21 +48,33 @@ const addForumName = ref("");
{{fetchedPost.content}}
</div>
<div id="Messages">
<p v-for="msg in fetchedPost.messages">{{msg.author}} - {{msg.content}}</p>
<p v-for="msg in fetchedPost.answers">{{msg.author.firtName}} {{msg.author.lastName}} - {{msg.content}}</p>
<input v-if=!fetchedPost.locked type="text" placeholder="response" @keyup.enter="sendAnswer(fetchedPost.id, $event.target.value)"/>
</div>
</div>
</div>
<div id="forumAdder" v-if=addForum @click.self="addForum = false">
<div id="addForumForm">
<div class=popup v-if="addForum || addPost" @click.self="addForum = false; addPost = false" >
<!-- Popup to add forum -->
<div id="addForumForm" v-if=addForum @keyup.enter="createForum(selectedCourse, addForumName); addForum = false;">
<label>New Forum:</label>
<input type="text" placeholder="Name" v-model=addForumName @keyup.enter="createForum(selectedCourse, $event.target.value); addForum = false;" />
<input type="text" placeholder="Name" v-model=addForumName />
</div>
<!-- Popup to add Post -->
<div id="addPostForm" v-if=addPost>
<label>New Post:</label>
<input type="text" placeholder="subject" v-model=addPostSubject @keyup.enter="createPost(selectedForum, addPostSubject, addPostContent); addForum = false;"/>
<textarea v-model="addPostContent" placeholder=content></textarea>
<input type="submit" value="send" @click="createPost(selectedForum, addPostSubject, addPostContent); addForum = false;">
</div>
</div>
</template>
<style scoped>
#forumAdder{
.popup{
position: fixed;
top: 0;
left: 0;
@ -84,6 +99,21 @@ const addForumName = ref("");
gap: 10px;
}
#addPostForm{
position: relative;
width: 30%;
left: calc(50% - 30% / 2);
top: calc(50% - 50% / 2);
border-radius: 10px;
height: 50%;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
#app{
display: grid;
width: 100%;

View File

@ -1,3 +1,10 @@
/*******************************************************
* File: forum.js
* Author: Anthony Debucquoy
* Scope: Extension messagerie
* Description: Forum related functions and calls
*******************************************************/
import { ref } from 'vue'
import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
@ -18,17 +25,11 @@ export function createForum(id, name){
* List post of a specified forum
*/
export async function getPostsOfForum(id){
PostsOfCurrentForum.value = [
{
id: 1,
name: "Post~1"
},
{
id: 2,
name: "Post~2"
},
]
// PostsCurrentForum.value = await restGet("/forum/" + id);
PostsOfCurrentForum.value = await restGet("/forum/" + id);
}
export function createPost(id, subject, content){
restPost("/forum/" + id, {subject: subject, content: content}).then(_ => getPostsOfForum(id));
}
export const PostsOfCurrentForum = ref();
@ -37,29 +38,11 @@ export const PostsOfCurrentForum = ref();
* Get a post and its responses
*/
export async function fetchPost(id){
fetchedPost.value = {
id: 1,
subject: "This is the subject of the post",
content: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
messages: [
{
id: 1,
author: "author~1",
content: "J'ai pas copris le message !"
},
{
id: 2,
author: "author~2",
content: "tu as fait une faute dans ton message..."
},
{
id: 3,
author: null,
content: "I'm anonymous noww..."
}
]
}
// fetchedPost.value = await restGet("/forum/post/" + id);
fetchedPost.value = await restGet("/forum/post/" + id);
}
export function sendAnswer(id, content){
restPost("/forum/post/" + id, {content: content}).then(_ => fetchPost(id))
}
export const fetchedPost = ref();