Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Status goals #56

Merged
merged 7 commits into from
Sep 6, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/main/java/lv/ctco/javaschool/goal/boundary/GoalApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lv.ctco.javaschool.goal.control.TagParser;
import lv.ctco.javaschool.goal.entity.domain.Comment;
import lv.ctco.javaschool.goal.entity.domain.Goal;
import lv.ctco.javaschool.goal.entity.domain.GoalStatus;
import lv.ctco.javaschool.goal.entity.domain.Tag;
import lv.ctco.javaschool.goal.entity.dto.CommentDto;
import lv.ctco.javaschool.goal.entity.dto.GoalDto;
Expand All @@ -17,6 +18,7 @@
import lv.ctco.javaschool.goal.entity.dto.UserDto;
import lv.ctco.javaschool.goal.entity.exception.InvalidGoalException;
import lv.ctco.javaschool.goal.entity.exception.InvalidUserException;
import lv.ctco.javaschool.goal.entity.exception.ValidationException;

import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;
Expand Down Expand Up @@ -81,7 +83,7 @@ public void createNewGoal(GoalFormDto goalDto) {
goal.setTags(tagSet);

goal.setDeadlineDate(goalDto.getDeadline());

goal.setStatus(GoalStatus.OPEN);
goal.setUser(user);
goal.setRegisteredDate(LocalDateTime.now());
goalStore.addGoal(goal);
Expand Down Expand Up @@ -152,7 +154,6 @@ public List<TagDto> returnAllTags() {
}

@POST
@RolesAllowed({"ADMIN", "USER"})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed? Do you want to allow users without these roles to use these methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they were moved to the top of the GoalApi because that all the methods are allowed to all users in GoalApi .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Did not see the class-level annotation at first, due to GitHub collapsing unchanged code.

@Path("/search-goals")
public List<GoalDto> getGoalsByTag(JsonObject searchDto) {
List<GoalDto> goalDtoList = new ArrayList<>();
Expand All @@ -173,7 +174,6 @@ public List<GoalDto> getGoalsByTag(JsonObject searchDto) {
}

@POST
@RolesAllowed({"ADMIN", "USER"})
@Path("/search-user")
public List<UserSearchDto> getUsersByUsername(JsonObject searchDto) {
List<UserSearchDto> userDtoList = new ArrayList<>();
Expand All @@ -191,7 +191,6 @@ public List<UserSearchDto> getUsersByUsername(JsonObject searchDto) {
}

@GET
@RolesAllowed({"ADMIN", "USER"})
@Path("/user/{id}")
public UserDto getUserById(@PathParam("id") Long id) {
Optional<User> user = userStore.findUserById(id);
Expand All @@ -204,5 +203,22 @@ public UserDto getUserById(@PathParam("id") Long id) {
throw new InvalidUserException();
}
}

@POST
@Path("/mygoals/{id}")
public void setStatusAchieved(@PathParam("id") Long goalId) {
User user = userStore.getCurrentUser();
Optional<Goal> goal = goalStore.getGoalById(goalId);
if (goal.isPresent()) {
Goal g = goal.get();
if (g.getUser() == user) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only primitives, Strings and Enums may be compared this way. Never use == to compare objects unless you are explicitly comparing references to the same object. Use equals() (making sure the class implements both equals() and hashCode()), or compare user IDs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be possible that they are the same object due to entity persistence framework (Hibernate), however we cannot rely on that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added equals() and hashCode()

g.setStatus(GoalStatus.ACHIEVED);
} else {
throw new ValidationException("Current Goal does not belong to you so you can not Edit Status");
}
} else {
throw new ValidationException("The Goal does not exist");
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public static GoalDto convertGoalToGoalDto(Goal goal) {
dto.setDaysLeft(DateTimeConverter.countDaysLeft(goal.getDeadlineDate()));
dto.setId(goal.getId());
dto.setTags(goal.getTags());
dto.setGoalStatus(goal.getStatus());
return dto;
}

Expand All @@ -38,6 +39,7 @@ public static UserLoginDto convertUserToUserLoginDto(User user) {

public static CommentDto convertCommentToCommentDto(Comment comment) {
CommentDto dto = new CommentDto();
dto.setUserId(comment.getUser().getId());
dto.setUsername(comment.getUser().getUsername());
dto.setRegisteredDate(comment.getRegisteredDate().format(DateTimeConverter.FORMATTER_DATE_TIME));
dto.setCommentMessage(comment.getCommentMessage());
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/lv/ctco/javaschool/goal/control/GoalStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import lv.ctco.javaschool.auth.entity.domain.User;
import lv.ctco.javaschool.goal.entity.domain.Comment;
import lv.ctco.javaschool.goal.entity.domain.Goal;
import lv.ctco.javaschool.goal.entity.domain.GoalStatus;
import lv.ctco.javaschool.goal.entity.domain.Tag;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
Expand All @@ -19,12 +22,26 @@ public class GoalStore {
private EntityManager em;

public List<Goal> getGoalsListFor(User user) {
return em.createQuery(
List<Goal> goals = em.createQuery(
"select g " +
"from Goal g " +
"where g.user = :user ", Goal.class)
.setParameter("user", user)
.getResultList();
return CheckStatus(goals);
}

private List<Goal> CheckStatus(List<Goal> goals) {
List<Goal> goalsToReturn = new ArrayList<>();
for (Goal goal : goals) {
if ((goal.getDeadlineDate().isBefore(LocalDate.now())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please extract LocalDate.now() to a variable and place it outside the for loop, to ensure consistent comparison of all goals against a single date and to reduce the amount of calls to LocalDate.now().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extracted thank you.

|| goal.getDeadlineDate().isEqual(LocalDate.now()))
&& goal.getStatus() != GoalStatus.ACHIEVED) {
goal.setStatus(GoalStatus.OVERDUE);
}
goalsToReturn.add(goal);
}
return goalsToReturn;
}

public void addGoal(Goal goal) {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/lv/ctco/javaschool/goal/entity/domain/Goal.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import lv.ctco.javaschool.auth.entity.domain.User;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
Expand Down Expand Up @@ -31,6 +33,16 @@ public class Goal {
private String goalMessage;
private LocalDate deadlineDate;
private LocalDateTime registeredDate;
@Enumerated(EnumType.STRING)
private GoalStatus status;

public GoalStatus getStatus() {
return status;
}

public void setStatus(GoalStatus status) {
this.status = status;
}

public Goal() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package lv.ctco.javaschool.goal.entity.domain;

public enum GoalStatus {
OPEN,
ACHIEVED,
OVERDUE
}
13 changes: 11 additions & 2 deletions src/main/java/lv/ctco/javaschool/goal/entity/dto/CommentDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@

public class CommentDto {
private String username;

private Long userId;
private String registeredDate;
private String commentMessage;

public CommentDto() {
}

public CommentDto(String username, String localDateTime, String msg) {
public CommentDto(String username, String localDateTime, String msg, Long id) {
this.username = username;
this.registeredDate = localDateTime;
this.commentMessage = msg;
this.userId = id;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
this.userId = userId;
}

public String getUsername() {
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/lv/ctco/javaschool/goal/entity/dto/GoalDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package lv.ctco.javaschool.goal.entity.dto;

import lv.ctco.javaschool.goal.entity.domain.GoalStatus;
import lv.ctco.javaschool.goal.entity.domain.Tag;

import java.time.LocalDate;
Expand All @@ -15,6 +16,15 @@ public class GoalDto {
private LocalDateTime registeredDate;
private Set<Tag> tags;
private int daysLeft;
private GoalStatus goalStatus;

public GoalStatus getGoalStatus() {
return goalStatus;
}

public void setGoalStatus(GoalStatus goalStatus) {
this.goalStatus = goalStatus;
}

public Long getUserId() {
return userId;
Expand Down
14 changes: 13 additions & 1 deletion src/main/webapp/app/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,21 @@ ul {
margin-bottom: 5%;
}

.ACHIEVED {
background-color: #27ff5a !important;
}

.OVERDUE {
background-color: #ff5953 !important;
}

input[type=date]::-webkit-clear-button,
input[type=date]::-webkit-inner-spin-button,
input[type=date]::-webkit-outer-spin-button {
display: none;
-webkit-appearance: none;
}
}

span.ACHIEVED {
visibility: hidden !important;
}
2 changes: 1 addition & 1 deletion src/main/webapp/app/findgoals.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<th>Deadline</th>
<th>Days left</th>
</tr>
<tr w3-repeat="goals" id="{{id}}" onclick="redirectToGoalsAndComments(id)">
<tr w3-repeat="goals" id="{{id}}" class="{{goalStatus}}" onclick="redirectToGoalsAndComments(id)">
<td>{{goalMessage}}</td>
<td>{{deadlineDate}}</td>
<td>{{daysLeft}}</td>
Expand Down
12 changes: 8 additions & 4 deletions src/main/webapp/app/goal.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@
<div class="button-div">
<button id="edit-button" class="menu-button" onclick="editGoal()" type="button">Edit Goal</button>
</div>
<div class="button-div" id="status-achieved">
<button class="menu-button" onclick="setStatusAchieved('{{id}}')" type="button">Achieved</button>
</div>
</div>
<div id="goal-fields">
<div id="show-goal">
<h3>Goal: {{goalMessage}}</h3>
<h5>Author: <a onclick="redirectToUserById('{{userId}}')">{{username}}</a></h5>
<h5>Deadline: {{deadlineDate}} (days left: {{daysLeft}})</h5>
<h5>Deadline: {{deadlineDate}}</h5>
<h5 class="{{goalStatus}}">Goal status: {{goalStatus}}</h5>
<div id="tags-list" w3-repeat="tags">
<span id="{{id}}">{{tagMessage}}</span>
</div>
Expand Down Expand Up @@ -61,12 +65,12 @@
<hr>
<ul id="sortable" class="w3-hide">
<li w3-repeat="comments" class="repeatable">
<strong>{{username}}</strong>
<strong> <a onclick="redirectToUserById('{{userId}}')">{{username}}</a></strong>
<small>
<span class="glyphicon glyphicon-time"></span>{{registeredDate}}
</small>
<br/>
<br/>
</br>
</br>
<p>{{commentMessage}}</p>
</li>
</ul>
Expand Down
28 changes: 27 additions & 1 deletion src/main/webapp/app/js/goal-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ function onLoad() {
}).then(function (goal) {
w3.displayObject("title", goal);
w3.displayObject("goal-fields", goal);
w3.displayObject("status-achieved", goal);
w3DisplayData("tags-list", goal);
document.getElementById("goal-deadline").setAttribute("value", goal.deadlineDate);
if (goal.goalStatus === "ACHIEVED") {
document.getElementById("status-achieved").classList.add("w3-hide");
}
getComments();
});
enableEditForGoalOwner();
Expand Down Expand Up @@ -94,8 +98,10 @@ function enableEditForGoalOwner() {
return false;
}
}).then(function (goalEdit) {
if (!goalEdit)
if (!goalEdit) {
document.getElementById("edit-button").classList.add("w3-hide");
document.getElementById("status-achieved").classList.add("w3-hide");
}
isMyGoal = goalEdit;
});
}
Expand All @@ -104,6 +110,8 @@ function editGoal() {
if (isMyGoal) {
document.getElementById("show-goal").classList.add("w3-hide");
document.getElementById("edit-goal").classList.remove("w3-hide");
document.getElementById("edit-button").classList.add("w3-hide");
document.getElementById("status-achieved").classList.add("w3-hide");
} else {
alert("You can edit only your own goals");
}
Expand Down Expand Up @@ -135,4 +143,22 @@ function saveEditGoal() {
return false;
}
});
}

function setStatusAchieved(id) {
fetch(path + "/api/goal/mygoals/" + id, {
"method": "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(function (response) {
if (response.status === 204) {
onLoad();
} else {
console.log(response);
Copy link
Contributor

@olegvm olegvm Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth it to extract console.log() and alert() to a single function which reports the error (e.g. displayError(response), and reuse that function over the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alert() extracted to function displayErrors() and removed all console.log()

alert("Something went wrong! error: " + response.status.toString());
return false;
}
});
}
3 changes: 3 additions & 0 deletions src/main/webapp/app/js/start-page.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var path = "";
var goalList;

function showUserProfile() {
fetch(path + "/api/auth/myprofile", {
Expand All @@ -25,6 +26,8 @@ function showUserGoals() {
}).then(function (response) {
return response.json();
}).then(function (goals) {
goalList = goals;
console.log(goals);
var tabledata;
if (goals.length > 0) {
tabledata = {"goals": goals};
Expand Down
8 changes: 6 additions & 2 deletions src/main/webapp/app/start.jsp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core' %>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
Expand All @@ -9,6 +10,7 @@
<script src="http://www.w3schools.com/lib/w3data.js"></script>
<title>My Goals</title>
</head>

<body onload="showUserProfile();showUserGoals();switchPersonalData();">
<div id="menu">
<div class="button-div">
Expand All @@ -35,10 +37,12 @@
<th>Deadline</th>
<th>Days left</th>
</tr>
<tr w3-repeat="goals" id="{{id}}" onclick="redirectToGoalsAndComments(id)">
<tr w3-repeat="goals" class="{{goalStatus}}" onclick="redirectToGoalsAndComments('{{id}}')">
<td>{{goalMessage}}</td>
<td>{{deadlineDate}}</td>
<td>{{daysLeft}}</td>
<td>
<span class="{{goalStatus}}">{{daysLeft}}</span>
</td>
</tr>
</table>
</body>
Expand Down
Loading