Compare View

switch
from
...
to
 
Commits (2)
Showing 151 changed files   Show diff stats

Too many changes.

To preserve performance only 100 of 151 files displayed.

.idea/2020-Herik-SRH.iml 0 → 100644
@@ -0,0 +1,9 @@ @@ -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 \ No newline at end of file 10 \ No newline at end of file
.idea/modules.xml 0 → 100644
@@ -0,0 +1,8 @@ @@ -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 \ No newline at end of file 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
.idea/sonarlint/issuestore/index.pb 0 → 100644
No preview for this file type
.idea/vcs.xml 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="" vcs="Git" />
  5 + </component>
  6 +</project>
0 \ No newline at end of file 7 \ No newline at end of file
.idea/workspace.xml 0 → 100644
@@ -0,0 +1,42 @@ @@ -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 \ No newline at end of file 43 \ No newline at end of file
codigos/backend/pom.xml
@@ -36,6 +36,10 @@ @@ -36,6 +36,10 @@
36 <groupId>org.springframework.boot</groupId> 36 <groupId>org.springframework.boot</groupId>
37 <artifactId>spring-boot-starter-security</artifactId> 37 <artifactId>spring-boot-starter-security</artifactId>
38 </dependency> 38 </dependency>
  39 + <dependency>
  40 + <groupId>org.springframework.boot</groupId>
  41 + <artifactId>spring-boot-starter-mail</artifactId>
  42 + </dependency>
39 <dependency> 43 <dependency>
40 <groupId>de.codecentric</groupId> 44 <groupId>de.codecentric</groupId>
41 <artifactId>spring-boot-admin-starter-client</artifactId> 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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +package com.srh.api.algorithms.utils;
  2 +
  3 +public class EuclideanDistance {
  4 +}
