Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 19 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#DB
DB_USERNAME=jira
DD_PASSWORD=JiraRush

#Github
GITHUB_CLIENT_ID=3d0d8738e65881fff266
GITHUB_CLIENT_SECRET=0f97031ce6178b7dfb67a6af587f37e222a16120

#Google
GOOGLE_CLIENT_ID=329113642700-f8if6pu68j2repq3ef6umd5jgiliup60.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=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

#Gitlab
GITLAB_CLIENT_ID=b8520a3266089063c0d8261cce36971defa513f5ffd9f9b7a3d16728fc83a494
GITLAB_CLIENT_SECRET=e72c65320cf9d6495984a37b0f9cc03ec46be0bb6f071feaebbfe75168117004

#Gmail
GMAIL_USERNAME=jira4jr@gmail.com
GMAIL_PASSWORD=zdfzsrqvgimldzyj
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
Expand Down Expand Up @@ -142,6 +144,11 @@
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
9 changes: 0 additions & 9 deletions resources/static/fontawesome/css/all.css
Original file line number Diff line number Diff line change
Expand Up @@ -8603,9 +8603,6 @@ readers do not read off random characters that represent icons */
content: "\f3e8";
}

.fa-vk:before {
content: "\f189";
}

.fa-untappd:before {
content: "\f405";
Expand Down Expand Up @@ -9955,9 +9952,6 @@ readers do not read off random characters that represent icons */
content: "\f3bc";
}

.fa-yandex:before {
content: "\f413";
}

.fa-readme:before {
content: "\f4d5";
Expand Down Expand Up @@ -10183,9 +10177,6 @@ readers do not read off random characters that represent icons */
content: "\f7c6";
}

.fa-yandex-international:before {
content: "\f414";
}

