Compare View
Commits (2)
Showing
151 changed files
Show diff stats
Too many changes.
To preserve performance only 100 of 151 files displayed.
| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<module type="JAVA_MODULE" version="4"> | |
| 3 | + <component name="NewModuleRootManager" inherit-compiler-output="true"> | |
| 4 | + <exclude-output /> | |
| 5 | + <content url="file://$MODULE_DIR$" /> | |
| 6 | + <orderEntry type="inheritedJdk" /> | |
| 7 | + <orderEntry type="sourceFolder" forTests="false" /> | |
| 8 | + </component> | |
| 9 | +</module> | |
| 0 | 10 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project version="4"> | |
| 3 | + <component name="ProjectModuleManager"> | |
| 4 | + <modules> | |
| 5 | + <module fileurl="file://$PROJECT_DIR$/.idea/2020-Herik-SRH.iml" filepath="$PROJECT_DIR$/.idea/2020-Herik-SRH.iml" /> | |
| 6 | + </modules> | |
| 7 | + </component> | |
| 8 | +</project> | |
| 0 | 9 | \ No newline at end of file | ... | ... |
.idea/sonarlint/issuestore/5/d/5d3445d1560f9fb50fd22131b2387e4661ecc6d7
0 → 100644
.idea/sonarlint/issuestore/8/e/8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d
0 → 100644
.idea/sonarlint/issuestore/9/6/962c419380565e1b39f0c2c642d055bb68106743
0 → 100644
.idea/sonarlint/issuestore/a/c/acd061af923379b136810cb92f99558057249ef9
0 → 100644
.idea/sonarlint/issuestore/b/d/bde5d5ddddf6982d30196f10e83c423802e01b75
0 → 100644
No preview for this file type
| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project version="4"> | |
| 3 | + <component name="ChangeListManager"> | |
| 4 | + <list default="true" id="d16a14de-0ce4-449c-88ef-95e346e97466" name="Default Changelist" comment="" /> | |
| 5 | + <option name="SHOW_DIALOG" value="false" /> | |
| 6 | + <option name="HIGHLIGHT_CONFLICTS" value="true" /> | |
| 7 | + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | |
| 8 | + <option name="LAST_RESOLUTION" value="IGNORE" /> | |
| 9 | + </component> | |
| 10 | + <component name="Git.Settings"> | |
| 11 | + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> | |
| 12 | + </component> | |
| 13 | + <component name="ProjectId" id="1eEDyolyBaYceGht1XHEwSuoSEW" /> | |
| 14 | + <component name="ProjectViewState"> | |
| 15 | + <option name="hideEmptyMiddlePackages" value="true" /> | |
| 16 | + <option name="showLibraryContents" value="true" /> | |
| 17 | + </component> | |
| 18 | + <component name="PropertiesComponent"> | |
| 19 | + <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" /> | |
| 20 | + <property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> | |
| 21 | + <property name="last_opened_file_path" value="$PROJECT_DIR$/../srh-backend" /> | |
| 22 | + </component> | |
| 23 | + <component name="SvnConfiguration"> | |
| 24 | + <configuration /> | |
| 25 | + </component> | |
| 26 | + <component name="TaskManager"> | |
| 27 | + <task active="true" id="Default" summary="Default task"> | |
| 28 | + <changelist id="d16a14de-0ce4-449c-88ef-95e346e97466" name="Default Changelist" comment="" /> | |
| 29 | + <created>1593878115840</created> | |
| 30 | + <option name="number" value="Default" /> | |
| 31 | + <option name="presentableId" value="Default" /> | |
| 32 | + <updated>1593878115840</updated> | |
| 33 | + </task> | |
| 34 | + <servers /> | |
| 35 | + </component> | |
| 36 | + <component name="WindowStateProjectService"> | |
| 37 | + <state x="466" y="144" width="424" height="480" key="FileChooserDialogImpl" timestamp="1593954397371"> | |
| 38 | + <screen x="0" y="30" width="1366" height="738" /> | |
| 39 | + </state> | |
| 40 | + <state x="466" y="144" width="424" height="480" key="FileChooserDialogImpl/0.30.1366.738@0.30.1366.738" timestamp="1593954397371" /> | |
| 41 | + </component> | |
| 42 | +</project> | |
| 0 | 43 | \ No newline at end of file | ... | ... |
codigos/backend/pom.xml
| ... | ... | @@ -36,6 +36,10 @@ |
| 36 | 36 | <groupId>org.springframework.boot</groupId> |
| 37 | 37 | <artifactId>spring-boot-starter-security</artifactId> |
| 38 | 38 | </dependency> |
| 39 | + <dependency> | |
| 40 | + <groupId>org.springframework.boot</groupId> | |
| 41 | + <artifactId>spring-boot-starter-mail</artifactId> | |
| 42 | + </dependency> | |
| 39 | 43 | <dependency> |
| 40 | 44 | <groupId>de.codecentric</groupId> |
| 41 | 45 | <artifactId>spring-boot-admin-starter-client</artifactId> | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/AlgorithmCalc.java
0 → 100644
| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | +package com.srh.api.algorithms; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 4 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 5 | + | |
| 6 | +import java.util.List; | |
| 7 | + | |
| 8 | +public interface AlgorithmCalc { | |
| 9 | + public List<RecommendationsByUser> calc(RecommendationForm recommendationInfo); | |
| 10 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/AlgorithmStrategy.java
0 → 100644
| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | +package com.srh.api.algorithms; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.strategies.*; | |
| 4 | +import com.srh.api.error.exception.InvalidAlgorithmRecommendationException; | |
| 5 | +import lombok.SneakyThrows; | |
| 6 | + | |
| 7 | +public class AlgorithmStrategy { | |
| 8 | + @SneakyThrows | |
| 9 | + public static AlgorithmCalc findInstance(Integer algorithmId) { | |
| 10 | + String idValue = String.valueOf(algorithmId); | |
| 11 | + | |
| 12 | + switch (idValue) { | |
| 13 | + case "1": | |
| 14 | + return new Collaborative(); | |
| 15 | + case "2": | |
| 16 | + return new BasedContent(); | |
| 17 | + case "3": | |
| 18 | + return new WeightedHybrid(); | |
| 19 | + case "4": | |
| 20 | + return new WeightedHybridWithThreads(); | |
| 21 | + case "5": | |
| 22 | + return new MixedHybrid(); | |
| 23 | + case "6": | |
| 24 | + return new MixedHybridWithThreads(); | |
| 25 | + default: | |
| 26 | + throw new InvalidAlgorithmRecommendationException("Algoritmo inválido"); | |
| 27 | + } | |
| 28 | + } | |
| 29 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/strategies/BasedContent.java
0 → 100644
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +package com.srh.api.algorithms.strategies; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.AlgorithmCalc; | |
| 4 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 5 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 6 | +import com.srh.api.model.Evaluator; | |
| 7 | + | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +public class BasedContent implements AlgorithmCalc { | |
| 11 | + @Override | |
| 12 | + public List<RecommendationsByUser> calc(RecommendationForm recommendationForm) { | |
| 13 | + return null; | |
| 14 | + } | |
| 15 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/strategies/Collaborative.java
0 → 100644
| ... | ... | @@ -0,0 +1,111 @@ |
| 1 | +package com.srh.api.algorithms.strategies; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.AlgorithmCalc; | |
| 4 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 5 | +import com.srh.api.builder.RecommendationBuilder; | |
| 6 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 7 | +import com.srh.api.model.*; | |
| 8 | +import com.srh.api.repository.EvaluatorRepository; | |
| 9 | +import com.srh.api.repository.ItemRepository; | |
| 10 | +import com.srh.api.repository.ProjectRepository; | |
| 11 | +import com.srh.api.repository.RecommendationRepository; | |
| 12 | +import com.srh.api.service.AlgorithmService; | |
| 13 | +import com.srh.api.service.EvaluatorService; | |
| 14 | +import com.srh.api.service.ProjectService; | |
| 15 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 16 | +import org.springframework.data.domain.Page; | |
| 17 | +import org.springframework.data.domain.Pageable; | |
| 18 | + | |
| 19 | +import java.time.LocalDateTime; | |
| 20 | +import java.util.ArrayList; | |
| 21 | +import java.util.List; | |
| 22 | +import java.util.Random; | |
| 23 | + | |
| 24 | +public class Collaborative implements AlgorithmCalc { | |
| 25 | + @Autowired | |
| 26 | + private EvaluatorService evaluatorService; | |
| 27 | + | |
| 28 | + @Autowired | |
| 29 | + private ItemRepository itemRepository; | |
| 30 | + | |
| 31 | + @Autowired | |
| 32 | + private RecommendationRepository recommendationRepository; | |
| 33 | + | |
| 34 | + @Autowired | |
| 35 | + private ProjectRepository projectRepository; | |
| 36 | + | |
| 37 | + @Autowired | |
| 38 | + private ProjectService projectService; | |
| 39 | + | |
| 40 | + @Autowired | |
| 41 | + private AlgorithmService algorithmService; | |
| 42 | + | |
| 43 | + @Override | |
| 44 | + public List<RecommendationsByUser> calc(RecommendationForm recommendationForm) { | |
| 45 | + Iterable<Evaluator> evaluators = evaluatorService.listAll(); | |
| 46 | + List<RecommendationsByUser> recommendations = new ArrayList<>(); | |
| 47 | + | |
| 48 | + for (Evaluator evaluator : evaluators) { | |
| 49 | + RecommendationsByUser recommendationsByUser = generateRecommendationByEvaluator( | |
| 50 | + evaluator, recommendationForm | |
| 51 | + ); | |
| 52 | + | |
| 53 | + if (recommendationsByUser == null) { | |
| 54 | + recommendations.add(recommendationsByUser); | |
| 55 | + } | |
| 56 | + } | |
| 57 | + | |
| 58 | + return recommendations; | |
| 59 | + } | |
| 60 | + | |
| 61 | + private RecommendationsByUser generateRecommendationByEvaluator(Evaluator evaluator, | |
| 62 | + RecommendationForm recommendationForm) { | |
| 63 | + Random random = new Random(); | |
| 64 | + | |
| 65 | + if (random.nextInt(2) == 1) { | |
| 66 | + RecommendationsByUser recommendationsByUser = new RecommendationsByUser(); | |
| 67 | + | |
| 68 | + recommendationsByUser.setEvaluator(evaluator); | |
| 69 | + recommendationsByUser.setRecommendations(calculateRecommendations(evaluator, | |
| 70 | + recommendationForm)); | |
| 71 | + | |
| 72 | + return recommendationsByUser; | |
| 73 | + } | |
| 74 | + | |
| 75 | + return null; | |
| 76 | + } | |
| 77 | + | |
| 78 | + private List<Recommendation> calculateRecommendations(Evaluator evaluator, | |
| 79 | + RecommendationForm recommendationForm) { | |
| 80 | + Random random = new Random(); | |
| 81 | + List<Recommendation> recommendations = new ArrayList<>(); | |
| 82 | + | |
| 83 | + Project project = projectService.find(recommendationForm.getProjectId()); | |
| 84 | + Integer matrixId = project.getLastMatrixId() + 1; | |
| 85 | + Algorithm algorithm = algorithmService.find(recommendationForm.getAlgorithmId()); | |
| 86 | + | |
| 87 | + for(Item item: itemRepository.findByProject(project)) { | |
| 88 | + Double score = random.nextDouble() * 5; | |
| 89 | + | |
| 90 | + if (score > recommendationForm.getPassingScore()) { | |
| 91 | + Recommendation recommendation = RecommendationBuilder.aRecommendation() | |
| 92 | + .withAlgorithm(algorithm) | |
| 93 | + .withItem(item) | |
| 94 | + .withDate(LocalDateTime.now()) | |
| 95 | + .withEvaluator(evaluator) | |
| 96 | + .withRuntimeInSeconds(1) | |
| 97 | + .withWeight(score) | |
| 98 | + .withMatrixId(matrixId) | |
| 99 | + .build(); | |
| 100 | + | |
| 101 | + recommendationRepository.save(recommendation); | |
| 102 | + recommendations.add(recommendation); | |
| 103 | + } | |
| 104 | + } | |
| 105 | + | |
| 106 | + project.setLastMatrixId(matrixId); | |
| 107 | + projectService.save(project); | |
| 108 | + | |
| 109 | + return recommendations; | |
| 110 | + } | |
| 111 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/strategies/MixedHybrid.java
0 → 100644
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +package com.srh.api.algorithms.strategies; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.AlgorithmCalc; | |
| 4 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 5 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 6 | +import com.srh.api.model.Evaluator; | |
| 7 | + | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +public class MixedHybrid implements AlgorithmCalc { | |
| 11 | + @Override | |
| 12 | + public List<RecommendationsByUser> calc(RecommendationForm recommendationForm) { | |
| 13 | + return null; | |
| 14 | + } | |
| 15 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/strategies/MixedHybridWithThreads.java
0 → 100644
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +package com.srh.api.algorithms.strategies; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.AlgorithmCalc; | |
| 4 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 5 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 6 | +import com.srh.api.model.Evaluator; | |
| 7 | + | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +public class MixedHybridWithThreads implements AlgorithmCalc { | |
| 11 | + @Override | |
| 12 | + public List<RecommendationsByUser> calc(RecommendationForm recommendationForm) { | |
| 13 | + return null; | |
| 14 | + } | |
| 15 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/strategies/WeightedHybrid.java
0 → 100644
| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | +package com.srh.api.algorithms.strategies; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.AlgorithmCalc; | |
| 4 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 5 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 6 | +import com.srh.api.model.Evaluator; | |
| 7 | + | |
| 8 | +import java.util.List; | |
| 9 | + | |
| 10 | +public class WeightedHybrid implements AlgorithmCalc { | |
| 11 | + public List<RecommendationsByUser> calc(RecommendationForm recommendationForm) { | |
| 12 | + return null; | |
| 13 | + } | |
| 14 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/strategies/WeightedHybridWithThreads.java
0 → 100644
| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | +package com.srh.api.algorithms.strategies; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.AlgorithmCalc; | |
| 4 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 5 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 6 | + | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +public class WeightedHybridWithThreads implements AlgorithmCalc { | |
| 10 | + @Override | |
| 11 | + public List<RecommendationsByUser> calc(RecommendationForm recommendationForm) { | |
| 12 | + return null; | |
| 13 | + } | |
| 14 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/structure/RecommendationsByUser.java
0 → 100644
| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | +package com.srh.api.algorithms.structure; | |
| 2 | + | |
| 3 | +import com.srh.api.model.Evaluator; | |
| 4 | +import com.srh.api.model.Recommendation; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +@Data | |
| 10 | +public class RecommendationsByUser { | |
| 11 | + private Evaluator evaluator; | |
| 12 | + private List<Recommendation> recommendations; | |
| 13 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/algorithms/utils/EuclideanDistance.java
0 → 100644
codigos/backend/src/main/java/com/srh/api/builder/ProjectBuilder.java
| ... | ... | @@ -11,6 +11,7 @@ public final class ProjectBuilder { |
| 11 | 11 | private String description; |
| 12 | 12 | private LocalDate date; |
| 13 | 13 | private Boolean visible; |
| 14 | + private Integer lastMatrixId; | |
| 14 | 15 | private Situations situation; |
| 15 | 16 | private Admin admin; |
| 16 | 17 | private List<Evaluator> evaluators; |
| ... | ... | @@ -48,6 +49,11 @@ public final class ProjectBuilder { |
| 48 | 49 | return this; |
| 49 | 50 | } |
| 50 | 51 | |
| 52 | + public ProjectBuilder withLastMatrixId(Integer lastMatrixId) { | |
| 53 | + this.lastMatrixId = lastMatrixId; | |
| 54 | + return this; | |
| 55 | + } | |
| 56 | + | |
| 51 | 57 | public ProjectBuilder withSituation(Situations situation) { |
| 52 | 58 | this.situation = situation; |
| 53 | 59 | return this; |
| ... | ... | @@ -75,6 +81,7 @@ public final class ProjectBuilder { |
| 75 | 81 | project.setDescription(description); |
| 76 | 82 | project.setDate(date); |
| 77 | 83 | project.setVisible(visible); |
| 84 | + project.setLastMatrixId(lastMatrixId); | |
| 78 | 85 | project.setSituation(situation); |
| 79 | 86 | project.setAdmin(admin); |
| 80 | 87 | project.setEvaluators(evaluators); | ... | ... |
codigos/backend/src/main/java/com/srh/api/builder/RecommendationBuilder.java
| ... | ... | @@ -10,6 +10,7 @@ public final class RecommendationBuilder { |
| 10 | 10 | private Double weight; |
| 11 | 11 | private LocalDateTime date; |
| 12 | 12 | private Integer runtimeInSeconds; |
| 13 | + private Integer matrixId; | |
| 13 | 14 | private Algorithm algorithm; |
| 14 | 15 | private Evaluator evaluator; |
| 15 | 16 | private Item item; |
| ... | ... | @@ -42,6 +43,11 @@ public final class RecommendationBuilder { |
| 42 | 43 | return this; |
| 43 | 44 | } |
| 44 | 45 | |
| 46 | + public RecommendationBuilder withMatrixId(Integer matrixId) { | |
| 47 | + this.matrixId = matrixId; | |
| 48 | + return this; | |
| 49 | + } | |
| 50 | + | |
| 45 | 51 | public RecommendationBuilder withAlgorithm(Algorithm algorithm) { |
| 46 | 52 | this.algorithm = algorithm; |
| 47 | 53 | return this; |
| ... | ... | @@ -68,6 +74,7 @@ public final class RecommendationBuilder { |
| 68 | 74 | recommendation.setWeight(weight); |
| 69 | 75 | recommendation.setDate(date); |
| 70 | 76 | recommendation.setRuntimeInSeconds(runtimeInSeconds); |
| 77 | + recommendation.setMatrixId(matrixId); | |
| 71 | 78 | recommendation.setAlgorithm(algorithm); |
| 72 | 79 | recommendation.setEvaluator(evaluator); |
| 73 | 80 | recommendation.setItem(item); | ... | ... |
codigos/backend/src/main/java/com/srh/api/config/DbSeeder.java
| 1 | 1 | package com.srh.api.config; |
| 2 | 2 | |
| 3 | +import com.srh.api.builder.AlgorithmBuilder; | |
| 3 | 4 | import com.srh.api.builder.ApiUserBuilder; |
| 4 | 5 | import com.srh.api.builder.ProfileBuilder; |
| 6 | +import com.srh.api.model.Algorithm; | |
| 5 | 7 | import com.srh.api.model.ApiUser; |
| 6 | 8 | import com.srh.api.model.Profile; |
| 9 | +import com.srh.api.model.TypeRecommendation; | |
| 10 | +import com.srh.api.repository.AlgorithmRepository; | |
| 7 | 11 | import com.srh.api.repository.ApiUserRepository; |
| 8 | 12 | import com.srh.api.repository.ProfileRepository; |
| 9 | 13 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | 14 | import org.springframework.stereotype.Service; |
| 11 | 15 | |
| 12 | 16 | import java.util.ArrayList; |
| 17 | +import java.util.Arrays; | |
| 13 | 18 | import java.util.List; |
| 14 | 19 | |
| 15 | 20 | @Service |
| ... | ... | @@ -20,6 +25,9 @@ public class DbSeeder { |
| 20 | 25 | @Autowired |
| 21 | 26 | private ProfileRepository profileRepository; |
| 22 | 27 | |
| 28 | + @Autowired | |
| 29 | + private AlgorithmRepository algorithmRepository; | |
| 30 | + | |
| 23 | 31 | private Profile adminProfile; |
| 24 | 32 | private Profile userProfile; |
| 25 | 33 | |
| ... | ... | @@ -30,6 +38,8 @@ public class DbSeeder { |
| 30 | 38 | createApiUserAdmin(); |
| 31 | 39 | createApiUserClient(); |
| 32 | 40 | |
| 41 | + createAlgorithms(); | |
| 42 | + | |
| 33 | 43 | return true; |
| 34 | 44 | } |
| 35 | 45 | |
| ... | ... | @@ -85,4 +95,47 @@ public class DbSeeder { |
| 85 | 95 | userProfile = profile; |
| 86 | 96 | profileRepository.save(profile); |
| 87 | 97 | } |
| 98 | + | |
| 99 | + private void createAlgorithms() { | |
| 100 | + Algorithm algorithm1 = AlgorithmBuilder.anAlgorithm() | |
| 101 | + .withId(1) | |
| 102 | + .withName("Filtragem Colaborativa") | |
| 103 | + .withTypeRecommendation(TypeRecommendation.COLLABORATIVE) | |
| 104 | + .build(); | |
| 105 | + | |
| 106 | + Algorithm algorithm2 = AlgorithmBuilder.anAlgorithm() | |
| 107 | + .withId(1) | |
| 108 | + .withName("Filtragem Baseada em Conteúdo") | |
| 109 | + .withTypeRecommendation(TypeRecommendation.COLLABORATIVE) | |
| 110 | + .build(); | |
| 111 | + | |
| 112 | + Algorithm algorithm3 = AlgorithmBuilder.anAlgorithm() | |
| 113 | + .withId(1) | |
| 114 | + .withName("Filtragem Híbrida ponderada - Single Thread") | |
| 115 | + .withTypeRecommendation(TypeRecommendation.COLLABORATIVE) | |
| 116 | + .build(); | |
| 117 | + | |
| 118 | + Algorithm algorithm4 = AlgorithmBuilder.anAlgorithm() | |
| 119 | + .withId(1) | |
| 120 | + .withName("Filtragem Híbrida ponderada - Multi Thread") | |
| 121 | + .withTypeRecommendation(TypeRecommendation.COLLABORATIVE) | |
| 122 | + .build(); | |
| 123 | + | |
| 124 | + Algorithm algorithm5 = AlgorithmBuilder.anAlgorithm() | |
| 125 | + .withId(1) | |
| 126 | + .withName("Filtragem Híbrida Mista - Single Thread") | |
| 127 | + .withTypeRecommendation(TypeRecommendation.COLLABORATIVE) | |
| 128 | + .build(); | |
| 129 | + | |
| 130 | + Algorithm algorithm6 = AlgorithmBuilder.anAlgorithm() | |
| 131 | + .withId(1) | |
| 132 | + .withName("Filtragem Híbrida Mista - Multi Thread") | |
| 133 | + .withTypeRecommendation(TypeRecommendation.COLLABORATIVE) | |
| 134 | + .build(); | |
| 135 | + | |
| 136 | + algorithmRepository.saveAll(Arrays.asList( | |
| 137 | + algorithm1, algorithm2, algorithm3, | |
| 138 | + algorithm4, algorithm5, algorithm6 | |
| 139 | + )); | |
| 140 | + } | |
| 88 | 141 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/config/EmailConfig.java
0 → 100644
| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | +package com.srh.api.config; | |
| 2 | + | |
| 3 | +import org.springframework.context.annotation.Bean; | |
| 4 | +import org.springframework.mail.javamail.JavaMailSender; | |
| 5 | +import org.springframework.mail.javamail.JavaMailSenderImpl; | |
| 6 | +import org.springframework.stereotype.Component; | |
| 7 | + | |
| 8 | +import java.util.Properties; | |
| 9 | + | |
| 10 | +@Component | |
| 11 | +public class EmailConfig { | |
| 12 | + @Bean | |
| 13 | + public JavaMailSender getJavaMailSender() { | |
| 14 | + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); | |
| 15 | + mailSender.setHost("smtp.gmail.com"); | |
| 16 | + mailSender.setPort(587); | |
| 17 | + | |
| 18 | + mailSender.setUsername("my.gmail@gmail.com"); | |
| 19 | + mailSender.setPassword("password"); | |
| 20 | + | |
| 21 | + Properties props = mailSender.getJavaMailProperties(); | |
| 22 | + props.put("mail.transport.protocol", "smtp"); | |
| 23 | + props.put("mail.smtp.auth", "true"); | |
| 24 | + props.put("mail.smtp.starttls.enable", "true"); | |
| 25 | + props.put("mail.debug", "true"); | |
| 26 | + | |
| 27 | + return mailSender; | |
| 28 | + } | |
| 29 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/controller/AdminController.java
| ... | ... | @@ -2,9 +2,14 @@ package com.srh.api.controller; |
| 2 | 2 | |
| 3 | 3 | import com.srh.api.dto.resource.AdminDto; |
| 4 | 4 | import com.srh.api.dto.resource.AdminForm; |
| 5 | +import com.srh.api.dto.resource.ProjectDto; | |
| 6 | +import com.srh.api.dto.resource.TypeItemDto; | |
| 5 | 7 | import com.srh.api.hypermedia.AdminModelAssembler; |
| 6 | 8 | import com.srh.api.model.Admin; |
| 9 | +import com.srh.api.model.Project; | |
| 10 | +import com.srh.api.model.TypeItem; | |
| 7 | 11 | import com.srh.api.service.AdminService; |
| 12 | +import com.srh.api.utils.PageUtil; | |
| 8 | 13 | import lombok.SneakyThrows; |
| 9 | 14 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | 15 | import org.springframework.data.domain.Page; |
| ... | ... | @@ -35,6 +40,9 @@ public class AdminController { |
| 35 | 40 | @Autowired |
| 36 | 41 | private PagedResourcesAssembler<AdminDto> pagedResourcesAssembler; |
| 37 | 42 | |
| 43 | + @Autowired | |
| 44 | + private PagedResourcesAssembler<ProjectDto> projectDtoPagedResourcesAssembler; | |
| 45 | + | |
| 38 | 46 | @GetMapping |
| 39 | 47 | public PagedModel<EntityModel<AdminDto>> listAll(@PageableDefault(page = 0, size = 5) Pageable pageInfo) { |
| 40 | 48 | Page<Admin> admins = adminService.findAll(pageInfo); |
| ... | ... | @@ -73,4 +81,17 @@ public class AdminController { |
| 73 | 81 | adminService.delete(id); |
| 74 | 82 | return ResponseEntity.noContent().build(); |
| 75 | 83 | } |
| 84 | + | |
| 85 | + @GetMapping("{adminId}/projects") | |
| 86 | + public PagedModel<EntityModel<ProjectDto>> findProjectsByAdmin( | |
| 87 | + @PathVariable Integer adminId, | |
| 88 | + @PageableDefault(page = 0, size = 5) Pageable pageInfo | |
| 89 | + ) { | |
| 90 | + PageUtil<Project> pageUtil = new PageUtil<>(pageInfo, adminService. | |
| 91 | + listProjectsByAdmin(adminId)); | |
| 92 | + | |
| 93 | + return projectDtoPagedResourcesAssembler.toModel(ProjectDto.convert( | |
| 94 | + pageUtil.getPage() | |
| 95 | + )); | |
| 96 | + } | |
| 76 | 97 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/controller/ForgetPasswordController.java
0 → 100644
codigos/backend/src/main/java/com/srh/api/controller/LoginAdminController.java
0 → 100644
| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | +package com.srh.api.controller; | |
| 2 | + | |
| 3 | +import com.srh.api.dto.resource.LoginClientForm; | |
| 4 | +import com.srh.api.service.LoginClientDto; | |
| 5 | +import com.srh.api.service.LoginClientService; | |
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 7 | +import org.springframework.http.ResponseEntity; | |
| 8 | +import org.springframework.web.bind.annotation.PostMapping; | |
| 9 | +import org.springframework.web.bind.annotation.RequestBody; | |
| 10 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 11 | +import org.springframework.web.bind.annotation.RestController; | |
| 12 | + | |
| 13 | +import javax.validation.Valid; | |
| 14 | + | |
| 15 | +@RestController | |
| 16 | +@RequestMapping("/admins/login") | |
| 17 | +public class LoginAdminController { | |
| 18 | + @Autowired | |
| 19 | + private LoginClientService loginClientService; | |
| 20 | + | |
| 21 | + @PostMapping | |
| 22 | + public ResponseEntity<LoginClientDto> loginUser(@RequestBody @Valid LoginClientForm loginForm) { | |
| 23 | + Boolean validUser = loginClientService.generateLoginTokenByAdmins( | |
| 24 | + loginForm.getLogin(), loginForm.getPassword() | |
| 25 | + ); | |
| 26 | + Integer adminId = loginClientService.getAdminId(loginForm.getLogin()); | |
| 27 | + return ResponseEntity.ok(new LoginClientDto(validUser, adminId)); | |
| 28 | + } | |
| 29 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/controller/LoginEvaluatorController.java
0 → 100644
| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | +package com.srh.api.controller; | |
| 2 | + | |
| 3 | +import com.srh.api.dto.resource.LoginClientForm; | |
| 4 | +import com.srh.api.service.LoginClientDto; | |
| 5 | +import com.srh.api.service.LoginClientService; | |
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 7 | +import org.springframework.http.ResponseEntity; | |
| 8 | +import org.springframework.web.bind.annotation.PostMapping; | |
| 9 | +import org.springframework.web.bind.annotation.RequestBody; | |
| 10 | +import org.springframework.web.bind.annotation.RequestMapping; | |
| 11 | +import org.springframework.web.bind.annotation.RestController; | |
| 12 | + | |
| 13 | +import javax.validation.Valid; | |
| 14 | + | |
| 15 | +@RestController | |
| 16 | +@RequestMapping("/evaluators/login") | |
| 17 | +public class LoginEvaluatorController { | |
| 18 | + @Autowired | |
| 19 | + private LoginClientService loginClientService; | |
| 20 | + | |
| 21 | + @PostMapping | |
| 22 | + public ResponseEntity<LoginClientDto> loginUser(@RequestBody @Valid LoginClientForm loginForm) { | |
| 23 | + Boolean validUser = loginClientService.verifyEvaluators( | |
| 24 | + loginForm.getLogin(), loginForm.getPassword() | |
| 25 | + ); | |
| 26 | + Integer evaluatorId = loginClientService.getEvaluatorId(loginForm.getLogin()); | |
| 27 | + return ResponseEntity.ok(new LoginClientDto(validUser, evaluatorId)); | |
| 28 | + } | |
| 29 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/controller/ProjectController.java
| 1 | 1 | package com.srh.api.controller; |
| 2 | 2 | |
| 3 | -import com.srh.api.dto.resource.ItemDto; | |
| 4 | -import com.srh.api.dto.resource.ProjectDto; | |
| 5 | -import com.srh.api.dto.resource.ProjectForm; | |
| 6 | -import com.srh.api.hypermedia.ItemModelAssembler; | |
| 3 | +import com.srh.api.dto.resource.*; | |
| 7 | 4 | import com.srh.api.hypermedia.ProjectModelAssembler; |
| 8 | -import com.srh.api.model.Item; | |
| 9 | -import com.srh.api.model.Project; | |
| 5 | +import com.srh.api.model.*; | |
| 10 | 6 | import com.srh.api.service.ProjectService; |
| 11 | 7 | import com.srh.api.utils.PageUtil; |
| 12 | 8 | import lombok.SneakyThrows; |
| ... | ... | @@ -42,6 +38,18 @@ public class ProjectController { |
| 42 | 38 | @Autowired |
| 43 | 39 | private PagedResourcesAssembler<ItemDto> itemDtoPagedResourcesAssembler; |
| 44 | 40 | |
| 41 | + @Autowired | |
| 42 | + private PagedResourcesAssembler<RecommendationDto> recommendationDtoPagedResourcesAssembler; | |
| 43 | + | |
| 44 | + @Autowired | |
| 45 | + private PagedResourcesAssembler<ItemRatingDto> itemRatingDtoPagedResourcesAssembler; | |
| 46 | + | |
| 47 | + @Autowired | |
| 48 | + private PagedResourcesAssembler<TagDto> tagDtoPagedResourcesAssembler; | |
| 49 | + | |
| 50 | + @Autowired | |
| 51 | + private PagedResourcesAssembler<TypeItemDto> typeItemDtoPagedResourcesAssembler; | |
| 52 | + | |
| 45 | 53 | @GetMapping |
| 46 | 54 | public PagedModel<EntityModel<ProjectDto>> listAll(@PageableDefault(page = 0, size = 5) |
| 47 | 55 | Pageable pageInfo) { |
| ... | ... | @@ -89,9 +97,61 @@ public class ProjectController { |
| 89 | 97 | @PathVariable Integer projectId, |
| 90 | 98 | @PageableDefault(page = 0, size = 5) Pageable pageInfo |
| 91 | 99 | ) { |
| 92 | - Project project = projectService.find(projectId); | |
| 93 | - PageUtil<Item> pageUtil = new PageUtil<>(pageInfo, project.getItens()); | |
| 100 | + PageUtil<Item> pageUtil = new PageUtil<>(pageInfo, projectService. | |
| 101 | + listItensByProject(projectId)); | |
| 94 | 102 | |
| 95 | 103 | return itemDtoPagedResourcesAssembler.toModel(ItemDto.convert(pageUtil.getPage())); |
| 96 | 104 | } |
| 105 | + | |
| 106 | + @GetMapping("{projectId}/recommendations") | |
| 107 | + public PagedModel<EntityModel<RecommendationDto>> findRecommendationsByProject( | |
| 108 | + @PathVariable Integer projectId, | |
| 109 | + @PageableDefault(page = 0, size = 5) Pageable pageInfo | |
| 110 | + ) { | |
| 111 | + PageUtil<Recommendation> pageUtil = new PageUtil<>(pageInfo, projectService. | |
| 112 | + listRecommendationsByProject(projectId)); | |
| 113 | + | |
| 114 | + return recommendationDtoPagedResourcesAssembler.toModel(RecommendationDto.convert( | |
| 115 | + pageUtil.getPage() | |
| 116 | + )); | |
| 117 | + } | |
| 118 | + | |
| 119 | + @GetMapping("{projectId}/itemratings") | |
| 120 | + public PagedModel<EntityModel<ItemRatingDto>> findItemRatingsByProject( | |
| 121 | + @PathVariable Integer projectId, | |
| 122 | + @PageableDefault(page = 0, size = 5) Pageable pageInfo | |
| 123 | + ) { | |
| 124 | + PageUtil<ItemRating> pageUtil = new PageUtil<>(pageInfo, projectService. | |
| 125 | + listItemRatingsByProject(projectId)); | |
| 126 | + | |
| 127 | + return itemRatingDtoPagedResourcesAssembler.toModel(ItemRatingDto.convert( | |
| 128 | + pageUtil.getPage() | |
| 129 | + )); | |
| 130 | + } | |
| 131 | + | |
| 132 | + @GetMapping("{projectId}/tags") | |
| 133 | + public PagedModel<EntityModel<TagDto>> findTagsByProject( | |
| 134 | + @PathVariable Integer projectId, | |
| 135 | + @PageableDefault(page = 0, size = 5) Pageable pageInfo | |
| 136 | + ) { | |
| 137 | + PageUtil<Tag> pageUtil = new PageUtil<>(pageInfo, projectService. | |
| 138 | + listTagsByProject(projectId)); | |
| 139 | + | |
| 140 | + return tagDtoPagedResourcesAssembler.toModel(TagDto.convert( | |
| 141 | + pageUtil.getPage() | |
| 142 | + )); | |
| 143 | + } | |
| 144 | + | |
| 145 | + @GetMapping("{projectId}/typeitens") | |
| 146 | + public PagedModel<EntityModel<TypeItemDto>> findTypeItensByProject( | |
| 147 | + @PathVariable Integer projectId, | |
| 148 | + @PageableDefault(page = 0, size = 5) Pageable pageInfo | |
| 149 | + ) { | |
| 150 | + PageUtil<TypeItem> pageUtil = new PageUtil<>(pageInfo, projectService. | |
| 151 | + listTypeItensByProject(projectId)); | |
| 152 | + | |
| 153 | + return typeItemDtoPagedResourcesAssembler.toModel(TypeItemDto.convert( | |
| 154 | + pageUtil.getPage() | |
| 155 | + )); | |
| 156 | + } | |
| 97 | 157 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/controller/RecommendationController.java
| 1 | 1 | package com.srh.api.controller; |
| 2 | 2 | |
| 3 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 3 | 4 | import com.srh.api.dto.resource.RecommendationDto; |
| 5 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 6 | +import com.srh.api.dto.resource.RecommendationUserDto; | |
| 4 | 7 | import com.srh.api.hypermedia.RecommendationModelAssembler; |
| 5 | 8 | import com.srh.api.model.Recommendation; |
| 6 | 9 | import com.srh.api.service.RecommendationService; |
| ... | ... | @@ -15,6 +18,10 @@ import org.springframework.http.ResponseEntity; |
| 15 | 18 | import org.springframework.web.bind.annotation.*; |
| 16 | 19 | |
| 17 | 20 | import javax.transaction.Transactional; |
| 21 | +import javax.validation.Valid; | |
| 22 | + | |
| 23 | +import java.util.ArrayList; | |
| 24 | +import java.util.List; | |
| 18 | 25 | |
| 19 | 26 | import static com.srh.api.dto.resource.RecommendationDto.convert; |
| 20 | 27 | |
| ... | ... | @@ -43,6 +50,19 @@ public class RecommendationController { |
| 43 | 50 | return recommendationModelAssembler.toModel(new RecommendationDto(recommendation)); |
| 44 | 51 | } |
| 45 | 52 | |
| 53 | + @PostMapping | |
| 54 | + public ResponseEntity<List<RecommendationUserDto>> generateRecommendations( | |
| 55 | + @RequestBody @Valid RecommendationForm form) { | |
| 56 | + List<RecommendationsByUser> recommendations = recommendationService.generateRecommendation(form); | |
| 57 | + List<RecommendationUserDto> recommendationUserDtos = new ArrayList<>(); | |
| 58 | + | |
| 59 | + for (RecommendationsByUser recommendationByUser : recommendations) { | |
| 60 | + recommendationUserDtos.add(new RecommendationUserDto(recommendationByUser)); | |
| 61 | + } | |
| 62 | + | |
| 63 | + return ResponseEntity.ok(recommendationUserDtos); | |
| 64 | + } | |
| 65 | + | |
| 46 | 66 | @DeleteMapping("/{id}") |
| 47 | 67 | @Transactional |
| 48 | 68 | public ResponseEntity<Void> delete(@PathVariable Integer id) { | ... | ... |
codigos/backend/src/main/java/com/srh/api/dto/resource/ItemForm.java
| ... | ... | @@ -2,8 +2,10 @@ package com.srh.api.dto.resource; |
| 2 | 2 | |
| 3 | 3 | import com.srh.api.builder.ItemBuilder; |
| 4 | 4 | import com.srh.api.builder.ProjectBuilder; |
| 5 | +import com.srh.api.builder.TypeItemBuilder; | |
| 5 | 6 | import com.srh.api.model.Item; |
| 6 | 7 | import com.srh.api.model.Project; |
| 8 | +import com.srh.api.model.TypeItem; | |
| 7 | 9 | import lombok.AllArgsConstructor; |
| 8 | 10 | import lombok.Getter; |
| 9 | 11 | import lombok.NoArgsConstructor; |
| ... | ... | @@ -29,11 +31,26 @@ public class ItemForm { |
| 29 | 31 | @NotNull |
| 30 | 32 | private Integer projectId; |
| 31 | 33 | |
| 34 | + private Integer typeItemId; | |
| 35 | + | |
| 32 | 36 | public Item build() { |
| 33 | 37 | Project project = ProjectBuilder.aProject() |
| 34 | 38 | .withId(projectId) |
| 35 | 39 | .build(); |
| 36 | 40 | |
| 41 | + if (typeItemId != null) { | |
| 42 | + TypeItem typeItem = TypeItemBuilder.aTypeItem() | |
| 43 | + .withId(typeItemId) | |
| 44 | + .build(); | |
| 45 | + | |
| 46 | + return ItemBuilder.anItem() | |
| 47 | + .withName(name) | |
| 48 | + .withDescription(description) | |
| 49 | + .withProject(project) | |
| 50 | + .withTypeItem(typeItem) | |
| 51 | + .build(); | |
| 52 | + } | |
| 53 | + | |
| 37 | 54 | return ItemBuilder.anItem() |
| 38 | 55 | .withName(name) |
| 39 | 56 | .withDescription(description) | ... | ... |
codigos/backend/src/main/java/com/srh/api/dto/resource/LoginClientForm.java
0 → 100644
| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | +package com.srh.api.dto.resource; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | +import lombok.NoArgsConstructor; | |
| 6 | +import org.hibernate.validator.constraints.Length; | |
| 7 | + | |
| 8 | +import javax.validation.constraints.NotEmpty; | |
| 9 | +import javax.validation.constraints.NotNull; | |
| 10 | + | |
| 11 | +@Getter | |
| 12 | +@AllArgsConstructor | |
| 13 | +@NoArgsConstructor | |
| 14 | +public class LoginClientForm { | |
| 15 | + @NotNull | |
| 16 | + @NotEmpty | |
| 17 | + @Length(min = 3) | |
| 18 | + private String login; | |
| 19 | + | |
| 20 | + @NotNull | |
| 21 | + @NotEmpty | |
| 22 | + @Length(min = 6) | |
| 23 | + private String password; | |
| 24 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/dto/resource/ProjectForm.java
codigos/backend/src/main/java/com/srh/api/dto/resource/RecommendationForm.java
0 → 100644
| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | +package com.srh.api.dto.resource; | |
| 2 | + | |
| 3 | +import lombok.AllArgsConstructor; | |
| 4 | +import lombok.Getter; | |
| 5 | +import lombok.NoArgsConstructor; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.Max; | |
| 8 | +import javax.validation.constraints.Min; | |
| 9 | +import javax.validation.constraints.NotNull; | |
| 10 | + | |
| 11 | +@Getter | |
| 12 | +@AllArgsConstructor | |
| 13 | +@NoArgsConstructor | |
| 14 | +public class RecommendationForm { | |
| 15 | + @Min(value = 0) | |
| 16 | + @Max(value = 5) | |
| 17 | + @NotNull | |
| 18 | + private Double passingScore; | |
| 19 | + | |
| 20 | + @NotNull | |
| 21 | + private Integer algorithmId; | |
| 22 | + | |
| 23 | + @NotNull | |
| 24 | + private Boolean offline; | |
| 25 | + | |
| 26 | + @NotNull | |
| 27 | + private Integer projectId; | |
| 28 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/dto/resource/RecommendationUserDto.java
0 → 100644
| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | +package com.srh.api.dto.resource; | |
| 2 | + | |
| 3 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 4 | +import com.srh.api.model.Recommendation; | |
| 5 | +import org.springframework.data.domain.Page; | |
| 6 | + | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 9 | +public class RecommendationUserDto { | |
| 10 | + private Integer userId; | |
| 11 | + private List<Recommendation> recommendations; | |
| 12 | + | |
| 13 | + public RecommendationUserDto(RecommendationsByUser recommendationsByUser) { | |
| 14 | + this.userId = recommendationsByUser.getEvaluator().getId(); | |
| 15 | + this.recommendations = recommendationsByUser.getRecommendations(); | |
| 16 | + } | |
| 17 | + | |
| 18 | + public static Page<RecommendationUserDto> convert(Page<RecommendationsByUser> recommendations) { | |
| 19 | + return recommendations.map(RecommendationUserDto::new); | |
| 20 | + } | |
| 21 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/error/exception/InvalidAlgorithmRecommendationException.java
0 → 100644
codigos/backend/src/main/java/com/srh/api/error/exception/InvalidLoginUserException.java
0 → 100644
codigos/backend/src/main/java/com/srh/api/error/exception/InvalidPasswordUserException.java
0 → 100644
codigos/backend/src/main/java/com/srh/api/error/handler/FormHandler.java
| ... | ... | @@ -19,7 +19,7 @@ public class FormHandler { |
| 19 | 19 | @Autowired |
| 20 | 20 | private MessageSource messageSource; |
| 21 | 21 | |
| 22 | - @ResponseStatus(code = HttpStatus.BAD_REQUEST) | |
| 22 | + @ResponseStatus(code = HttpStatus.UNPROCESSABLE_ENTITY) | |
| 23 | 23 | @ExceptionHandler(MethodArgumentNotValidException.class) |
| 24 | 24 | public List<FormErrorDto> handle(MethodArgumentNotValidException exception) { |
| 25 | 25 | List<FormErrorDto> dtos = new ArrayList<>(); | ... | ... |
codigos/backend/src/main/java/com/srh/api/error/handler/InvaliLoginUserHandler.java
0 → 100644
| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | +package com.srh.api.error.handler; | |
| 2 | + | |
| 3 | +import com.srh.api.dto.error.DefaultErrorDto; | |
| 4 | +import com.srh.api.error.exception.InvalidLoginUserException; | |
| 5 | +import org.springframework.http.HttpStatus; | |
| 6 | +import org.springframework.web.bind.annotation.ExceptionHandler; | |
| 7 | +import org.springframework.web.bind.annotation.ResponseStatus; | |
| 8 | +import org.springframework.web.bind.annotation.RestControllerAdvice; | |
| 9 | + | |
| 10 | +@RestControllerAdvice | |
| 11 | +public class InvaliLoginUserHandler { | |
| 12 | + @ResponseStatus(HttpStatus.BAD_REQUEST) | |
| 13 | + @ExceptionHandler(InvalidLoginUserException.class) | |
| 14 | + public DefaultErrorDto handle(Exception exception) { | |
| 15 | + return new DefaultErrorDto( | |
| 16 | + "Login inválido", | |
| 17 | + "O login informado não foi encontrado no sistema" | |
| 18 | + ); | |
| 19 | + } | |
| 20 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/error/handler/InvalidAlgorithmRecommendationHandler.java
0 → 100644
| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | +package com.srh.api.error.handler; | |
| 2 | + | |
| 3 | +import com.srh.api.dto.error.DefaultErrorDto; | |
| 4 | +import com.srh.api.error.exception.InvalidAlgorithmRecommendationException; | |
| 5 | +import org.springframework.http.HttpStatus; | |
| 6 | +import org.springframework.web.bind.annotation.ExceptionHandler; | |
| 7 | +import org.springframework.web.bind.annotation.ResponseStatus; | |
| 8 | +import org.springframework.web.bind.annotation.RestControllerAdvice; | |
| 9 | + | |
| 10 | +@RestControllerAdvice | |
| 11 | +public class InvalidAlgorithmRecommendationHandler { | |
| 12 | + @ResponseStatus(HttpStatus.BAD_REQUEST) | |
| 13 | + @ExceptionHandler(InvalidAlgorithmRecommendationException.class) | |
| 14 | + public DefaultErrorDto handle(Exception exception) { | |
| 15 | + return new DefaultErrorDto( | |
| 16 | + "Algoritmo inválido", | |
| 17 | + "O id de algoritmo enviado não foi encontrado no sistema" | |
| 18 | + ); | |
| 19 | + } | |
| 20 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/error/handler/InvalidPasswordUserHandler.java
0 → 100644
| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | +package com.srh.api.error.handler; | |
| 2 | + | |
| 3 | +import com.srh.api.dto.error.DefaultErrorDto; | |
| 4 | +import com.srh.api.error.exception.InvalidPasswordUserException; | |
| 5 | +import org.springframework.http.HttpStatus; | |
| 6 | +import org.springframework.web.bind.annotation.ExceptionHandler; | |
| 7 | +import org.springframework.web.bind.annotation.ResponseStatus; | |
| 8 | +import org.springframework.web.bind.annotation.RestControllerAdvice; | |
| 9 | + | |
| 10 | +@RestControllerAdvice | |
| 11 | +public class InvalidPasswordUserHandler { | |
| 12 | + @ResponseStatus(HttpStatus.BAD_REQUEST) | |
| 13 | + @ExceptionHandler(InvalidPasswordUserException.class) | |
| 14 | + public DefaultErrorDto handle(Exception exception) { | |
| 15 | + return new DefaultErrorDto( | |
| 16 | + "A senha informada está incorreta", | |
| 17 | + "Informe a senha correta do usuário" | |
| 18 | + ); | |
| 19 | + } | |
| 20 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/model/Project.java
codigos/backend/src/main/java/com/srh/api/model/Recommendation.java
codigos/backend/src/main/java/com/srh/api/model/TypeItem.java
codigos/backend/src/main/java/com/srh/api/repository/AdminRepository.java
| ... | ... | @@ -3,5 +3,8 @@ package com.srh.api.repository; |
| 3 | 3 | import com.srh.api.model.Admin; |
| 4 | 4 | import org.springframework.data.repository.PagingAndSortingRepository; |
| 5 | 5 | |
| 6 | +import java.util.Optional; | |
| 7 | + | |
| 6 | 8 | public interface AdminRepository extends PagingAndSortingRepository<Admin, Integer> { |
| 9 | + Optional<Admin> findByLogin(String login); | |
| 7 | 10 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/repository/EvaluatorRepository.java
| ... | ... | @@ -3,5 +3,8 @@ package com.srh.api.repository; |
| 3 | 3 | import com.srh.api.model.Evaluator; |
| 4 | 4 | import org.springframework.data.repository.PagingAndSortingRepository; |
| 5 | 5 | |
| 6 | +import java.util.Optional; | |
| 7 | + | |
| 6 | 8 | public interface EvaluatorRepository extends PagingAndSortingRepository<Evaluator, Integer> { |
| 9 | + Optional<Evaluator> findByLogin(String login); | |
| 7 | 10 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/repository/ItemRepository.java
| 1 | 1 | package com.srh.api.repository; |
| 2 | 2 | |
| 3 | 3 | import com.srh.api.model.Item; |
| 4 | +import com.srh.api.model.Project; | |
| 4 | 5 | import org.springframework.data.repository.PagingAndSortingRepository; |
| 5 | 6 | |
| 7 | +import java.util.List; | |
| 8 | + | |
| 6 | 9 | public interface ItemRepository extends PagingAndSortingRepository<Item, Integer> { |
| 10 | + List<Item> findByProject(Project project); | |
| 7 | 11 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/service/AdminService.java
| 1 | 1 | package com.srh.api.service; |
| 2 | 2 | |
| 3 | 3 | import com.srh.api.model.Admin; |
| 4 | +import com.srh.api.model.Project; | |
| 4 | 5 | import com.srh.api.repository.AdminRepository; |
| 5 | 6 | import com.srh.api.utils.PasswordUtil; |
| 6 | 7 | import lombok.SneakyThrows; |
| ... | ... | @@ -10,6 +11,7 @@ import org.springframework.data.domain.Page; |
| 10 | 11 | import org.springframework.data.domain.Pageable; |
| 11 | 12 | import org.springframework.stereotype.Service; |
| 12 | 13 | |
| 14 | +import java.util.List; | |
| 13 | 15 | import java.util.Optional; |
| 14 | 16 | |
| 15 | 17 | @Service |
| ... | ... | @@ -49,4 +51,19 @@ public class AdminService { |
| 49 | 51 | find(id); |
| 50 | 52 | adminRepository.deleteById(id); |
| 51 | 53 | } |
| 54 | + | |
| 55 | + public Admin findByLogin(String login) { | |
| 56 | + Optional<Admin> admin = adminRepository.findByLogin(login); | |
| 57 | + | |
| 58 | + if (admin.isPresent()) | |
| 59 | + return admin.get(); | |
| 60 | + | |
| 61 | + throw new ObjectNotFoundException(login, Admin.class.getName()); | |
| 62 | + } | |
| 63 | + | |
| 64 | + public List<Project> listProjectsByAdmin(Integer adminId) { | |
| 65 | + Admin admin = find(adminId); | |
| 66 | + List<Project> projects = admin.getProjects(); | |
| 67 | + return projects; | |
| 68 | + } | |
| 52 | 69 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/service/EvaluatorService.java
| ... | ... | @@ -9,6 +9,7 @@ import org.springframework.data.domain.Page; |
| 9 | 9 | import org.springframework.data.domain.Pageable; |
| 10 | 10 | import org.springframework.stereotype.Service; |
| 11 | 11 | |
| 12 | +import java.util.List; | |
| 12 | 13 | import java.util.Optional; |
| 13 | 14 | |
| 14 | 15 | @Service |
| ... | ... | @@ -31,6 +32,10 @@ public class EvaluatorService { |
| 31 | 32 | return evaluatorRepository.findAll(pageInfo); |
| 32 | 33 | } |
| 33 | 34 | |
| 35 | + public Iterable<Evaluator> listAll() { | |
| 36 | + return evaluatorRepository.findAll(); | |
| 37 | + } | |
| 38 | + | |
| 34 | 39 | public Evaluator save(Evaluator evaluator) { |
| 35 | 40 | Evaluator evaluatorEncoded = passwordUtil.encodedPasswordForUser(evaluator); |
| 36 | 41 | return evaluatorRepository.save(evaluatorEncoded); |
| ... | ... | @@ -52,4 +57,13 @@ public class EvaluatorService { |
| 52 | 57 | find(id); |
| 53 | 58 | evaluatorRepository.deleteById(id); |
| 54 | 59 | } |
| 60 | + | |
| 61 | + public Evaluator findByLogin(String login) { | |
| 62 | + Optional<Evaluator> evaluator = evaluatorRepository.findByLogin(login); | |
| 63 | + | |
| 64 | + if (evaluator.isPresent()) | |
| 65 | + return evaluator.get(); | |
| 66 | + | |
| 67 | + throw new ObjectNotFoundException(login, Evaluator.class.getName()); | |
| 68 | + } | |
| 55 | 69 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/service/ItemService.java
| ... | ... | @@ -37,7 +37,12 @@ public class ItemService { |
| 37 | 37 | return itemRepository.findAll(pageInfo); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | + @SneakyThrows | |
| 40 | 41 | public Item save(Item item) { |
| 42 | + if (!itemProjectIsOpenAndVisible(item)) { | |
| 43 | + throw new ProjectNotOpenedException("The project is closed or invisible"); | |
| 44 | + } | |
| 45 | + | |
| 41 | 46 | return itemRepository.save(item); |
| 42 | 47 | } |
| 43 | 48 | ... | ... |
codigos/backend/src/main/java/com/srh/api/service/LoginClientDto.java
0 → 100644
codigos/backend/src/main/java/com/srh/api/service/LoginClientService.java
0 → 100644
| ... | ... | @@ -0,0 +1,77 @@ |
| 1 | +package com.srh.api.service; | |
| 2 | + | |
| 3 | +import com.srh.api.error.exception.InvalidLoginUserException; | |
| 4 | +import com.srh.api.error.exception.InvalidPasswordUserException; | |
| 5 | +import com.srh.api.model.Admin; | |
| 6 | +import com.srh.api.model.Evaluator; | |
| 7 | +import com.srh.api.utils.PasswordUtil; | |
| 8 | +import lombok.SneakyThrows; | |
| 9 | +import org.hibernate.ObjectNotFoundException; | |
| 10 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 11 | +import org.springframework.stereotype.Service; | |
| 12 | + | |
| 13 | +@Service | |
| 14 | +public class LoginClientService { | |
| 15 | + @Autowired | |
| 16 | + EvaluatorService evaluatorService; | |
| 17 | + | |
| 18 | + @Autowired | |
| 19 | + AdminService adminService; | |
| 20 | + | |
| 21 | + PasswordUtil<Evaluator> passwordUtilEvaluator = new PasswordUtil<>(); | |
| 22 | + PasswordUtil<Admin> passwordUtilAdmin = new PasswordUtil<>(); | |
| 23 | + | |
| 24 | + @SneakyThrows | |
| 25 | + public Boolean verifyEvaluators(String login, String rawPassword) { | |
| 26 | + Evaluator evaluator; | |
| 27 | + | |
| 28 | + try { | |
| 29 | + evaluator = evaluatorService.findByLogin(login); | |
| 30 | + } catch (ObjectNotFoundException e) { | |
| 31 | + throw new InvalidLoginUserException(); | |
| 32 | + } | |
| 33 | + | |
| 34 | + if (!passwordUtilEvaluator.isEqualsPasswords(rawPassword, evaluator.getPassword())) { | |
| 35 | + throw new InvalidPasswordUserException(); | |
| 36 | + } | |
| 37 | + | |
| 38 | + return true; | |
| 39 | + } | |
| 40 | + | |
| 41 | + @SneakyThrows | |
| 42 | + public Boolean generateLoginTokenByAdmins(String login, String rawPassword) { | |
| 43 | + Admin admin; | |
| 44 | + | |
| 45 | + try { | |
| 46 | + admin = adminService.findByLogin(login); | |
| 47 | + } catch (ObjectNotFoundException e) { | |
| 48 | + throw new InvalidLoginUserException(); | |
| 49 | + } | |
| 50 | + | |
| 51 | + if (!passwordUtilEvaluator.isEqualsPasswords(rawPassword, admin.getPassword())) { | |
| 52 | + throw new InvalidPasswordUserException(); | |
| 53 | + } | |
| 54 | + | |
| 55 | + return true; | |
| 56 | + } | |
| 57 | + | |
| 58 | + @SneakyThrows | |
| 59 | + public Integer getAdminId(String login) { | |
| 60 | + try { | |
| 61 | + Admin admin = adminService.findByLogin(login); | |
| 62 | + return admin.getId(); | |
| 63 | + } catch (ObjectNotFoundException e) { | |
| 64 | + throw new InvalidLoginUserException(); | |
| 65 | + } | |
| 66 | + } | |
| 67 | + | |
| 68 | + @SneakyThrows | |
| 69 | + public Integer getEvaluatorId(String login) { | |
| 70 | + try { | |
| 71 | + Evaluator evaluator = evaluatorService.findByLogin(login); | |
| 72 | + return evaluator.getId(); | |
| 73 | + } catch (ObjectNotFoundException e) { | |
| 74 | + throw new InvalidLoginUserException(); | |
| 75 | + } | |
| 76 | + } | |
| 77 | +} | ... | ... |
codigos/backend/src/main/java/com/srh/api/service/ProjectService.java
| 1 | 1 | package com.srh.api.service; |
| 2 | 2 | |
| 3 | 3 | import com.srh.api.error.exception.ChangeRootRelationException; |
| 4 | -import com.srh.api.model.Admin; | |
| 5 | -import com.srh.api.model.Project; | |
| 4 | +import com.srh.api.model.*; | |
| 6 | 5 | import com.srh.api.repository.ProjectRepository; |
| 7 | 6 | import lombok.SneakyThrows; |
| 8 | 7 | import org.hibernate.ObjectNotFoundException; |
| ... | ... | @@ -11,6 +10,8 @@ import org.springframework.data.domain.Page; |
| 11 | 10 | import org.springframework.data.domain.Pageable; |
| 12 | 11 | import org.springframework.stereotype.Service; |
| 13 | 12 | |
| 13 | +import java.util.ArrayList; | |
| 14 | +import java.util.List; | |
| 14 | 15 | import java.util.Optional; |
| 15 | 16 | |
| 16 | 17 | @Service |
| ... | ... | @@ -57,4 +58,55 @@ public class ProjectService { |
| 57 | 58 | find(id); |
| 58 | 59 | projectRepository.deleteById(id); |
| 59 | 60 | } |
| 61 | + | |
| 62 | + public List<Item> listItensByProject(Integer projectId) { | |
| 63 | + Project project = find(projectId); | |
| 64 | + return project.getItens(); | |
| 65 | + } | |
| 66 | + | |
| 67 | + public List<Recommendation> listRecommendationsByProject(Integer projectId) { | |
| 68 | + List<Item> itens = listItensByProject(projectId); | |
| 69 | + List<Recommendation> recommendations = new ArrayList<>(); | |
| 70 | + | |
| 71 | + for (Item item : itens) { | |
| 72 | + recommendations.addAll(item.getRecommendations()); | |
| 73 | + } | |
| 74 | + | |
| 75 | + return recommendations; | |
| 76 | + } | |
| 77 | + | |
| 78 | + public List<ItemRating> listItemRatingsByProject(Integer projectId) { | |
| 79 | + List<Item> itens = listItensByProject(projectId); | |
| 80 | + List<ItemRating> itemRatings = new ArrayList<>(); | |
| 81 | + | |
| 82 | + for (Item item : itens) { | |
| 83 | + itemRatings.addAll(item.getItemRatings()); | |
| 84 | + } | |
| 85 | + | |
| 86 | + return itemRatings; | |
| 87 | + } | |
| 88 | + | |
| 89 | + public List<Tag> listTagsByProject(Integer projectId) { | |
| 90 | + List<Item> itens = listItensByProject(projectId); | |
| 91 | + List<Tag> tags = new ArrayList<>(); | |
| 92 | + | |
| 93 | + for (Item item : itens) { | |
| 94 | + tags.addAll(item.getTags()); | |
| 95 | + } | |
| 96 | + | |
| 97 | + return tags; | |
| 98 | + } | |
| 99 | + | |
| 100 | + public List<TypeItem> listTypeItensByProject(Integer projectId) { | |
| 101 | + List<Item> itens = listItensByProject(projectId); | |
| 102 | + List<TypeItem> typeItems = new ArrayList<>(); | |
| 103 | + | |
| 104 | + for (Item item : itens) { | |
| 105 | + if (item.getTypeItem() != null) { | |
| 106 | + typeItems.add(item.getTypeItem()); | |
| 107 | + } | |
| 108 | + } | |
| 109 | + | |
| 110 | + return typeItems; | |
| 111 | + } | |
| 60 | 112 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/service/RecommendationService.java
| 1 | 1 | package com.srh.api.service; |
| 2 | 2 | |
| 3 | +import com.srh.api.algorithms.AlgorithmCalc; | |
| 4 | +import com.srh.api.algorithms.AlgorithmStrategy; | |
| 5 | +import com.srh.api.algorithms.structure.RecommendationsByUser; | |
| 6 | +import com.srh.api.dto.resource.RecommendationForm; | |
| 7 | +import com.srh.api.model.Evaluator; | |
| 3 | 8 | import com.srh.api.model.Recommendation; |
| 4 | 9 | import com.srh.api.repository.RecommendationRepository; |
| 5 | 10 | import org.hibernate.ObjectNotFoundException; |
| ... | ... | @@ -8,6 +13,8 @@ import org.springframework.data.domain.Page; |
| 8 | 13 | import org.springframework.data.domain.Pageable; |
| 9 | 14 | import org.springframework.stereotype.Service; |
| 10 | 15 | |
| 16 | +import java.util.ArrayList; | |
| 17 | +import java.util.List; | |
| 11 | 18 | import java.util.Optional; |
| 12 | 19 | |
| 13 | 20 | @Service |
| ... | ... | @@ -41,4 +48,9 @@ public class RecommendationService { |
| 41 | 48 | find(id); |
| 42 | 49 | recommendationRepository.deleteById(id); |
| 43 | 50 | } |
| 51 | + | |
| 52 | + public List<RecommendationsByUser> generateRecommendation(RecommendationForm recommendationInfo) { | |
| 53 | + AlgorithmCalc algorithm = AlgorithmStrategy.findInstance(recommendationInfo.getAlgorithmId()); | |
| 54 | + return algorithm.calc(recommendationInfo); | |
| 55 | + } | |
| 44 | 56 | } | ... | ... |
codigos/backend/src/main/java/com/srh/api/utils/PasswordUtil.java
| ... | ... | @@ -23,6 +23,10 @@ public class PasswordUtil<T extends User> { |
| 23 | 23 | return encodedPasswordForUser(newUser, newRawPassword); |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | + public boolean isEqualsPasswords(String rawPassword, String encodedPassword) { | |
| 27 | + return BcriptyUtil.compareValues(rawPassword, encodedPassword); | |
| 28 | + } | |
| 29 | + | |
| 26 | 30 | private T encodedPasswordForUser(T user, String newRawPassword) { |
| 27 | 31 | String encodedPassword = BcriptyUtil.encripty(newRawPassword); |
| 28 | 32 | user.setPassword(encodedPassword); |
| ... | ... | @@ -40,8 +44,4 @@ public class PasswordUtil<T extends User> { |
| 40 | 44 | throw new NotEqualsPasswordException("A senha antiga não confere com a cadastrada"); |
| 41 | 45 | } |
| 42 | 46 | } |
| 43 | - | |
| 44 | - private boolean isEqualsPasswords(String rawPassword, String encodedPassword) { | |
| 45 | - return BcriptyUtil.compareValues(rawPassword, encodedPassword); | |
| 46 | - } | |
| 47 | 47 | } | ... | ... |
codigos/backend/src/main/resources/application.properties
| 1 | 1 | # Profile |
| 2 | -spring.profiles.active=test | |
| 2 | +spring.profiles.active=dev | |
| 3 | 3 | |
| 4 | 4 | # jwt |
| 5 | -srh.jwt.secret=A+X;fTJP&Pd,TD9dwVq(hsHX,ya^<wsD_UK7L+@=S;{'CydP]{v@}G'b>et;yz$*\yL5S8EJN:%P:X%H9>#nYLrX}@\s?CQcpspH,2emzBc!Q[V'AYa~uzF8WR~AUrMzxp/V$9([S9X#zj/CH('#]B_Hc+%fGhe27YB;^j4\Xk=Ju"Ap~_&<L;=!Z;!,2UP;!hF3P]j85#*`&T]/kB/W^6$v~u6qpejL>kY^f)sy4:qTq_Ec!-z!@aAp~sLKGU>$ | |
| 5 | +srh.jwt.secret=VGFrZSBPbiBNZSBUYWtlIE1lIE9u | |
| 6 | 6 | srh.jwt.expiration=86400000 |
| 7 | 7 | |
| 8 | 8 | # actuator |
| ... | ... | @@ -14,3 +14,10 @@ info.app.version=@project.version@ |
| 14 | 14 | info.app.encoding=@project.build.sourceEncoding@ |
| 15 | 15 | info.app.java.version=@java.version@ |
| 16 | 16 | |
| 17 | ||
| 18 | +spring.mail.host=smtp.mailtrap.io | |
| 19 | +spring.mail.port=587 | |
| 20 | +spring.mail.username=f51ab4b9bfc3ec | |
| 21 | +spring.mail.password=d6a3cbd03b13ae | |
| 22 | +spring.mail.properties.mail.smtp.auth=true | |
| 23 | +spring.mail.properties.mail.smtp.starttls.enable=true | |
| 17 | 24 | \ No newline at end of file | ... | ... |
codigos/frontend/.eslintrc.js
| 1 | +const { resolve } = require('path'); | |
| 2 | + | |
| 1 | 3 | module.exports = { |
| 2 | 4 | // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy |
| 3 | 5 | // This option interrupts the configuration hierarchy at this file |
| 4 | 6 | // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos) |
| 5 | 7 | root: true, |
| 6 | 8 | |
| 9 | + // https://eslint.vuejs.org/user-guide/#how-to-use-custom-parser | |
| 10 | + // Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working | |
| 11 | + // `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted | |
| 7 | 12 | parserOptions: { |
| 8 | - parser: 'babel-eslint', | |
| 13 | + // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/parser#configuration | |
| 14 | + // https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#eslint | |
| 15 | + // Needed to make the parser take into account 'vue' files | |
| 16 | + extraFileExtensions: ['.vue'], | |
| 17 | + parser: '@typescript-eslint/parser', | |
| 18 | + project: resolve(__dirname, './tsconfig.json'), | |
| 19 | + tsconfigRootDir: __dirname, | |
| 9 | 20 | ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features |
| 10 | - sourceType: 'module' // Allows for the use of imports | |
| 11 | - }, | |
| 12 | - | |
| 13 | - env: { | |
| 14 | - browser: true | |
| 21 | + sourceType: 'module', // Allows for the use of imports | |
| 15 | 22 | }, |
| 16 | 23 | |
| 17 | 24 | // Rules order is important, please avoid shuffling them |
| 18 | 25 | extends: [ |
| 19 | 26 | // Base ESLint recommended rules |
| 20 | - // 'eslint:recommended', | |
| 27 | + 'eslint:recommended', | |
| 21 | 28 | |
| 29 | + // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#usage | |
| 30 | + // ESLint typescript rules | |
| 31 | + 'plugin:@typescript-eslint/eslint-recommended', | |
| 32 | + 'plugin:@typescript-eslint/recommended', | |
| 33 | + // consider disabling this class of rules if linting takes too long | |
| 34 | + 'plugin:@typescript-eslint/recommended-requiring-type-checking', | |
| 22 | 35 | |
| 23 | - // Uncomment any of the lines below to choose desired strictness, | |
| 24 | - // but leave only one uncommented! | |
| 25 | - // See https://eslint.vuejs.org/rules/#available-rules | |
| 26 | - 'plugin:vue/essential', // Priority A: Essential (Error Prevention) | |
| 27 | - // 'plugin:vue/strongly-recommended', // Priority B: Strongly Recommended (Improving Readability) | |
| 28 | - // 'plugin:vue/recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead) | |
| 29 | - | |
| 30 | - 'standard' | |
| 36 | + // https://eslint.vuejs.org/rules/#priority-a-essential-error-prevention | |
| 37 | + // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules | |
| 38 | + 'plugin:vue/essential', | |
| 31 | 39 | |
| 40 | + // --- ONLY WHEN USING PRETTIER --- | |
| 41 | + // https://github.com/prettier/eslint-config-prettier#installation | |
| 42 | + // usage with Prettier, provided by 'eslint-config-prettier'. | |
| 43 | + 'prettier', | |
| 44 | + 'prettier/@typescript-eslint', | |
| 45 | + 'prettier/vue', | |
| 32 | 46 | ], |
| 33 | 47 | |
| 34 | 48 | plugins: [ |
| 49 | + // required to apply rules which need type information | |
| 50 | + '@typescript-eslint', | |
| 51 | + | |
| 35 | 52 | // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file |
| 36 | 53 | // required to lint *.vue files |
| 37 | 54 | 'vue', |
| 38 | - | |
| 39 | 55 | ], |
| 40 | 56 | |
| 41 | - globals: { | |
| 42 | - ga: true, // Google Analytics | |
| 43 | - cordova: true, | |
| 44 | - __statics: true, | |
| 45 | - process: true, | |
| 46 | - Capacitor: true, | |
| 47 | - chrome: true | |
| 48 | - }, | |
| 49 | - | |
| 50 | 57 | // add your custom rules here |
| 51 | 58 | rules: { |
| 52 | - // allow async-await | |
| 53 | - 'generator-star-spacing': 'off', | |
| 54 | - // allow paren-less arrow functions | |
| 55 | - 'arrow-parens': 'off', | |
| 56 | - 'one-var': 'off', | |
| 57 | - | |
| 58 | - 'import/first': 'off', | |
| 59 | - 'import/named': 'error', | |
| 60 | - 'import/namespace': 'error', | |
| 61 | - 'import/default': 'error', | |
| 62 | - 'import/export': 'error', | |
| 63 | - 'import/extensions': 'off', | |
| 64 | - 'import/no-unresolved': 'off', | |
| 65 | - 'import/no-extraneous-dependencies': 'off', | |
| 66 | - 'prefer-promise-reject-errors': 'off', | |
| 67 | - | |
| 59 | + // others rules... | |
| 68 | 60 | |
| 69 | - // allow debugger during development only | |
| 70 | - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' | |
| 61 | + // TypeScript | |
| 62 | + 'quotes': ['warn', 'single'], | |
| 63 | + '@typescript-eslint/explicit-function-return-type': 'off', | |
| 71 | 64 | } |
| 72 | 65 | } | ... | ... |
codigos/frontend/.vscode/settings.json
| ... | ... | @@ -2,6 +2,6 @@ |
| 2 | 2 | "vetur.validation.template": false, |
| 3 | 3 | "vetur.format.enable": false, |
| 4 | 4 | "eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"], |
| 5 | - | |
| 5 | + "typescript.tsdk": "node_modules/typescript/lib", | |
| 6 | 6 | "vetur.experimental.templateInterpolationService": true |
| 7 | 7 | } | ... | ... |
codigos/frontend/README.md
codigos/frontend/babel.config.js
codigos/frontend/package.json
| 1 | 1 | { |
| 2 | - "name": "srh-frontend-admin", | |
| 2 | + "name": "srh-admin-client", | |
| 3 | 3 | "version": "0.0.1", |
| 4 | - "description": "A admin client from System Recommendation Hybrid", | |
| 5 | - "productName": "SRH Frontend Admin", | |
| 4 | + "description": "A client for SRH", | |
| 5 | + "productName": "SRH Admin Client", | |
| 6 | 6 | "author": "Herik dos Santos Lorenção <heriksantoslorencao@gmail.com>", |
| 7 | 7 | "private": true, |
| 8 | 8 | "scripts": { |
| 9 | 9 | "lint": "eslint --ext .js,.vue ./", |
| 10 | 10 | "test": "echo \"No test specified\" && exit 0", |
| 11 | - "dev": "quasar dev --port 3000", | |
| 11 | + "dev": "quasar dev", | |
| 12 | 12 | "build": "quasar build", |
| 13 | 13 | "build:pwa": "quasar build -m pwa" |
| 14 | 14 | }, |
| 15 | 15 | "dependencies": { |
| 16 | 16 | "@quasar/extras": "^1.0.0", |
| 17 | - "axios": "^0.18.1", | |
| 17 | + "@types/jsonwebtoken": "^8.5.0", | |
| 18 | + "axios": "^0.19.2", | |
| 19 | + "chart.js": "^2.9.3", | |
| 18 | 20 | "core-js": "^3.6.5", |
| 21 | + "jsonwebtoken": "^8.5.1", | |
| 19 | 22 | "quasar": "^1.0.0", |
| 20 | - "vue-mc": "^0.6.0" | |
| 23 | + "vue-chartjs": "^3.5.0", | |
| 24 | + "vue-class-component": "^7.2.2", | |
| 25 | + "vue-property-decorator": "^8.3.0" | |
| 21 | 26 | }, |
| 22 | 27 | "devDependencies": { |
| 23 | 28 | "@quasar/app": "^2.0.0", |
| 29 | + "@types/node": "^10.17.15", | |
| 30 | + "@typescript-eslint/eslint-plugin": "^3.3.0", | |
| 31 | + "@typescript-eslint/parser": "^3.3.0", | |
| 24 | 32 | "babel-eslint": "^10.0.1", |
| 25 | 33 | "eslint": "^6.8.0", |
| 26 | - "eslint-config-standard": "^14.1.0", | |
| 34 | + "eslint-config-airbnb-base": "^14.0.0", | |
| 27 | 35 | "eslint-loader": "^3.0.3", |
| 28 | - "eslint-plugin-import": "^2.14.0", | |
| 29 | - "eslint-plugin-node": "^11.0.0", | |
| 30 | - "eslint-plugin-promise": "^4.0.1", | |
| 31 | - "eslint-plugin-standard": "^4.0.0", | |
| 36 | + "eslint-plugin-import": "^2.20.1", | |
| 32 | 37 | "eslint-plugin-vue": "^6.1.2" |
| 33 | 38 | }, |
| 34 | 39 | "browserslist": [ | ... | ... |
codigos/frontend/quasar.conf.js
| ... | ... | @@ -6,190 +6,206 @@ |
| 6 | 6 | // Configuration for your app |
| 7 | 7 | // https://quasar.dev/quasar-cli/quasar-conf-js |
| 8 | 8 | /* eslint-env node */ |
| 9 | - | |
| 10 | -module.exports = function (/* ctx */) { | |
| 11 | - return { | |
| 12 | - // https://quasar.dev/quasar-cli/supporting-ts | |
| 13 | - supportTS: false, | |
| 14 | - | |
| 15 | - // https://quasar.dev/quasar-cli/prefetch-feature | |
| 16 | - // preFetch: true, | |
| 17 | - | |
| 18 | - // app boot file (/src/boot) | |
| 19 | - // --> boot files are part of "main.js" | |
| 20 | - // https://quasar.dev/quasar-cli/boot-files | |
| 21 | - boot: [ | |
| 22 | - | |
| 23 | - 'axios' | |
| 24 | - ], | |
| 25 | - | |
| 26 | - // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css | |
| 27 | - css: [ | |
| 28 | - 'app.scss' | |
| 29 | - ], | |
| 30 | - | |
| 31 | - // https://github.com/quasarframework/quasar/tree/dev/extras | |
| 32 | - extras: [ | |
| 33 | - // 'ionicons-v4', | |
| 34 | - // 'mdi-v5', | |
| 35 | - // 'fontawesome-v5', | |
| 36 | - // 'eva-icons', | |
| 37 | - // 'themify', | |
| 38 | - // 'line-awesome', | |
| 39 | - // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! | |
| 40 | - | |
| 41 | - 'roboto-font', // optional, you are not bound to it | |
| 42 | - 'material-icons' // optional, you are not bound to it | |
| 43 | - ], | |
| 44 | - | |
| 45 | - // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build | |
| 46 | - build: { | |
| 47 | - vueRouterMode: 'hash', // available values: 'hash', 'history' | |
| 48 | - | |
| 49 | - // transpile: false, | |
| 50 | - | |
| 51 | - // Add dependencies for transpiling with Babel (Array of string/regex) | |
| 52 | - // (from node_modules, which are by default not transpiled). | |
| 53 | - // Applies only if "transpile" is set to true. | |
| 54 | - // transpileDependencies: [], | |
| 55 | - | |
| 56 | - // rtl: false, // https://quasar.dev/options/rtl-support | |
| 57 | - // preloadChunks: true, | |
| 58 | - // showProgress: false, | |
| 59 | - // gzip: true, | |
| 60 | - // analyze: true, | |
| 61 | - | |
| 62 | - // Options below are automatically set depending on the env, set them if you want to override | |
| 63 | - // extractCSS: false, | |
| 64 | - | |
| 65 | - // https://quasar.dev/quasar-cli/handling-webpack | |
| 66 | - extendWebpack (cfg) { | |
| 9 | +/* eslint func-names: 0 */ | |
| 10 | +/* eslint global-require: 0 */ | |
| 11 | +/* eslint-disable @typescript-eslint/no-var-requires */ | |
| 12 | +const { configure } = require('quasar/wrappers'); | |
| 13 | + | |
| 14 | +module.exports = configure((ctx) => ({ | |
| 15 | + // https://quasar.dev/quasar-cli/supporting-ts | |
| 16 | + supportTS: { | |
| 17 | + tsCheckerConfig: { | |
| 18 | + eslint: true, | |
| 19 | + }, | |
| 20 | + }, | |
| 21 | + | |
| 22 | + // https://quasar.dev/quasar-cli/prefetch-feature | |
| 23 | + // preFetch: true, | |
| 24 | + | |
| 25 | + // app boot file (/src/boot) | |
| 26 | + // --> boot files are part of "main.js" | |
| 27 | + // https://quasar.dev/quasar-cli/boot-files | |
| 28 | + boot: [ | |
| 29 | + 'loginRouteGuard', 'loginAdminRouteGuard' | |
| 30 | + ], | |
| 31 | + | |
| 32 | + // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css | |
| 33 | + css: [ | |
| 34 | + 'app.scss', | |
| 35 | + ], | |
| 36 | + | |
| 37 | + // https://github.com/quasarframework/quasar/tree/dev/extras | |
| 38 | + extras: [ | |
| 39 | + // 'ionicons-v4', | |
| 40 | + // 'mdi-v5', | |
| 41 | + 'fontawesome-v5', | |
| 42 | + // 'eva-icons', | |
| 43 | + // 'themify', | |
| 44 | + // 'line-awesome', | |
| 45 | + // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! | |
| 46 | + | |
| 47 | + 'roboto-font', // optional, you are not bound to it | |
| 48 | + 'material-icons', // optional, you are not bound to it | |
| 49 | + ], | |
| 50 | + | |
| 51 | + // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build | |
| 52 | + build: { | |
| 53 | + vueRouterMode: 'history', // available values: 'hash', 'history' | |
| 54 | + | |
| 55 | + // transpile: false, | |
| 56 | + | |
| 57 | + // Add dependencies for transpiling with Babel (Array of string/regex) | |
| 58 | + // (from node_modules, which are by default not transpiled). | |
| 59 | + // Applies only if "transpile" is set to true. | |
| 60 | + // transpileDependencies: [], | |
| 61 | + | |
| 62 | + // rtl: false, // https://quasar.dev/options/rtl-support | |
| 63 | + // preloadChunks: true, | |
| 64 | + // showProgress: false, | |
| 65 | + // gzip: true, | |
| 66 | + // analyze: true, | |
| 67 | + | |
| 68 | + // Options below are automatically set depending on the env, set them if you want to override | |
| 69 | + // extractCSS: false, | |
| 70 | + | |
| 71 | + // https://quasar.dev/quasar-cli/handling-webpack | |
| 72 | + extendWebpack(cfg) { | |
| 73 | + // linting is slow in TS projects, we execute it only for production builds | |
| 74 | + if (ctx.prod) { | |
| 67 | 75 | cfg.module.rules.push({ |
| 68 | 76 | enforce: 'pre', |
| 69 | 77 | test: /\.(js|vue)$/, |
| 70 | 78 | loader: 'eslint-loader', |
| 71 | - exclude: /node_modules/ | |
| 72 | - }) | |
| 79 | + exclude: /node_modules/, | |
| 80 | + }); | |
| 73 | 81 | } |
| 74 | 82 | }, |
| 83 | + }, | |
| 75 | 84 | |
| 76 | - // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer | |
| 77 | - devServer: { | |
| 78 | - https: false, | |
| 79 | - port: 8080, | |
| 80 | - open: true // opens browser window automatically | |
| 81 | - }, | |
| 85 | + // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer | |
| 86 | + devServer: { | |
| 87 | + https: false, | |
| 88 | + port: 8080, | |
| 89 | + open: true, // opens browser window automatically | |
| 90 | + }, | |
| 82 | 91 | |
| 83 | - // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework | |
| 84 | - framework: { | |
| 85 | - iconSet: 'material-icons', // Quasar icon set | |
| 86 | - lang: 'en-us', // Quasar language pack | |
| 87 | - config: { | |
| 88 | - notify: {} | |
| 89 | - }, | |
| 90 | - | |
| 91 | - // Possible values for "importStrategy": | |
| 92 | - // * 'auto' - (DEFAULT) Auto-import needed Quasar components & directives | |
| 93 | - // * 'all' - Manually specify what to import | |
| 94 | - importStrategy: 'auto', | |
| 95 | - | |
| 96 | - // Quasar plugins | |
| 97 | - plugins: [ | |
| 98 | - 'Notify' | |
| 99 | - ] | |
| 100 | - }, | |
| 92 | + // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework | |
| 93 | + framework: { | |
| 94 | + iconSet: 'material-icons', // Quasar icon set | |
| 95 | + lang: 'en-us', // Quasar language pack | |
| 96 | + config: { | |
| 101 | 97 | |
| 102 | - // animations: 'all', // --- includes all animations | |
| 103 | - // https://quasar.dev/options/animations | |
| 104 | - animations: [], | |
| 105 | - | |
| 106 | - // https://quasar.dev/quasar-cli/developing-ssr/configuring-ssr | |
| 107 | - ssr: { | |
| 108 | - pwa: false | |
| 109 | 98 | }, |
| 110 | 99 | |
| 111 | - // https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa | |
| 112 | - pwa: { | |
| 113 | - workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' | |
| 114 | - workboxOptions: {}, // only for GenerateSW | |
| 115 | - manifest: { | |
| 116 | - name: 'SRH Frontend Admin', | |
| 117 | - short_name: 'SRH Frontend Admin', | |
| 118 | - description: 'A admin client from System Recommendation Hybrid', | |
| 119 | - display: 'standalone', | |
| 120 | - orientation: 'portrait', | |
| 121 | - background_color: '#ffffff', | |
| 122 | - theme_color: '#027be3', | |
| 123 | - icons: [ | |
| 124 | - { | |
| 125 | - src: 'icons/icon-128x128.png', | |
| 126 | - sizes: '128x128', | |
| 127 | - type: 'image/png' | |
| 128 | - }, | |
| 129 | - { | |
| 130 | - src: 'icons/icon-192x192.png', | |
| 131 | - sizes: '192x192', | |
| 132 | - type: 'image/png' | |
| 133 | - }, | |
| 134 | - { | |
| 135 | - src: 'icons/icon-256x256.png', | |
| 136 | - sizes: '256x256', | |
| 137 | - type: 'image/png' | |
| 138 | - }, | |
| 139 | - { | |
| 140 | - src: 'icons/icon-384x384.png', | |
| 141 | - sizes: '384x384', | |
| 142 | - type: 'image/png' | |
| 143 | - }, | |
| 144 | - { | |
| 145 | - src: 'icons/icon-512x512.png', | |
| 146 | - sizes: '512x512', | |
| 147 | - type: 'image/png' | |
| 148 | - } | |
| 149 | - ] | |
| 150 | - } | |
| 100 | + // Possible values for "importStrategy": | |
| 101 | + // * 'auto' - (DEFAULT) Auto-import needed Quasar components & directives | |
| 102 | + // * 'all' - Manually specify what to import | |
| 103 | + importStrategy: 'auto', | |
| 104 | + cssAddon: true, | |
| 105 | + | |
| 106 | + // For special cases outside of where "auto" importStrategy can have an impact | |
| 107 | + // (like functional components as one of the examples), | |
| 108 | + // you can manually specify Quasar components/directives to be available everywhere: | |
| 109 | + // | |
| 110 | + // components: [], | |
| 111 | + // directives: [], | |
| 112 | + | |
| 113 | + // Quasar plugins | |
| 114 | + plugins: [ | |
| 115 | + 'Notify' | |
| 116 | + ], | |
| 117 | + }, | |
| 118 | + | |
| 119 | + // animations: 'all', // --- includes all animations | |
| 120 | + // https://quasar.dev/options/animations | |
| 121 | + animations: [], | |
| 122 | + | |
| 123 | + // https://quasar.dev/quasar-cli/developing-ssr/configuring-ssr | |
| 124 | + ssr: { | |
| 125 | + pwa: false, | |
| 126 | + }, | |
| 127 | + | |
| 128 | + // https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa | |
| 129 | + pwa: { | |
| 130 | + workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest' | |
| 131 | + workboxOptions: {}, // only for GenerateSW | |
| 132 | + manifest: { | |
| 133 | + name: 'SRH Admin Client', | |
| 134 | + short_name: 'SRH Admin Client', | |
| 135 | + description: 'A client for SRH', | |
| 136 | + display: 'standalone', | |
| 137 | + orientation: 'portrait', | |
| 138 | + background_color: '#ffffff', | |
| 139 | + theme_color: '#027be3', | |
| 140 | + icons: [ | |
| 141 | + { | |
| 142 | + src: 'icons/icon-128x128.png', | |
| 143 | + sizes: '128x128', | |
| 144 | + type: 'image/png', | |
| 145 | + }, | |
| 146 | + { | |
| 147 | + src: 'icons/icon-192x192.png', | |
| 148 | + sizes: '192x192', | |
| 149 | + type: 'image/png', | |
| 150 | + }, | |
| 151 | + { | |
| 152 | + src: 'icons/icon-256x256.png', | |
| 153 | + sizes: '256x256', | |
| 154 | + type: 'image/png', | |
| 155 | + }, | |
| 156 | + { | |
| 157 | + src: 'icons/icon-384x384.png', | |
| 158 | + sizes: '384x384', | |
| 159 | + type: 'image/png', | |
| 160 | + }, | |
| 161 | + { | |
| 162 | + src: 'icons/icon-512x512.png', | |
| 163 | + sizes: '512x512', | |
| 164 | + type: 'image/png', | |
| 165 | + }, | |
| 166 | + ], | |
| 151 | 167 | }, |
| 168 | + }, | |
| 152 | 169 | |
| 153 | - // Full list of options: https://quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova | |
| 154 | - cordova: { | |
| 155 | - // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing | |
| 156 | - }, | |
| 170 | + // Full list of options: https://quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova | |
| 171 | + cordova: { | |
| 172 | + // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing | |
| 173 | + }, | |
| 157 | 174 | |
| 158 | - // Full list of options: https://quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor | |
| 159 | - capacitor: { | |
| 160 | - hideSplashscreen: true | |
| 161 | - }, | |
| 175 | + // Full list of options: https://quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor | |
| 176 | + capacitor: { | |
| 177 | + hideSplashscreen: true, | |
| 178 | + }, | |
| 162 | 179 | |
| 163 | - // Full list of options: https://quasar.dev/quasar-cli/developing-electron-apps/configuring-electron | |
| 164 | - electron: { | |
| 165 | - bundler: 'packager', // 'packager' or 'builder' | |
| 180 | + // Full list of options: https://quasar.dev/quasar-cli/developing-electron-apps/configuring-electron | |
| 181 | + electron: { | |
| 182 | + bundler: 'packager', // 'packager' or 'builder' | |
| 166 | 183 | |
| 167 | - packager: { | |
| 168 | - // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options | |
| 184 | + packager: { | |
| 185 | + // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options | |
| 169 | 186 | |
| 170 | - // OS X / Mac App Store | |
| 171 | - // appBundleId: '', | |
| 172 | - // appCategoryType: '', | |
| 173 | - // osxSign: '', | |
| 174 | - // protocol: 'myapp://path', | |
| 187 | + // OS X / Mac App Store | |
| 188 | + // appBundleId: '', | |
| 189 | + // appCategoryType: '', | |
| 190 | + // osxSign: '', | |
| 191 | + // protocol: 'myapp://path', | |
| 175 | 192 | |
| 176 | - // Windows only | |
| 177 | - // win32metadata: { ... } | |
| 178 | - }, | |
| 193 | + // Windows only | |
| 194 | + // win32metadata: { ... } | |
| 195 | + }, | |
| 179 | 196 | |
| 180 | - builder: { | |
| 181 | - // https://www.electron.build/configuration/configuration | |
| 197 | + builder: { | |
| 198 | + // https://www.electron.build/configuration/configuration | |
| 182 | 199 | |
| 183 | - appId: 'srh-frontend-admin' | |
| 184 | - }, | |
| 200 | + appId: 'srh-admin-client', | |
| 201 | + }, | |
| 185 | 202 | |
| 186 | - // More info: https://quasar.dev/quasar-cli/developing-electron-apps/node-integration | |
| 187 | - nodeIntegration: true, | |
| 203 | + // More info: https://quasar.dev/quasar-cli/developing-electron-apps/node-integration | |
| 204 | + nodeIntegration: true, | |
| 188 | 205 | |
| 189 | - extendWebpack (/* cfg */) { | |
| 190 | - // do something with Electron main process Webpack cfg | |
| 191 | - // chainWebpack also available besides this extendWebpack | |
| 192 | - } | |
| 193 | - } | |
| 194 | - } | |
| 195 | -} | |
| 206 | + extendWebpack(/* cfg */) { | |
| 207 | + // do something with Electron main process Webpack cfg | |
| 208 | + // chainWebpack also available besides this extendWebpack | |
| 209 | + }, | |
| 210 | + }, | |
| 211 | +})); | ... | ... |
codigos/frontend/src/App.vue
| 1 | 1 | <template> |
| 2 | 2 | <div id="q-app"> |
| 3 | - <router-view/> | |
| 3 | + <router-view /> | |
| 4 | 4 | </div> |
| 5 | 5 | </template> |
| 6 | +<script lang="ts"> | |
| 7 | +import { Vue, Component } from 'vue-property-decorator'; | |
| 6 | 8 | |
| 7 | -<script> | |
| 8 | -export default { | |
| 9 | - name: 'App' | |
| 10 | -} | |
| 9 | +@Component | |
| 10 | +export default class App extends Vue {} | |
| 11 | 11 | </script> | ... | ... |
68.3 KB
| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | +import AuthApiService from "../services/AuthApiService"; | |
| 2 | +import Login from "../models/Login"; | |
| 3 | + | |
| 4 | +export default async ({ router, store }) => { | |
| 5 | + router.beforeEach((to, from, next) => { | |
| 6 | + const idUsuario = store.getters['login/getIdUsuario']; | |
| 7 | + | |
| 8 | + if (idUsuario === null && to.path !== '/login') { | |
| 9 | + const authApiService = new AuthApiService(); | |
| 10 | + const token = store.getters['login/getToken'] | |
| 11 | + | |
| 12 | + if (authApiService.verifyToken(token)) next(); | |
| 13 | + | |
| 14 | + const loginForm = new Login('admin', '123456'); | |
| 15 | + authApiService.generateJwt(loginForm).then(resp => { | |
| 16 | + store.commit('login/defineToken', resp); | |
| 17 | + }); | |
| 18 | + | |
| 19 | + next('/login'); | |
| 20 | + } | |
| 21 | + | |
| 22 | + next(); | |
| 23 | + }) | |
| 24 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | +import AuthApiService from "src/services/AuthApiService"; | |
| 2 | +import Login from '../models/Login'; | |
| 3 | + | |
| 4 | +export default async({ router, store }) => { | |
| 5 | + router.beforeEach((to, from, next) => { | |
| 6 | + const token = store.getters['login/getToken']; | |
| 7 | + const authApiService = new AuthApiService(); | |
| 8 | + | |
| 9 | + if (authApiService.verifyToken(token)) next(); | |
| 10 | + | |
| 11 | + const loginForm = new Login('admin', '123456'); | |
| 12 | + authApiService.generateJwt(loginForm).then(resp => { | |
| 13 | + store.commit('login/defineToken', resp); | |
| 14 | + }); | |
| 15 | + | |
| 16 | + next(); | |
| 17 | + }) | |
| 18 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | +<template> | |
| 2 | + <q-list> | |
| 3 | + <q-item class="item-list-menu column"> | |
| 4 | + <ItemMenu v-for="item in menuList" :key="item.id" :path="item.path" :label="item.label" | |
| 5 | + :icon="item.icon" :selectedItemMenu="selectedItemMenu" :items="item.subitems" | |
| 6 | + @selectedItem="changeSelectedItemMenu" /> | |
| 7 | + </q-item> | |
| 8 | + </q-list> | |
| 9 | +</template> | |
| 10 | + | |
| 11 | +<script lang="ts"> | |
| 12 | +import {Vue, Component} from 'vue-property-decorator'; | |
| 13 | +import ItemMenu from "./components/ItemMenu.vue"; | |
| 14 | +import itemMenuList from '../../mixins/itemMenuList'; | |
| 15 | + | |
| 16 | +@Component({ | |
| 17 | + components: {ItemMenu} | |
| 18 | +}) | |
| 19 | +export default class Menu extends Vue { | |
| 20 | + readonly menuList = itemMenuList; | |
| 21 | + selectedItemMenu = "" | |
| 22 | + | |
| 23 | + changeSelectedItemMenu(value: string) { | |
| 24 | + this.selectedItemMenu = value; | |
| 25 | + } | |
| 26 | +} | |
| 27 | +</script> | |
| 28 | + | |
| 29 | +<style lang="scss" scoped> | |
| 30 | +.item-list-menu { | |
| 31 | + padding: 0; | |
| 32 | +} | |
| 33 | +</style> | ... | ... |
codigos/frontend/src/components/menu/components/ItemMenu.vue
0 → 100644
| ... | ... | @@ -0,0 +1,137 @@ |
| 1 | +<template> | |
| 2 | + <div class="column"> | |
| 3 | + <div class="column"> | |
| 4 | + <q-item class="col-12" clickable @click="openSubMenuOrItem" :class="generateCssClass()"> | |
| 5 | + <q-item-section class="col-2 icon"> | |
| 6 | + <q-icon :name="icon"/> | |
| 7 | + </q-item-section> | |
| 8 | + <q-item-section class="col-10 justify-start label"> | |
| 9 | + <q-item-label> | |
| 10 | + {{ label }} | |
| 11 | + </q-item-label> | |
| 12 | + </q-item-section> | |
| 13 | + </q-item> | |
| 14 | + </div> | |
| 15 | + <div class="column" v-show="items && subMenuVisible"> | |
| 16 | + <SubItemMenu v-for="subitem in items" :icon="subitem.icon" :label="subitem.label" | |
| 17 | + :path="subitem.path" :key="subitem.id" :selected-item-menu="selectedItemMenu" | |
| 18 | + :itemId="itemId" @selectedItem="emitSelectedItem" | |
| 19 | + /> | |
| 20 | + </div> | |
| 21 | + </div> | |
| 22 | +</template> | |
| 23 | + | |
| 24 | +<script lang="ts"> | |
| 25 | +import {Vue, Component, Prop, Emit} from 'vue-property-decorator'; | |
| 26 | +import SubItemMenu from "components/menu/components/SubItemMenu.vue"; | |
| 27 | +import {SubItem} from "src/models/models"; | |
| 28 | + | |
| 29 | +@Component({ | |
| 30 | + components: {SubItemMenu} | |
| 31 | +}) | |
| 32 | +export default class ItemMenu extends Vue { | |
| 33 | + @Prop({type: String, required: true}) | |
| 34 | + readonly label !: string; | |
| 35 | + | |
| 36 | + @Prop({type: String, required: true}) | |
| 37 | + readonly path !: string; | |
| 38 | + | |
| 39 | + @Prop({type: String, required: true}) | |
| 40 | + readonly icon !: string; | |
| 41 | + | |
| 42 | + @Prop({type: String, required: true}) | |
| 43 | + selectedItemMenu !: string; | |
| 44 | + | |
| 45 | + @Prop({type: Array, required: true}) | |
| 46 | + readonly items !: SubItem[]; | |
| 47 | + | |
| 48 | + itemId = 0; | |
| 49 | + subMenuVisible = false; | |
| 50 | + | |
| 51 | + get isSelectedItemMenu() { | |
| 52 | + const isSelectedItem = this.selectedItemMenu === this.label || | |
| 53 | + this.selectedItemMenu === this.path; | |
| 54 | + | |
| 55 | + let subItemSelected = false; | |
| 56 | + | |
| 57 | + this.items.forEach(subitem => { | |
| 58 | + if (subitem.path === this.selectedItemMenu) | |
| 59 | + subItemSelected = true; | |
| 60 | + }) | |
| 61 | + | |
| 62 | + return isSelectedItem || subItemSelected; | |
| 63 | + } | |
| 64 | + | |
| 65 | + @Emit('selectedItem') | |
| 66 | + openSubMenuOrItem() { | |
| 67 | + if (this.$route.path !== this.path) { | |
| 68 | + this.$router.push(this.path) | |
| 69 | + } | |
| 70 | + | |
| 71 | + // TODO: Pegar Item Id pelo Vuex e definir aqui | |
| 72 | + // this.itemId = Vuex.get() | |
| 73 | + | |
| 74 | + this.subMenuVisible = !this.subMenuVisible; | |
| 75 | + if (this.itemId) { | |
| 76 | + } | |
| 77 | + | |
| 78 | + return this.path; | |
| 79 | + } | |
| 80 | + | |
| 81 | + @Emit('selectedItem') | |
| 82 | + emitSelectedItem(event: any) { | |
| 83 | + return event; | |
| 84 | + } | |
| 85 | + | |
| 86 | + generateCssClass(): string { | |
| 87 | + if (!this.isSelectedItemMenu) { | |
| 88 | + this.subMenuVisible = false; | |
| 89 | + } | |
| 90 | + | |
| 91 | + return this.isSelectedItemMenu ? 'item-menu selected' : 'item-menu no-selected' | |
| 92 | + } | |
| 93 | + | |
| 94 | + mounted() { | |
| 95 | + this.itemId = this.$store.getters['navigationInfo/projectId']; | |
| 96 | + } | |
| 97 | +} | |
| 98 | +</script> | |
| 99 | + | |
| 100 | +<style lang="scss" scoped> | |
| 101 | +.item-menu { | |
| 102 | + .icon { | |
| 103 | + font-size: $font-h1; | |
| 104 | + } | |
| 105 | + | |
| 106 | + .label { | |
| 107 | + font-size: $font-normal; | |
| 108 | + } | |
| 109 | +} | |
| 110 | + | |
| 111 | +.no-selected { | |
| 112 | + background-color: $white; | |
| 113 | + color: $gunmetal; | |
| 114 | + | |
| 115 | + .icon { | |
| 116 | + color: $yellow-orange; | |
| 117 | + } | |
| 118 | +} | |
| 119 | + | |
| 120 | +.no-selected:hover { | |
| 121 | + background-color: $yellow-orange; | |
| 122 | + color: $white; | |
| 123 | + | |
| 124 | + .icon { | |
| 125 | + color: $white; | |
| 126 | + } | |
| 127 | +} | |
| 128 | + | |
| 129 | +.selected { | |
| 130 | + background-color: $gunmetal-2; | |
| 131 | + color: $white; | |
| 132 | + | |
| 133 | + .icon { | |
| 134 | + color: $yellow-orange; | |
| 135 | + } | |
| 136 | +} | |
| 137 | +</style> | ... | ... |
codigos/frontend/src/components/menu/components/SubItemMenu.vue
0 → 100644
| ... | ... | @@ -0,0 +1,92 @@ |
| 1 | +<template> | |
| 2 | + <q-item class="col-12" clickable @click="navigateTo" :class="generateCssClass()"> | |
| 3 | + <div class="content row"> | |
| 4 | + <q-item-section class="col-2 icon"> | |
| 5 | + <q-icon :name="icon"/> | |
| 6 | + </q-item-section> | |
| 7 | + <q-item-section class="col-10 justify-start label"> | |
| 8 | + <q-item-label> | |
| 9 | + {{ label }} | |
| 10 | + </q-item-label> | |
| 11 | + </q-item-section> | |
| 12 | + </div> | |
| 13 | + </q-item> | |
| 14 | +</template> | |
| 15 | + | |
| 16 | +<script lang="ts"> | |
| 17 | +import {Vue, Component, Prop, Emit} from 'vue-property-decorator'; | |
| 18 | + | |
| 19 | +@Component | |
| 20 | +export default class SubItemMenu extends Vue { | |
| 21 | + @Prop({type: String, required: true}) | |
| 22 | + readonly label !: string; | |
| 23 | + | |
| 24 | + @Prop({type: String, required: true}) | |
| 25 | + readonly path !: string; | |
| 26 | + | |
| 27 | + @Prop({type: String, required: true}) | |
| 28 | + readonly icon !: string; | |
| 29 | + | |
| 30 | + @Prop({type: Number, required: true}) | |
| 31 | + readonly itemId !: number; | |
| 32 | + | |
| 33 | + @Prop({type: String, required: true}) | |
| 34 | + selectedItemMenu !: string; | |
| 35 | + | |
| 36 | + get isSelectedItemMenu() { | |
| 37 | + return this.selectedItemMenu === this.label || | |
| 38 | + this.selectedItemMenu === this.path; | |
| 39 | + } | |
| 40 | + | |
| 41 | + @Emit('selectedItem') | |
| 42 | + navigateTo() { | |
| 43 | + if (this.$route.path !== this.path) { | |
| 44 | + this.$router.push(this.path); | |
| 45 | + } | |
| 46 | + return this.path; | |
| 47 | + } | |
| 48 | + | |
| 49 | + generateCssClass(): string { | |
| 50 | + return this.isSelectedItemMenu ? 'subitem-menu selected-subitem' : 'subitem-menu no-selected-subitem' | |
| 51 | + } | |
| 52 | +} | |
| 53 | +</script> | |
| 54 | + | |
| 55 | +<style lang="scss" scoped> | |
| 56 | +.subitem-menu { | |
| 57 | + .content { | |
| 58 | + margin-left: 5%; | |
| 59 | + width: 100%; | |
| 60 | + flex-wrap: nowrap; | |
| 61 | + } | |
| 62 | + | |
| 63 | + .icon { | |
| 64 | + font-size: $font-h1; | |
| 65 | + } | |
| 66 | + | |
| 67 | + .label { | |
| 68 | + font-size: $font-normal; | |
| 69 | + } | |
| 70 | +} | |
| 71 | + | |
| 72 | +.no-selected-subitem { | |
| 73 | + .icon { | |
| 74 | + color: $yellow-orange; | |
| 75 | + } | |
| 76 | +} | |
| 77 | + | |
| 78 | +.no-selected-subitem:hover { | |
| 79 | + background-color: $yellow-orange; | |
| 80 | + color: $white; | |
| 81 | + | |
| 82 | + .icon { | |
| 83 | + color: $white; | |
| 84 | + } | |
| 85 | +} | |
| 86 | + | |
| 87 | +.selected-subitem { | |
| 88 | + background-color: $yellow-orange; | |
| 89 | + color: $white; | |
| 90 | +} | |
| 91 | + | |
| 92 | +</style> | ... | ... |
codigos/frontend/src/css/app.scss
| 1 | -// app global css in SCSS form | |
| 1 | +@import 'pages/login'; | |
| 2 | +@import 'pages/index'; | |
| 3 | +@import 'pages/projects'; | |
| 4 | +@import 'pages/users'; | |
| 5 | + | |
| 6 | +* { | |
| 7 | + font-family: 'Roboto', '-apple-system', 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
| 8 | +} | |
| 9 | + | |
| 10 | +.header-style { | |
| 11 | + background-color: $yellow-orange; | |
| 12 | + color: $white; | |
| 13 | + border: none; | |
| 14 | +} | |
| 15 | + | |
| 16 | +.side-menu { | |
| 17 | + min-height: 100%; | |
| 18 | +} | |
| 19 | + | |
| 20 | +.menu-logo { | |
| 21 | + width: 100%; | |
| 22 | + margin-bottom: 20px; | |
| 23 | + | |
| 24 | + .image-logo { | |
| 25 | + width: 60%; | |
| 26 | + margin-left: -10%; | |
| 27 | + } | |
| 28 | +} | |
| 29 | + | |
| 30 | +.menu-logo-ifes { | |
| 31 | + width: 100%; | |
| 32 | + padding-top: 30px; | |
| 33 | + | |
| 34 | + .image-logo { | |
| 35 | + width: 70%; | |
| 36 | + } | |
| 37 | +} | |
| 38 | + | |
| 39 | +.menu-user { | |
| 40 | + .btn { | |
| 41 | + margin-left: 10px; | |
| 42 | + border-radius: 0; | |
| 43 | + } | |
| 44 | + | |
| 45 | + .btn-logout { | |
| 46 | + padding: 0 30px; | |
| 47 | + border-radius: 10px; | |
| 48 | + background-color: $gunmetal; | |
| 49 | + } | |
| 50 | +} | |
| 51 | + | |
| 52 | +.page { | |
| 53 | + background-color: $yellow-orange-bg; | |
| 54 | +} | |
| 55 | + | |
| 56 | +.footer-style { | |
| 57 | + background-color: $yellow-orange-bg; | |
| 58 | + font-weight: 500; | |
| 59 | + height: 50px; | |
| 60 | +} | |
| 61 | + | |
| 62 | +.card { | |
| 63 | + border-radius: 20px; | |
| 64 | + | |
| 65 | + .card-header { | |
| 66 | + width: 100%; | |
| 67 | + text-align: center; | |
| 68 | + font-size: $font-normal; | |
| 69 | + } | |
| 70 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | +// Default Application Variables | |
| 2 | +$tart-orange: #f94144ff; | |
| 3 | +$orange-red: #f3722cff; | |
| 4 | +$yellow-orange: #f8961eff; | |
| 5 | +$yellow-orange-bg: #fda53a; | |
| 6 | +$maize-crayola: #f9c74fff; | |
| 7 | +$pistachio: #90be6dff; | |
| 8 | +$jungle-green: #43aa8bff; | |
| 9 | +$queen-blue: #577590ff; | |
| 10 | +$gunmetal: #27333dff; | |
| 11 | +$gunmetal-2: #202931ff; | |
| 12 | +$white: #ffffff; | |
| 13 | +$transparent: transparent; | |
| 14 | + | |
| 15 | +$font-h1: 2em; | |
| 16 | +$font-h1-small: 1.6em; | |
| 17 | +$font-h2: 1.4em; | |
| 18 | +$font-normal: 1.2em; | |
| 19 | +$font-text: 1em; | |
| 20 | +$font-obs: 0.8em; | ... | ... |
| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | +.login-page { | |
| 2 | + width: 100%; | |
| 3 | + | |
| 4 | + .card { | |
| 5 | + width: 25%; | |
| 6 | + } | |
| 7 | + | |
| 8 | + .login-logo { | |
| 9 | + margin-top: 20px; | |
| 10 | + width: 50%; | |
| 11 | + } | |
| 12 | + | |
| 13 | + .login-btn { | |
| 14 | + width: 40%; | |
| 15 | + background-color: $yellow-orange; | |
| 16 | + color: $white; | |
| 17 | + } | |
| 18 | + | |
| 19 | + .forget-password { | |
| 20 | + margin: 25px 0; | |
| 21 | + text-decoration: none; | |
| 22 | + color: $gunmetal; | |
| 23 | + } | |
| 24 | +} | |
| 25 | + | ... | ... |
| ... | ... | @@ -0,0 +1,97 @@ |
| 1 | +.initial-menu-buttons { | |
| 2 | + color: $white; | |
| 3 | + width: 60%; | |
| 4 | + | |
| 5 | + .project-btn { | |
| 6 | + font-size: 10em; | |
| 7 | + cursor: pointer; | |
| 8 | + | |
| 9 | + span { | |
| 10 | + margin-top: 30px; | |
| 11 | + font-size: 0.18em; | |
| 12 | + } | |
| 13 | + } | |
| 14 | +} | |
| 15 | + | |
| 16 | +.create-project { | |
| 17 | + width: 100%; | |
| 18 | + height: 100%; | |
| 19 | + | |
| 20 | + .card { | |
| 21 | + height: 470px; | |
| 22 | + } | |
| 23 | + | |
| 24 | + .form { | |
| 25 | + height: 375px; | |
| 26 | + | |
| 27 | + .fields { | |
| 28 | + width: 50%; | |
| 29 | + } | |
| 30 | + | |
| 31 | + .field-text { | |
| 32 | + margin-top: 30px; | |
| 33 | + | |
| 34 | + textarea { | |
| 35 | + resize: none; | |
| 36 | + overflow: hidden; | |
| 37 | + } | |
| 38 | + } | |
| 39 | + | |
| 40 | + .create-btn { | |
| 41 | + color: $white; | |
| 42 | + background-color: $yellow-orange; | |
| 43 | + width: 30%; | |
| 44 | + } | |
| 45 | + } | |
| 46 | + | |
| 47 | + .project-attributes { | |
| 48 | + height: 230px; | |
| 49 | + | |
| 50 | + p { | |
| 51 | + text-align: center; | |
| 52 | + font-size: $font-normal; | |
| 53 | + } | |
| 54 | + | |
| 55 | + .label { | |
| 56 | + color: $yellow-orange; | |
| 57 | + } | |
| 58 | + | |
| 59 | + .fields { | |
| 60 | + width: 80%; | |
| 61 | + } | |
| 62 | + | |
| 63 | + .attribute-btn { | |
| 64 | + width: 80%; | |
| 65 | + color: $white; | |
| 66 | + font-size: $font-text; | |
| 67 | + background-color: $yellow-orange; | |
| 68 | + } | |
| 69 | + } | |
| 70 | +} | |
| 71 | + | |
| 72 | +.list-projects { | |
| 73 | + width: 100%; | |
| 74 | + | |
| 75 | + .card { | |
| 76 | + width: 60%; | |
| 77 | + } | |
| 78 | + | |
| 79 | + .list-projects-content { | |
| 80 | + height: 100%; | |
| 81 | + overflow-y: auto; | |
| 82 | + height: 400px; | |
| 83 | + | |
| 84 | + .projects-table { | |
| 85 | + width: 80%; | |
| 86 | + max-height: 300px; | |
| 87 | + } | |
| 88 | + | |
| 89 | + .action-buttons { | |
| 90 | + width: 80%; | |
| 91 | + | |
| 92 | + * { | |
| 93 | + color: $white; | |
| 94 | + } | |
| 95 | + } | |
| 96 | + } | |
| 97 | +} | ... | ... |
codigos/frontend/src/css/quasar.variables.scss
| ... | ... | @@ -11,6 +11,7 @@ |
| 11 | 11 | // It's highly recommended to change the default colors |
| 12 | 12 | // to match your app's branding. |
| 13 | 13 | // Tip: Use the "Theme Builder" on Quasar's documentation website. |
| 14 | +@import "app.variables"; | |
| 14 | 15 | |
| 15 | 16 | $primary : #1976D2; |
| 16 | 17 | $secondary : #26A69A; |
| ... | ... | @@ -22,13 +23,3 @@ $positive : #21BA45; |
| 22 | 23 | $negative : #C10015; |
| 23 | 24 | $info : #31CCEC; |
| 24 | 25 | $warning : #F2C037; |
| 25 | - | |
| 26 | -$tart-orange: #f94144ff; | |
| 27 | -$orange-red: #f3722cff; | |
| 28 | -$yellow-orange-color-wheel: #f8961eff; | |
| 29 | -$maize-crayola: #f9c74fff; | |
| 30 | -$pistachio: #90be6dff; | |
| 31 | -$jungle-green: #43aa8bff; | |
| 32 | -$queen-blue: #577590ff; | |
| 33 | -$gunmetal: #27333dff; | |
| 34 | -$gunmetal-2: #202931ff; | ... | ... |
| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | +<template> | |
| 2 | + <q-layout view="hhh lpr fff"> | |
| 3 | + <q-page-container> | |
| 4 | + <router-view /> | |
| 5 | + </q-page-container> | |
| 6 | + | |
| 7 | + <q-footer class="footer-style row justify-center items-center"> | |
| 8 | + Desenvolvido por Herik S.Lorenção | |
| 9 | + </q-footer> | |
| 10 | + </q-layout> | |
| 11 | +</template> | |
| 12 | + | |
| 13 | +<script lang="ts"> | |
| 14 | +import {Vue, Component} from 'vue-property-decorator'; | |
| 15 | + | |
| 16 | +@Component | |
| 17 | +export default class LoginLayout extends Vue{ | |
| 18 | +} | |
| 19 | +</script> | ... | ... |
| ... | ... | @@ -0,0 +1,99 @@ |
| 1 | +<template> | |
| 2 | + <q-layout view="lHh Lpr lFf"> | |
| 3 | + <q-header bordered class="header-style" elevated> | |
| 4 | + <q-toolbar class="row justify-between"> | |
| 5 | + <div> | |
| 6 | + <q-btn | |
| 7 | + flat | |
| 8 | + dense | |
| 9 | + round | |
| 10 | + icon="menu" | |
| 11 | + aria-label="Menu" | |
| 12 | + @click="leftDrawerOpen = !leftDrawerOpen" | |
| 13 | + /> | |
| 14 | + <q-btn icon="home" @click="navigateToHome" flat /> | |
| 15 | + </div> | |
| 16 | + | |
| 17 | + <div class="menu-user row items-center"> | |
| 18 | + <q-fab square class="btn" icon="person" :label="adminName" direction="down" flat | |
| 19 | + no-caps> | |
| 20 | + <q-fab-action class="btn-logout" @click="logout" text-color="white"> | |
| 21 | + Sair | |
| 22 | + </q-fab-action> | |
| 23 | + </q-fab> | |
| 24 | + </div> | |
| 25 | + </q-toolbar> | |
| 26 | + </q-header> | |
| 27 | + | |
| 28 | + <q-drawer | |
| 29 | + v-model="leftDrawerOpen" | |
| 30 | + show-if-above | |
| 31 | + bordered | |
| 32 | + > | |
| 33 | + <q-list class="side-menu column justify-between"> | |
| 34 | + <div> | |
| 35 | + <q-item-label | |
| 36 | + header | |
| 37 | + class="text-grey-8" | |
| 38 | + > | |
| 39 | + <div class="menu-logo row justify-center"> | |
| 40 | + <q-img class="image-logo" src="../assets/logo/primaryLogo.png" /> | |
| 41 | + </div> | |
| 42 | + </q-item-label> | |
| 43 | + <Menu></Menu> | |
| 44 | + <q-item-label | |
| 45 | + class="self-end" | |
| 46 | + > | |
| 47 | + </q-item-label> | |
| 48 | + </div> | |
| 49 | + <div class="menu-logo-ifes row justify-center"> | |
| 50 | + <q-img class="image-logo" src="../assets/ifes-logo.png" /> | |
| 51 | + </div> | |
| 52 | + </q-list> | |
| 53 | + </q-drawer> | |
| 54 | + | |
| 55 | + <q-page-container> | |
| 56 | + <router-view /> | |
| 57 | + </q-page-container> | |
| 58 | + | |
| 59 | + <q-footer class="footer-style row justify-center items-center"> | |
| 60 | + Desenvolvido por Herik S.Lorenção | |
| 61 | + </q-footer> | |
| 62 | + </q-layout> | |
| 63 | +</template> | |
| 64 | + | |
| 65 | +<script lang="ts"> | |
| 66 | +import { Vue, Component } from 'vue-property-decorator'; | |
| 67 | +import Menu from "components/menu/Menu.vue"; | |
| 68 | +import AdminService from "src/services/AdminService"; | |
| 69 | + | |
| 70 | +@Component({ | |
| 71 | + components: { Menu }, | |
| 72 | +}) | |
| 73 | +export default class MainLayout extends Vue { | |
| 74 | + leftDrawerOpen = false; | |
| 75 | + adminName = ''; | |
| 76 | + | |
| 77 | + navigateToHome() { | |
| 78 | + if (this.$route.path !== '/') { | |
| 79 | + this.$router.push('/'); | |
| 80 | + } | |
| 81 | + } | |
| 82 | + | |
| 83 | + logout() { | |
| 84 | + this.$store.commit('login/defineUserId', null); | |
| 85 | + this.$router.push('/login'); | |
| 86 | + } | |
| 87 | + | |
| 88 | + async mounted() { | |
| 89 | + const adminService = new AdminService(); | |
| 90 | + const userId = this.$store.getters['login/getIdUsuario']; | |
| 91 | + | |
| 92 | + const admin = await adminService.find(userId); | |
| 93 | + | |
| 94 | + if (admin && admin.name) { | |
| 95 | + this.adminName = admin.name; | |
| 96 | + } | |
| 97 | + } | |
| 98 | +} | |
| 99 | +</script> | ... | ... |
| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | +import {ItemMenu} from "src/models/models"; | |
| 2 | + | |
| 3 | +const values: ItemMenu[] = [ | |
| 4 | + { | |
| 5 | + id: 1, | |
| 6 | + path: '/projetos', | |
| 7 | + label: 'Projetos', | |
| 8 | + icon: 'attach_file', | |
| 9 | + subitems: [ | |
| 10 | + { | |
| 11 | + id: 1, | |
| 12 | + label: 'Usuários', | |
| 13 | + path: 'projetos/usuarios', | |
| 14 | + icon: 'person' | |
| 15 | + }, | |
| 16 | + { | |
| 17 | + id: 2, | |
| 18 | + label: 'Recomendações', | |
| 19 | + path: 'projetos/recomendacoes', | |
| 20 | + icon: 'emoji_objects' | |
| 21 | + }, | |
| 22 | + { | |
| 23 | + id: 3, | |
| 24 | + label: 'Avaliações', | |
| 25 | + path: 'projetos/avaliacoes', | |
| 26 | + icon: 'edit' | |
| 27 | + }, | |
| 28 | + { | |
| 29 | + id: 4, | |
| 30 | + label: 'Tags', | |
| 31 | + path: 'projetos/tags', | |
| 32 | + icon: 'local_offer' | |
| 33 | + }, | |
| 34 | + { | |
| 35 | + id: 5, | |
| 36 | + label: 'Tipos de Item', | |
| 37 | + path: 'projetos/tipositens', | |
| 38 | + icon: 'category' | |
| 39 | + }, | |
| 40 | + { | |
| 41 | + id: 6, | |
| 42 | + label: 'Itens', | |
| 43 | + path: 'projetos/itens', | |
| 44 | + icon: 'pageview' | |
| 45 | + } | |
| 46 | + ] | |
| 47 | + }, | |
| 48 | + { | |
| 49 | + id: 2, | |
| 50 | + path: 'tags', | |
| 51 | + label: 'Tags', | |
| 52 | + icon: 'local_offer', | |
| 53 | + subitems: [] | |
| 54 | + }, | |
| 55 | + { | |
| 56 | + id: 3, | |
| 57 | + path: 'tipoitens', | |
| 58 | + label: 'Tipos de Item', | |
| 59 | + icon: 'category', | |
| 60 | + subitems: [] | |
| 61 | + }, | |
| 62 | + { | |
| 63 | + id: 4, | |
| 64 | + path: "apis", | |
| 65 | + label: 'APIs', | |
| 66 | + icon: 'settings', | |
| 67 | + subitems: [] | |
| 68 | + }, | |
| 69 | +]; | |
| 70 | + | |
| 71 | +export default values; | ... | ... |
| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | +import {Notify} from 'quasar' | |
| 2 | + | |
| 3 | +export const TypeMessage = { | |
| 4 | + success: 'positive', | |
| 5 | + warning: 'warning', | |
| 6 | + info: 'info', | |
| 7 | + error: 'negative' | |
| 8 | +} | |
| 9 | + | |
| 10 | +export default function notify(this: any, message: string, type: string) { | |
| 11 | + Notify.create({message, type, position: 'bottom-right'}); | |
| 12 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | +export default { | |
| 2 | + columns: [ | |
| 3 | + { | |
| 4 | + name: 'id', | |
| 5 | + field: 'id', | |
| 6 | + label: 'Código', | |
| 7 | + align: 'center', | |
| 8 | + sortable: true | |
| 9 | + }, | |
| 10 | + { | |
| 11 | + name: 'name', | |
| 12 | + field: 'name', | |
| 13 | + label: 'Nome', | |
| 14 | + align: 'center', | |
| 15 | + sortable: true | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + name: 'email', | |
| 19 | + field: 'email', | |
| 20 | + label: 'Email', | |
| 21 | + align: 'center', | |
| 22 | + sortable: true | |
| 23 | + } | |
| 24 | + ] | |
| 25 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | +import FormRequest from "src/models/FormRequest"; | |
| 2 | + | |
| 3 | +export default class Admin extends FormRequest { | |
| 4 | + private _id: number; | |
| 5 | + private _name: string; | |
| 6 | + private _login: string; | |
| 7 | + private _email: string; | |
| 8 | + | |
| 9 | + constructor(id: number, name: string, login: string, email: string) { | |
| 10 | + super(); | |
| 11 | + this._id = id; | |
| 12 | + this._name = name; | |
| 13 | + this._login = login; | |
| 14 | + this._email = email; | |
| 15 | + } | |
| 16 | + | |
| 17 | + get id(): number { | |
| 18 | + return this._id; | |
| 19 | + } | |
| 20 | + | |
| 21 | + set id(value: number) { | |
| 22 | + this._id = value; | |
| 23 | + } | |
| 24 | + | |
| 25 | + get name(): string { | |
| 26 | + return this._name; | |
| 27 | + } | |
| 28 | + | |
| 29 | + set name(value: string) { | |
| 30 | + this._name = value; | |
| 31 | + } | |
| 32 | + | |
| 33 | + get login(): string { | |
| 34 | + return this._login; | |
| 35 | + } | |
| 36 | + | |
| 37 | + set login(value: string) { | |
| 38 | + this._login = value; | |
| 39 | + } | |
| 40 | + | |
| 41 | + get email(): string { | |
| 42 | + return this._email; | |
| 43 | + } | |
| 44 | + | |
| 45 | + set email(value: string) { | |
| 46 | + this._email = value; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public build(): object { | |
| 50 | + return { | |
| 51 | + id: this._id, | |
| 52 | + name: this._name, | |
| 53 | + login: this._login, | |
| 54 | + email: this._email | |
| 55 | + } | |
| 56 | + } | |
| 57 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | +import FormRequest from "src/models/FormRequest"; | |
| 2 | + | |
| 3 | +export default class Login extends FormRequest{ | |
| 4 | + private _login: string; | |
| 5 | + private _password: string; | |
| 6 | + | |
| 7 | + | |
| 8 | + constructor(login: string, password: string) { | |
| 9 | + super(); | |
| 10 | + this._login = login; | |
| 11 | + this._password = password; | |
| 12 | + } | |
| 13 | + | |
| 14 | + | |
| 15 | + get login(): string { | |
| 16 | + return this._login; | |
| 17 | + } | |
| 18 | + | |
| 19 | + set login(value: string) { | |
| 20 | + this._login = value; | |
| 21 | + } | |
| 22 | + | |
| 23 | + get password(): string { | |
| 24 | + return this._password; | |
| 25 | + } | |
| 26 | + | |
| 27 | + set password(value: string) { | |
| 28 | + this._password = value; | |
| 29 | + } | |
| 30 | + | |
| 31 | + public build(): object { | |
| 32 | + return { | |
| 33 | + login: this._login, | |
| 34 | + password: this._password | |
| 35 | + } | |
| 36 | + } | |
| 37 | +} | ... | ... |