From caaa9610dc7bb66f24556f94cd1553faca3b0643 Mon Sep 17 00:00:00 2001 From: Slava Date: Mon, 19 Jul 2021 23:13:13 +0600 Subject: [PATCH 001/149] Added the ability to leave reviews about the user, there is no display of reviews yet --- README.md | 3 - docker-compose.yml | 42 +++---- med-web-app-front/.env | 2 +- .../src/components/create-record.component.js | 1 - .../src/components/profile.component.js | 16 ++- .../src/components/review.component.js | 105 ++++++++++++++++++ .../src/services/review.service.js | 21 ++++ med-web-app-front/src/styles/Review.css | 11 ++ .../controllers/ReviewController.java | 61 ++++++++++ .../requestbody/ReviewRequest.java | 16 +++ .../com/app/medicalwebapp/model/Review.java | 48 ++++++++ .../repositories/ReviewRepository.java | 16 +++ .../medicalwebapp/services/ReviewService.java | 31 ++++++ 13 files changed, 344 insertions(+), 29 deletions(-) create mode 100644 med-web-app-front/src/components/review.component.js create mode 100644 med-web-app-front/src/services/review.service.js create mode 100644 med-web-app-front/src/styles/Review.css create mode 100644 src/main/java/com/app/medicalwebapp/controllers/ReviewController.java create mode 100644 src/main/java/com/app/medicalwebapp/controllers/requestbody/ReviewRequest.java create mode 100644 src/main/java/com/app/medicalwebapp/model/Review.java create mode 100644 src/main/java/com/app/medicalwebapp/repositories/ReviewRepository.java create mode 100644 src/main/java/com/app/medicalwebapp/services/ReviewService.java diff --git a/README.md b/README.md index 230e9391..7388d009 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,6 @@ The system is integrated with a bunch of services. The essential ones are SFTP s $ cd ../../../../med-web-app-front $ npm run build $ cd .. - $ docker run -d --name sftp -p 4999:22 --rm atmoz/sftp medwebuser:secretpassword:::upload - $ docker run -d --name medwebpostgres -p 5555:5555 --rm medwebpostgres - $ docker run -d --name ortanc -p 8042:8042 --rm jodogne/orthanc $ mvn compile jib:dockerBuild $ docker-compose up Four essential containers should be up and running. (You can uncomment other containers in docker-compose.yml but I don't recommend to do it locally) diff --git a/docker-compose.yml b/docker-compose.yml index b9be93f2..f5512577 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -157,27 +157,27 @@ services: - app_net - medwebapp: - image: ashvyrkova/medwebapp - environment: - - SERVER_PORT=7999 - - MIRF_ORCHESTRATOR_URL=orchestrator - - MIRF_ORCHESTRATOR_PORT=5011 - - MIRF_REPOSITORY_URL=mirfrepository - - MIRF_REPOSITORY_PORT=8050 - - ORTHANC_URL=http://orthanc:8042 - - SPRING_DATASOURCE_URL=jdbc:postgresql://medwebpostgres:5555/medwebappdb - - SFTP_URL=sftp - - SFTP_PORT=22 - ports: - - "7999:7999" - depends_on: -# - pipelinealg -# - mirfrepository - - medwebpostgres - - sftp - networks: - - app_net +# medwebapp: +# image: ashvyrkova/medwebapp +# environment: +# - SERVER_PORT=7999 +# - MIRF_ORCHESTRATOR_URL=orchestrator +# - MIRF_ORCHESTRATOR_PORT=5011 +# - MIRF_REPOSITORY_URL=mirfrepository +# - MIRF_REPOSITORY_PORT=8050 +# - ORTHANC_URL=http://orthanc:8042 +# - SPRING_DATASOURCE_URL=jdbc:postgresql://medwebpostgres:5555/medwebappdb +# - SFTP_URL=sftp +# - SFTP_PORT=22 +# ports: +# - "7999:7999" +# depends_on: +## - pipelinealg +## - mirfrepository +# - medwebpostgres +# - sftp +# networks: +# - app_net networks: app_net: diff --git a/med-web-app-front/.env b/med-web-app-front/.env index 13954e1b..a10b68c3 100644 --- a/med-web-app-front/.env +++ b/med-web-app-front/.env @@ -1,2 +1,2 @@ PORT=8081 -REACT_APP_API_URL=http://medicalwebapp.us-east-1.elasticbeanstalk.com \ No newline at end of file +REACT_APP_API_URL=http://localhost:7999 \ No newline at end of file diff --git a/med-web-app-front/src/components/create-record.component.js b/med-web-app-front/src/components/create-record.component.js index c8e9a941..dcebba13 100644 --- a/med-web-app-front/src/components/create-record.component.js +++ b/med-web-app-front/src/components/create-record.component.js @@ -70,7 +70,6 @@ export default class ReplyRecordForm extends Component { selectedFilesValue: [], selectedTopics: [], selectedTopicsValue: [], - submittedSuccessfuly: true }); }, error => { diff --git a/med-web-app-front/src/components/profile.component.js b/med-web-app-front/src/components/profile.component.js index d67287c6..23500977 100644 --- a/med-web-app-front/src/components/profile.component.js +++ b/med-web-app-front/src/components/profile.component.js @@ -1,21 +1,24 @@ import React, { Component } from "react"; +import { Route } from "react-router-dom"; import AuthService from "../services/auth.service"; import '../styles/Profile.css' import {Link} from "react-router-dom"; +import Review from "./review.component" export default class Profile extends Component { constructor(props) { super(props); this.state = { - currentUser: AuthService.getCurrentUser() + currentUser: AuthService.getCurrentUser(), + showReviews: true, }; } render() { const { currentUser } = this.state; - + const { showReviews } = this.state; return (
@@ -34,6 +37,13 @@ export default class Profile extends Component {
{new Date(currentUser.registeredDate).toLocaleDateString()}
+ + { showReviews && ( +
+ +
+ )} +
@@ -44,7 +54,7 @@ export default class Profile extends Component {
-
+
); diff --git a/med-web-app-front/src/components/review.component.js b/med-web-app-front/src/components/review.component.js new file mode 100644 index 00000000..5dec6384 --- /dev/null +++ b/med-web-app-front/src/components/review.component.js @@ -0,0 +1,105 @@ +import React, {Component} from "react"; +import AuthService from "../services/auth.service"; +import AttachmentService from "../services/attachment.service"; +import ReviewService from "../services/review.service" +import Form from "react-validation/build/form"; +import CheckButton from "react-validation/build/button"; + +export default class reviewComponent extends Component { + constructor(props) { + super(props); + this.handleSubmitReview = this.handleSubmitReview.bind(this); + this.onChangeContent = this.onChangeContent.bind(this); + + this.state = { + content: "", + submittedSuccessfully: false, + message: null, + }; + } + + handleSubmitReview(e) { + e.preventDefault(); + if (this.checkBtn.context._errors.length === 0) { + ReviewService.saveReview(this.state.content).then( + () => { + this.setState({ + submittedSuccessfully: true, + message: "Успешно опубликовано", + content: "", + }); + }, + error => { + const resMessage = + (error.response && error.response.data && error.response.data.message) || error.message || error.toString(); + + this.setState({ + submittedSuccessfully: false, + message: resMessage + }); + } + ) + } else { + this.setState({ + loading: false + }); + } + } + + onChangeContent(e) { + this.setState({ + content: e.target.value + }); + } + + render() { + return ( +
{this.inputForm = c;}} + > +
+ + +
+ +
+ +
+ + {this.state.message && ( +
+
+ {this.state.message} +
+
+ )} + + {this.checkBtn = c;}} + /> + + + ) + } +} \ No newline at end of file diff --git a/med-web-app-front/src/services/review.service.js b/med-web-app-front/src/services/review.service.js new file mode 100644 index 00000000..434d3c32 --- /dev/null +++ b/med-web-app-front/src/services/review.service.js @@ -0,0 +1,21 @@ +import axios from "axios"; +import authHeader from "./auth-header"; + +const API_URL = process.env.REACT_APP_API_URL + '/api/reviews/'; + +class ReviewService { + constructor(props) { + } + + getAllReviews() { + return axios.get(API_URL + 'all', + {headers: authHeader()}) + } + + saveReview(content, parent = -1) { + return axios.post(API_URL + 'save', {content, parent},{ headers: authHeader() }); + } + +} + +export default new ReviewService() \ No newline at end of file diff --git a/med-web-app-front/src/styles/Review.css b/med-web-app-front/src/styles/Review.css new file mode 100644 index 00000000..2c477132 --- /dev/null +++ b/med-web-app-front/src/styles/Review.css @@ -0,0 +1,11 @@ +.review-create-form { + font-size: medium; + max-width: 800px !important; + width: 100%; + border-style: none; + /*background-color: #f7f7f7;*/ + padding: 10px 5px 20px; + margin: 0 auto 25px; + margin-top: 30px; + border-radius: 4px; +} diff --git a/src/main/java/com/app/medicalwebapp/controllers/ReviewController.java b/src/main/java/com/app/medicalwebapp/controllers/ReviewController.java new file mode 100644 index 00000000..ae8dfb79 --- /dev/null +++ b/src/main/java/com/app/medicalwebapp/controllers/ReviewController.java @@ -0,0 +1,61 @@ +package com.app.medicalwebapp.controllers; + +import com.app.medicalwebapp.controllers.requestbody.ReviewRequest; +import com.app.medicalwebapp.model.Review; +import com.app.medicalwebapp.model.User; +import com.app.medicalwebapp.repositories.ReviewRepository; +import com.app.medicalwebapp.security.UserDetailsImpl; +import com.app.medicalwebapp.services.ReviewService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.time.LocalDateTime; +import java.util.List; + +@CrossOrigin(origins = "*", maxAge = 604800) +@RestController +@RequestMapping("/api/reviews") +public class ReviewController { + + Logger log = LoggerFactory.getLogger(ReviewController.class); + + @Autowired + ReviewRepository reviewRepository; + + @Autowired + ReviewService reviewService; + + @GetMapping("/all") + public ResponseEntity getAllReviews(@PathVariable String profileName) { + try { + List reviews = reviewRepository.findAll()/*.orElse(null)*/;; + return ResponseEntity.ok().body(reviews); + } catch (Exception e) { + e.printStackTrace(); + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + @PostMapping("/save") + public ResponseEntity saveReview(@Valid @RequestBody ReviewRequest request) { + try { + reviewService.saveReview(request, getAuthenticatedUserId()); + } catch (Exception e) { + e.printStackTrace(); + return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + return ResponseEntity.ok().build(); + } + + private Long getAuthenticatedUserId() { + UserDetailsImpl principal = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + return principal != null ? principal.getId() : null; + } + +} diff --git a/src/main/java/com/app/medicalwebapp/controllers/requestbody/ReviewRequest.java b/src/main/java/com/app/medicalwebapp/controllers/requestbody/ReviewRequest.java new file mode 100644 index 00000000..276fe359 --- /dev/null +++ b/src/main/java/com/app/medicalwebapp/controllers/requestbody/ReviewRequest.java @@ -0,0 +1,16 @@ +package com.app.medicalwebapp.controllers.requestbody; + +import lombok.Getter; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +@Getter +@ToString +public class ReviewRequest { + + @NotNull + String content; + + Long parentId; +} diff --git a/src/main/java/com/app/medicalwebapp/model/Review.java b/src/main/java/com/app/medicalwebapp/model/Review.java new file mode 100644 index 00000000..093e211e --- /dev/null +++ b/src/main/java/com/app/medicalwebapp/model/Review.java @@ -0,0 +1,48 @@ +package com.app.medicalwebapp.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Table(name="reviews") +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Review { + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + @Column(name="id") + private Long id; + + @Column(name="content", length = 1500) + private String content; + + @Column(name="parent") + private Long parent; //чтобы оставить комментарий к комментарию + + @Column(name="creation_time") + private LocalDateTime creationTime; + + @ManyToOne + @JoinColumn(name="creator", nullable=false) + private User creator; + +// @ManyToOne +// @JoinColumn(name="target", nullable=false) +// private User target; + + @Column(name="num_replies") + private int numberOfReplies; + + @Column(name="likes") + private int likes; + + @Column(name="dislikes") + private int dislikes; +} diff --git a/src/main/java/com/app/medicalwebapp/repositories/ReviewRepository.java b/src/main/java/com/app/medicalwebapp/repositories/ReviewRepository.java new file mode 100644 index 00000000..04d89a0f --- /dev/null +++ b/src/main/java/com/app/medicalwebapp/repositories/ReviewRepository.java @@ -0,0 +1,16 @@ +package com.app.medicalwebapp.repositories; + +import com.app.medicalwebapp.model.Review; +import com.app.medicalwebapp.model.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ReviewRepository extends JpaRepository { + + List findAll(); + +// List findByTarget(User target); +} diff --git a/src/main/java/com/app/medicalwebapp/services/ReviewService.java b/src/main/java/com/app/medicalwebapp/services/ReviewService.java new file mode 100644 index 00000000..5662c223 --- /dev/null +++ b/src/main/java/com/app/medicalwebapp/services/ReviewService.java @@ -0,0 +1,31 @@ +package com.app.medicalwebapp.services; + +import com.app.medicalwebapp.controllers.requestbody.ReviewRequest; +import com.app.medicalwebapp.model.Review; +import com.app.medicalwebapp.model.User; +import com.app.medicalwebapp.repositories.ReviewRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; + +@Service +public class ReviewService { + + @Autowired + ReviewRepository reviewRepository; + + public void saveReview (ReviewRequest request, Long creatorId) throws Exception { + User creator = new User(); + creator.setId(creatorId); + Review review = Review.builder() + .content(request.getContent()) + .creationTime(LocalDateTime.now()) + .creator(creator) + //.edited(false) + .parent(request.getParentId()) + .build(); + reviewRepository.save(review); + } + +} From f0cb6e5ecb5e9412ba56ae80f16a45f7372ec7ca Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 20 Jul 2021 00:58:05 +0600 Subject: [PATCH 002/149] Implementation of search by username --- med-web-app-front/.env | 2 +- med-web-app-front/src/App.js | 7 + .../src/components/search.component.js | 128 ++++++++++++++++++ .../src/components/user-card.component.js | 27 ++++ .../src/components/view-records.component.js | 5 +- .../src/services/user.service.js | 31 +++++ med-web-app-front/src/styles/Search.css | 27 ++++ .../controllers/UserController.java | 53 ++++++++ .../controllers/requestbody/UserResponse.java | 15 ++ .../medicalwebapp/services/UserService.java | 3 +- 10 files changed, 294 insertions(+), 4 deletions(-) create mode 100644 med-web-app-front/src/components/search.component.js create mode 100644 med-web-app-front/src/components/user-card.component.js create mode 100644 med-web-app-front/src/services/user.service.js create mode 100644 med-web-app-front/src/styles/Search.css create mode 100644 src/main/java/com/app/medicalwebapp/controllers/UserController.java create mode 100644 src/main/java/com/app/medicalwebapp/controllers/requestbody/UserResponse.java diff --git a/med-web-app-front/.env b/med-web-app-front/.env index 13954e1b..a10b68c3 100644 --- a/med-web-app-front/.env +++ b/med-web-app-front/.env @@ -1,2 +1,2 @@ PORT=8081 -REACT_APP_API_URL=http://medicalwebapp.us-east-1.elasticbeanstalk.com \ No newline at end of file +REACT_APP_API_URL=http://localhost:7999 \ No newline at end of file diff --git a/med-web-app-front/src/App.js b/med-web-app-front/src/App.js index 17157237..d074726c 100644 --- a/med-web-app-front/src/App.js +++ b/med-web-app-front/src/App.js @@ -9,6 +9,7 @@ import Login from "./components/login.component"; import Register from "./components/register.component"; import Home from "./components/home.component"; import Profile from "./components/profile.component"; +import Search from "./components/search.component"; import ViewAttachmentsComponent from "./components/view-attachments.component"; import UploadAttachmentsComponent from "./components/upload-attachments.component"; import PipelinesComponent from "./components/pipelines.component"; @@ -84,6 +85,11 @@ class App extends Component { {currentUser ? (
+
  • + + Поиск + +
  • Мой профиль @@ -120,6 +126,7 @@ class App extends Component { + diff --git a/med-web-app-front/src/components/search.component.js b/med-web-app-front/src/components/search.component.js new file mode 100644 index 00000000..fed3dfd5 --- /dev/null +++ b/med-web-app-front/src/components/search.component.js @@ -0,0 +1,128 @@ +import React, {Component} from "react"; +import '../styles/Search.css' +import UserService from "../services/user.service"; +import UserCard from "./user-card.component"; + + +export default class Search extends Component { + constructor(props) { + super(props); + this.getUsers = this.getUsers.bind(this) + this.onChangeLogin = this.onChangeLogin.bind(this) + this.refreshList = this.refreshList.bind(this); + this.state = { + username: "", + }; + console.log("constructor") + } + + onChangeLogin(e) { + const username = e.target.value; + this.setState({ + username: username, + }); + } + + getUsers() { + console.log("getUsers") + const {username} = this.state + console.log(username) + UserService.getAll(username) + .then((response) => { + const {username} = response.data; + console.log(username) + console.log(response) + console.log(response.data) + this.refreshList(); + + this.setState({ + username: username, + }); + }) + .catch((e) => { + console.log(e); + }); + } + + refreshList() { + this.setState({ + username: "", + }); + } + + componentDidMount() { + this.getUsers(); + } + + render() { + const { + username, + } = this.state; + console.log("search.comp") + console.log(this.state.username) + console.log(username) + return ( +
    +
    + +