.fa-cc-amex:before {
content: "\f1f3";
Expand Down
2 changes: 1 addition & 1 deletion resources/static/fontawesome/css/all.min.css

Large diffs are not rendered by default.

8 changes: 0 additions & 8 deletions resources/view/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ <h3 class="mb-3">Sign in</h3>
type="button">
<i class="fa-brands fa-google"></i>
</a>
<a class="btn btn-primary btn-lg me-2" href="/oauth2/authorization/vk" style="padding-left: 17px; padding-right: 17px;"
type="button">
<i class="fa-brands fa-vk"></i>
</a>
<a class="btn btn-danger btn-lg me-2" href="/oauth2/authorization/yandex" style="padding-left: 21px; padding-right: 21px;"
type="button">
<i class="fa-brands fa-yandex"></i>
</a>
<a class="btn btn-dark btn-lg me-2" href="/oauth2/authorization/github" type="button">
<i class="fa-brands fa-github"></i>
</a>
Expand Down
8 changes: 0 additions & 8 deletions resources/view/unauth/register.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,6 @@ <h3 class="mb-3">Registration</h3>
type="button">
<i class="fa-brands fa-google"></i>
</a>
<a class="btn btn-primary btn-lg me-2" href="/oauth2/authorization/vk" style="padding-left: 17px; padding-right: 17px;"
type="button">
<i class="fa-brands fa-vk"></i>
</a>
<a class="btn btn-danger btn-lg me-2" href="/oauth2/authorization/yandex" style="padding-left: 21px; padding-right: 21px;"
type="button">
<i class="fa-brands fa-yandex"></i>
</a>
<a class="btn btn-dark btn-lg me-2" href="/oauth2/authorization/github" type="button">
<i class="fa-brands fa-github"></i>
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
import org.springframework.core.io.UrlResource;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -25,17 +22,18 @@ public static void upload(MultipartFile multipartFile, String directoryPath, Str
throw new IllegalRequestDataException("Select a file to upload.");
}

File dir = new File(directoryPath);
if (dir.exists() || dir.mkdirs()) {
File file = new File(directoryPath + fileName);
try (OutputStream outStream = new FileOutputStream(file)) {
outStream.write(multipartFile.getBytes());
} catch (IOException ex) {
throw new IllegalRequestDataException("Failed to upload file" + multipartFile.getOriginalFilename());
}
try {
Path directory = Paths.get(directoryPath);
Files.createDirectories(directory);

Path filePath = directory.resolve(fileName);
Files.write(filePath, multipartFile.getBytes());
} catch (IOException ex) {
throw new IllegalRequestDataException("Failed to upload file " + multipartFile.getOriginalFilename());
}
}


public static Resource download(String fileLink) {
Path path = Paths.get(fileLink);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import static com.javarush.jira.common.BaseHandler.createdResponse;

Expand Down Expand Up @@ -151,6 +152,20 @@ public void delete(@PathVariable long id) {
activityService.delete(id);
}

@PostMapping("/{id}/tags")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void addTagsToTask(@PathVariable long id, @RequestBody Set<String> tags) {
log.info("Add tags {} to task with id={}", tags, id);
taskService.addTagsToTask(id, tags);
}
@DeleteMapping("/{id}/tags")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void removeTagsFromTask(@PathVariable long id, @RequestParam Set<String> tags) {
taskService.removeTagsFromTask(id, tags);
}



private record TaskTreeNode(TaskTo taskTo, List<TaskTreeNode> subNodes) implements ITreeNode<TaskTo, TaskTreeNode> {
public TaskTreeNode(TaskTo taskTo) {
this(taskTo, new LinkedList<>());
Expand Down
77 changes: 77 additions & 0 deletions src/main/java/com/javarush/jira/bugtracking/task/TaskService.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

import static com.javarush.jira.bugtracking.ObjectType.TASK;
import static com.javarush.jira.bugtracking.task.TaskUtil.fillExtraFields;
Expand All @@ -32,6 +34,9 @@
public class TaskService {
static final String CANNOT_ASSIGN = "Cannot assign as %s to task with status=%s";
static final String CANNOT_UN_ASSIGN = "Cannot unassign as %s from task with status=%s";
static final String IN_PROGRESS_STATUS = "in_progress";
static final String READY_FOR_REVIEW_STATUS = "ready_for_review";
static final String DONE_STATUS = "done";

private final Handlers.TaskExtHandler handler;
private final Handlers.ActivityHandler activityHandler;
Expand Down Expand Up @@ -140,4 +145,76 @@ private void checkAssignmentActionPossible(long id, String userType, boolean ass
throw new DataConflictException(String.format(assign ? CANNOT_ASSIGN : CANNOT_UN_ASSIGN, userType, task.getStatusCode()));
}
}

@Transactional
public void addTagsToTask(long id, Set<String> tags) {
Task task = handler.getRepository().getExisted(id);
if (task == null) {
throw new NotFoundException("Task with id " + id + " not found");
}
if (tags == null || tags.isEmpty()) {
throw new IllegalArgumentException("Tags list must not be empty");
}
for (String tag : tags) {
if (tag != null && !tag.isEmpty()) {
task.getTags().add(tag);
}
}
handler.getRepository().save(task);
}
@Transactional
public void removeTagsFromTask(long id, Set<String> tags) {
Task task = handler.getRepository().getExisted(id);

if (task == null) {
throw new NotFoundException("Task with id " + id + " not found");
}

if (tags == null || tags.isEmpty()) {
throw new IllegalArgumentException("Tags list must not be empty");
}
for (String tag : tags) {
if (tag != null && !tag.isEmpty()) {
task.getTags().remove(tag);
}
}
handler.getRepository().save(task);
}
public Long calculateTimeInProgress(Task task) {
Long taskId = task.getId();
List<Activity> activities = task.getActivities();
LocalDateTime readyForReviewTime = LocalDateTime.now();
LocalDateTime inProgressTime = LocalDateTime.now();

for (Activity activity : activities) {
if (activity.getTaskId().equals(taskId)) {
String statusCode = activity.getStatusCode();
if (READY_FOR_REVIEW_STATUS.equals(statusCode)) {
readyForReviewTime = activity.getUpdated();
} else if (IN_PROGRESS_STATUS.equals(statusCode)) {
inProgressTime = activity.getUpdated();
}
}
}
return Duration.between(inProgressTime, readyForReviewTime).getSeconds();
}

public Long calculateTimeInTesting(Task task) {
Long taskId = task.getId();
List<Activity> activities = task.getActivities();
LocalDateTime doneTime = LocalDateTime.now();
LocalDateTime readyForReviewTime = LocalDateTime.now();

for (Activity activity : activities) {
if (activity.getTaskId().equals(taskId)) {
String statusCode = activity.getStatusCode();
if (DONE_STATUS.equals(statusCode)) {
doneTime = activity.getUpdated();
} else if (READY_FOR_REVIEW_STATUS.equals(statusCode)) {
readyForReviewTime = activity.getUpdated();
}
}
}
return Duration.between(readyForReviewTime, doneTime).getSeconds();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

@Getter
public class TaskToFull extends TaskToExt {
Expand All @@ -14,14 +15,16 @@ public class TaskToFull extends TaskToExt {
CodeTo sprint;
@Setter
List<ActivityTo> activityTos;
Set<String> tags;

public TaskToFull(Long id, String code, String title, String description, String typeCode, String statusCode, String priorityCode,
LocalDateTime updated, Integer estimate, CodeTo parent, CodeTo project, CodeTo sprint, List<ActivityTo> activityTos) {
LocalDateTime updated, Integer estimate, CodeTo parent, CodeTo project, CodeTo sprint, Set<String> tags, List<ActivityTo> activityTos) {
super(id, code, title, description, typeCode, statusCode, priorityCode, updated, estimate,
parent == null ? null : parent.getId(), project.getId(), sprint == null ? null : sprint.getId());
this.parent = parent;
this.project = project;
this.sprint = sprint;
this.activityTos = activityTos;
this.tags = tags;
}
}

This file was deleted.

This file was deleted.

Loading