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

68.3 KB

codigos/frontend/src/boot/loginAdminRouteGuard.js 0 → 100644
... ... @@ -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 @@
  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 @@
  1 +<template>
  2 + <q-list>
  3 + <q-item class="item-list-menu column">
  4 + <ItemMenu v-for="item in menuList" :key="item.id" :path="item.path" :label="item.label"
  5 + :icon="item.icon" :selectedItemMenu="selectedItemMenu" :items="item.subitems"
  6 + @selectedItem="changeSelectedItemMenu" />
  7 + </q-item>
  8 + </q-list>
  9 +</template>
  10 +
  11 +<script lang="ts">
  12 +import {Vue, Component} from 'vue-property-decorator';
  13 +import ItemMenu from "./components/ItemMenu.vue";
  14 +import itemMenuList from '../../mixins/itemMenuList';
  15 +
  16 +@Component({
  17 + components: {ItemMenu}
  18 +})
  19 +export default class Menu extends Vue {
  20 + readonly menuList = itemMenuList;
  21 + selectedItemMenu = ""
  22 +
  23 + changeSelectedItemMenu(value: string) {
  24 + this.selectedItemMenu = value;
  25 + }
  26 +}
  27 +</script>
  28 +
  29 +<style lang="scss" scoped>
  30 +.item-list-menu {
  31 + padding: 0;
  32 +}
  33 +</style>
... ...
codigos/frontend/src/components/menu/components/ItemMenu.vue 0 → 100644
... ... @@ -0,0 +1,137 @@
  1 +<template>
  2 + <div class="column">
  3 + <div class="column">
  4 + <q-item class="col-12" clickable @click="openSubMenuOrItem" :class="generateCssClass()">
  5 + <q-item-section class="col-2 icon">
  6 + <q-icon :name="icon"/>
  7 + </q-item-section>
  8 + <q-item-section class="col-10 justify-start label">
  9 + <q-item-label>
  10 + {{ label }}
  11 + </q-item-label>
  12 + </q-item-section>
  13 + </q-item>
  14 + </div>
  15 + <div class="column" v-show="items && subMenuVisible">
  16 + <SubItemMenu v-for="subitem in items" :icon="subitem.icon" :label="subitem.label"
  17 + :path="subitem.path" :key="subitem.id" :selected-item-menu="selectedItemMenu"
  18 + :itemId="itemId" @selectedItem="emitSelectedItem"
  19 + />
  20 + </div>
  21 + </div>
  22 +</template>
  23 +
  24 +<script lang="ts">
  25 +import {Vue, Component, Prop, Emit} from 'vue-property-decorator';
  26 +import SubItemMenu from "components/menu/components/SubItemMenu.vue";
  27 +import {SubItem} from "src/models/models";
  28 +
  29 +@Component({
  30 + components: {SubItemMenu}
  31 +})
  32 +export default class ItemMenu extends Vue {
  33 + @Prop({type: String, required: true})
  34 + readonly label !: string;
  35 +
  36 + @Prop({type: String, required: true})
  37 + readonly path !: string;
  38 +
  39 + @Prop({type: String, required: true})
  40 + readonly icon !: string;
  41 +
  42 + @Prop({type: String, required: true})
  43 + selectedItemMenu !: string;
  44 +
  45 + @Prop({type: Array, required: true})
  46 + readonly items !: SubItem[];
  47 +
  48 + itemId = 0;
  49 + subMenuVisible = false;
  50 +
  51 + get isSelectedItemMenu() {
  52 + const isSelectedItem = this.selectedItemMenu === this.label ||
  53 + this.selectedItemMenu === this.path;
  54 +
  55 + let subItemSelected = false;
  56 +
  57 + this.items.forEach(subitem => {
  58 + if (subitem.path === this.selectedItemMenu)
  59 + subItemSelected = true;
  60 + })
  61 +
  62 + return isSelectedItem || subItemSelected;
  63 + }
  64 +
  65 + @Emit('selectedItem')
  66 + openSubMenuOrItem() {
  67 + if (this.$route.path !== this.path) {
  68 + this.$router.push(this.path)
  69 + }
  70 +
  71 + // TODO: Pegar Item Id pelo Vuex e definir aqui
  72 + // this.itemId = Vuex.get()
  73 +
  74 + this.subMenuVisible = !this.subMenuVisible;
  75 + if (this.itemId) {
  76 + }
  77 +
  78 + return this.path;
  79 + }
  80 +
  81 + @Emit('selectedItem')
  82 + emitSelectedItem(event: any) {
  83 + return event;
  84 + }
  85 +
  86 + generateCssClass(): string {
  87 + if (!this.isSelectedItemMenu) {
  88 + this.subMenuVisible = false;
  89 + }
  90 +
  91 + return this.isSelectedItemMenu ? 'item-menu selected' : 'item-menu no-selected'
  92 + }
  93 +
  94 + mounted() {
  95 + this.itemId = this.$store.getters['navigationInfo/projectId'];
  96 + }
  97 +}
  98 +</script>
  99 +
  100 +<style lang="scss" scoped>
  101 +.item-menu {
  102 + .icon {
  103 + font-size: $font-h1;
  104 + }
  105 +
  106 + .label {
  107 + font-size: $font-normal;
  108 + }
  109 +}
  110 +
  111 +.no-selected {
  112 + background-color: $white;
  113 + color: $gunmetal;
  114 +
  115 + .icon {
  116 + color: $yellow-orange;
  117 + }
  118 +}
  119 +
  120 +.no-selected:hover {
  121 + background-color: $yellow-orange;
  122 + color: $white;
  123 +
  124 + .icon {
  125 + color: $white;
  126 + }
  127 +}
  128 +
  129 +.selected {
  130 + background-color: $gunmetal-2;
  131 + color: $white;
  132 +
  133 + .icon {
  134 + color: $yellow-orange;
  135 + }
  136 +}
  137 +</style>
