Compare View

switch
from
...
to
 
Commits (2)
Showing 151 changed files   Show diff stats
.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 +}
... ...
codigos/frontend/src/models/Project.ts 0 → 100644
... ... @@ -0,0 +1,80 @@
  1 +import FormRequest from "src/models/FormRequest";
  2 +import {ParseItem} from "src/models/models";
  3 +
  4 +export default class Project extends FormRequest {
  5 + private _name: string;
  6 + private _description: string;
  7 + private _adminId: number;
  8 + private _situation: string;
  9 + private _visible: boolean;
  10 +
  11 + public parseNames: ParseItem[] = [
  12 + {
  13 + fieldName: 'name',
  14 + translation: 'nome'
  15 + },
  16 + {
  17 + fieldName: 'description',
  18 + translation: 'descrição'
  19 + }
  20 + ];
  21 +
  22 + constructor(name: string, description: string, adminId: number, situation: string, visible: boolean) {
  23 + super();
  24 + this._name = name;
  25 + this._description = description;
  26 + this._adminId = adminId;
  27 + this._situation = situation;
  28 + this._visible = visible;
  29 + }
  30 +
  31 + get name(): string {
  32 + return this._name;
  33 + }
  34 +
  35 + set name(value: string) {
  36 + this._name = value;
  37 + }
  38 +
  39 + get description(): string {
  40 + return this._description;
  41 + }
  42 +
  43 + set description(value: string) {
  44 + this._description = value;
  45 + }
  46 +
  47 + get adminId(): number {
  48 + return this._adminId;
  49 + }
  50 +
  51 + set adminId(value: number) {
  52 + this._adminId = value;
  53 + }
  54 +
  55 + get situation(): string {
  56 + return this._situation;
  57 + }
  58 +
  59 + set situation(value: string) {
  60 + this._situation = value;
  61 + }
  62 +
  63 + get visible(): boolean {
  64 + return this._visible;
  65 + }
  66 +
  67 + set visible(value: boolean) {
  68 + this._visible = value;
  69 + }
  70 +
  71 + public build(): object {
  72 + return {
  73 + name: this._name,
  74 + description: this._description,
  75 + adminId: this._adminId,
  76 + situation: this._situation,
  77 + visible: this._visible
  78 + };
  79 + }
  80 +}
... ...
codigos/frontend/src/models/User.ts 0 → 100644
... ... @@ -0,0 +1,72 @@
  1 +import FormRequest from "src/models/FormRequest";
  2 +import {ParseItem} from "src/models/models";
  3 +
  4 +export default class User extends FormRequest {
  5 + private _name: string;
  6 + private _login: string;
  7 + private _password: string;
  8 + private _email: string;
  9 +
  10 + public parseNames: ParseItem[] = [
  11 + {
  12 + fieldName: 'name',
  13 + translation: 'nome'
  14 + },
  15 + {
  16 + fieldName: 'description',
  17 + translation: 'descrição'
  18 + }
  19 + ];
  20 +
  21 +
  22 + constructor(name: string, login: string, password: string, email: string, parseNames: ParseItem[]) {
  23 + super();
  24 + this._name = name;
  25 + this._login = login;
  26 + this._password = password;
  27 + this._email = email;
  28 + this.parseNames = parseNames;
  29 + }
  30 +
  31 +
  32 + get name(): string {
  33 + return this._name;
  34 + }
  35 +
  36 + set name(value: string) {
  37 + this._name = value;
  38 + }
  39 +
  40 + get login(): string {
  41 + return this._login;
  42 + }
  43 +
  44 + set login(value: string) {
  45 + this._login = value;
  46 + }
  47 +
  48 + get password(): string {
  49 + return this._password;
  50 + }
  51 +
  52 + set password(value: string) {
  53 + this._password = value;
  54 + }
  55 +
  56 + get email(): string {
  57 + return this._email;
  58 + }
  59 +
  60 + set email(value: string) {
  61 + this._email = value;
  62 + }
  63 +
  64 + public build(): object {
  65 + return {
  66 + name: this._name,
  67 + login: this._login,
  68 + password: this._password,
  69 + email: this._email
  70 + }
  71 + }
  72 +}
... ...
codigos/frontend/src/models/models.ts 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +export interface SubItem {
  2 + id: number,
  3 + label: string,
  4 + path: string,
  5 + icon: string
  6 +}
  7 +
  8 +export interface ItemMenu {
  9 + id: number,
  10 + label: string,
  11 + path: string,
  12 + icon: string,
  13 + subitems: SubItem[]
  14 +}
  15 +
  16 +
  17 +export interface ParseItem {
  18 + fieldName: string,
  19 + translation: string
  20 +}
... ...
codigos/frontend/src/pages/Error404.vue
... ... @@ -22,8 +22,9 @@
22 22 </div>
23 23 </template>
24 24  
25   -<script >
26   -export default {
27   - name: 'Error404'
28   -}
  25 +<script lang="ts">
  26 +import { Vue, Component } from 'vue-property-decorator';
  27 +
  28 +@Component
  29 +export default class Error404 extends Vue {}
29 30 </script>
... ...
codigos/frontend/src/pages/Index.vue
1 1 <template>
2   - <q-page class="flex flex-center">
3   - <img
4   - alt="Quasar logo"
5   - src="~assets/quasar-logo-full.svg"
6   - >
  2 + <q-page class="column items-center justify-start page">
  3 + <div class="home-title">
  4 + Bem vindo Usuário!
  5 + </div>
  6 + <div class="info row justify-around">
  7 + <q-card flat bordered class="card">
  8 + <q-card-section>
  9 + <div class="card-header">Usuários que receberam recomendações</div>
  10 + </q-card-section>
  11 + </q-card>
  12 +
  13 + <q-card flat bordered class="card">
  14 + <q-card-section>
  15 + <div class="card-header">Usuários que receberam recomendações</div>
  16 + </q-card-section>
  17 + </q-card>
  18 + </div>
