Skip to content

Commit

Permalink
Study settings - tags and zones
Browse files Browse the repository at this point in the history
  • Loading branch information
whiteship committed Mar 4, 2020
1 parent 920185d commit 4afe1c3
Show file tree
Hide file tree
Showing 14 changed files with 406 additions and 114 deletions.
6 changes: 6 additions & 0 deletions src/main/java/com/studyolle/domain/Study.java
Expand Up @@ -13,6 +13,12 @@
@NamedAttributeNode("zones"),
@NamedAttributeNode("managers"),
@NamedAttributeNode("members")})
@NamedEntityGraph(name = "Study.withTagsAndManagers", attributeNodes = {
@NamedAttributeNode("tags"),
@NamedAttributeNode("managers")})
@NamedEntityGraph(name = "Study.withZonesAndManagers", attributeNodes = {
@NamedAttributeNode("zones"),
@NamedAttributeNode("managers")})
@Entity
@Getter @Setter @EqualsAndHashCode(of = "id")
@Builder @AllArgsConstructor @NoArgsConstructor
Expand Down
11 changes: 5 additions & 6 deletions src/main/java/com/studyolle/settings/SettingsController.java
Expand Up @@ -10,7 +10,10 @@
import com.studyolle.settings.form.*;
import com.studyolle.settings.validator.NicknameValidator;
import com.studyolle.settings.validator.PasswordFormValidator;
import com.studyolle.tag.TagForm;
import com.studyolle.tag.TagRepository;
import com.studyolle.tag.TagService;
import com.studyolle.zone.ZoneForm;
import com.studyolle.zone.ZoneRepository;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
Expand Down Expand Up @@ -47,6 +50,7 @@ public class SettingsController {
private final AccountService accountService;
private final ModelMapper modelMapper;
private final NicknameValidator nicknameValidator;
private final TagService tagService;
private final TagRepository tagRepository;
private final ZoneRepository zoneRepository;
private final ObjectMapper objectMapper;
Expand Down Expand Up @@ -137,12 +141,7 @@ public String updateTags(@CurrentAccount Account account, Model model) throws Js
@PostMapping(TAGS + "/add")
@ResponseBody
public ResponseEntity addTag(@CurrentAccount Account account, @RequestBody TagForm tagForm) {
String title = tagForm.getTagTitle();
Tag tag = tagRepository.findByTitle(title);
if (tag == null) {
tag = tagRepository.save(Tag.builder().title(title).build());
}

Tag tag = tagService.findOrCreateNew(tagForm.getTagTitle());
accountService.addTag(account, tag);
return ResponseEntity.ok().build();
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/studyolle/study/StudyRepository.java
Expand Up @@ -12,4 +12,10 @@ public interface StudyRepository extends JpaRepository<Study, Long> {

@EntityGraph(value = "Study.withAll", type = EntityGraph.EntityGraphType.LOAD)
Study findByPath(String path);

@EntityGraph(value = "Study.withTagsAndManagers", type = EntityGraph.EntityGraphType.FETCH)
Study findAccountWithTagsByPath(String path);

@EntityGraph(value = "Study.withZonesAndManagers", type = EntityGraph.EntityGraphType.FETCH)
Study findAccountWithZonesByPath(String path);
}
55 changes: 47 additions & 8 deletions src/main/java/com/studyolle/study/StudyService.java
Expand Up @@ -2,6 +2,8 @@

import com.studyolle.domain.Account;
import com.studyolle.domain.Study;
import com.studyolle.domain.Tag;
import com.studyolle.domain.Zone;
import com.studyolle.study.form.StudyDescriptionForm;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
Expand All @@ -25,19 +27,13 @@ public Study createNewStudy(Study study, Account account) {

public Study getStudyToUpdate(Account account, String path) {
Study study = this.getStudy(path);
if (!account.isManagerOf(study)) {
throw new AccessDeniedException("해당 기능을 사용할 수 없습니다.");
}

checkIfManager(account, study);
return study;
}

public Study getStudy(String path) {
Study study = this.repository.findByPath(path);
if (study == null) {
throw new IllegalArgumentException(path + "에 해당하는 스터디가 없습니다.");
}

checkIfExistingStudy(path, study);
return study;
}

Expand All @@ -56,4 +52,47 @@ public void enableStudyBanner(Study study) {
public void disableStudyBanner(Study study) {
study.setUseBanner(false);
}

public void addTag(Study study, Tag tag) {
study.getTags().add(tag);
}

public void removeTag(Study study, Tag tag) {
study.getTags().remove(tag);
}

public void addZone(Study study, Zone zone) {
study.getZones().add(zone);
}

public void removeZone(Study study, Zone zone) {
study.getZones().remove(zone);
}

public Study getStudyToUpdateTag(Account account, String path) {
Study study = repository.findAccountWithTagsByPath(path);
checkIfExistingStudy(path, study);
checkIfManager(account, study);
return study;
}

public Study getStudyToUpdateZone(Account account, String path) {
Study study = repository.findAccountWithZonesByPath(path);
checkIfExistingStudy(path, study);
checkIfManager(account, study);
return study;
}

private void checkIfManager(Account account, Study study) {
if (!account.isManagerOf(study)) {
throw new AccessDeniedException("해당 기능을 사용할 수 없습니다.");
}
}

private void checkIfExistingStudy(String path, Study study) {
if (study == null) {
throw new IllegalArgumentException(path + "에 해당하는 스터디가 없습니다.");
}
}

}
97 changes: 97 additions & 0 deletions src/main/java/com/studyolle/study/StudySettingsController.java
@@ -1,11 +1,21 @@
package com.studyolle.study;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.studyolle.account.CurrentAccount;
import com.studyolle.domain.Account;
import com.studyolle.domain.Study;
import com.studyolle.domain.Tag;
import com.studyolle.domain.Zone;
import com.studyolle.study.form.StudyDescriptionForm;
import com.studyolle.tag.TagForm;
import com.studyolle.tag.TagRepository;
import com.studyolle.tag.TagService;
import com.studyolle.zone.ZoneForm;
import com.studyolle.zone.ZoneRepository;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
Expand All @@ -16,6 +26,9 @@
import javax.validation.Valid;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/study/{path}/settings")
Expand All @@ -24,6 +37,10 @@ public class StudySettingsController {

private final StudyService studyService;
private final ModelMapper modelMapper;
private final TagService tagService;
private final TagRepository tagRepository;
private final ZoneRepository zoneRepository;
private final ObjectMapper objectMapper;

@GetMapping("/description")
public String viewStudySetting(@CurrentAccount Account account, @PathVariable String path, Model model) {
Expand Down Expand Up @@ -86,4 +103,84 @@ public String disableStudyBanner(@CurrentAccount Account account, @PathVariable
return "redirect:/study/" + getPath(path) + "/settings/banner";
}

@GetMapping("/tags")
public String studyTagsForm(@CurrentAccount Account account, @PathVariable String path, Model model)
throws JsonProcessingException {
Study study = studyService.getStudyToUpdate(account, path);
model.addAttribute(account);
model.addAttribute(study);

model.addAttribute("tags", study.getTags().stream()
.map(Tag::getTitle).collect(Collectors.toList()));
List<String> allTagTitles = tagRepository.findAll().stream()
.map(Tag::getTitle).collect(Collectors.toList());
model.addAttribute("whitelist", objectMapper.writeValueAsString(allTagTitles));
return "study/settings/tags";
}

@PostMapping("/tags/add")
@ResponseBody
public ResponseEntity addTag(@CurrentAccount Account account, @PathVariable String path,
@RequestBody TagForm tagForm) {
Study study = studyService.getStudyToUpdateTag(account, path);
Tag tag = tagService.findOrCreateNew(tagForm.getTagTitle());
studyService.addTag(study, tag);
return ResponseEntity.ok().build();
}

@PostMapping("/tags/remove")
@ResponseBody
public ResponseEntity removeTag(@CurrentAccount Account account, @PathVariable String path,
@RequestBody TagForm tagForm) {
Study study = studyService.getStudyToUpdateTag(account, path);
Tag tag = tagRepository.findByTitle(tagForm.getTagTitle());
if (tag == null) {
return ResponseEntity.badRequest().build();
}

studyService.removeTag(study, tag);
return ResponseEntity.ok().build();
}

@GetMapping("/zones")
public String studyZonesForm(@CurrentAccount Account account, @PathVariable String path, Model model)
throws JsonProcessingException {
Study study = studyService.getStudyToUpdate(account, path);
model.addAttribute(account);
model.addAttribute(study);
model.addAttribute("zones", study.getZones().stream()
.map(Zone::toString).collect(Collectors.toList()));
List<String> allZones = zoneRepository.findAll().stream().map(Zone::toString).collect(Collectors.toList());
model.addAttribute("whitelist", objectMapper.writeValueAsString(allZones));
return "study/settings/zones";
}

@PostMapping("/zones/add")
@ResponseBody
public ResponseEntity addZone(@CurrentAccount Account account, @PathVariable String path,
@RequestBody ZoneForm zoneForm) {
Study study = studyService.getStudyToUpdateZone(account, path);
Zone zone = zoneRepository.findByCityAndProvince(zoneForm.getCityName(), zoneForm.getProvinceName());
if (zone == null) {
return ResponseEntity.badRequest().build();
}

studyService.addZone(study, zone);
return ResponseEntity.ok().build();
}

@PostMapping("/zones/remove")
@ResponseBody
public ResponseEntity removeZone(@CurrentAccount Account account, @PathVariable String path,
@RequestBody ZoneForm zoneForm) {
Study study = studyService.getStudyToUpdateZone(account, path);
Zone zone = zoneRepository.findByCityAndProvince(zoneForm.getCityName(), zoneForm.getProvinceName());
if (zone == null) {
return ResponseEntity.badRequest().build();
}

studyService.removeZone(study, zone);
return ResponseEntity.ok().build();
}

}
@@ -1,4 +1,4 @@
package com.studyolle.settings.form;
package com.studyolle.tag;

import lombok.Data;

Expand Down
25 changes: 25 additions & 0 deletions src/main/java/com/studyolle/tag/TagService.java
@@ -0,0 +1,25 @@
package com.studyolle.tag;

import com.studyolle.domain.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Transactional
@RequiredArgsConstructor
public class TagService {

private final TagRepository tagRepository;

public Tag findOrCreateNew(String tagTitle) {
Tag tag = tagRepository.findByTitle(tagTitle);
if (tag == null) {
tag = tagRepository.save(Tag.builder().title(tagTitle).build());
}
return tag;
}

}
@@ -1,4 +1,4 @@
package com.studyolle.settings.form;
package com.studyolle.zone;

import com.studyolle.domain.Zone;
import lombok.Data;
Expand Down

0 comments on commit 4afe1c3

Please sign in to comment.