... ...
codigos/frontend/src/components/menu/components/SubItemMenu.vue 0 → 100644
... ... @@ -0,0 +1,92 @@
  1 +<template>
  2 + <q-item class="col-12" clickable @click="navigateTo" :class="generateCssClass()">
  3 + <div class="content row">
  4 + <q-item-section class="col-2 icon">
  5 + <q-icon :name="icon"/>
  6 + </q-item-section>
  7 + <q-item-section class="col-10 justify-start label">
  8 + <q-item-label>
  9 + {{ label }}
  10 + </q-item-label>
  11 + </q-item-section>
  12 + </div>
  13 + </q-item>
  14 +</template>
  15 +
  16 +<script lang="ts">
  17 +import {Vue, Component, Prop, Emit} from 'vue-property-decorator';
  18 +
  19 +@Component
  20 +export default class SubItemMenu extends Vue {
  21 + @Prop({type: String, required: true})
  22 + readonly label !: string;
  23 +
  24 + @Prop({type: String, required: true})
  25 + readonly path !: string;
  26 +
  27 + @Prop({type: String, required: true})
  28 + readonly icon !: string;
  29 +
  30 + @Prop({type: Number, required: true})
  31 + readonly itemId !: number;
  32 +
  33 + @Prop({type: String, required: true})
  34 + selectedItemMenu !: string;
  35 +
  36 + get isSelectedItemMenu() {
  37 + return this.selectedItemMenu === this.label ||
  38 + this.selectedItemMenu === this.path;
  39 + }
  40 +
  41 + @Emit('selectedItem')
  42 + navigateTo() {
  43 + if (this.$route.path !== this.path) {
  44 + this.$router.push(this.path);
  45 + }
  46 + return this.path;
  47 + }
  48 +
  49 + generateCssClass(): string {
  50 + return this.isSelectedItemMenu ? 'subitem-menu selected-subitem' : 'subitem-menu no-selected-subitem'
  51 + }
  52 +}
  53 +</script>
  54 +
  55 +<style lang="scss" scoped>
  56 +.subitem-menu {
  57 + .content {
  58 + margin-left: 5%;
  59 + width: 100%;
  60 + flex-wrap: nowrap;
  61 + }
  62 +
  63 + .icon {
  64 + font-size: $font-h1;
  65 + }
  66 +
  67 + .label {
  68 + font-size: $font-normal;
  69 + }
  70 +}
  71 +
  72 +.no-selected-subitem {
  73 + .icon {
  74 + color: $yellow-orange;
  75 + }
  76 +}
  77 +
  78 +.no-selected-subitem:hover {
  79 + background-color: $yellow-orange;
  80 + color: $white;
  81 +
  82 + .icon {
  83 + color: $white;
  84 + }
  85 +}
  86 +
  87 +.selected-subitem {
  88 + background-color: $yellow-orange;
  89 + color: $white;
  90 +}
  91 +
  92 +</style>