7 19 </q-page>
8 20 </template>
9 21  
10   -<script>
11   -export default {
12   - name: 'PageIndex'
  22 +<script lang="ts">
  23 +import { Vue, Component } from 'vue-property-decorator';
  24 +
  25 +@Component
  26 +export default class Index extends Vue {
13 27 }
14 28 </script>
... ...
codigos/frontend/src/pages/Login.vue 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +<template>
  2 + <q-page class="login-page column items-center justify-center page">
  3 + <q-card flat bordered class="card col-6">
  4 + <q-card-section class="column items-center">
  5 + <q-img class="login-logo" src="../assets/logo/loginLogo.png" />
  6 + </q-card-section>
  7 + <q-card-section class="form column items-center">
  8 + <q-input v-model="username" color="orange" placeholder="Login">
  9 + <template v-slot:prepend>
  10 + <q-icon name="person" />
  11 + </template>
  12 + </q-input>
  13 + <q-input v-model="password" color="orange" placeholder="Senha" type="password">
  14 + <template v-slot:prepend>
  15 + <q-icon name="vpn_key" />
  16 + </template>
  17 + </q-input>
  18 + </q-card-section>
  19 + <q-card-section class="column items-center">
  20 + <q-btn @click="logInto" class="login-btn" label="Entrar" no-caps />
  21 + <router-link class="forget-password" to="cadastrar">
  22 + Esqueceu a Senha?
  23 + </router-link>
  24 + </q-card-section>
  25 + </q-card>
  26 + </q-page>
  27 +</template>
  28 +
  29 +<script lang="ts">
  30 +import { Vue, Component } from 'vue-property-decorator';
  31 +import LoginService from "src/services/LoginService";
  32 +
  33 +@Component
  34 +export default class Login extends Vue{
  35 + username: string = '';
  36 + password: string = '';
  37 + loginService = new LoginService();
  38 +
  39 + async logInto() {
  40 + const logged = await this.loginService.login(this.username, this.password);
  41 +
  42 + if (logged) {
  43 + this.$router.push('/');
  44 + }
  45 + }
  46 +}
  47 +</script>
... ...
codigos/frontend/src/pages/Projects.vue 0 → 100644
... ... @@ -0,0 +1,79 @@
  1 +<template>
  2 + <q-page class="column items-center justify-center page">
  3 + <div v-show="initialMenuIsVisible" class="initial-menu-buttons row justify-around">
  4 + <div @click="createNewProject" class="project-btn column items-center">
  5 + <q-icon name="add_circle"/>
  6 + <span>Criar Projeto</span>
  7 + </div>
  8 + <div @click="showListProjectsPage" class="project-btn column items-center">
  9 + <q-icon name="edit"/>
  10 + <span>Listar Existentes</span>
  11 + </div>
  12 + </div>
  13 +
  14 + <div class="row justify-around create-project" v-if="createProjectIsVisible">
  15 + <CreateProject @projectCreated="hideCreateProjectPageAndShowList"></CreateProject>
  16 + </div>
  17 +
  18 + <div class="row justify-around create-project" v-if="listProjectsIsVisible">
  19 + <ListProjects @editProject="showEditProjectPage"/>
  20 + </div>
  21 +
  22 + <div class="row justify-around create-project" v-if="editProjectIsVisible">
  23 + <EditProject :projectData="projectEditInfo" />
  24 + </div>
  25 + </q-page>
  26 +</template>
  27 +
  28 +<script lang="ts">
  29 +import {Vue, Component} from 'vue-property-decorator';
  30 +import CreateProject from './projects/CreateProject.vue';
  31 +import ListProjects from './projects/ListProjects.vue';
  32 +import EditProject from "pages/projects/EditProject.vue";
  33 +
  34 +@Component({
  35 + components: {CreateProject, ListProjects, EditProject}
  36 +})
  37 +export default class Projects extends Vue {
  38 + initialMenuIsVisible: boolean = true;
  39 + createProjectIsVisible: boolean = false;
  40 + listProjectsIsVisible: boolean = false;
  41 + editProjectIsVisible: boolean = false;
  42 + projectEditInfo: any = {};
  43 +
  44 + hideInitialMenu() {
  45 + this.initialMenuIsVisible = false;
  46 + }
  47 +
  48 + showCreateProjectPage() {
  49 + this.hideInitialMenu();
  50 + this.createProjectIsVisible = true;
  51 + }
  52 +
  53 + showListProjectsPage() {
  54 + this.hideInitialMenu();
  55 + this.listProjectsIsVisible = true;
  56 + this.editProjectIsVisible = false;
  57 + }
  58 +
  59 + hideCreateProjectPageAndShowList() {
  60 + this.hideInitialMenu();
  61 + this.createProjectIsVisible = false;
  62 + this.editProjectIsVisible = false;
  63 + this.listProjectsIsVisible = true;
  64 + }
  65 +
  66 + showEditProjectPage(projectInfo: any) {
  67 + this.hideInitialMenu();
  68 + this.createProjectIsVisible = false;
  69 + this.editProjectIsVisible = true;
  70 + this.listProjectsIsVisible = false;
  71 +
  72 + this.projectEditInfo = projectInfo;
  73 + }
  74 +
  75 + createNewProject() {
  76 + this.showCreateProjectPage();
  77 + }
  78 +}
  79 +</script>
... ...
codigos/frontend/src/pages/projects/CreateProject.vue 0 → 100644
... ... @@ -0,0 +1,90 @@
  1 +<template>
  2 + <div class="row justify-around create-project">
  3 + <q-card flat bordered class="card col-6">
  4 + <q-card-section>
  5 + <div class="card-header">Criar Projeto</div>
  6 + </q-card-section>
  7 + <q-card-section class="form column justify-between items-center">
  8 + <div class="fields">
  9 + <div class="field">
  10 + <q-input v-model="projectForm.name" color="orange" label="Nome"
  11 + ref="nameInput"
  12 + placeholder="Informe o nome"/>
  13 + </div>
  14 + <div class="field-text">
  15 + <q-input v-model="projectForm.description" type="textarea" color="orange"
  16 + placeholder="Informe a descrição" label="Descrição" outlined
  17 + />
  18 + </div>
  19 + </div>
  20 + <q-btn @click="createProject" class="create-btn" label="Criar" no-caps/>
  21 + </q-card-section>
  22 + </q-card>
  23 +
  24 + <q-card flat bordered class="card col-4 project-attributes column items-center">
  25 + <q-card-section>
  26 + <div class="card-header">Atributos do Projeto</div>
  27 + </q-card-section>
  28 + <q-card-section class="fields column">
  29 + <div class="field column">
  30 + <p><span class="label">Status:</span> {{ projectStatus }}</p>
  31 + </div>
  32 + <div class="field column items-center">
  33 + <p><span class="label">Visibilidade:</span> {{ projectVisibility }}</p>
  34 + <q-btn @click="changeVisible" class="attribute-btn" :label="getVisibilityBtnLabel()"
  35 + no-caps/>
  36 + </div>
  37 + </q-card-section>
  38 + </q-card>
  39 + </div>
  40 +</template>
  41 +
  42 +<script>
  43 +import {Vue, Component, Prop} from 'vue-property-decorator';
  44 +import ProjectService from "src/services/ProjectService";
  45 +import Project from "src/models/Project";
  46 +
  47 +@Component
  48 +export default class CreateProject extends Vue {
  49 + projectForm = {
  50 + name: '',
  51 + description: '',
  52 + visible: false,
  53 + situation: 'OPEN',
  54 + adminId: this.$store.getters['login/getIdUsuario']
  55 + }
  56 +
  57 + get projectStatus() {
  58 + return this.projectForm.situation === 'OPEN' ? 'Aberto' : 'Fechado';
  59 + }
  60 +
  61 + get projectVisibility() {
  62 + return this.projectForm.visible ? 'Visível' : 'Invisível';
  63 + }
  64 +
  65 + getVisibilityBtnLabel() {
  66 + return this.projectForm.visible ? 'Tornar Invisível' : 'Tornar Visível';
  67 + }
  68 +
  69 + changeVisible() {
  70 + return this.projectForm.visible = !this.projectForm.visible;
  71 + }
  72 +
  73 + async createProject() {
  74 + const projectService = new ProjectService();
  75 + const projectForm = new Project(
  76 + this.projectForm.name,
  77 + this.projectForm.description,
  78 + this.projectForm.adminId,
  79 + this.projectForm.situation,
  80 + this.projectForm.visible
  81 + );
  82 +
  83 + const projectIsCreated = await projectService.create(projectForm);
  84 +
  85 + if (projectIsCreated !== false) {
  86 + this.$emit('projectCreated')
  87 + }
  88 + }
  89 +}
  90 +</script>
... ...
codigos/frontend/src/pages/projects/EditProject.vue 0 → 100644
... ... @@ -0,0 +1,109 @@
  1 +<template>
  2 + <div class="row justify-around create-project">
  3 + <q-card flat bordered class="card col-6">
  4 + <q-card-section>
  5 + <div class="card-header">Editar Projeto</div>
  6 + </q-card-section>
  7 + <q-card-section class="form column justify-between items-center">
  8 + <div class="fields">
  9 + <div class="field">
  10 + <q-input v-model="projectForm.name" color="orange" label="Nome"
  11 + ref="nameInput"
  12 + placeholder="Informe o nome"/>
  13 + </div>
  14 + <div class="field-text">
  15 + <q-input v-model="projectForm.description" type="textarea" color="orange"
  16 + placeholder="Informe a descrição" label="Descrição" outlined
  17 + />
  18 + </div>
  19 + </div>
  20 + <div class="actions-buttons">
  21 + <q-btn @click="editProject" class="create-btn" label="Remover" no-caps/>
  22 + <q-btn @click="editProject" class="create-btn" label="Salvar" no-caps/>
  23 + </div>
  24 + </q-card-section>
  25 + </q-card>
  26 +
  27 + <q-card flat bordered class="card col-4 project-attributes column items-center">
  28 + <q-card-section>
  29 + <div class="card-header">Atributos do Projeto</div>
  30 + </q-card-section>
  31 + <q-card-section class="fields column">
  32 + <div class="field column">
  33 + <p><span class="label">Status:</span> {{ projectStatus }}</p>
  34 + <q-btn @click="changeStatus" class="attribute-btn" :label="getStatusBtnLabel()"
  35 + no-caps/>
  36 + </div>
  37 + <div class="field column items-center">
  38 + <p><span class="label">Visibilidade:</span> {{ projectVisibility }}</p>
  39 + <q-btn @click="changeVisible" class="attribute-btn" :label="getVisibilityBtnLabel()"
  40 + no-caps/>
  41 + </div>
  42 + </q-card-section>
  43 + </q-card>
  44 + </div>
  45 +</template>
  46 +
  47 +<script lang="ts">
  48 +import {Vue, Component, Prop} from 'vue-property-decorator';
  49 +import ProjectService from "src/services/ProjectService";
  50 +import Project from "src/models/Project";
  51 +
  52 +@Component
  53 +export default class EditProject extends Vue {
  54 + @Prop({required: true, type: Object})
  55 + projectData: any;
  56 + projectForm: any = {}
  57 +
  58 + get projectStatus() {
  59 + return this.projectForm.situation === 'OPEN' ? 'Aberto' : 'Fechado';
  60 + }
  61 +
  62 + get projectVisibility() {
  63 + return this.projectForm.visible ? 'Visível' : 'Invisível';
  64 + }
  65 +
  66 + getVisibilityBtnLabel() {
  67 + return this.projectForm.visible ? 'Tornar Invisível' : 'Tornar Visível';
  68 + }
  69 +
  70 + getStatusBtnLabel() {
  71 + return this.projectForm.situation === 'OPEN' ? 'Fechar Projeto': 'Abrir Projeto';
  72 + }
  73 +
  74 + changeVisible() {
  75 + return this.projectForm.visible = !this.projectForm.visible;
  76 + }
  77 +
  78 + changeStatus() {
  79 + return this.projectForm.situation === 'OPEN' ? 'CLOSED': 'OPEN';
  80 + }
  81 +
  82 + async editProject() {
  83 + const projectService = new ProjectService();
  84 + const projectData = new Project(
  85 + this.projectForm.name,
  86 + this.projectForm.description,
  87 + this.projectForm.adminId,
  88 + this.projectForm.projectStatus,
  89 + this.projectForm.visible
  90 + );
  91 +
  92 + await projectService.update(projectData, this.projectData.id);
  93 + }
  94 +
  95 + async removeProject() {
  96 + const projectService = new ProjectService();
  97 + }
  98 +
  99 + created() {
  100 + this.projectForm = {
  101 + name: this.projectData.name,
  102 + description: this.projectData.description,
  103 + visible: this.projectData.visible,
  104 + situation: this.projectData.situation,
  105 + adminId: this.$store.getters['login/getIdUsuario']
  106 + }
  107 + }
  108 +}
  109 +</script>
... ...
codigos/frontend/src/pages/projects/ListProjects.vue 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +<template>
  2 + <div class="list-projects column justify-center items-center">
  3 + <q-card flat bordered class="card col-6">
  4 + <q-card-section>
  5 + <div class="card-header">Selecione o Projeto</div>
  6 + </q-card-section>
  7 + <q-card-section class="list-projects-content column justify-between items-center">
  8 + <q-table
  9 + class="projects-table"
  10 + row-key="id"
  11 + :data="tableInfo.data"
  12 + :columns="tableInfo.columns"
  13 + :pagination="tableInfo.pagination"
  14 + selection="single"
  15 + :selected.sync="selectedItem"
  16 + />
  17 + <div class="action-buttons row justify-around" v-show="isProjectSelected">
  18 + <q-btn color="orange" @click="selectedProject"
  19 + label="Selecionar Projeto" no-caps />
  20 + <q-btn @click="editProject" color="orange" label="Alterar Projeto" no-caps />
  21 + </div>
  22 + </q-card-section>
  23 + </q-card>
  24 + </div>
  25 +</template>
  26 +
  27 +<script lang="ts">
  28 +import {Vue, Component, Prop} from 'vue-property-decorator';
  29 +import projectsTableInfo from '../../mixins/tableInfo/listProject';
  30 +import notify, {TypeMessage} from "src/mixins/notification";
  31 +import ProjectService from "src/services/ProjectService";
  32 +
  33 +@Component
  34 +export default class ListProjects extends Vue {
  35 + tableInfo: any = {};
  36 + selectedItem: any = [];
  37 +
  38 +
  39 + get isProjectSelected() {
  40 + return this.selectedItem.length > 0;
  41 + }
  42 +
  43 + async selectedProject() {
  44 + await this.$store.commit('navigationInfo/defineProjectId', this.selectedItem[0].id);
  45 + notify('Um projeto foi selecionado', TypeMessage.success);
  46 + notify('Esse projeto servirá de base para navegação nos menus', TypeMessage.info);
  47 + }
  48 +
  49 + editProject() {
  50 + this.$emit('editProject', this.selectedItem[0]);
  51 + }
  52 +
  53 + async mounted() {
  54 + const projectService = new ProjectService();
  55 + const projectsResponse = await projectService.findAll();
  56 + this.tableInfo = projectsTableInfo;
  57 + this.tableInfo.data = projectsResponse;
  58 + }
  59 +}
  60 +</script>
... ...
codigos/frontend/src/pages/users/ListUsers.vue 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +<template>
  2 + <q-page class="column items-center justify-center page">
  3 + <div class="info-users row justify-around">
  4 + <q-card flat bordered class="card col-6">
  5 + <q-card-section>
  6 + <div class="card-header">Dados dos Usuários</div>
  7 + </q-card-section>
  8 + <q-card-section class="info-fields">
  9 + <div class="row">
  10 + <span class="label">Nome:</span>
  11 + <span class="content"></span>
  12 + </div>
  13 + <div class="row">
  14 + <span class="label">Login:</span>
  15 + <span class="content"></span>
  16 + </div>
  17 + <div class="row">
  18 + <span class="label">Email:</span>
  19 + <span class="content"></span>
  20 + </div>
  21 + </q-card-section>
  22 + </q-card>
  23 + <q-card flat bordered class="card col-6">
  24 + <q-card-section>
  25 + <div class="card-header">Informações dos Usuários</div>
  26 + </q-card-section>
  27 + <q-card-section>
  28 +
  29 + </q-card-section>
  30 + </q-card>
  31 + </div>
  32 + </q-page>
  33 +</template>
  34 +
  35 +<script>
  36 +import { Vue, Component } from 'vue-property-decorator';
  37 +
  38 +@Component
  39 +export default class ListUsers extends Vue {
  40 + mounted() {
  41 +
  42 + }
  43 +}
  44 +</script>
... ...
codigos/frontend/src/router/index.ts 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +import { route } from 'quasar/wrappers';
  2 +import VueRouter from 'vue-router';
  3 +import { Store } from 'vuex';
  4 +import {StateInterface} from '../store';
  5 +import routes from './routes';
  6 +
  7 +/*
  8 + * If not building with SSR mode, you can
  9 + * directly export the Router instantiation
  10 + */
  11 +
  12 +export default route<Store<StateInterface>>(({ Vue }) => {
  13 + Vue.use(VueRouter);
  14 +
  15 + const Router = new VueRouter({
  16 + scrollBehavior: () => ({ x: 0, y: 0 }),
  17 + routes,
  18 +
  19 + // Leave these as is and change from quasar.conf.js instead!
  20 + // quasar.conf.js -> build -> vueRouterMode
  21 + // quasar.conf.js -> build -> publicPath
  22 + mode: process.env.VUE_ROUTER_MODE,
  23 + base: process.env.VUE_ROUTER_BASE,
  24 + });
  25 +
  26 + return Router;
  27 +});
... ...
codigos/frontend/src/router/routes.ts 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +import {RouteConfig} from 'vue-router';
  2 +
  3 +const routes: RouteConfig[] = [
  4 + {
  5 + path: '/',
  6 + component: () => import('layouts/MainLayout.vue'),
  7 + children: [
  8 + {path: '', component: () => import('pages/Index.vue')},
  9 + {path: 'projetos', component: () => import('pages/Projects.vue')},
  10 + {path: 'projetos/usuarios', component: () => import('pages/users/ListUsers.vue')}
  11 + ],
  12 + },
  13 + {
  14 + path: '/login',
  15 + component: () => import('layouts/LoginLayout.vue'),
  16 + children: [
  17 + {path: '', component: () => import('pages/Login.vue')},
  18 + ],
  19 + },
  20 + // Always leave this as last one,
  21 + // but you can also remove it
  22 + {
  23 + path: '*',
  24 + component: () => import('pages/Error404.vue'),
  25 + },
  26 +];
  27 +
  28 +export default routes;
... ...
codigos/frontend/src/services/AdminService.ts 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +import Admin from "src/models/Admin";
  2 +import notify, {TypeMessage} from "src/mixins/notification";
  3 +import DefaultService from "src/services/DefaultService";
  4 +
  5 +export default class AdminService extends DefaultService<Admin>{
  6 +
  7 + public async find(id: number) {
  8 + try {
  9 + const resp = await this.client.get('/users/admins', id);
  10 + return new Admin(
  11 + id, resp.name,
  12 + resp.login, resp.email
  13 + );
  14 + } catch (e) {
  15 + notify('Não foi possível encontrar seus dados da conta', TypeMessage.error);
  16 + }
  17 + }
  18 +}
... ...
codigos/frontend/src/services/AuthApiService.ts 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +import Login from "src/models/Login";
  2 +import notify, {TypeMessage} from "src/mixins/notification";
  3 +
  4 +import jwt from "jsonwebtoken";
  5 +import DefaultService from "src/services/DefaultService";
  6 +
  7 +export default class AuthApiService extends DefaultService<Login> {
  8 +
  9 + public async generateJwt(loginForm: Login) {
  10 + try {
  11 + const tokenData = await this.client.post('auth', loginForm);
  12 + return tokenData.token;
  13 + } catch (e) {
  14 + notify('Não foi possível autenticar na API', TypeMessage.error);
  15 + }
  16 + }
  17 +
  18 + public verifyToken(token: string | null) {
  19 + if (token === null) return false;
  20 +
  21 + try {
  22 + jwt.verify(token, Buffer.from('VGFrZSBPbiBNZSBUYWtlIE1lIE9u', 'base64'), {
  23 + subject: 'Hybrid Recommendation System - SRH'
  24 + })
  25 + return true;
  26 + } catch (e) {
  27 + return false;
  28 + }
  29 + };
  30 +}
... ...
codigos/frontend/src/services/DefaultService.ts 0 → 100644
... ... @@ -0,0 +1,36 @@
  1 +import Client from "src/services/webClient/Client";
  2 +import FormRequest from "src/models/FormRequest";
  3 +import notify, {TypeMessage} from "src/mixins/notification";
  4 +import {ParseItem} from "src/models/models";
  5 +
  6 +export default abstract class DefaultService<T extends FormRequest> {
  7 + public client: Client<T>
  8 +
  9 + public constructor() {
  10 + this.client = new Client<T>();
  11 + }
  12 +
  13 + public handleErrors(response: any, resource: T) {
  14 + if (response.status === 422) {
  15 + for(let i = 0; i < response.data.length; i++) {
  16 + console.log(response.data[i]);
  17 +
  18 + notify(`
  19 + (Campo: ${this.translateFields(response.data[i].error, resource.parseNames)})
  20 + ${response.data[i].field}`, TypeMessage.error);
  21 + }
  22 + }
  23 + }
  24 +
  25 + private translateFields(fieldName: string, fieldsTranslation: ParseItem[]) {
  26 + let translateField: string | boolean = false;
  27 +
  28 + fieldsTranslation.forEach(translationObject => {
  29 + if (translationObject.fieldName === fieldName) {
  30 + translateField = translationObject.translation;
  31 + }
  32 + });
  33 +
  34 + return translateField ? translateField : fieldName;
  35 + }
  36 +}
... ...
codigos/frontend/src/services/LoginService.ts 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +import Login from "src/models/Login";
  2 +import notify, {TypeMessage} from "src/mixins/notification";
  3 +
  4 +// @ts-ignore
  5 +import {Store} from "src/store";
  6 +import DefaultService from "src/services/DefaultService";
  7 +
  8 +export default class LoginService extends DefaultService<Login>{
  9 +
  10 + async login(username: string, password: string) {
  11 + const loginForm = new Login(username, password);
  12 +
  13 + try {
  14 + const resp = await this.client.post('/admins/login', loginForm);
  15 +
  16 + if (resp.validUser) {
  17 + // @ts-ignore
  18 + Store.commit('login/defineUserId', resp.userId);
  19 + notify('Login realizado com sucesso!', TypeMessage.success);
  20 + return true;
  21 + }
  22 + } catch (e) {
  23 + notify('Não foi possível realizar o login', TypeMessage.error);
  24 + return false;
  25 + }
  26 + }
  27 +}
... ...
codigos/frontend/src/services/ProjectService.ts 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +import DefaultService from "src/services/DefaultService";
  2 +import Project from "src/models/Project";
  3 +import notify, {TypeMessage} from "src/mixins/notification";
  4 +
  5 +export default class ProjectService extends DefaultService<Project>{
  6 + async findAll() {
  7 + try {
  8 + const resp = await this.client.list('/projects')
  9 + return resp._embedded.projects;
  10 + } catch (e) {
  11 + notify('Não foi possível buscar os projetos', TypeMessage.error);
  12 + return false;
  13 + }
  14 + }
  15 +
  16 + async create(project: Project) {
  17 + try {
  18 + const resp = await this.client.post('/projects', project);
  19 + notify('Projeto criado com sucesso', TypeMessage.success);
  20 + return resp.data;
  21 + } catch (e) {
  22 + this.handleErrors(e.response, project);
  23 + notify('Não foi possível criar o projeto', TypeMessage.error);
  24 + return false;
  25 + }
  26 + }
  27 +
  28 + async update(project: Project, id: number) {
  29 + try {
  30 + const resp = await this.client.put('/projects', id, project);
  31 + return resp.data;
  32 + } catch (e) {
  33 + this.handleErrors(e.response, project);
  34 + notify('Não foi possível alterar o projeto', TypeMessage.error);
  35 + return false;
  36 + }
  37 + }
  38 +}
... ...
codigos/frontend/src/services/UserService.ts 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +import DefaultService from "./DefaultService";
  2 +
  3 +export default class UserService extends DefaultService<any>{
  4 +
  5 +}
... ...
codigos/frontend/src/services/webClient/Client.ts 0 → 100644
... ... @@ -0,0 +1,40 @@
  1 +import axios, {AxiosInstance} from 'axios'
  2 +import FormRequest from "src/models/FormRequest";
  3 +// @ts-ignore
  4 +import {Store} from "src/store";
  5 +
  6 +export default class Client<T extends FormRequest> {
  7 + private client: AxiosInstance;
  8 +
  9 + constructor() {
  10 + // @ts-ignore
  11 + const token = Store.getters['login/getToken'];
  12 +
  13 + this.client = axios.create({
  14 + baseURL: 'http://localhost:8080',
  15 + headers: {
  16 + Authorization: 'Bearer ' + token
  17 + }
  18 + });
  19 + }
  20 +
  21 + public async get(uri: string, id: number) {
  22 + const resp = await this.client.get(`${uri}/${id}`);
  23 + return resp.data;
  24 + }
  25 +
  26 + public async list(uri: string) {
  27 + const resp = await this.client.get(uri);
  28 + return resp.data;
  29 + }
  30 +
  31 + public async post(uri: string, data: T) {
  32 + const resp = await this.client.post(uri, data.build());
  33 + return resp.data;
  34 + }
  35 +
  36 + public async put(uri: string, id: number, data: T) {
  37 + const resp = await this.client.put(`${uri}/${id}`, data.build())
  38 + return resp.data;
  39 + }
  40 +}
... ...
codigos/frontend/src/shims-vue.d.ts 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +// Mocks all files ending in `.vue` showing them as plain Vue instances
  2 +declare module '*.vue' {
  3 + import Vue from 'vue';
  4 +
  5 + export default Vue;
  6 +}
... ...
codigos/frontend/src/store/index.ts 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +import {store} from 'quasar/wrappers';
  2 +import Vuex from 'vuex';
  3 +
  4 +// @ts-ignore
  5 +import login from './login/index';
  6 +import navigationInfo from './navigationInfo/index';
  7 +// @ts-ignore
  8 +import {LoginStateInterface} from "src/store/login/state";
  9 +import {NavigationInfoStateInterface} from "src/store/navigationInfo/state";
  10 +
  11 +export interface StateInterface {
  12 + login: LoginStateInterface;
  13 + navigationInfo: NavigationInfoStateInterface;
  14 +}
  15 +
  16 +let Store = null;
  17 +
  18 +export default store(({ Vue }) => {
  19 + Vue.use(Vuex);
  20 +
  21 + Store = new Vuex.Store<StateInterface>({
  22 + modules: {
  23 + login,
  24 + navigationInfo
  25 + },
  26 +
  27 + // enable strict mode (adds overhead!)
  28 + // for dev mode only
  29 + strict: !!process.env.DEV,
  30 + });
  31 +
  32 + return Store;
  33 +});
  34 +
  35 +export {Store}
... ...
codigos/frontend/src/store/login/getters.ts 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +import { GetterTree } from 'vuex';
  2 +import { StateInterface } from '../index';
  3 +import { LoginStateInterface } from './state';
  4 +
  5 +const getters: GetterTree<LoginStateInterface, StateInterface> = {
  6 + infoUsuario(state: any) {
  7 + return state.userLoginInfo;
  8 + },
  9 + getIdUsuario(state: any) {
  10 + return state.userLoginInfo.userId;
  11 + },
  12 + getToken(state: any) {
  13 + return state.userLoginInfo.token;
  14 + }
  15 +};
  16 +
  17 +export default getters;
... ...
codigos/frontend/src/store/login/index.ts 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +import {Module} from 'vuex';
  2 +import {StateInterface} from '../index';
  3 +import state, {LoginStateInterface} from './state';
  4 +import getters from "src/store/login/getters";
  5 +import mutations from "src/store/login/mutations";
  6 +
  7 +const loginModule: Module<LoginStateInterface, StateInterface> = {
  8 + namespaced: true,
  9 + getters,
  10 + state,
  11 + mutations
  12 +}
  13 +
  14 +export default loginModule;
... ...
codigos/frontend/src/store/login/mutations.ts 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +import { MutationTree } from 'vuex';
  2 +import {LoginStateInterface} from './state';
  3 +
  4 +const mutation: MutationTree<LoginStateInterface> = {
  5 + defineToken(state: any, token) {
  6 + state.userLoginInfo.token = token;
  7 + },
  8 + defineUserId(state: any, id: number | null) {
  9 + state.userLoginInfo.userId = id;
  10 + }
  11 +};
  12 +
  13 +export default mutation;
... ...
codigos/frontend/src/store/login/state.ts 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +interface Login {
  2 + userId: Number | null,
  3 + token: String | null
  4 +}
  5 +
  6 +export interface LoginStateInterface {
  7 + userLoginInfo: Login;
  8 +}
  9 +
  10 +const state: LoginStateInterface = {
  11 + userLoginInfo: {
  12 + userId: null,
  13 + token: null
  14 + },
  15 +};
  16 +
  17 +export default state;
... ...
codigos/frontend/src/store/module-example/actions.ts 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +import { ActionTree } from 'vuex';
  2 +import { StateInterface } from '../index';
  3 +import { ExampleStateInterface } from './state';
  4 +
  5 +const actions: ActionTree<ExampleStateInterface, StateInterface> = {
  6 + someAction(/* context */) {
  7 + // your code
  8 + },
  9 +};
  10 +
  11 +export default actions;
... ...
codigos/frontend/src/store/module-example/getters.ts 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +import { GetterTree } from 'vuex';
  2 +import { StateInterface } from '../index';
  3 +import { ExampleStateInterface } from './state';
  4 +
  5 +const getters: GetterTree<ExampleStateInterface, StateInterface> = {
  6 + someAction(/* context */) {
  7 + // your code
  8 + },
  9 +};
  10 +
  11 +export default getters;
... ...
codigos/frontend/src/store/module-example/index.ts 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +import { Module } from 'vuex';
  2 +import { StateInterface } from '../index';
  3 +import state, { ExampleStateInterface } from './state';
  4 +import actions from './actions';
  5 +import getters from './getters';
  6 +import mutations from './mutations';
  7 +
  8 +const exampleModule: Module<ExampleStateInterface, StateInterface> = {
  9 + namespaced: true,
  10 + actions,
  11 + getters,
  12 + mutations,
  13 + state,
  14 +};
  15 +
  16 +export default exampleModule;
... ...
codigos/frontend/src/store/module-example/mutations.ts 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +import { MutationTree } from 'vuex';
  2 +import { ExampleStateInterface } from './state';
  3 +
  4 +const mutation: MutationTree<ExampleStateInterface> = {
  5 + someMutation(/* state: ExampleStateInterface */) {
  6 + // your code
  7 + },
  8 +};
  9 +
  10 +export default mutation;
... ...
codigos/frontend/src/store/module-example/state.ts 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +export interface ExampleStateInterface {
  2 + prop: boolean;
  3 +}
  4 +
  5 +const state: ExampleStateInterface = {
  6 + prop: false,
  7 +};
  8 +
  9 +export default state;
... ...
codigos/frontend/src/store/navigationInfo/getters.ts 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +import { GetterTree } from 'vuex';
  2 +import { StateInterface } from '../index';
  3 +import {NavigationInfoStateInterface} from "src/store/navigationInfo/state";
  4 +
  5 +const getters: GetterTree<NavigationInfoStateInterface, StateInterface> = {
  6 + projectId(state: any) {
  7 + return state.navigationInfo.projectId;
  8 + },
  9 +};
  10 +
  11 +export default getters;
... ...
codigos/frontend/src/store/navigationInfo/index.ts 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +import {Module} from 'vuex';
  2 +import {StateInterface} from '../index';
  3 +import state, {NavigationInfoStateInterface} from 'src/store/navigationInfo/state';
  4 +import getters from "src/store/navigationInfo/getters";
  5 +import mutations from "src/store/navigationInfo/mutations";
  6 +
  7 +const loginModule: Module<NavigationInfoStateInterface, StateInterface> = {
  8 + namespaced: true,
  9 + getters,
  10 + state,
  11 + mutations
  12 +}
  13 +
  14 +export default loginModule;
... ...
codigos/frontend/src/store/navigationInfo/mutations.ts 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +import { MutationTree } from 'vuex';
  2 +import {NavigationInfoStateInterface} from 'src/store/navigationInfo/state';
  3 +
  4 +const mutation: MutationTree<NavigationInfoStateInterface> = {
  5 + defineProjectId(state: any, id: number | null) {
  6 + state.navigationInfo.projectId = id;
  7 + }
  8 +};
  9 +
  10 +export default mutation;
... ...
codigos/frontend/src/store/navigationInfo/state.ts 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +interface NavigationInfo {
  2 + projectId: number | null
  3 +}
  4 +
  5 +export interface NavigationInfoStateInterface {
  6 + navigationInfo: NavigationInfo;
  7 +}
  8 +
  9 +const state: NavigationInfoStateInterface = {
  10 + navigationInfo: {
  11 + projectId: null
  12 + }
  13 +};
  14 +
  15 +export default state;
... ...
codigos/frontend/tsconfig.json 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +{
  2 + "extends": "@quasar/app/tsconfig-preset",
  3 + "compilerOptions": {
  4 + "baseUrl": ".",
  5 + "experimentalDecorators": true
  6 + },
  7 + "strictPropertyInitialization": false
  8 +}
... ...
codigos/frontend/yarn.lock
... ... @@ -10,44 +10,43 @@
10 10 "@babel/highlight" "^7.10.4"
11 11  
12 12 "@babel/compat-data@^7.10.4":
13   - version "7.10.4"
14   - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.4.tgz#706a6484ee6f910b719b696a9194f8da7d7ac241"
15   - integrity sha512-t+rjExOrSVvjQQXNp5zAIYDp00KjdvGl/TpDX5REPr0S9IAIPQMTilcfG6q8c0QFmj9lSTVySV2VTsyggvtNIw==
  13 + version "7.10.5"
  14 + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.5.tgz#d38425e67ea96b1480a3f50404d1bf85676301a6"
  15 + integrity sha512-mPVoWNzIpYJHbWje0if7Ck36bpbtTvIxOi9+6WSK9wjGEXearAqlwBoTQvVjsAY2VIwgcs8V940geY3okzRCEw==
16 16 dependencies:
17 17 browserslist "^4.12.0"
18 18 invariant "^2.2.4"
19 19 semver "^5.5.0"
20 20  
21 21 "@babel/core@^7.9.0":
22   - version "7.10.4"
23   - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.4.tgz#780e8b83e496152f8dd7df63892b2e052bf1d51d"
24   - integrity sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==
  22 + version "7.10.5"
  23 + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.5.tgz#1f15e2cca8ad9a1d78a38ddba612f5e7cdbbd330"
  24 + integrity sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==
25 25 dependencies:
26 26 "@babel/code-frame" "^7.10.4"
27   - "@babel/generator" "^7.10.4"
28   - "@babel/helper-module-transforms" "^7.10.4"
  27 + "@babel/generator" "^7.10.5"
  28 + "@babel/helper-module-transforms" "^7.10.5"
29 29 "@babel/helpers" "^7.10.4"
30   - "@babel/parser" "^7.10.4"
  30 + "@babel/parser" "^7.10.5"
31 31 "@babel/template" "^7.10.4"
32   - "@babel/traverse" "^7.10.4"
33   - "@babel/types" "^7.10.4"
  32 + "@babel/traverse" "^7.10.5"
  33 + "@babel/types" "^7.10.5"
34 34 convert-source-map "^1.7.0"
35 35 debug "^4.1.0"
36 36 gensync "^1.0.0-beta.1"
37 37 json5 "^2.1.2"
38   - lodash "^4.17.13"
  38 + lodash "^4.17.19"
39 39 resolve "^1.3.2"
40 40 semver "^5.4.1"
41 41 source-map "^0.5.0"
42 42  
43   -"@babel/generator@^7.10.4":
44   - version "7.10.4"
45   - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.4.tgz#e49eeed9fe114b62fa5b181856a43a5e32f5f243"
46   - integrity sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==
  43 +"@babel/generator@^7.10.5":
  44 + version "7.10.5"
  45 + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.5.tgz#1b903554bc8c583ee8d25f1e8969732e6b829a69"
  46 + integrity sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==
47 47 dependencies:
48   - "@babel/types" "^7.10.4"
  48 + "@babel/types" "^7.10.5"
49 49 jsesc "^2.5.1"
50   - lodash "^4.17.13"
51 50 source-map "^0.5.0"
52 51  
53 52 "@babel/helper-annotate-as-pure@^7.10.4":
... ... @@ -76,13 +75,13 @@
76 75 levenary "^1.1.1"
77 76 semver "^5.5.0"
78 77  
79   -"@babel/helper-create-class-features-plugin@^7.10.4":
80   - version "7.10.4"
81   - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.4.tgz#2d4015d0136bd314103a70d84a7183e4b344a355"
82   - integrity sha512-9raUiOsXPxzzLjCXeosApJItoMnX3uyT4QdM2UldffuGApNrF8e938MwNpDCK9CPoyxrEoCgT+hObJc3mZa6lQ==
  78 +"@babel/helper-create-class-features-plugin@^7.10.4", "@babel/helper-create-class-features-plugin@^7.10.5":
  79 + version "7.10.5"
  80 + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d"
  81 + integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==
83 82 dependencies:
84 83 "@babel/helper-function-name" "^7.10.4"
85   - "@babel/helper-member-expression-to-functions" "^7.10.4"
  84 + "@babel/helper-member-expression-to-functions" "^7.10.5"
86 85 "@babel/helper-optimise-call-expression" "^7.10.4"
87 86 "@babel/helper-plugin-utils" "^7.10.4"
88 87 "@babel/helper-replace-supers" "^7.10.4"
... ... @@ -98,13 +97,13 @@
98 97 regexpu-core "^4.7.0"
99 98  
100 99 "@babel/helper-define-map@^7.10.4":
101   - version "7.10.4"
102   - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.4.tgz#f037ad794264f729eda1889f4ee210b870999092"
103   - integrity sha512-nIij0oKErfCnLUCWaCaHW0Bmtl2RO9cN7+u2QT8yqTywgALKlyUVOvHDElh+b5DwVC6YB1FOYFOTWcN/+41EDA==
  100 + version "7.10.5"
  101 + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30"
  102 + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==
104 103 dependencies:
105 104 "@babel/helper-function-name" "^7.10.4"
106   - "@babel/types" "^7.10.4"
107   - lodash "^4.17.13"
  105 + "@babel/types" "^7.10.5"
  106 + lodash "^4.17.19"
108 107  
109 108 "@babel/helper-explode-assignable-expression@^7.10.4":
110 109 version "7.10.4"
... ... @@ -137,12 +136,12 @@
137 136 dependencies:
138 137 "@babel/types" "^7.10.4"
139 138  
140   -"@babel/helper-member-expression-to-functions@^7.10.4":
141   - version "7.10.4"
142   - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz#7cd04b57dfcf82fce9aeae7d4e4452fa31b8c7c4"
143   - integrity sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==
  139 +"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5":
  140 + version "7.10.5"
  141 + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz#172f56e7a63e78112f3a04055f24365af702e7ee"
  142 + integrity sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==
144 143 dependencies:
145   - "@babel/types" "^7.10.4"
  144 + "@babel/types" "^7.10.5"
146 145  
147 146 "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.8.3":
148 147 version "7.10.4"
... ... @@ -151,18 +150,18 @@
151 150 dependencies:
152 151 "@babel/types" "^7.10.4"
153 152  
154   -"@babel/helper-module-transforms@^7.10.4":
155   - version "7.10.4"
156   - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz#ca1f01fdb84e48c24d7506bb818c961f1da8805d"
157   - integrity sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==
  153 +"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5":
  154 + version "7.10.5"
  155 + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz#120c271c0b3353673fcdfd8c053db3c544a260d6"
  156 + integrity sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==
158 157 dependencies:
159 158 "@babel/helper-module-imports" "^7.10.4"
160 159 "@babel/helper-replace-supers" "^7.10.4"
161 160 "@babel/helper-simple-access" "^7.10.4"
162 161 "@babel/helper-split-export-declaration" "^7.10.4"
163 162 "@babel/template" "^7.10.4"
164   - "@babel/types" "^7.10.4"
165   - lodash "^4.17.13"
  163 + "@babel/types" "^7.10.5"
  164 + lodash "^4.17.19"
166 165  
167 166 "@babel/helper-optimise-call-expression@^7.10.4":
168 167 version "7.10.4"
... ... @@ -177,11 +176,11 @@
177 176 integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==
178 177  
179 178 "@babel/helper-regex@^7.10.4":
180   - version "7.10.4"
181   - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.4.tgz#59b373daaf3458e5747dece71bbaf45f9676af6d"
182   - integrity sha512-inWpnHGgtg5NOF0eyHlC0/74/VkdRITY9dtTpB2PrxKKn+AkVMRiZz/Adrx+Ssg+MLDesi2zohBW6MVq6b4pOQ==
  179 + version "7.10.5"
  180 + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0"
  181 + integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg==
183 182 dependencies:
184   - lodash "^4.17.13"
  183 + lodash "^4.17.19"
185 184  
186 185 "@babel/helper-remap-async-to-generator@^7.10.4":
187 186 version "7.10.4"
... ... @@ -252,15 +251,15 @@
252 251 chalk "^2.0.0"
253 252 js-tokens "^4.0.0"
254 253  
255   -"@babel/parser@^7.10.4", "@babel/parser@^7.7.0":
256   - version "7.10.4"
257   - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.4.tgz#9eedf27e1998d87739fb5028a5120557c06a1a64"
258   - integrity sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==
  254 +"@babel/parser@^7.10.4", "@babel/parser@^7.10.5", "@babel/parser@^7.7.0":
  255 + version "7.10.5"
  256 + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.5.tgz#e7c6bf5a7deff957cec9f04b551e2762909d826b"
  257 + integrity sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==
259 258  
260 259 "@babel/plugin-proposal-async-generator-functions@^7.10.4":
261   - version "7.10.4"
262   - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz#4b65abb3d9bacc6c657aaa413e56696f9f170fc6"
263   - integrity sha512-MJbxGSmejEFVOANAezdO39SObkURO5o/8b6fSH6D1pi9RZQt+ldppKPXfqgUWpSQ9asM6xaSaSJIaeWMDRP0Zg==
  260 + version "7.10.5"
  261 + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558"
  262 + integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==
264 263 dependencies:
265 264 "@babel/helper-plugin-utils" "^7.10.4"
266 265 "@babel/helper-remap-async-to-generator" "^7.10.4"
... ... @@ -275,11 +274,11 @@
275 274 "@babel/helper-plugin-utils" "^7.10.4"
276 275  
277 276 "@babel/plugin-proposal-decorators@^7.4.4":
278   - version "7.10.4"
279   - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.4.tgz#fe20ef10cc73f386f70910fca48798041cd357c7"
280   - integrity sha512-JHTWjQngOPv+ZQQqOGv2x6sCCr4IYWy7S1/VH6BE9ZfkoLrdQ2GpEP3tfb5M++G9PwvqjhY8VC/C3tXm+/eHvA==
  277 + version "7.10.5"
  278 + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz#42898bba478bc4b1ae242a703a953a7ad350ffb4"
  279 + integrity sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ==
281 280 dependencies:
282   - "@babel/helper-create-class-features-plugin" "^7.10.4"
  281 + "@babel/helper-create-class-features-plugin" "^7.10.5"
283 282 "@babel/helper-plugin-utils" "^7.10.4"
284 283 "@babel/plugin-syntax-decorators" "^7.10.4"
285 284  
... ... @@ -510,12 +509,11 @@
510 509 "@babel/helper-plugin-utils" "^7.10.4"
511 510  
512 511 "@babel/plugin-transform-block-scoping@^7.10.4":
513   - version "7.10.4"
514   - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.4.tgz#a670d1364bb5019a621b9ea2001482876d734787"
515   - integrity sha512-J3b5CluMg3hPUii2onJDRiaVbPtKFPLEaV5dOPY5OeAbDi1iU/UbbFFTgwb7WnanaDy7bjU35kc26W3eM5Qa0A==
  512 + version "7.10.5"
  513 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.5.tgz#b81b8aafefbfe68f0f65f7ef397b9ece68a6037d"
  514 + integrity sha512-6Ycw3hjpQti0qssQcA6AMSFDHeNJ++R6dIMnpRqUjFeBBTmTDPa8zgF90OVfTvAo11mXZTlVUViY1g8ffrURLg==
516 515 dependencies:
517 516 "@babel/helper-plugin-utils" "^7.10.4"
518   - lodash "^4.17.13"
519 517  
520 518 "@babel/plugin-transform-classes@^7.10.4":
521 519 version "7.10.4"
... ... @@ -598,11 +596,11 @@
598 596 "@babel/helper-plugin-utils" "^7.10.4"
599 597  
600 598 "@babel/plugin-transform-modules-amd@^7.10.4":
601   - version "7.10.4"
602   - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.4.tgz#cb407c68b862e4c1d13a2fc738c7ec5ed75fc520"
603   - integrity sha512-3Fw+H3WLUrTlzi3zMiZWp3AR4xadAEMv6XRCYnd5jAlLM61Rn+CRJaZMaNvIpcJpQ3vs1kyifYvEVPFfoSkKOA==
  599 + version "7.10.5"
  600 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1"
  601 + integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==
604 602 dependencies:
605   - "@babel/helper-module-transforms" "^7.10.4"
  603 + "@babel/helper-module-transforms" "^7.10.5"
606 604 "@babel/helper-plugin-utils" "^7.10.4"
607 605 babel-plugin-dynamic-import-node "^2.3.3"
608 606  
... ... @@ -617,12 +615,12 @@
617 615 babel-plugin-dynamic-import-node "^2.3.3"
618 616  
619 617 "@babel/plugin-transform-modules-systemjs@^7.10.4":
620   - version "7.10.4"
621   - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.4.tgz#8f576afd943ac2f789b35ded0a6312f929c633f9"
622   - integrity sha512-Tb28LlfxrTiOTGtZFsvkjpyjCl9IoaRI52AEU/VIwOwvDQWtbNJsAqTXzh+5R7i74e/OZHH2c2w2fsOqAfnQYQ==
  618 + version "7.10.5"
  619 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85"
  620 + integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==
623 621 dependencies:
624 622 "@babel/helper-hoist-variables" "^7.10.4"
625   - "@babel/helper-module-transforms" "^7.10.4"
  623 + "@babel/helper-module-transforms" "^7.10.5"
626 624 "@babel/helper-plugin-utils" "^7.10.4"
627 625 babel-plugin-dynamic-import-node "^2.3.3"
628 626  
... ... @@ -657,9 +655,9 @@
657 655 "@babel/helper-replace-supers" "^7.10.4"
658 656  
659 657 "@babel/plugin-transform-parameters@^7.10.4":
660   - version "7.10.4"
661   - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.4.tgz#7b4d137c87ea7adc2a0f3ebf53266871daa6fced"
662   - integrity sha512-RurVtZ/D5nYfEg0iVERXYKEgDFeesHrHfx8RT05Sq57ucj2eOYAP6eu5fynL4Adju4I/mP/I6SO0DqNWAXjfLQ==
  658 + version "7.10.5"
  659 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a"
  660 + integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==
663 661 dependencies:
664 662 "@babel/helper-get-function-arity" "^7.10.4"
665 663 "@babel/helper-plugin-utils" "^7.10.4"
... ... @@ -686,9 +684,9 @@
686 684 "@babel/helper-plugin-utils" "^7.10.4"
687 685  
688 686 "@babel/plugin-transform-runtime@^7.9.0":
689   - version "7.10.4"
690   - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.4.tgz#594fb53453ea1b6f0779cceb48ce0718a447feb7"
691   - integrity sha512-8ULlGv8p+Vuxu+kz2Y1dk6MYS2b/Dki+NO6/0ZlfSj5tMalfDL7jI/o/2a+rrWLqSXvnadEqc2WguB4gdQIxZw==
  687 + version "7.10.5"
  688 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.5.tgz#3b39b7b24830e0c2d8ff7a4489fe5cf99fbace86"
  689 + integrity sha512-tV4V/FjElJ9lQtyjr5xD2IFFbgY46r7EeVu5a8CpEKT5laheHKSlFeHjpkPppW3PqzGLAuv5k2qZX5LgVZIX5w==
692 690 dependencies:
693 691 "@babel/helper-module-imports" "^7.10.4"
694 692 "@babel/helper-plugin-utils" "^7.10.4"
... ... @@ -718,9 +716,9 @@
718 716 "@babel/helper-regex" "^7.10.4"
719 717  
720 718 "@babel/plugin-transform-template-literals@^7.10.4":
721   - version "7.10.4"
722   - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.4.tgz#e6375407b30fcb7fcfdbba3bb98ef3e9d36df7bc"
723   - integrity sha512-4NErciJkAYe+xI5cqfS8pV/0ntlY5N5Ske/4ImxAVX7mk9Rxt2bwDTGv1Msc2BRJvWQcmYEC+yoMLdX22aE4VQ==
  719 + version "7.10.5"
  720 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c"
  721 + integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==
724 722 dependencies:
725 723 "@babel/helper-annotate-as-pure" "^7.10.4"
726 724 "@babel/helper-plugin-utils" "^7.10.4"
... ... @@ -829,9 +827,9 @@
829 827 esutils "^2.0.2"
830 828  
831 829 "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.0":
832   - version "7.10.4"
833   - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99"
834   - integrity sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==
  830 + version "7.10.5"
  831 + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.5.tgz#303d8bd440ecd5a491eae6117fd3367698674c5c"
  832 + integrity sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==
835 833 dependencies:
836 834 regenerator-runtime "^0.13.4"
837 835  
... ... @@ -844,28 +842,28 @@
844 842 "@babel/parser" "^7.10.4"
845 843 "@babel/types" "^7.10.4"
846 844  
847   -"@babel/traverse@^7.10.4", "@babel/traverse@^7.7.0":
848   - version "7.10.4"
849   - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.4.tgz#e642e5395a3b09cc95c8e74a27432b484b697818"
850   - integrity sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==
  845 +"@babel/traverse@^7.10.4", "@babel/traverse@^7.10.5", "@babel/traverse@^7.7.0":
  846 + version "7.10.5"
  847 + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.5.tgz#77ce464f5b258be265af618d8fddf0536f20b564"
  848 + integrity sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==
851 849 dependencies:
852 850 "@babel/code-frame" "^7.10.4"
853   - "@babel/generator" "^7.10.4"
  851 + "@babel/generator" "^7.10.5"
854 852 "@babel/helper-function-name" "^7.10.4"
855 853 "@babel/helper-split-export-declaration" "^7.10.4"
856   - "@babel/parser" "^7.10.4"
857   - "@babel/types" "^7.10.4"
  854 + "@babel/parser" "^7.10.5"
  855 + "@babel/types" "^7.10.5"
858 856 debug "^4.1.0"
859 857 globals "^11.1.0"
860   - lodash "^4.17.13"
  858 + lodash "^4.17.19"
861 859  
862   -"@babel/types@^7.10.4", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
863   - version "7.10.4"
864   - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.4.tgz#369517188352e18219981efd156bfdb199fff1ee"
865   - integrity sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==
  860 +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
  861 + version "7.10.5"
  862 + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.5.tgz#d88ae7e2fde86bfbfe851d4d81afa70a997b5d15"
  863 + integrity sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==
866 864 dependencies:
867 865 "@babel/helper-validator-identifier" "^7.10.4"
868   - lodash "^4.17.13"
  866 + lodash "^4.17.19"
869 867 to-fast-properties "^2.0.0"
870 868  
871 869 "@electron/get@^1.3.1":
... ... @@ -918,9 +916,9 @@
918 916 integrity sha1-FPzHEqUwA475vhzmlSMVqDn0Zqg=
919 917  
920 918 "@quasar/app@^2.0.0":
921   - version "2.0.4"
922   - resolved "https://registry.yarnpkg.com/@quasar/app/-/app-2.0.4.tgz#b68043c9db445cc6dfa5be4649b986bf105b75ef"
923   - integrity sha512-OesnQeFezPjds7gvFR6TJR1rE6en4Oz80Xsl/0HnG8yGx5wmFRF8R5gJsqeiCeFS3AIhcQ1lDWamh885YBlBAQ==
  919 + version "2.0.6"
  920 + resolved "https://registry.yarnpkg.com/@quasar/app/-/app-2.0.6.tgz#4462da617b3b1d4c405bd57bc8a92d9b4109eace"
  921 + integrity sha512-4A98sb9Y4NPPrIPo7HXJABUzptHp3ji87hD2wDQxpzijhhJmEJpDSiWZR3o3ngP8j/eP3mqJeYbCnXbB6ZnyuA==
924 922 dependencies:
925 923 "@quasar/babel-preset-app" "2.0.1"
926 924 "@quasar/fastclick" "1.1.4"
... ... @@ -1027,9 +1025,9 @@
1027 1025 core-js-compat "^3.6.5"
1028 1026  
1029 1027 "@quasar/extras@^1.0.0":
1030   - version "1.8.2"
1031   - resolved "https://registry.yarnpkg.com/@quasar/extras/-/extras-1.8.2.tgz#54ff5e0c8fc17763c083c4f0dcd3a60e1b00b4a8"
1032   - integrity sha512-y3A4OO4DGDxuFyh/X4k5fS17TTxhpPauZv8Qr/0bso+RTk5f+3X4lLAcP7aaiqcBLOV8HsUKpGzNArMleClYgg==
  1028 + version "1.9.2"
  1029 + resolved "https://registry.yarnpkg.com/@quasar/extras/-/extras-1.9.2.tgz#088b4c6e2d8d0ae625cad311e9c0f9502cab11e2"
  1030 + integrity sha512-OP2qTOveQHkTmaxsEhSPhXTs3s0MxGevIjQMZ8e79U3HhlGYSO48wBH2iUrK5c6XlALOq9zqHQJoGt5QnhWdUA==
1033 1031  
1034 1032 "@quasar/fastclick@1.1.4":
1035 1033 version "1.1.4"
... ... @@ -1096,10 +1094,15 @@
1096 1094 electron-notarize "^0.1.1"
1097 1095 electron-osx-sign "^0.4.11"
1098 1096  
  1097 +"@types/eslint-visitor-keys@^1.0.0":
  1098 + version "1.0.0"
  1099 + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
  1100 + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
  1101 +
1099 1102 "@types/express-serve-static-core@*":
1100   - version "4.17.8"
1101   - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.8.tgz#b8f7b714138536742da222839892e203df569d1c"
1102   - integrity sha512-1SJZ+R3Q/7mLkOD9ewCBDYD2k0WyZQtWYqF/2VvoNN2/uhI49J9CDN4OAm+wGMA0DbArA4ef27xl4+JwMtGggw==
  1103 + version "4.17.9"
  1104 + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.9.tgz#2d7b34dcfd25ec663c25c85d76608f8b249667f1"
  1105 + integrity sha512-DG0BYg6yO+ePW+XoDENYz8zhNGC3jDDEpComMYn7WJc4mY1Us8Rw9ax2YhJXxpyk2SF47PQAoQ0YyVT1a0bEkA==
1103 1106 dependencies:
1104 1107 "@types/node" "*"
1105 1108 "@types/qs" "*"
... ... @@ -1154,7 +1157,7 @@
1154 1157 dependencies:
1155 1158 "@types/node" "*"
1156 1159  
1157   -"@types/json-schema@^7.0.4":
  1160 +"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
1158 1161 version "7.0.5"
1159 1162 resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
1160 1163 integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
... ... @@ -1164,15 +1167,22 @@
1164 1167 resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
1165 1168 integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
1166 1169  
  1170 +"@types/jsonwebtoken@^8.5.0":
  1171 + version "8.5.0"
  1172 + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz#2531d5e300803aa63279b232c014acf780c981c5"
  1173 + integrity sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg==
  1174 + dependencies:
  1175 + "@types/node" "*"
  1176 +
1167 1177 "@types/lru-cache@5.1.0":
1168 1178 version "5.1.0"
1169 1179 resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03"
1170 1180 integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==
1171 1181  
1172 1182 "@types/mime@*":
1173   - version "2.0.2"
1174   - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5"
1175   - integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q==
  1183 + version "2.0.3"
  1184 + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a"
  1185 + integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==
1176 1186  
1177 1187 "@types/minimatch@*":
1178 1188 version "3.0.3"
... ... @@ -1180,9 +1190,14 @@
1180 1190 integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
1181 1191  
1182 1192 "@types/node@*":
1183   - version "14.0.22"
1184   - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.22.tgz#23ea4d88189cec7d58f9e6b66f786b215eb61bdc"
1185   - integrity sha512-emeGcJvdiZ4Z3ohbmw93E/64jRzUHAItSHt8nF7M4TGgQTiWqFVGB8KNpLGFmUHmHLvjvBgFwVlqNcq+VuGv9g==
  1193 + version "14.0.27"
  1194 + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1"
  1195 + integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==
  1196 +
  1197 +"@types/node@^10.17.15":
  1198 + version "10.17.28"
  1199 + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.28.tgz#0e36d718a29355ee51cec83b42d921299200f6d9"
  1200 + integrity sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ==
1186 1201  
1187 1202 "@types/q@^1.5.1":
1188 1203 version "1.5.4"
... ... @@ -1190,9 +1205,9 @@
1190 1205 integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
1191 1206  
1192 1207 "@types/qs@*":
1193   - version "6.9.3"
1194   - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.3.tgz#b755a0934564a200d3efdf88546ec93c369abd03"
1195   - integrity sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA==
  1208 + version "6.9.4"
  1209 + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a"
  1210 + integrity sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ==
1196 1211  
1197 1212 "@types/range-parser@*":
1198 1213 version "1.2.3"
... ... @@ -1200,9 +1215,9 @@
1200 1215 integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==
1201 1216  
1202 1217 "@types/serve-static@*":
1203   - version "1.13.4"
1204   - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.4.tgz#6662a93583e5a6cabca1b23592eb91e12fa80e7c"
1205   - integrity sha512-jTDt0o/YbpNwZbQmE/+2e+lfjJEJJR0I3OFaKQKPWkASkCoW3i6fsUnqudSMcNAfbtmADGu8f4MV4q+GqULmug==
  1218 + version "1.13.5"
  1219 + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.5.tgz#3d25d941a18415d3ab092def846e135a08bbcf53"
  1220 + integrity sha512-6M64P58N+OXjU432WoLLBQxbA0LRGBCRm7aAGQJ+SMC1IMl0dgRVi9EFfoDcS2a7Xogygk/eGN94CfwU9UF7UQ==
1206 1221 dependencies:
1207 1222 "@types/express-serve-static-core" "*"
1208 1223 "@types/mime" "*"
... ... @@ -1251,9 +1266,9 @@
1251 1266 "@types/webpack" "*"
1252 1267  
1253 1268 "@types/webpack-sources@*":
1254   - version "1.4.0"
1255   - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-1.4.0.tgz#e58f1f05f87d39a5c64cf85705bdbdbb94d4d57e"
1256   - integrity sha512-c88dKrpSle9BtTqR6ifdaxu1Lvjsl3C5OsfvuUbUwdXymshv1TkufUAXBajCCUM/f/TmnkZC/Esb03MinzSiXQ==
  1269 + version "1.4.2"
  1270 + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-1.4.2.tgz#5d3d4dea04008a779a90135ff96fb5c0c9e6292c"
  1271 + integrity sha512-77T++JyKow4BQB/m9O96n9d/UUHWLQHlcqXb9Vsf4F1+wKNrrlWNFPDLKNT92RJnCSL6CieTc+NDXtCVZswdTw==
1257 1272 dependencies:
1258 1273 "@types/node" "*"
1259 1274 "@types/source-list-map" "*"
... ... @@ -1283,10 +1298,70 @@
1283 1298 "@types/webpack-sources" "*"
1284 1299 source-map "^0.6.0"
1285 1300  
  1301 +"@typescript-eslint/eslint-plugin@^3.3.0":
  1302 + version "3.7.1"
  1303 + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.1.tgz#d144c49a9a0ffe8dd704bb179c243df76c111bc9"
  1304 + integrity sha512-3DB9JDYkMrc8Au00rGFiJLK2Ja9CoMP6Ut0sHsXp3ZtSugjNxvSSHTnKLfo4o+QmjYBJqEznDqsG1zj4F2xnsg==
  1305 + dependencies:
  1306 + "@typescript-eslint/experimental-utils" "3.7.1"
  1307 + debug "^4.1.1"
  1308 + functional-red-black-tree "^1.0.1"
  1309 + regexpp "^3.0.0"
  1310 + semver "^7.3.2"
  1311 + tsutils "^3.17.1"
  1312 +
  1313 +"@typescript-eslint/experimental-utils@3.7.1":
  1314 + version "3.7.1"
  1315 + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.1.tgz#ab036caaed4c870d22531d41f9352f3147364d61"
  1316 + integrity sha512-TqE97pv7HrqWcGJbLbZt1v59tcqsSVpWTOf1AqrWK7n8nok2sGgVtYRuGXeNeLw3wXlLEbY1MKP3saB2HsO/Ng==
  1317 + dependencies:
  1318 + "@types/json-schema" "^7.0.3"
  1319 + "@typescript-eslint/types" "3.7.1"
  1320 + "@typescript-eslint/typescript-estree" "3.7.1"
  1321 + eslint-scope "^5.0.0"
  1322 + eslint-utils "^2.0.0"
  1323 +
  1324 +"@typescript-eslint/parser@^3.3.0":
  1325 + version "3.7.1"
  1326 + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.7.1.tgz#5d9ccecb116d12d9c6073e9861c57c9b1aa88128"
  1327 + integrity sha512-W4QV/gXvfIsccN8225784LNOorcm7ch68Fi3V4Wg7gmkWSQRKevO4RrRqWo6N/Z/myK1QAiGgeaXN57m+R/8iQ==
  1328 + dependencies:
  1329 + "@types/eslint-visitor-keys" "^1.0.0"
  1330 + "@typescript-eslint/experimental-utils" "3.7.1"
  1331 + "@typescript-eslint/types" "3.7.1"
  1332 + "@typescript-eslint/typescript-estree" "3.7.1"
  1333 + eslint-visitor-keys "^1.1.0"
  1334 +
  1335 +"@typescript-eslint/types@3.7.1":
  1336 + version "3.7.1"
  1337 + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.7.1.tgz#90375606b2fd73c1224fe9e397ee151e28fa1e0c"
  1338 + integrity sha512-PZe8twm5Z4b61jt7GAQDor6KiMhgPgf4XmUb9zdrwTbgtC/Sj29gXP1dws9yEn4+aJeyXrjsD9XN7AWFhmnUfg==
  1339 +
  1340 +"@typescript-eslint/typescript-estree@3.7.1":
  1341 + version "3.7.1"
  1342 + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.1.tgz#ce1ffbd0fa53f34d4ce851a7a364e392432f6eb3"
  1343 + integrity sha512-m97vNZkI08dunYOr2lVZOHoyfpqRs0KDpd6qkGaIcLGhQ2WPtgHOd/eVbsJZ0VYCQvupKrObAGTOvk3tfpybYA==
  1344 + dependencies:
  1345 + "@typescript-eslint/types" "3.7.1"
  1346 + "@typescript-eslint/visitor-keys" "3.7.1"
  1347 + debug "^4.1.1"
  1348 + glob "^7.1.6"
  1349 + is-glob "^4.0.1"
  1350 + lodash "^4.17.15"
  1351 + semver "^7.3.2"
  1352 + tsutils "^3.17.1"
  1353 +
  1354 +"@typescript-eslint/visitor-keys@3.7.1":
  1355 + version "3.7.1"
  1356 + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.1.tgz#b90191e74efdee656be8c5a30f428ed16dda46d1"
  1357 + integrity sha512-xn22sQbEya+Utj2IqJHGLA3i1jDzR43RzWupxojbSWnj3nnPLavaQmWe5utw03CwYao3r00qzXfgJMGNkrzrAA==
  1358 + dependencies:
  1359 + eslint-visitor-keys "^1.1.0"
  1360 +
1286 1361 "@vue/component-compiler-utils@^3.1.0":
1287   - version "3.1.2"
1288   - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz#8213a5ff3202f9f2137fe55370f9e8b9656081c3"
1289   - integrity sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug==
  1362 + version "3.2.0"
  1363 + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz#8f85182ceed28e9b3c75313de669f83166d11e5d"
  1364 + integrity sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==
1290 1365 dependencies:
1291 1366 consolidate "^0.15.1"
1292 1367 hash-sum "^1.0.2"
... ... @@ -1501,9 +1576,9 @@ ajv-errors@^1.0.0:
1501 1576 integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
1502 1577  
1503 1578 ajv-keywords@^3.1.0, ajv-keywords@^3.4.1:
1504   - version "3.5.1"
1505   - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.1.tgz#b83ca89c5d42d69031f424cad49aada0236c6957"
1506   - integrity sha512-KWcq3xN8fDjSB+IMoh2VaXVhRI0BBGxoYp3rx7Pkb6z0cFjYR9Q9l4yZqqals0/zsioCmocC5H6UvsGD4MoIBA==
  1579 + version "3.5.2"
  1580 + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
  1581 + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
1507 1582  
1508 1583 ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.5.5:
1509 1584 version "6.12.3"
... ... @@ -1820,21 +1895,12 @@ aws4@^1.8.0:
1820 1895 resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2"
1821 1896 integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==
1822 1897  
1823   -axios@0.19.0:
1824   - version "0.19.0"
1825   - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
1826   - integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
1827   - dependencies:
1828   - follow-redirects "1.5.10"
1829   - is-buffer "^2.0.2"
1830   -
1831   -axios@^0.18.1:
1832   - version "0.18.1"
1833   - resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
1834   - integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==
  1898 +axios@^0.19.2:
  1899 + version "0.19.2"
  1900 + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
  1901 + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
1835 1902 dependencies:
1836 1903 follow-redirects "1.5.10"
1837   - is-buffer "^2.0.2"
1838 1904  
1839 1905 babel-eslint@^10.0.1:
1840 1906 version "10.1.0"
... ... @@ -2138,6 +2204,11 @@ buffer-crc32@^0.2.1, buffer-crc32@^0.2.13:
2138 2204 resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
2139 2205 integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
2140 2206  
  2207 +buffer-equal-constant-time@1.0.1:
  2208 + version "1.0.1"
  2209 + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
  2210 + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
  2211 +
2141 2212 buffer-fill@^1.0.0:
2142 2213 version "1.0.0"
2143 2214 resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
... ... @@ -2331,9 +2402,9 @@ caniuse-api@^3.0.0:
2331 2402 lodash.uniq "^4.5.0"
2332 2403  
2333 2404 caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001061, caniuse-lite@^1.0.30001093:
2334   - version "1.0.30001099"
2335   - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001099.tgz#540118fcc6842d1fde62f4ee5521d1ec6afdb40e"
2336   - integrity sha512-sdS9A+sQTk7wKoeuZBN/YMAHVztUfVnjDi4/UV3sDE8xoh7YR12hKW+pIdB3oqKGwr9XaFL2ovfzt9w8eUI5CA==
  2405 + version "1.0.30001107"
  2406 + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001107.tgz#809360df7a5b3458f627aa46b0f6ed6d5239da9a"
  2407 + integrity sha512-86rCH+G8onCmdN4VZzJet5uPELII59cUzDphko3thQFgAQG1RNa+sVLDoALIhRYmflo5iSIzWY3vu1XTWtNMQQ==
2337 2408  
2338 2409 caseless@~0.12.0:
2339 2410 version "0.12.0"
... ... @@ -2381,12 +2452,35 @@ chardet@^0.7.0:
2381 2452 resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
2382 2453 integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
2383 2454  
  2455 +chart.js@^2.9.3:
  2456 + version "2.9.3"
  2457 + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.3.tgz#ae3884114dafd381bc600f5b35a189138aac1ef7"
  2458 + integrity sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==
  2459 + dependencies:
  2460 + chartjs-color "^2.1.0"
  2461 + moment "^2.10.2"
  2462 +
  2463 +chartjs-color-string@^0.6.0:
  2464 + version "0.6.0"
  2465 + resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71"
  2466 + integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==
  2467 + dependencies:
  2468 + color-name "^1.0.0"
  2469 +
  2470 +chartjs-color@^2.1.0:
  2471 + version "2.4.1"
  2472 + resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0"
  2473 + integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==
  2474 + dependencies:
  2475 + chartjs-color-string "^0.6.0"
  2476 + color-convert "^1.9.3"
  2477 +
2384 2478 check-types@^8.0.3:
2385 2479 version "8.0.3"
2386 2480 resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552"
2387 2481 integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==
2388 2482  
2389   -chokidar@3.4.0, chokidar@^3.4.0:
  2483 +chokidar@3.4.0:
2390 2484 version "3.4.0"
2391 2485 resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.0.tgz#b30611423ce376357c765b9b8f904b9fba3c0be8"
2392 2486 integrity sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==
... ... @@ -2420,6 +2514,21 @@ chokidar@^2.1.8:
2420 2514 optionalDependencies:
2421 2515 fsevents "^1.2.7"
2422 2516  
  2517 +chokidar@^3.4.1:
  2518 + version "3.4.1"
  2519 + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.1.tgz#e905bdecf10eaa0a0b1db0c664481cc4cbc22ba1"
  2520 + integrity sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==
  2521 + dependencies:
  2522 + anymatch "~3.1.1"
  2523 + braces "~3.0.2"
  2524 + glob-parent "~5.1.0"
  2525 + is-binary-path "~2.1.0"
  2526 + is-glob "~4.0.1"
  2527 + normalize-path "~3.0.0"
  2528 + readdirp "~3.4.0"
  2529 + optionalDependencies:
  2530 + fsevents "~2.1.2"
  2531 +
2423 2532 chownr@^1.1.1:
2424 2533 version "1.1.4"
2425 2534 resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
... ... @@ -2545,7 +2654,7 @@ collection-visit@^1.0.0:
2545 2654 map-visit "^1.0.0"
2546 2655 object-visit "^1.0.0"
2547 2656  
2548   -color-convert@^1.9.0, color-convert@^1.9.1:
  2657 +color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3:
2549 2658 version "1.9.3"
2550 2659 resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
2551 2660 integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
... ... @@ -2691,6 +2800,11 @@ config-chain@^1.1.11:
2691 2800 ini "^1.3.4"
2692 2801 proto-list "~1.2.1"
2693 2802  
  2803 +confusing-browser-globals@^1.0.9:
  2804 + version "1.0.9"
  2805 + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd"
  2806 + integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==
  2807 +
2694 2808 connect-history-api-fallback@^1.6.0:
2695 2809 version "1.6.0"
2696 2810 resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
... ... @@ -3104,11 +3218,6 @@ dashdash@^1.12.0:
3104 3218 dependencies:
3105 3219 assert-plus "^1.0.0"
3106 3220  
3107   -date-fns@^2.0.0-beta.4:
3108   - version "2.14.0"
3109   - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.14.0.tgz#359a87a265bb34ef2e38f93ecf63ac453f9bc7ba"
3110   - integrity sha512-1zD+68jhFgDIM0rF05rcwYO8cExdNqxjq4xP1QKM60Q45mnO6zaMWB4tOzrIr4M4GSLntsKeE4c9Bdl2jhL/yw==
3111   -
3112 3221 de-indent@^1.0.2:
3113 3222 version "1.0.2"
3114 3223 resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
... ... @@ -3416,6 +3525,13 @@ ecc-jsbn@~0.1.1:
3416 3525 jsbn "~0.1.0"
3417 3526 safer-buffer "^2.1.0"
3418 3527  
  3528 +ecdsa-sig-formatter@1.0.11:
  3529 + version "1.0.11"
  3530 + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
  3531 + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
  3532 + dependencies:
  3533 + safe-buffer "^5.0.1"
  3534 +
3419 3535 ee-first@1.1.1:
3420 3536 version "1.1.1"
3421 3537 resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
... ... @@ -3447,9 +3563,9 @@ electron-osx-sign@^0.4.11:
3447 3563 plist "^3.0.1"
3448 3564  
3449 3565 electron-to-chromium@^1.3.488:
3450   - version "1.3.496"
3451   - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.496.tgz#3f43d32930481d82ad3663d79658e7c59a58af0b"
3452   - integrity sha512-TXY4mwoyowwi4Lsrq9vcTUYBThyc1b2hXaTZI13p8/FRhY2CTaq5lK+DVjhYkKiTLsKt569Xes+0J5JsVXFurQ==
  3566 + version "1.3.512"
  3567 + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.512.tgz#620e6731c693ddaaf3750f23dde7f7c4347b7327"
  3568 + integrity sha512-y02hdFg7c4jTfREcXf4fRhHLt7BzofMgd7JAKY+u9i62E0D1eIpLQPFo5/eboZL0bIVY9YHZA53+vCGNFREOXA==
3453 3569  
3454 3570 elementtree@0.1.7:
3455 3571 version "0.1.7"
... ... @@ -3499,9 +3615,9 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
3499 3615 once "^1.4.0"
3500 3616  
3501 3617 enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0:
3502   - version "4.2.0"
3503   - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d"
3504   - integrity sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==
  3618 + version "4.3.0"
  3619 + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz#3b806f3bfafc1ec7de69551ef93cca46c1704126"
  3620 + integrity sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==
3505 3621 dependencies:
3506 3622 graceful-fs "^4.1.2"
3507 3623 memory-fs "^0.5.0"
... ... @@ -3575,9 +3691,9 @@ es6-error@^4.1.1:
3575 3691 integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
3576 3692  
3577 3693 escalade@^3.0.1:
3578   - version "3.0.1"
3579   - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.1.tgz#52568a77443f6927cd0ab9c73129137533c965ed"
3580   - integrity sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA==
  3694 + version "3.0.2"
  3695 + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4"
  3696 + integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==
3581 3697  
3582 3698 escape-html@^1.0.1, escape-html@~1.0.3:
3583 3699 version "1.0.3"
... ... @@ -3594,10 +3710,14 @@ escape-string-regexp@^4.0.0:
3594 3710 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
3595 3711 integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
3596 3712  
3597   -eslint-config-standard@^14.1.0:
3598   - version "14.1.1"
3599   - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea"
3600   - integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==
  3713 +eslint-config-airbnb-base@^14.0.0:
  3714 + version "14.2.0"
  3715 + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz#fe89c24b3f9dc8008c9c0d0d88c28f95ed65e9c4"
  3716 + integrity sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q==
  3717 + dependencies:
  3718 + confusing-browser-globals "^1.0.9"
  3719 + object.assign "^4.1.0"
  3720 + object.entries "^1.1.2"
3601 3721  
3602 3722 eslint-import-resolver-node@^0.3.3:
3603 3723 version "0.3.4"
... ... @@ -3626,15 +3746,7 @@ eslint-module-utils@^2.6.0:
3626 3746 debug "^2.6.9"
3627 3747 pkg-dir "^2.0.0"
3628 3748  
3629   -eslint-plugin-es@^3.0.0:
3630   - version "3.0.1"
3631   - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893"
3632   - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==
3633   - dependencies:
3634   - eslint-utils "^2.0.0"
3635   - regexpp "^3.0.0"
3636   -
3637   -eslint-plugin-import@^2.14.0:
  3749 +eslint-plugin-import@^2.20.1:
3638 3750 version "2.22.0"
3639 3751 resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e"
3640 3752 integrity sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==
... ... @@ -3653,28 +3765,6 @@ eslint-plugin-import@^2.14.0:
3653 3765 resolve "^1.17.0"
3654 3766 tsconfig-paths "^3.9.0"
3655 3767  
3656   -eslint-plugin-node@^11.0.0:
3657   - version "11.1.0"
3658   - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d"
3659   - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==
3660   - dependencies:
3661   - eslint-plugin-es "^3.0.0"
3662   - eslint-utils "^2.0.0"
3663   - ignore "^5.1.1"
3664   - minimatch "^3.0.4"
3665   - resolve "^1.10.1"
3666   - semver "^6.1.0"
3667   -
3668   -eslint-plugin-promise@^4.0.1:
3669   - version "4.2.1"
3670   - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a"
3671   - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
3672   -
3673   -eslint-plugin-standard@^4.0.0:
3674   - version "4.0.1"
3675   - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4"
3676   - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==
3677   -
3678 3768 eslint-plugin-vue@^6.1.2:
3679 3769 version "6.2.2"
3680 3770 resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz#27fecd9a3a24789b0f111ecdd540a9e56198e0fe"
... ... @@ -3816,9 +3906,9 @@ eventemitter3@^4.0.0:
3816 3906 integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==
3817 3907  
3818 3908 events@^3.0.0:
3819   - version "3.1.0"
3820   - resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59"
3821   - integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==
  3909 + version "3.2.0"
  3910 + resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379"
  3911 + integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==
3822 3912  
3823 3913 eventsource@^1.0.7:
3824 3914 version "1.0.7"
... ... @@ -4836,7 +4926,7 @@ ignore@^4.0.6:
4836 4926 resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
4837 4927 integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
4838 4928  
4839   -ignore@^5.1.1, ignore@^5.1.4:
  4929 +ignore@^5.1.4:
4840 4930 version "5.1.8"
4841 4931 resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
4842 4932 integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
... ... @@ -4959,9 +5049,9 @@ inquirer@7.2.0:
4959 5049 through "^2.3.6"
4960 5050  
4961 5051 inquirer@^7.0.0:
4962   - version "7.3.1"
4963   - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.1.tgz#ac6aba1abdfdd5ad34e7069370411edba17f6439"
4964   - integrity sha512-/+vOpHQHhoh90Znev8BXiuw1TDQ7IDxWsQnFafUEoK5+4uN5Eoz1p+3GqOj/NtzEi9VzWKQcV9Bm+i8moxedsA==
  5052 + version "7.3.3"
  5053 + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003"
  5054 + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==
4965 5055 dependencies:
4966 5056 ansi-escapes "^4.2.1"
4967 5057 chalk "^4.1.0"
... ... @@ -4969,7 +5059,7 @@ inquirer@^7.0.0:
4969 5059 cli-width "^3.0.0"
4970 5060 external-editor "^3.0.3"
4971 5061 figures "^3.0.0"
4972   - lodash "^4.17.16"
  5062 + lodash "^4.17.19"
4973 5063 mute-stream "0.0.8"
4974 5064 run-async "^2.4.0"
4975 5065 rxjs "^6.6.0"
... ... @@ -5065,11 +5155,6 @@ is-buffer@^1.1.5:
5065 5155 resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
5066 5156 integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
5067 5157  
5068   -is-buffer@^2.0.2:
5069   - version "2.0.4"
5070   - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
5071   - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
5072   -
5073 5158 is-callable@^1.1.4, is-callable@^1.2.0:
5074 5159 version "1.2.0"
5075 5160 resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
... ... @@ -5453,6 +5538,22 @@ jsonfile@^6.0.1:
5453 5538 optionalDependencies:
5454 5539 graceful-fs "^4.1.6"
5455 5540  
  5541 +jsonwebtoken@^8.5.1:
  5542 + version "8.5.1"
  5543 + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
  5544 + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
  5545 + dependencies:
  5546 + jws "^3.2.2"
  5547 + lodash.includes "^4.3.0"
  5548 + lodash.isboolean "^3.0.3"
  5549 + lodash.isinteger "^4.0.4"
  5550 + lodash.isnumber "^3.0.3"
  5551 + lodash.isplainobject "^4.0.6"
  5552 + lodash.isstring "^4.0.1"
  5553 + lodash.once "^4.0.0"
  5554 + ms "^2.1.1"
  5555 + semver "^5.6.0"
  5556 +
5456 5557 jsprim@^1.2.2:
5457 5558 version "1.4.1"
5458 5559 resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
... ... @@ -5463,6 +5564,23 @@ jsprim@^1.2.2:
5463 5564 json-schema "0.2.3"
5464 5565 verror "1.10.0"
5465 5566  
  5567 +jwa@^1.4.1:
  5568 + version "1.4.1"
  5569 + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
  5570 + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
  5571 + dependencies:
  5572 + buffer-equal-constant-time "1.0.1"
  5573 + ecdsa-sig-formatter "1.0.11"
  5574 + safe-buffer "^5.0.1"
  5575 +
  5576 +jws@^3.2.2:
  5577 + version "3.2.2"
  5578 + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
  5579 + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
  5580 + dependencies:
  5581 + jwa "^1.4.1"
  5582 + safe-buffer "^5.0.1"
  5583 +
5466 5584 keyv@^3.0.0:
5467 5585 version "3.1.0"
5468 5586 resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
... ... @@ -5654,16 +5772,46 @@ lodash.flatten@^4.4.0:
5654 5772 resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
5655 5773 integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
5656 5774  
  5775 +lodash.includes@^4.3.0:
  5776 + version "4.3.0"
  5777 + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
  5778 + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
  5779 +
  5780 +lodash.isboolean@^3.0.3:
  5781 + version "3.0.3"
  5782 + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
  5783 + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
  5784 +
  5785 +lodash.isinteger@^4.0.4:
  5786 + version "4.0.4"
  5787 + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
  5788 + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
  5789 +
  5790 +lodash.isnumber@^3.0.3:
  5791 + version "3.0.3"
  5792 + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
  5793 + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
  5794 +
5657 5795 lodash.isplainobject@^4.0.6:
5658 5796 version "4.0.6"
5659 5797 resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
5660 5798 integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
5661 5799  
  5800 +lodash.isstring@^4.0.1:
  5801 + version "4.0.1"
  5802 + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
  5803 + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
  5804 +
5662 5805 lodash.memoize@^4.1.2:
5663 5806 version "4.1.2"
5664 5807 resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
5665 5808 integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
5666 5809  
  5810 +lodash.once@^4.0.0:
  5811 + version "4.1.1"
  5812 + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
  5813 + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
  5814 +
5667 5815 lodash.template@4.5.0, lodash.template@^4.5.0:
5668 5816 version "4.5.0"
5669 5817 resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
... ... @@ -5694,7 +5842,7 @@ lodash.uniq@^4.5.0:
5694 5842 resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
5695 5843 integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
5696 5844  
5697   -lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.5, lodash@~4.17.10:
  5845 +lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.5, lodash@~4.17.10:
5698 5846 version "4.17.19"
5699 5847 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
5700 5848 integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
... ... @@ -6014,9 +6162,9 @@ minipass-flush@^1.0.5:
6014 6162 minipass "^3.0.0"
6015 6163  
6016 6164 minipass-pipeline@^1.2.2:
6017   - version "1.2.3"
6018   - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz#55f7839307d74859d6e8ada9c3ebe72cec216a34"
6019   - integrity sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==
  6165 + version "1.2.4"
  6166 + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c"
  6167 + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==
6020 6168 dependencies:
6021 6169 minipass "^3.0.0"
6022 6170  
... ... @@ -6059,7 +6207,7 @@ mixin-deep@^1.2.0:
6059 6207 for-in "^1.0.2"
6060 6208 is-extendable "^1.0.1"
6061 6209  
6062   -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1, mkdirp@~0.5.x:
  6210 +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1, mkdirp@~0.5.x:
6063 6211 version "0.5.5"
6064 6212 resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
6065 6213 integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
... ... @@ -6071,7 +6219,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
6071 6219 resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
6072 6220 integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
6073 6221  
6074   -moment@^2.22.1:
  6222 +moment@^2.10.2, moment@^2.22.1:
6075 6223 version "2.27.0"
6076 6224 resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d"
6077 6225 integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==
... ... @@ -6236,9 +6384,9 @@ node-loader@0.6.0:
6236 6384 integrity sha1-x5fvUQle1YWZArFX9jhPY2HgWug=
6237 6385  
6238 6386 node-releases@^1.1.58:
6239   - version "1.1.59"
6240   - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.59.tgz#4d648330641cec704bff10f8e4fe28e453ab8e8e"
6241   - integrity sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw==
  6387 + version "1.1.60"
  6388 + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084"
  6389 + integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==
6242 6390  
6243 6391 node-sass@4.14.1:
6244 6392 version "4.14.1"
... ... @@ -6418,6 +6566,15 @@ object.assign@^4.1.0:
6418 6566 has-symbols "^1.0.0"
6419 6567 object-keys "^1.0.11"
6420 6568  
  6569 +object.entries@^1.1.2:
  6570 + version "1.1.2"
  6571 + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add"
  6572 + integrity sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==
  6573 + dependencies:
  6574 + define-properties "^1.1.3"
  6575 + es-abstract "^1.17.5"
  6576 + has "^1.0.3"
  6577 +
6421 6578 object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0:
6422 6579 version "2.1.0"
6423 6580 resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649"
... ... @@ -6887,13 +7044,13 @@ plist@^3.0.1:
6887 7044 xmldom "0.1.x"
6888 7045  
6889 7046 portfinder@^1.0.26:
6890   - version "1.0.26"
6891   - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70"
6892   - integrity sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==
  7047 + version "1.0.28"
  7048 + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778"
  7049 + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==
6893 7050 dependencies:
6894 7051 async "^2.6.2"
6895 7052 debug "^3.1.1"
6896   - mkdirp "^0.5.1"
  7053 + mkdirp "^0.5.5"
6897 7054  
6898 7055 posix-character-classes@^0.1.0:
6899 7056 version "0.1.1"
... ... @@ -7044,14 +7201,14 @@ postcss-modules-extract-imports@^2.0.0:
7044 7201 postcss "^7.0.5"
7045 7202  
7046 7203 postcss-modules-local-by-default@^3.0.2:
7047   - version "3.0.2"
7048   - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915"
7049   - integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ==
  7204 + version "3.0.3"
  7205 + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0"
  7206 + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==
7050 7207 dependencies:
7051 7208 icss-utils "^4.1.1"
7052   - postcss "^7.0.16"
  7209 + postcss "^7.0.32"
7053 7210 postcss-selector-parser "^6.0.2"
7054   - postcss-value-parser "^4.0.0"
  7211 + postcss-value-parser "^4.1.0"
7055 7212  
7056 7213 postcss-modules-scope@^2.2.0:
7057 7214 version "2.2.0"
... ... @@ -7235,7 +7392,7 @@ postcss-value-parser@^3.0.0:
7235 7392 resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281"
7236 7393 integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==
7237 7394  
7238   -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
  7395 +postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
7239 7396 version "4.1.0"
7240 7397 resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
7241 7398 integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
... ... @@ -7249,7 +7406,7 @@ postcss@^6.0.23:
7249 7406 source-map "^0.6.1"
7250 7407 supports-color "^5.4.0"
7251 7408  
7252   -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.30, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
  7409 +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.30, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6:
7253 7410 version "7.0.32"
7254 7411 resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d"
7255 7412 integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==
... ... @@ -7402,9 +7559,9 @@ qs@~6.5.2:
7402 7559 integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
7403 7560  
7404 7561 quasar@^1.0.0:
7405   - version "1.12.10"
7406   - resolved "https://registry.yarnpkg.com/quasar/-/quasar-1.12.10.tgz#45daa4bfd14d66b67bb2da8413d0ae09a32af518"
7407   - integrity sha512-O8BQeRIfA/oun5YwUV7aMeKhqfmGy38EqTf4lWxPXhVo3Bs4ZN4r6DeR2X8OQHqr76fblQWxU48uPIZgB68VBg==
  7562 + version "1.12.13"
  7563 + resolved "https://registry.yarnpkg.com/quasar/-/quasar-1.12.13.tgz#236331b55a5403e42db5202ef8e66629aef4adf5"
  7564 + integrity sha512-e5cU3cxwZEc+MIJ6/a5IyV5HJ4B1WJscpEqDi+1BpIfVu4/9/WS9a0dnki5jVEvcsbuV4G133XCHQ09fdXoL1A==
7408 7565  
7409 7566 query-string@^4.1.0:
7410 7567 version "4.3.4"
... ... @@ -7552,9 +7709,9 @@ regenerate@^1.4.0:
7552 7709 integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==
7553 7710  
7554 7711 regenerator-runtime@^0.13.4:
7555   - version "0.13.5"
7556   - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
7557   - integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
  7712 + version "0.13.7"
  7713 + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
  7714 + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==
7558 7715  
7559 7716 regenerator-transform@^0.14.2:
7560 7717 version "0.14.5"
... ... @@ -7724,7 +7881,7 @@ resolve-url@^0.2.1:
7724 7881 resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
7725 7882 integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
7726 7883  
7727   -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.8.1:
  7884 +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.8.1:
7728 7885 version "1.17.0"
7729 7886 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
7730 7887 integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
... ... @@ -7965,7 +8122,7 @@ semver@7.3.2, semver@^7.3.2:
7965 8122 resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
7966 8123 integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
7967 8124  
7968   -semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0:
  8125 +semver@^6.0.0, semver@^6.1.2, semver@^6.3.0:
7969 8126 version "6.3.0"
7970 8127 resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
7971 8128 integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
... ... @@ -8872,11 +9029,18 @@ tsconfig-paths@^3.9.0:
8872 9029 minimist "^1.2.0"
8873 9030 strip-bom "^3.0.0"
8874 9031  
8875   -tslib@^1.10.0, tslib@^1.9.0:
  9032 +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
8876 9033 version "1.13.0"
8877 9034 resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
8878 9035 integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
8879 9036  
  9037 +tsutils@^3.17.1:
  9038 + version "3.17.1"
  9039 + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"
  9040 + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==
  9041 + dependencies:
  9042 + tslib "^1.8.1"
  9043 +
8880 9044 tty-browserify@0.0.0:
8881 9045 version "0.0.0"
8882 9046 resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
... ... @@ -9158,11 +9322,6 @@ validate-npm-package-license@^3.0.1:
9158 9322 spdx-correct "^3.0.0"
9159 9323 spdx-expression-parse "^3.0.0"
9160 9324  
9161   -validator@^10.9.0:
9162   - version "10.11.0"
9163   - resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228"
9164   - integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==
9165   -
9166 9325 vary@~1.1.2:
9167 9326 version "1.1.2"
9168 9327 resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
... ... @@ -9187,6 +9346,16 @@ vm-browserify@^1.0.1:
9187 9346 resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
9188 9347 integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
9189 9348  
  9349 +vue-chartjs@^3.5.0:
  9350 + version "3.5.0"
  9351 + resolved "https://registry.yarnpkg.com/vue-chartjs/-/vue-chartjs-3.5.0.tgz#edd0c2be94c521bcbc5357c24afb9f3560855f84"
  9352 + integrity sha512-yWNhG3B6g6lvYqNInP0WaDWNZG/SNb6XnltkjR0wYC5pmLm6jvdiotj8er7Mui8qkJGfLZe6ULjrZdHWjegAUg==
  9353 +
  9354 +vue-class-component@^7.1.0, vue-class-component@^7.2.2:
  9355 + version "7.2.5"
  9356 + resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.5.tgz#212b3548c4fdd3314774c4adbc1c3792a40b52d0"
  9357 + integrity sha512-0CSftHY0bDTD+4FbYkuFf6+iKDjZ4h2in2YYJDRMk5daZIjrgT9LjFHvP7Rzqy9/s1pij3zDtTSLRUjsPWMwqg==
  9358 +
9190 9359 vue-eslint-parser@^7.0.0:
9191 9360 version "7.1.0"
9192 9361 resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-7.1.0.tgz#9cdbcc823e656b087507a1911732b867ac101e83"
... ... @@ -9215,16 +9384,12 @@ vue-loader@15.9.2:
9215 9384 vue-hot-reload-api "^2.3.0"
9216 9385 vue-style-loader "^4.1.0"
9217 9386  
9218   -vue-mc@^0.6.0:
9219   - version "0.6.0"
9220   - resolved "https://registry.yarnpkg.com/vue-mc/-/vue-mc-0.6.0.tgz#cb5383e33b335f6109ff63451242b1e57cabc0af"
9221   - integrity sha512-URLyySD1qpa1uPtlOe8eBZIfk6gnKSC53JtP46gbNxbsQ+xcR5H1wohsxn5KrGVxKCMX2mqIElimLoixdahETw==
  9387 +vue-property-decorator@^8.3.0:
  9388 + version "8.5.1"
  9389 + resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz#571a91cf8d2b507f537d79bf8275af3184572fff"
  9390 + integrity sha512-O6OUN2OMsYTGPvgFtXeBU3jPnX5ffQ9V4I1WfxFQ6dqz6cOUbR3Usou7kgFpfiXDvV7dJQSFcJ5yUPgOtPPm1Q==
9222 9391 dependencies:
9223   - axios "0.19.0"
9224   - date-fns "^2.0.0-beta.4"
9225   - lodash "^4.17.11"
9226   - validator "^10.9.0"
9227   - vue "^2.5.17"
  9392 + vue-class-component "^7.1.0"
9228 9393  
9229 9394 vue-router@3.2.0:
9230 9395 version "3.2.0"
... ... @@ -9266,7 +9431,7 @@ vue-template-es2015-compiler@^1.9.0:
9266 9431 resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
9267 9432 integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
9268 9433  
9269   -vue@2.6.11, vue@^2.5.17:
  9434 +vue@2.6.11:
9270 9435 version "2.6.11"
9271 9436 resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
9272 9437 integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
... ... @@ -9284,14 +9449,14 @@ watchpack-chokidar2@^2.0.0:
9284 9449 chokidar "^2.1.8"
9285 9450  
9286 9451 watchpack@^1.6.1:
9287   - version "1.7.2"
9288   - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.2.tgz#c02e4d4d49913c3e7e122c3325365af9d331e9aa"
9289   - integrity sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==
  9452 + version "1.7.4"
  9453 + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.4.tgz#6e9da53b3c80bb2d6508188f5b200410866cd30b"
  9454 + integrity sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==
9290 9455 dependencies:
9291 9456 graceful-fs "^4.1.2"
9292 9457 neo-async "^2.5.0"
9293 9458 optionalDependencies:
9294   - chokidar "^3.4.0"
  9459 + chokidar "^3.4.1"
9295 9460 watchpack-chokidar2 "^2.0.0"
9296 9461  
9297 9462 wbuf@^1.1.0, wbuf@^1.7.3:
... ...