codigos/backend/src/main/java/com/srh/api/builder/ProjectBuilder.java
@@ -11,6 +11,7 @@ public final class ProjectBuilder { @@ -11,6 +11,7 @@ public final class ProjectBuilder {
11 private String description; 11 private String description;
12 private LocalDate date; 12 private LocalDate date;
13 private Boolean visible; 13 private Boolean visible;
  14 + private Integer lastMatrixId;
14 private Situations situation; 15 private Situations situation;
15 private Admin admin; 16 private Admin admin;
16 private List<Evaluator> evaluators; 17 private List<Evaluator> evaluators;
@@ -48,6 +49,11 @@ public final class ProjectBuilder { @@ -48,6 +49,11 @@ public final class ProjectBuilder {
48 return this; 49 return this;
49 } 50 }
50 51
  52 + public ProjectBuilder withLastMatrixId(Integer lastMatrixId) {
  53 + this.lastMatrixId = lastMatrixId;
  54 + return this;
  55 + }
  56 +
51 public ProjectBuilder withSituation(Situations situation) { 57 public ProjectBuilder withSituation(Situations situation) {
52 this.situation = situation; 58 this.situation = situation;
53 return this; 59 return this;
@@ -75,6 +81,7 @@ public final class ProjectBuilder { @@ -75,6 +81,7 @@ public final class ProjectBuilder {
75 project.setDescription(description); 81 project.setDescription(description);
76 project.setDate(date); 82 project.setDate(date);
77 project.setVisible(visible); 83 project.setVisible(visible);
  84 + project.setLastMatrixId(lastMatrixId);
78 project.setSituation(situation); 85 project.setSituation(situation);
79 project.setAdmin(admin); 86 project.setAdmin(admin);
80 project.setEvaluators(evaluators); 87 project.setEvaluators(evaluators);
codigos/backend/src/main/java/com/srh/api/builder/RecommendationBuilder.java
@@ -10,6 +10,7 @@ public final class RecommendationBuilder { @@ -10,6 +10,7 @@ public final class RecommendationBuilder {
10 private Double weight; 10 private Double weight;
11 private LocalDateTime date; 11 private LocalDateTime date;
12 private Integer runtimeInSeconds; 12 private Integer runtimeInSeconds;
  13 + private Integer matrixId;
13 private Algorithm algorithm; 14 private Algorithm algorithm;
14 private Evaluator evaluator; 15 private Evaluator evaluator;
15 private Item item; 16 private Item item;
@@ -42,6 +43,11 @@ public final class RecommendationBuilder { @@ -42,6 +43,11 @@ public final class RecommendationBuilder {
42 return this; 43 return this;
43 } 44 }
44 45
  46 + public RecommendationBuilder withMatrixId(Integer matrixId) {
  47 + this.matrixId = matrixId;
  48 + return this;
  49 + }
  50 +
45 public RecommendationBuilder withAlgorithm(Algorithm algorithm) { 51 public RecommendationBuilder withAlgorithm(Algorithm algorithm) {
46 this.algorithm = algorithm; 52 this.algorithm = algorithm;
47 return this; 53 return this;
@@ -68,6 +74,7 @@ public final class RecommendationBuilder { @@ -68,6 +74,7 @@ public final class RecommendationBuilder {
68 recommendation.setWeight(weight); 74 recommendation.setWeight(weight);
69 recommendation.setDate(date); 75 recommendation.setDate(date);
70 recommendation.setRuntimeInSeconds(runtimeInSeconds); 76 recommendation.setRuntimeInSeconds(runtimeInSeconds);
  77 + recommendation.setMatrixId(matrixId);
71 recommendation.setAlgorithm(algorithm); 78 recommendation.setAlgorithm(algorithm);
72 recommendation.setEvaluator(evaluator); 79 recommendation.setEvaluator(evaluator);
73 recommendation.setItem(item); 80 recommendation.setItem(item);
codigos/backend/src/main/java/com/srh/api/config/DbSeeder.java
1 package com.srh.api.config; 1 package com.srh.api.config;
2 2
  3 +import com.srh.api.builder.AlgorithmBuilder;
3 import com.srh.api.builder.ApiUserBuilder; 4 import com.srh.api.builder.ApiUserBuilder;
4 import com.srh.api.builder.ProfileBuilder; 5 import com.srh.api.builder.ProfileBuilder;
  6 +import com.srh.api.model.Algorithm;
5 import com.srh.api.model.ApiUser; 7 import com.srh.api.model.ApiUser;
6 import com.srh.api.model.Profile; 8 import com.srh.api.model.Profile;
  9 +import com.srh.api.model.TypeRecommendation;
  10 +import com.srh.api.repository.AlgorithmRepository;
7 import com.srh.api.repository.ApiUserRepository; 11 import com.srh.api.repository.ApiUserRepository;
8 import com.srh.api.repository.ProfileRepository; 12 import com.srh.api.repository.ProfileRepository;
9 import org.springframework.beans.factory.annotation.Autowired; 13 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
11 15
12 import java.util.ArrayList; 16 import java.util.ArrayList;
  17 +import java.util.Arrays;
13 import java.util.List; 18 import java.util.List;
14 19
15 @Service 20 @Service
@@ -20,6 +25,9 @@ public class DbSeeder { @@ -20,6 +25,9 @@ public class DbSeeder {
20 @Autowired 25 @Autowired
21 private ProfileRepository profileRepository; 26 private ProfileRepository profileRepository;
22 27
  28 + @Autowired
  29 + private AlgorithmRepository algorithmRepository;
  30 +
23 private Profile adminProfile; 31 private Profile adminProfile;
24 private Profile userProfile; 32 private Profile userProfile;
25 33
@@ -30,6 +38,8 @@ public class DbSeeder { @@ -30,6 +38,8 @@ public class DbSeeder {
30 createApiUserAdmin(); 38 createApiUserAdmin();
31 createApiUserClient(); 39 createApiUserClient();
32 40
  41 + createAlgorithms();
  42 +
33 return true; 43 return true;
34 } 44 }
35 45
@@ -85,4 +95,47 @@ public class DbSeeder { @@ -85,4 +95,47 @@ public class DbSeeder {
85 userProfile = profile; 95 userProfile = profile;
86 profileRepository.save(profile); 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 @@ @@ -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,9 +2,14 @@ package com.srh.api.controller;
2 2
3 import com.srh.api.dto.resource.AdminDto; 3 import com.srh.api.dto.resource.AdminDto;
4 import com.srh.api.dto.resource.AdminForm; 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 import com.srh.api.hypermedia.AdminModelAssembler; 7 import com.srh.api.hypermedia.AdminModelAssembler;
6 import com.srh.api.model.Admin; 8 import com.srh.api.model.Admin;
  9 +import com.srh.api.model.Project;
  10 +import com.srh.api.model.TypeItem;
7 import com.srh.api.service.AdminService; 11 import com.srh.api.service.AdminService;
  12 +import com.srh.api.utils.PageUtil;
8 import lombok.SneakyThrows; 13 import lombok.SneakyThrows;
9 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.data.domain.Page; 15 import org.springframework.data.domain.Page;
@@ -35,6 +40,9 @@ public class AdminController { @@ -35,6 +40,9 @@ public class AdminController {
35 @Autowired 40 @Autowired
36 private PagedResourcesAssembler<AdminDto> pagedResourcesAssembler; 41 private PagedResourcesAssembler<AdminDto> pagedResourcesAssembler;
37 42
  43 + @Autowired
  44 + private PagedResourcesAssembler<ProjectDto> projectDtoPagedResourcesAssembler;
  45 +
38 @GetMapping 46 @GetMapping
39 public PagedModel<EntityModel<AdminDto>> listAll(@PageableDefault(page = 0, size = 5) Pageable pageInfo) { 47 public PagedModel<EntityModel<AdminDto>> listAll(@PageableDefault(page = 0, size = 5) Pageable pageInfo) {
40 Page<Admin> admins = adminService.findAll(pageInfo); 48 Page<Admin> admins = adminService.findAll(pageInfo);
@@ -73,4 +81,17 @@ public class AdminController { @@ -73,4 +81,17 @@ public class AdminController {
73 adminService.delete(id); 81 adminService.delete(id);
74 return ResponseEntity.noContent().build(); 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
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +package com.srh.api.controller;
  2 +
  3 +public class ForgetPasswordController {
  4 +}
codigos/backend/src/main/java/com/srh/api/controller/LoginAdminController.java 0 → 100644
@@ -0,0 +1,29 @@ @@ -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 @@ @@ -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 package com.srh.api.controller; 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 import com.srh.api.hypermedia.ProjectModelAssembler; 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 import com.srh.api.service.ProjectService; 6 import com.srh.api.service.ProjectService;
11 import com.srh.api.utils.PageUtil; 7 import com.srh.api.utils.PageUtil;
12 import lombok.SneakyThrows; 8 import lombok.SneakyThrows;
@@ -42,6 +38,18 @@ public class ProjectController { @@ -42,6 +38,18 @@ public class ProjectController {
42 @Autowired 38 @Autowired
43 private PagedResourcesAssembler<ItemDto> itemDtoPagedResourcesAssembler; 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 @GetMapping 53 @GetMapping
46 public PagedModel<EntityModel<ProjectDto>> listAll(@PageableDefault(page = 0, size = 5) 54 public PagedModel<EntityModel<ProjectDto>> listAll(@PageableDefault(page = 0, size = 5)
47 Pageable pageInfo) { 55 Pageable pageInfo) {
@@ -89,9 +97,61 @@ public class ProjectController { @@ -89,9 +97,61 @@ public class ProjectController {
89 @PathVariable Integer projectId, 97 @PathVariable Integer projectId,
90 @PageableDefault(page = 0, size = 5) Pageable pageInfo 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 return itemDtoPagedResourcesAssembler.toModel(ItemDto.convert(pageUtil.getPage())); 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 package com.srh.api.controller; 1 package com.srh.api.controller;
2 2
  3 +import com.srh.api.algorithms.structure.RecommendationsByUser;
3 import com.srh.api.dto.resource.RecommendationDto; 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 import com.srh.api.hypermedia.RecommendationModelAssembler; 7 import com.srh.api.hypermedia.RecommendationModelAssembler;
5 import com.srh.api.model.Recommendation; 8 import com.srh.api.model.Recommendation;
6 import com.srh.api.service.RecommendationService; 9 import com.srh.api.service.RecommendationService;
@@ -15,6 +18,10 @@ import org.springframework.http.ResponseEntity; @@ -15,6 +18,10 @@ import org.springframework.http.ResponseEntity;
15 import org.springframework.web.bind.annotation.*; 18 import org.springframework.web.bind.annotation.*;
16 19
17 import javax.transaction.Transactional; 20 import javax.transaction.Transactional;
  21 +import javax.validation.Valid;
  22 +
  23 +import java.util.ArrayList;
  24 +import java.util.List;
18 25
19 import static com.srh.api.dto.resource.RecommendationDto.convert; 26 import static com.srh.api.dto.resource.RecommendationDto.convert;
20 27
@@ -43,6 +50,19 @@ public class RecommendationController { @@ -43,6 +50,19 @@ public class RecommendationController {
43 return recommendationModelAssembler.toModel(new RecommendationDto(recommendation)); 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 @DeleteMapping("/{id}") 66 @DeleteMapping("/{id}")
47 @Transactional 67 @Transactional
48 public ResponseEntity<Void> delete(@PathVariable Integer id) { 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,8 +2,10 @@ package com.srh.api.dto.resource;
2 2
3 import com.srh.api.builder.ItemBuilder; 3 import com.srh.api.builder.ItemBuilder;
4 import com.srh.api.builder.ProjectBuilder; 4 import com.srh.api.builder.ProjectBuilder;
  5 +import com.srh.api.builder.TypeItemBuilder;
5 import com.srh.api.model.Item; 6 import com.srh.api.model.Item;
6 import com.srh.api.model.Project; 7 import com.srh.api.model.Project;
  8 +import com.srh.api.model.TypeItem;
7 import lombok.AllArgsConstructor; 9 import lombok.AllArgsConstructor;
8 import lombok.Getter; 10 import lombok.Getter;
9 import lombok.NoArgsConstructor; 11 import lombok.NoArgsConstructor;
@@ -29,11 +31,26 @@ public class ItemForm { @@ -29,11 +31,26 @@ public class ItemForm {
29 @NotNull 31 @NotNull
30 private Integer projectId; 32 private Integer projectId;
31 33
  34 + private Integer typeItemId;
  35 +
32 public Item build() { 36 public Item build() {
33 Project project = ProjectBuilder.aProject() 37 Project project = ProjectBuilder.aProject()
34 .withId(projectId) 38 .withId(projectId)
35 .build(); 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 return ItemBuilder.anItem() 54 return ItemBuilder.anItem()
38 .withName(name) 55 .withName(name)
39 .withDescription(description) 56 .withDescription(description)
codigos/backend/src/main/java/com/srh/api/dto/resource/LoginClientForm.java 0 → 100644
@@ -0,0 +1,24 @@ @@ -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
@@ -51,6 +51,7 @@ public class ProjectForm { @@ -51,6 +51,7 @@ public class ProjectForm {
51 .withSituation(Situations.valueOf(situation)) 51 .withSituation(Situations.valueOf(situation))
52 .withDate(LocalDate.now()) 52 .withDate(LocalDate.now())
53 .withVisible(visible) 53 .withVisible(visible)
  54 + .withLastMatrixId(0)
54 .build(); 55 .build();
55 } 56 }
56 } 57 }
codigos/backend/src/main/java/com/srh/api/dto/resource/RecommendationForm.java 0 → 100644
@@ -0,0 +1,28 @@ @@ -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 @@ @@ -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
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +package com.srh.api.error.exception;
  2 +
  3 +public class InvalidAlgorithmRecommendationException extends Exception {
  4 + public InvalidAlgorithmRecommendationException(String message) {
  5 + super(message);
  6 + }
  7 +}
codigos/backend/src/main/java/com/srh/api/error/exception/InvalidLoginUserException.java 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +package com.srh.api.error.exception;
  2 +
  3 +public class InvalidLoginUserException extends Exception {
  4 + public InvalidLoginUserException() {
  5 + super();
  6 + }
  7 +}
codigos/backend/src/main/java/com/srh/api/error/exception/InvalidPasswordUserException.java 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +package com.srh.api.error.exception;
  2 +
  3 +public class InvalidPasswordUserException extends Exception {
  4 + public InvalidPasswordUserException() {
  5 + super();
  6 + }
  7 +}
codigos/backend/src/main/java/com/srh/api/error/handler/FormHandler.java
@@ -19,7 +19,7 @@ public class FormHandler { @@ -19,7 +19,7 @@ public class FormHandler {
19 @Autowired 19 @Autowired
20 private MessageSource messageSource; 20 private MessageSource messageSource;
21 21
22 - @ResponseStatus(code = HttpStatus.BAD_REQUEST) 22 + @ResponseStatus(code = HttpStatus.UNPROCESSABLE_ENTITY)
23 @ExceptionHandler(MethodArgumentNotValidException.class) 23 @ExceptionHandler(MethodArgumentNotValidException.class)
24 public List<FormErrorDto> handle(MethodArgumentNotValidException exception) { 24 public List<FormErrorDto> handle(MethodArgumentNotValidException exception) {
25 List<FormErrorDto> dtos = new ArrayList<>(); 25 List<FormErrorDto> dtos = new ArrayList<>();
codigos/backend/src/main/java/com/srh/api/error/handler/InvaliLoginUserHandler.java 0 → 100644
@@ -0,0 +1,20 @@ @@ -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 @@ @@ -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 @@ @@ -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
@@ -17,6 +17,7 @@ public class Project { @@ -17,6 +17,7 @@ public class Project {
17 private String description; 17 private String description;
18 private LocalDate date; 18 private LocalDate date;
19 private Boolean visible; 19 private Boolean visible;
  20 + private Integer lastMatrixId;
20 21
21 @Enumerated(EnumType.STRING) 22 @Enumerated(EnumType.STRING)
22 private Situations situation; 23 private Situations situation;
codigos/backend/src/main/java/com/srh/api/model/Recommendation.java
@@ -16,6 +16,7 @@ public class Recommendation { @@ -16,6 +16,7 @@ public class Recommendation {
16 private Double weight; 16 private Double weight;
17 private LocalDateTime date; 17 private LocalDateTime date;
18 private Integer runtimeInSeconds; 18 private Integer runtimeInSeconds;
  19 + private Integer matrixId;
19 20
20 @ManyToOne 21 @ManyToOne
21 private Algorithm algorithm; 22 private Algorithm algorithm;
codigos/backend/src/main/java/com/srh/api/model/TypeItem.java
@@ -12,6 +12,7 @@ public class TypeItem { @@ -12,6 +12,7 @@ public class TypeItem {
12 @GeneratedValue(strategy = GenerationType.IDENTITY) 12 @GeneratedValue(strategy = GenerationType.IDENTITY)
13 private Integer id; 13 private Integer id;
14 14
  15 + @Column(unique = true)
15 private String name; 16 private String name;
16 17
17 @OneToMany(mappedBy = "typeItem") 18 @OneToMany(mappedBy = "typeItem")
codigos/backend/src/main/java/com/srh/api/repository/AdminRepository.java
@@ -3,5 +3,8 @@ package com.srh.api.repository; @@ -3,5 +3,8 @@ package com.srh.api.repository;
3 import com.srh.api.model.Admin; 3 import com.srh.api.model.Admin;
4 import org.springframework.data.repository.PagingAndSortingRepository; 4 import org.springframework.data.repository.PagingAndSortingRepository;
5 5
  6 +import java.util.Optional;
  7 +
6 public interface AdminRepository extends PagingAndSortingRepository<Admin, Integer> { 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,5 +3,8 @@ package com.srh.api.repository;
3 import com.srh.api.model.Evaluator; 3 import com.srh.api.model.Evaluator;
4 import org.springframework.data.repository.PagingAndSortingRepository; 4 import org.springframework.data.repository.PagingAndSortingRepository;
5 5
  6 +import java.util.Optional;
  7 +
6 public interface EvaluatorRepository extends PagingAndSortingRepository<Evaluator, Integer> { 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 package com.srh.api.repository; 1 package com.srh.api.repository;
2 2
3 import com.srh.api.model.Item; 3 import com.srh.api.model.Item;
  4 +import com.srh.api.model.Project;
4 import org.springframework.data.repository.PagingAndSortingRepository; 5 import org.springframework.data.repository.PagingAndSortingRepository;
5 6
  7 +import java.util.List;
  8 +
6 public interface ItemRepository extends PagingAndSortingRepository<Item, Integer> { 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 package com.srh.api.service; 1 package com.srh.api.service;
2 2
3 import com.srh.api.model.Admin; 3 import com.srh.api.model.Admin;
  4 +import com.srh.api.model.Project;
4 import com.srh.api.repository.AdminRepository; 5 import com.srh.api.repository.AdminRepository;
5 import com.srh.api.utils.PasswordUtil; 6 import com.srh.api.utils.PasswordUtil;
6 import lombok.SneakyThrows; 7 import lombok.SneakyThrows;
@@ -10,6 +11,7 @@ import org.springframework.data.domain.Page; @@ -10,6 +11,7 @@ import org.springframework.data.domain.Page;
10 import org.springframework.data.domain.Pageable; 11 import org.springframework.data.domain.Pageable;
11 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
12 13
  14 +import java.util.List;
13 import java.util.Optional; 15 import java.util.Optional;
14 16
15 @Service 17 @Service
@@ -49,4 +51,19 @@ public class AdminService { @@ -49,4 +51,19 @@ public class AdminService {
49 find(id); 51 find(id);
50 adminRepository.deleteById(id); 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,6 +9,7 @@ import org.springframework.data.domain.Page;
9 import org.springframework.data.domain.Pageable; 9 import org.springframework.data.domain.Pageable;
10 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
11 11
  12 +import java.util.List;
12 import java.util.Optional; 13 import java.util.Optional;
13 14
14 @Service 15 @Service
@@ -31,6 +32,10 @@ public class EvaluatorService { @@ -31,6 +32,10 @@ public class EvaluatorService {
31 return evaluatorRepository.findAll(pageInfo); 32 return evaluatorRepository.findAll(pageInfo);
32 } 33 }
33 34
  35 + public Iterable<Evaluator> listAll() {
  36 + return evaluatorRepository.findAll();
  37 + }
  38 +
34 public Evaluator save(Evaluator evaluator) { 39 public Evaluator save(Evaluator evaluator) {
35 Evaluator evaluatorEncoded = passwordUtil.encodedPasswordForUser(evaluator); 40 Evaluator evaluatorEncoded = passwordUtil.encodedPasswordForUser(evaluator);
36 return evaluatorRepository.save(evaluatorEncoded); 41 return evaluatorRepository.save(evaluatorEncoded);
@@ -52,4 +57,13 @@ public class EvaluatorService { @@ -52,4 +57,13 @@ public class EvaluatorService {
52 find(id); 57 find(id);
53 evaluatorRepository.deleteById(id); 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,7 +37,12 @@ public class ItemService {
37 return itemRepository.findAll(pageInfo); 37 return itemRepository.findAll(pageInfo);
38 } 38 }
39 39
  40 + @SneakyThrows
40 public Item save(Item item) { 41 public Item save(Item item) {
  42 + if (!itemProjectIsOpenAndVisible(item)) {
  43 + throw new ProjectNotOpenedException("The project is closed or invisible");
  44 + }
  45 +
41 return itemRepository.save(item); 46 return itemRepository.save(item);
42 } 47 }
43 48
codigos/backend/src/main/java/com/srh/api/service/LoginClientDto.java 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +package com.srh.api.service;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +
  6 +@Getter
  7 +@AllArgsConstructor
  8 +public class LoginClientDto {
  9 + private final Boolean validUser;
  10 + private Integer userId;
  11 +}
codigos/backend/src/main/java/com/srh/api/service/LoginClientService.java 0 → 100644
@@ -0,0 +1,77 @@ @@ -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 package com.srh.api.service; 1 package com.srh.api.service;
2 2
3 import com.srh.api.error.exception.ChangeRootRelationException; 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 import com.srh.api.repository.ProjectRepository; 5 import com.srh.api.repository.ProjectRepository;
7 import lombok.SneakyThrows; 6 import lombok.SneakyThrows;
8 import org.hibernate.ObjectNotFoundException; 7 import org.hibernate.ObjectNotFoundException;
@@ -11,6 +10,8 @@ import org.springframework.data.domain.Page; @@ -11,6 +10,8 @@ import org.springframework.data.domain.Page;
11 import org.springframework.data.domain.Pageable; 10 import org.springframework.data.domain.Pageable;
12 import org.springframework.stereotype.Service; 11 import org.springframework.stereotype.Service;
13 12
  13 +import java.util.ArrayList;
  14 +import java.util.List;
14 import java.util.Optional; 15 import java.util.Optional;
15 16
16 @Service 17 @Service
@@ -57,4 +58,55 @@ public class ProjectService { @@ -57,4 +58,55 @@ public class ProjectService {
57 find(id); 58 find(id);
58 projectRepository.deleteById(id); 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 package com.srh.api.service; 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 import com.srh.api.model.Recommendation; 8 import com.srh.api.model.Recommendation;
4 import com.srh.api.repository.RecommendationRepository; 9 import com.srh.api.repository.RecommendationRepository;
5 import org.hibernate.ObjectNotFoundException; 10 import org.hibernate.ObjectNotFoundException;
@@ -8,6 +13,8 @@ import org.springframework.data.domain.Page; @@ -8,6 +13,8 @@ import org.springframework.data.domain.Page;
8 import org.springframework.data.domain.Pageable; 13 import org.springframework.data.domain.Pageable;
9 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
10 15
  16 +import java.util.ArrayList;
  17 +import java.util.List;
11 import java.util.Optional; 18 import java.util.Optional;
12 19
13 @Service 20 @Service
@@ -41,4 +48,9 @@ public class RecommendationService { @@ -41,4 +48,9 @@ public class RecommendationService {
41 find(id); 48 find(id);
42 recommendationRepository.deleteById(id); 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&lt;T extends User&gt; { @@ -23,6 +23,10 @@ public class PasswordUtil&lt;T extends User&gt; {
23 return encodedPasswordForUser(newUser, newRawPassword); 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 private T encodedPasswordForUser(T user, String newRawPassword) { 30 private T encodedPasswordForUser(T user, String newRawPassword) {
27 String encodedPassword = BcriptyUtil.encripty(newRawPassword); 31 String encodedPassword = BcriptyUtil.encripty(newRawPassword);
28 user.setPassword(encodedPassword); 32 user.setPassword(encodedPassword);
@@ -40,8 +44,4 @@ public class PasswordUtil&lt;T extends User&gt; { @@ -40,8 +44,4 @@ public class PasswordUtil&lt;T extends User&gt; {
40 throw new NotEqualsPasswordException("A senha antiga não confere com a cadastrada"); 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 # Profile 1 # Profile
2 -spring.profiles.active=test 2 +spring.profiles.active=dev
3 3
4 # jwt 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 srh.jwt.expiration=86400000 6 srh.jwt.expiration=86400000
7 7
8 # actuator 8 # actuator
@@ -14,3 +14,10 @@ info.app.version=@project.version@ @@ -14,3 +14,10 @@ info.app.version=@project.version@
14 info.app.encoding=@project.build.sourceEncoding@ 14 info.app.encoding=@project.build.sourceEncoding@
15 info.app.java.version=@java.version@ 15 info.app.java.version=@java.version@
16 16
  17 +#mail
  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 \ No newline at end of file 24 \ No newline at end of file
codigos/frontend/.eslintrc.js
  1 +const { resolve } = require('path');
  2 +
1 module.exports = { 3 module.exports = {
2 // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy 4 // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
3 // This option interrupts the configuration hierarchy at this file 5 // This option interrupts the configuration hierarchy at this file
4 // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos) 6 // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
5 root: true, 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 parserOptions: { 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 ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features 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 // Rules order is important, please avoid shuffling them 24 // Rules order is important, please avoid shuffling them
18 extends: [ 25 extends: [
19 // Base ESLint recommended rules 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 plugins: [ 48 plugins: [
  49 + // required to apply rules which need type information
  50 + '@typescript-eslint',
  51 +
35 // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file 52 // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-file
36 // required to lint *.vue files 53 // required to lint *.vue files
37 'vue', 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 // add your custom rules here 57 // add your custom rules here
51 rules: { 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,6 +2,6 @@
2 "vetur.validation.template": false, 2 "vetur.validation.template": false,
3 "vetur.format.enable": false, 3 "vetur.format.enable": false,
4 "eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"], 4 "eslint.validate": ["javascript", "javascriptreact", "typescript", "vue"],
5 - 5 + "typescript.tsdk": "node_modules/typescript/lib",
6 "vetur.experimental.templateInterpolationService": true 6 "vetur.experimental.templateInterpolationService": true
7 } 7 }
codigos/frontend/README.md
1 -# SRH Frontend Admin (srh-frontend-admin) 1 +# SRH Admin Client (srh-admin-client)
2 2
3 -A admin client from System Recommendation Hybrid 3 +A client for SRH
4 4
5 ## Install the dependencies 5 ## Install the dependencies
6 ```bash 6 ```bash
codigos/frontend/babel.config.js
1 - 1 +/* eslint-env node */
2 module.exports = { 2 module.exports = {
3 presets: [ 3 presets: [
4 - '@quasar/babel-preset-app'  
5 - ]  
6 -} 4 + '@quasar/babel-preset-app',
  5 + ],
  6 +};
codigos/frontend/package.json
1 { 1 {
2 - "name": "srh-frontend-admin", 2 + "name": "srh-admin-client",
3 "version": "0.0.1", 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 "author": "Herik dos Santos Lorenção <heriksantoslorencao@gmail.com>", 6 "author": "Herik dos Santos Lorenção <heriksantoslorencao@gmail.com>",
7 "private": true, 7 "private": true,
8 "scripts": { 8 "scripts": {
9 "lint": "eslint --ext .js,.vue ./", 9 "lint": "eslint --ext .js,.vue ./",
10 "test": "echo \"No test specified\" && exit 0", 10 "test": "echo \"No test specified\" && exit 0",
11 - "dev": "quasar dev --port 3000", 11 + "dev": "quasar dev",
12 "build": "quasar build", 12 "build": "quasar build",
13 "build:pwa": "quasar build -m pwa" 13 "build:pwa": "quasar build -m pwa"
14 }, 14 },
15 "dependencies": { 15 "dependencies": {
16 "@quasar/extras": "^1.0.0", 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 "core-js": "^3.6.5", 20 "core-js": "^3.6.5",
  21 + "jsonwebtoken": "^8.5.1",
19 "quasar": "^1.0.0", 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 "devDependencies": { 27 "devDependencies": {
23 "@quasar/app": "^2.0.0", 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 "babel-eslint": "^10.0.1", 32 "babel-eslint": "^10.0.1",
25 "eslint": "^6.8.0", 33 "eslint": "^6.8.0",
26 - "eslint-config-standard": "^14.1.0", 34 + "eslint-config-airbnb-base": "^14.0.0",
27 "eslint-loader": "^3.0.3", 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 "eslint-plugin-vue": "^6.1.2" 37 "eslint-plugin-vue": "^6.1.2"
33 }, 38 },
34 "browserslist": [ 39 "browserslist": [
codigos/frontend/quasar.conf.js
@@ -6,190 +6,206 @@ @@ -6,190 +6,206 @@
6 // Configuration for your app 6 // Configuration for your app
7 // https://quasar.dev/quasar-cli/quasar-conf-js 7 // https://quasar.dev/quasar-cli/quasar-conf-js
8 /* eslint-env node */ 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 cfg.module.rules.push({ 75 cfg.module.rules.push({
68 enforce: 'pre', 76 enforce: 'pre',
69 test: /\.(js|vue)$/, 77 test: /\.(js|vue)$/,
70 loader: 'eslint-loader', 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 <template> 1 <template>
2 <div id="q-app"> 2 <div id="q-app">
3 - <router-view/> 3 + <router-view />
4 </div> 4 </div>
5 </template> 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 </script> 11 </script>
codigos/frontend/src/assets/ifes-logo.png 0 → 100644

68.3 KB

codigos/frontend/src/boot/loginAdminRouteGuard.js 0 → 100644
@@ -0,0 +1,24 @@ @@ -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 +}
codigos/frontend/src/boot/loginRouteGuard.js 0 → 100644
@@ -0,0 +1,18 @@ @@ -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 +}
codigos/frontend/src/components/menu/Menu.vue 0 → 100644
@@ -0,0 +1,33 @@ @@ -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 @@ @@ -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 @@ @@ -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 +}
codigos/frontend/src/css/app.variables.scss 0 → 100644
@@ -0,0 +1,20 @@ @@ -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;
codigos/frontend/src/css/pages/index.scss 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +.home-title {
  2 + color: $white;
  3 + font-size: $font-h1-small;
  4 + margin-top: 50px;
  5 + margin-bottom: 50px;
  6 +}
  7 +
  8 +.info {
  9 + width: 100%;
  10 +
  11 + .card {
  12 + width: 42%;
  13 + height: 350px;
  14 + }
  15 +}
codigos/frontend/src/css/pages/login.scss 0 → 100644
@@ -0,0 +1,25 @@ @@ -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 +
codigos/frontend/src/css/pages/projects.scss 0 → 100644
@@ -0,0 +1,97 @@ @@ -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/pages/users.scss 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +.info-users {
  2 + width: 100%;
  3 +
  4 + .card {
  5 + width: 45%;
  6 + }
  7 +
  8 + .info-fields {
  9 + font-size: $font-text;
  10 + width: 80%;
  11 +
  12 + div {
  13 + margin-bottom: 10px;
  14 + }
  15 +
  16 + .label {
  17 + color: $yellow-orange;
  18 + }
  19 + }
  20 +}
codigos/frontend/src/css/quasar.variables.scss
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 // It's highly recommended to change the default colors 11 // It's highly recommended to change the default colors
12 // to match your app's branding. 12 // to match your app's branding.
13 // Tip: Use the "Theme Builder" on Quasar's documentation website. 13 // Tip: Use the "Theme Builder" on Quasar's documentation website.
  14 +@import "app.variables";
14 15
15 $primary : #1976D2; 16 $primary : #1976D2;
16 $secondary : #26A69A; 17 $secondary : #26A69A;
@@ -22,13 +23,3 @@ $positive : #21BA45; @@ -22,13 +23,3 @@ $positive : #21BA45;
22 $negative : #C10015; 23 $negative : #C10015;
23 $info : #31CCEC; 24 $info : #31CCEC;
24 $warning : #F2C037; 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;  
codigos/frontend/src/env.d.ts 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +declare namespace NodeJS {
  2 + interface ProcessEnv {
  3 + NODE_ENV: string;
  4 + VUE_ROUTER_MODE: 'hash' | 'history' | 'abstract' | undefined;
  5 + VUE_ROUTER_BASE: string | undefined;
  6 + }
  7 +}
codigos/frontend/src/layouts/LoginLayout.vue 0 → 100644
@@ -0,0 +1,19 @@ @@ -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>
codigos/frontend/src/layouts/MainLayout.vue 0 → 100644
@@ -0,0 +1,99 @@ @@ -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>
codigos/frontend/src/mixins/itemMenuList.ts 0 → 100644
@@ -0,0 +1,71 @@ @@ -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;
codigos/frontend/src/mixins/notification.ts 0 → 100644
@@ -0,0 +1,12 @@ @@ -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 +}
codigos/frontend/src/mixins/tableInfo/listProject.ts 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +export default {
  2 + pagination: {
  3 + sortBy: 'desc',
  4 + descending: false,
  5 + page: 1,
  6 + rowsPerPage: 3
  7 + },
  8 + columns: [
  9 + {
  10 + name: 'name',
  11 + field: 'name',
  12 + label: 'Nome',
  13 + align: 'center',
  14 + sortable: true
  15 + }
  16 + ]
  17 +}
codigos/frontend/src/mixins/tableInfo/listUser.ts 0 → 100644
@@ -0,0 +1,25 @@ @@ -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 +}
codigos/frontend/src/models/Admin.ts 0 → 100644
@@ -0,0 +1,57 @@ @@ -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 +}
codigos/frontend/src/models/FormRequest.ts 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +import {ParseItem} from "src/models/models";
  2 +
  3 +export default abstract class FormRequest {
  4 + build(): object {
  5 + return {}
  6 + }
  7 +
  8 + public parseNames: ParseItem[] = [];
  9 +}
codigos/frontend/src/models/Login.ts 0 → 100644
@@ -0,0 +1,37 @@ @@ -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 +}