... ...
codigos/frontend/src/css/app.scss
1   -// app global css in SCSS form
  1 +@import 'pages/login';
  2 +@import 'pages/index';
  3 +@import 'pages/projects';
  4 +@import 'pages/users';
  5 +
  6 +* {
  7 + font-family: 'Roboto', '-apple-system', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  8 +}
  9 +
  10 +.header-style {
  11 + background-color: $yellow-orange;
  12 + color: $white;
  13 + border: none;
  14 +}
  15 +
  16 +.side-menu {
  17 + min-height: 100%;
  18 +}
  19 +
  20 +.menu-logo {
  21 + width: 100%;
  22 + margin-bottom: 20px;
  23 +
  24 + .image-logo {
  25 + width: 60%;
  26 + margin-left: -10%;
  27 + }
  28 +}
  29 +
  30 +.menu-logo-ifes {
  31 + width: 100%;
  32 + padding-top: 30px;
  33 +
  34 + .image-logo {
  35 + width: 70%;
  36 + }
  37 +}
  38 +
  39 +.menu-user {
  40 + .btn {
  41 + margin-left: 10px;
  42 + border-radius: 0;
  43 + }
  44 +
  45 + .btn-logout {
  46 + padding: 0 30px;
  47 + border-radius: 10px;
  48 + background-color: $gunmetal;
  49 + }
  50 +}
  51 +
  52 +.page {
  53 + background-color: $yellow-orange-bg;
  54 +}
  55 +
  56 +.footer-style {
  57 + background-color: $yellow-orange-bg;
  58 + font-weight: 500;
  59 + height: 50px;
  60 +}
  61 +
  62 +.card {
  63 + border-radius: 20px;
  64 +
  65 + .card-header {
  66 + width: 100%;
  67 + text-align: center;
  68 + font-size: $font-normal;
  69 + }
  70 +}
... ...
codigos/frontend/src/css/app.variables.scss 0 → 100644
... ... @@ -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 @@
  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 @@
  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 @@
  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 @@
  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 11 // It's highly recommended to change the default colors
12 12 // to match your app's branding.
13 13 // Tip: Use the "Theme Builder" on Quasar's documentation website.
  14 +@import "app.variables";
14 15  
15 16 $primary : #1976D2;
16 17 $secondary : #26A69A;
... ... @@ -22,13 +23,3 @@ $positive : #21BA45;
22 23 $negative : #C10015;
23 24 $info : #31CCEC;
24 25 $warning : #F2C037;
25   -
26   -$tart-orange: #f94144ff;
27   -$orange-red: #f3722cff;
28   -$yellow-orange-color-wheel: #f8961eff;
29   -$maize-crayola: #f9c74fff;
30   -$pistachio: #90be6dff;
31   -$jungle-green: #43aa8bff;
32   -$queen-blue: #577590ff;
33   -$gunmetal: #27333dff;
34   -$gunmetal-2: #202931ff;
... ...
codigos/frontend/src/env.d.ts 0 → 100644
... ... @@ -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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 @@
  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 +}
... ...