responses and general modifications
This commit is contained in:
parent
7b0d76dae8
commit
106bf96a98
@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import jakarta.websocket.server.PathParam;
|
import jakarta.websocket.server.PathParam;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import ovh.herisson.Clyde.Repositories.CourseRepository;
|
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.ForumRepository;
|
||||||
import ovh.herisson.Clyde.Repositories.Msg.TopicRepository;
|
import ovh.herisson.Clyde.Repositories.Msg.TopicRepository;
|
||||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
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.Role;
|
||||||
import ovh.herisson.Clyde.Tables.Token;
|
import ovh.herisson.Clyde.Tables.Token;
|
||||||
import ovh.herisson.Clyde.Tables.User;
|
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.Forum;
|
||||||
import ovh.herisson.Clyde.Tables.Msg.Topic;
|
import ovh.herisson.Clyde.Tables.Msg.Topic;
|
||||||
|
|
||||||
@ -36,7 +38,6 @@ import ovh.herisson.Clyde.Tables.Msg.Topic;
|
|||||||
public class ForumController {
|
public class ForumController {
|
||||||
|
|
||||||
private CourseRepository courseRepo;
|
private CourseRepository courseRepo;
|
||||||
private CourseService courseServ;
|
|
||||||
private AuthenticatorService authServ;
|
private AuthenticatorService authServ;
|
||||||
private ForumService forumServ;
|
private ForumService forumServ;
|
||||||
private ForumRepository forumRepo;
|
private ForumRepository forumRepo;
|
||||||
@ -69,7 +70,7 @@ public class ForumController {
|
|||||||
@GetMapping("/forum/{id}")
|
@GetMapping("/forum/{id}")
|
||||||
public ResponseEntity<List<Topic>> getTopicsFromForumId(@RequestHeader("Authorization") String token, @PathVariable long id){
|
public ResponseEntity<List<Topic>> getTopicsFromForumId(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||||
User u = authServ.getUserFromToken(token);
|
User u = authServ.getUserFromToken(token);
|
||||||
if(u != null){
|
if(u == null){
|
||||||
return new UnauthorizedResponse<>(null);
|
return new UnauthorizedResponse<>(null);
|
||||||
}
|
}
|
||||||
return new ResponseEntity<>(forumRepo.findById(id).orElse(null).getTopics(), HttpStatus.OK);
|
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){
|
public ResponseEntity<Topic> postTopicToForum(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Topic data){
|
||||||
User u = authServ.getUserFromToken(token);
|
User u = authServ.getUserFromToken(token);
|
||||||
Forum f = forumRepo.findById(id).orElse(null);
|
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);
|
return new UnauthorizedResponse<>(null);
|
||||||
}
|
}
|
||||||
forumServ.createTopic(f, data);
|
forumServ.createTopic(f, data);
|
||||||
@ -91,13 +92,25 @@ public class ForumController {
|
|||||||
@GetMapping("/forum/post/{id}")
|
@GetMapping("/forum/post/{id}")
|
||||||
public ResponseEntity<Topic> getPost(@RequestHeader("Authorization") String token, @PathVariable long id){
|
public ResponseEntity<Topic> getPost(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||||
User u = authServ.getUserFromToken(token);
|
User u = authServ.getUserFromToken(token);
|
||||||
if(u != null){
|
if(u == null){
|
||||||
return new UnauthorizedResponse<>(null);
|
return new UnauthorizedResponse<>(null);
|
||||||
}
|
}
|
||||||
Topic t = topicRepo.findById(id).orElse(null);
|
Topic t = topicRepo.findById(id).orElse(null);
|
||||||
return new ResponseEntity<>(t, HttpStatus.OK);
|
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/...
|
||||||
}
|
}
|
||||||
|
@ -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> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,10 @@ import org.springframework.stereotype.Service;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import ovh.herisson.Clyde.Repositories.CourseRepository;
|
import ovh.herisson.Clyde.Repositories.CourseRepository;
|
||||||
import ovh.herisson.Clyde.Repositories.Msg.ForumRepository;
|
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.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.Forum;
|
||||||
import ovh.herisson.Clyde.Tables.Msg.Topic;
|
import ovh.herisson.Clyde.Tables.Msg.Topic;
|
||||||
|
|
||||||
@ -15,6 +18,7 @@ public class ForumService {
|
|||||||
|
|
||||||
private CourseRepository courseRepo;
|
private CourseRepository courseRepo;
|
||||||
private ForumRepository forumRepo;
|
private ForumRepository forumRepo;
|
||||||
|
private TopicRepository topicRepo;
|
||||||
|
|
||||||
public void createForum(Course c, Forum f){
|
public void createForum(Course c, Forum f){
|
||||||
c.addForum(f);
|
c.addForum(f);
|
||||||
@ -25,4 +29,10 @@ public class ForumService {
|
|||||||
f.addTopic(data);
|
f.addTopic(data);
|
||||||
forumRepo.save(f);
|
forumRepo.save(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void answerTopic(Topic t, Answer data, User u) {
|
||||||
|
data.setAuthor(u);
|
||||||
|
t.addAnswer(data);
|
||||||
|
topicRepo.save(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import ovh.herisson.Clyde.Tables.User;
|
|||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Data
|
@Data
|
||||||
public class Answers {
|
public class Answer {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private int id;
|
private int id;
|
||||||
@ -19,12 +19,9 @@ public class Answers {
|
|||||||
@CreationTimestamp
|
@CreationTimestamp
|
||||||
private Date creation;
|
private Date creation;
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
private Topic topic;
|
|
||||||
|
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
@OneToOne
|
@ManyToOne(cascade=CascadeType.ALL)
|
||||||
private User author;
|
private User author;
|
||||||
|
|
||||||
private boolean anonymous;
|
private boolean anonymous;
|
@ -20,7 +20,7 @@ public class Forum {
|
|||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@OneToMany
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
private List<Topic> topics;
|
private List<Topic> topics;
|
||||||
|
|
||||||
public void addTopic(Topic t) {
|
public void addTopic(Topic t) {
|
||||||
|
@ -16,11 +16,16 @@ public class Topic {
|
|||||||
|
|
||||||
private String subject, content;
|
private String subject, content;
|
||||||
|
|
||||||
@OneToOne
|
@ManyToOne
|
||||||
private User author;
|
private User author;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "topic", cascade = CascadeType.ALL)
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
private List<Answers> answers;
|
private List<Answer> answers;
|
||||||
|
|
||||||
|
public void addAnswer(Answer a){
|
||||||
|
answers.add(a);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean locked; // true if new messages can be posted
|
private boolean locked; // true if new messages can be posted
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import { getCourses } from '@/rest/courses.js'
|
import { getCourses } from '@/rest/courses.js'
|
||||||
import { ForumsOfCurrentCourse, getForumsOfCourse, createForum } from '@/rest/forum.js'
|
import { ForumsOfCurrentCourse, getForumsOfCourse, createForum } from '@/rest/forum.js'
|
||||||
import { PostsOfCurrentForum, getPostsOfForum } from '@/rest/forum.js'
|
import { PostsOfCurrentForum, getPostsOfForum, createPost } from '@/rest/forum.js'
|
||||||
import { fetchedPost, fetchPost } from '@/rest/forum.js'
|
import { fetchedPost, fetchPost, sendAnswer } from '@/rest/forum.js'
|
||||||
import { getSelf } from '@/rest/Users.js'
|
import { getSelf } from '@/rest/Users.js'
|
||||||
|
|
||||||
const courses = await reactive(getCourses());
|
const courses = await reactive(getCourses());
|
||||||
@ -20,6 +20,9 @@ const Role = (await getSelf()).role;
|
|||||||
|
|
||||||
const addForum = ref(false);
|
const addForum = ref(false);
|
||||||
const addForumName = ref("");
|
const addForumName = ref("");
|
||||||
|
const addPost = ref(false);
|
||||||
|
const addPostSubject = ref("");
|
||||||
|
const addPostContent = ref("");
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -36,8 +39,8 @@ const addForumName = ref("");
|
|||||||
<button v-if="(Role === 'Admin' || Role === 'Teacher') && ForumsOfCurrentCourse != null " id="createPost" @click="addForum = true">+</button>
|
<button v-if="(Role === 'Admin' || Role === 'Teacher') && ForumsOfCurrentCourse != null " id="createPost" @click="addForum = true">+</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="PostSelector" v-if="PostsOfCurrentForum != null">
|
<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>
|
<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="createPost()">+</button>
|
<button v-if="Role === 'Admin' || Role === 'Teacher' " id="createPost" @click="addPost = true">+</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="PostViewer" v-if="fetchedPost != null">
|
<div id="PostViewer" v-if="fetchedPost != null">
|
||||||
<div id="Post">
|
<div id="Post">
|
||||||
@ -45,21 +48,33 @@ const addForumName = ref("");
|
|||||||
{{fetchedPost.content}}
|
{{fetchedPost.content}}
|
||||||
</div>
|
</div>
|
||||||
<div id="Messages">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<div id="forumAdder" v-if=addForum @click.self="addForum = false">
|
<div class=popup v-if="addForum || addPost" @click.self="addForum = false; addPost = false" >
|
||||||
<div id="addForumForm">
|
|
||||||
|
<!-- Popup to add forum -->
|
||||||
|
<div id="addForumForm" v-if=addForum @keyup.enter="createForum(selectedCourse, addForumName); addForum = false;">
|
||||||
<label>New Forum:</label>
|
<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>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
#forumAdder{
|
.popup{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -84,6 +99,21 @@ const addForumName = ref("");
|
|||||||
gap: 10px;
|
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{
|
#app{
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
/*******************************************************
|
||||||
|
* File: forum.js
|
||||||
|
* Author: Anthony Debucquoy
|
||||||
|
* Scope: Extension messagerie
|
||||||
|
* Description: Forum related functions and calls
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
|
import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
|
||||||
|
|
||||||
@ -18,17 +25,11 @@ export function createForum(id, name){
|
|||||||
* List post of a specified forum
|
* List post of a specified forum
|
||||||
*/
|
*/
|
||||||
export async function getPostsOfForum(id){
|
export async function getPostsOfForum(id){
|
||||||
PostsOfCurrentForum.value = [
|
PostsOfCurrentForum.value = await restGet("/forum/" + id);
|
||||||
{
|
}
|
||||||
id: 1,
|
|
||||||
name: "Post~1"
|
export function createPost(id, subject, content){
|
||||||
},
|
restPost("/forum/" + id, {subject: subject, content: content}).then(_ => getPostsOfForum(id));
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: "Post~2"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
// PostsCurrentForum.value = await restGet("/forum/" + id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PostsOfCurrentForum = ref();
|
export const PostsOfCurrentForum = ref();
|
||||||
@ -37,29 +38,11 @@ export const PostsOfCurrentForum = ref();
|
|||||||
* Get a post and its responses
|
* Get a post and its responses
|
||||||
*/
|
*/
|
||||||
export async function fetchPost(id){
|
export async function fetchPost(id){
|
||||||
fetchedPost.value = {
|
fetchedPost.value = await restGet("/forum/post/" + id);
|
||||||
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.",
|
export function sendAnswer(id, content){
|
||||||
messages: [
|
restPost("/forum/post/" + id, {content: content}).then(_ => fetchPost(id))
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchedPost = ref();
|
export const fetchedPost = ref();
|
||||||
|
Loading…
Reference in New Issue
Block a user