diff --git a/.gitignore b/.gitignore index 066e8b3..77ac0c0 100644 --- a/.gitignore +++ b/.gitignore @@ -257,7 +257,7 @@ local.properties # End of https://www.gitignore.io/api/java,node,intellij+all,visualstudiocode,eclipse -backend/src/main/resources/assets +backend/src/main/resources/static frontend/node !maven-wrapper.jar dependency-reduced-pom.xml diff --git a/backend/configuration.yml b/backend/configuration.yml deleted file mode 100644 index f2b2d14..0000000 --- a/backend/configuration.yml +++ /dev/null @@ -1,20 +0,0 @@ -database: - # the name of your JDBC driver - driverClass: org.h2.Driver - - # the JDBC URL - url: jdbc:h2:file:./sampledatabase.db - - # any properties specific to your JDBC driver: - properties: - foreign_keys: true - hibernate.hbm2ddl.auto: update - -server: - rootPath: /api/ - requestLog: - appenders: - - type: console - queueSize: 2048 - -adminPassword: "testPassword" diff --git a/backend/pom.xml b/backend/pom.xml index 6711818..f253932 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -1,198 +1,149 @@ - 4.0.0 - backend + uk.co.neviyn + observationdatabase + PRE-ALPHA jar + observationdatabase + Training observation database + - uk.co.neviyn - Observations - 0.0.1-SNAPSHOT + org.springframework.boot + spring-boot-starter-parent + 2.0.5.RELEASE + UTF-8 UTF-8 1.8 - 1.3.5 + 1.2.71 - org.projectlombok - lombok - 1.18.2 + org.springframework.boot + spring-boot-starter-actuator - io.dropwizard - dropwizard-core - ${dropwizard.version} + org.springframework.boot + spring-boot-starter-data-jpa - io.dropwizard - dropwizard-hibernate - ${dropwizard.version} + org.springframework.boot + spring-boot-starter-web - io.dropwizard - dropwizard-assets - ${dropwizard.version} + com.fasterxml.jackson.module + jackson-module-kotlin - io.dropwizard - dropwizard-testing - ${dropwizard.version} - test + org.jetbrains.kotlin + kotlin-stdlib-jdk8 - io.dropwizard - dropwizard-auth - ${dropwizard.version} + org.jetbrains.kotlin + kotlin-reflect + - org.mockito - mockito-core - 2.22.0 - test - - - org.apache.commons - commons-lang3 - 3.8 + org.springframework.boot + spring-boot-devtools + runtime com.h2database h2 - 1.4.197 + runtime + + + joda-time + joda-time + + + + org.springframework.boot + spring-boot-starter-test + test + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin - maven-resources-plugin - 3.1.0 - - - copy Vue.js frontend content - generate-resources - - copy-resources - - - src/main/resources/assets - true - - - ${project.parent.basedir}/frontend/target/dist - - **/*.map - - - - - - + org.springframework.boot + spring-boot-maven-plugin - maven-clean-plugin - 3.1.0 + kotlin-maven-plugin + org.jetbrains.kotlin - - - src/main/resources/assets - false - - + + -Xjsr305=strict + + + spring + jpa + + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-maven-noarg + ${kotlin.version} + + - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.0 - - - - true - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.0 - - true - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - uk.co.neviyn.observations.ObservationsApplication - - - - - - package - - shade - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - - - java - - - - - - server - configuration.yml - - uk.co.neviyn.observations.ObservationsApplication - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - - - + maven-resources-plugin + 3.1.0 + + + copy Vue.js frontend content + generate-resources + + copy-resources + + + src/main/resources/static + true + + + ../frontend/target/dist + + **/*.map + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + src/main/resources/static + false + + + + + diff --git a/backend/src/main/java/uk/co/neviyn/observations/ObservationsApplication.java b/backend/src/main/java/uk/co/neviyn/observations/ObservationsApplication.java deleted file mode 100644 index 73cedb9..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/ObservationsApplication.java +++ /dev/null @@ -1,65 +0,0 @@ -package uk.co.neviyn.observations; - -import io.dropwizard.Application; -import io.dropwizard.assets.AssetsBundle; -import io.dropwizard.auth.AuthDynamicFeature; -import io.dropwizard.auth.AuthValueFactoryProvider; -import io.dropwizard.auth.basic.BasicCredentialAuthFilter; -import io.dropwizard.db.DataSourceFactory; -import io.dropwizard.hibernate.HibernateBundle; -import io.dropwizard.jersey.setup.JerseyEnvironment; -import io.dropwizard.setup.Bootstrap; -import io.dropwizard.setup.Environment; -import uk.co.neviyn.observations.auth.SimpleAuthenticator; -import uk.co.neviyn.observations.core.Observation; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.Tutor; -import uk.co.neviyn.observations.core.User; -import uk.co.neviyn.observations.dao.ObservationDao; -import uk.co.neviyn.observations.dao.SiteDao; -import uk.co.neviyn.observations.dao.TutorDao; -import uk.co.neviyn.observations.resources.ObservationResource; -import uk.co.neviyn.observations.resources.SiteResource; -import uk.co.neviyn.observations.resources.TutorResource; - -public class ObservationsApplication extends Application { - - private final HibernateBundle hibernate = - new HibernateBundle(Observation.class, Tutor.class, Site.class) { - @Override - public DataSourceFactory getDataSourceFactory(ObservationsConfiguration configuration) { - return configuration.getDataSourceFactory(); - } - }; - - public static void main(String[] args) throws Exception { - new ObservationsApplication().run(args); - } - - @Override - public void initialize(Bootstrap bootstrap) { - super.initialize(bootstrap); - bootstrap.addBundle(hibernate); - bootstrap.addBundle(new AssetsBundle("/assets/", "/", "/index.html")); - } - - @Override - public void run(ObservationsConfiguration observationsConfiguration, Environment environment) { - final JerseyEnvironment jersey = environment.jersey(); - jersey.register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder() - .setAuthenticator(new SimpleAuthenticator( - observationsConfiguration.getAdminPassword()) - ).setRealm("SECURITY").buildAuthFilter())); - jersey.register(new AuthValueFactoryProvider.Binder<>(User.class)); - TutorDao tutorDao = new TutorDao(hibernate.getSessionFactory()); - SiteDao siteDao = new SiteDao(hibernate.getSessionFactory()); - ObservationDao observationDao = new ObservationDao(hibernate.getSessionFactory()); - final TutorResource tutorResource = new TutorResource(tutorDao, siteDao); - jersey.register(tutorResource); - final ObservationResource observationResource = - new ObservationResource(observationDao, tutorDao, siteDao); - jersey.register(observationResource); - final SiteResource siteResource = new SiteResource(siteDao); - jersey.register(siteResource); - } -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/ObservationsConfiguration.java b/backend/src/main/java/uk/co/neviyn/observations/ObservationsConfiguration.java deleted file mode 100644 index 31b61af..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/ObservationsConfiguration.java +++ /dev/null @@ -1,34 +0,0 @@ -package uk.co.neviyn.observations; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.dropwizard.Configuration; -import io.dropwizard.db.DataSourceFactory; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -public class ObservationsConfiguration extends Configuration { - @Valid - @NotNull - private DataSourceFactory database = new DataSourceFactory(); - - @Valid - @NotNull - private String adminPassword; - - @JsonProperty("database") - public void setDataSourceFactory(DataSourceFactory factory) { - this.database = factory; - } - - @JsonProperty("database") - public DataSourceFactory getDataSourceFactory() { - return database; - } - - @JsonProperty("adminPassword") - public String getAdminPassword() { - return adminPassword; - } - -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/api/AverageStats.java b/backend/src/main/java/uk/co/neviyn/observations/api/AverageStats.java deleted file mode 100644 index 62930f2..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/api/AverageStats.java +++ /dev/null @@ -1,34 +0,0 @@ -package uk.co.neviyn.observations.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import org.joda.time.DateTime; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class AverageStats { - - @NonNull - @JsonProperty - private double monitoring; - @NonNull - @JsonProperty - private double control; - @NonNull - @JsonProperty - private double conservatism; - @NonNull - @JsonProperty - private double teamwork; - @NonNull - @JsonProperty - private double knowledge; - - @NonNull - @JsonProperty - private DateTime date; -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/api/AverageStatsChartJs.java b/backend/src/main/java/uk/co/neviyn/observations/api/AverageStatsChartJs.java deleted file mode 100644 index a6cd89a..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/api/AverageStatsChartJs.java +++ /dev/null @@ -1,76 +0,0 @@ -package uk.co.neviyn.observations.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.ArrayList; -import java.util.List; - -import lombok.Data; -import lombok.NonNull; - -/** - * AverageStats in a format easily readable by Chart.js - */ -@Data -public class AverageStatsChartJs { - - @NonNull - @JsonProperty - private List labels = new ArrayList<>(); - - @NonNull - @JsonProperty - private List datasets = new ArrayList<>(); - - /** - * A list of AverageStats converted to a format compatible with Chart.js. - * @param inputData List of average stats. - */ - public AverageStatsChartJs(List inputData) { - List monitoring = new ArrayList<>(); - List control = new ArrayList<>(); - List conservatism = new ArrayList<>(); - List teamwork = new ArrayList<>(); - List knowledge = new ArrayList<>(); - for (AverageStats averageStats: inputData) { - labels.add(averageStats.getDate().toString("yyyy-MM-dd")); - monitoring.add(averageStats.getMonitoring()); - control.add(averageStats.getControl()); - conservatism.add(averageStats.getConservatism()); - teamwork.add(averageStats.getTeamwork()); - knowledge.add(averageStats.getKnowledge()); - } - datasets.add(new Dataset("Monitoring", "#F90", monitoring)); - datasets.add(new Dataset("Control", "#3F0", control)); - datasets.add(new Dataset("Conservatism", "#33F", conservatism)); - datasets.add(new Dataset("Teamwork", "#FF0", teamwork)); - datasets.add(new Dataset("Knowledge", "#000", knowledge)); - } - - class Dataset { - @NonNull - @JsonProperty - private final String label; - - @NonNull - @JsonProperty - private final String backgroundColor; - - @NonNull - @JsonProperty - private final String borderColor; - - @NonNull - @JsonProperty - private final List data; - - @JsonProperty - private final boolean fill = false; - - Dataset(String label, String color, List data) { - this.label = label; - this.backgroundColor = color; - this.borderColor = color; - this.data = data; - } - } -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/api/NewObservation.java b/backend/src/main/java/uk/co/neviyn/observations/api/NewObservation.java deleted file mode 100644 index 443a387..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/api/NewObservation.java +++ /dev/null @@ -1,57 +0,0 @@ -package uk.co.neviyn.observations.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import uk.co.neviyn.observations.core.ObservationEntry; - -@Data -@NoArgsConstructor -@Builder -@AllArgsConstructor(access = AccessLevel.PROTECTED) -public class NewObservation { - - @NonNull - @JsonProperty - private long siteId; - - @NonNull - @JsonProperty - private List tutorIds; - - @NonNull - @JsonProperty - private String observed; - @NonNull - @JsonProperty - private String type; - @NonNull - @JsonProperty - private String whom; - - @NonNull - @JsonProperty - private float monitoring; - @NonNull - @JsonProperty - private float control; - @NonNull - @JsonProperty - private float conservatism; - @NonNull - @JsonProperty - private float teamwork; - @NonNull - @JsonProperty - private float knowledge; - - @NonNull - @JsonProperty - private List rawData; - -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/api/SelectOption.java b/backend/src/main/java/uk/co/neviyn/observations/api/SelectOption.java deleted file mode 100644 index d4fcc0d..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/api/SelectOption.java +++ /dev/null @@ -1,21 +0,0 @@ -package uk.co.neviyn.observations.api; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class SelectOption { - @NonNull - @JsonProperty - private String text; - - @NonNull - @JsonProperty - private T value; - -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/auth/SimpleAuthenticator.java b/backend/src/main/java/uk/co/neviyn/observations/auth/SimpleAuthenticator.java deleted file mode 100644 index 6a254c1..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/auth/SimpleAuthenticator.java +++ /dev/null @@ -1,21 +0,0 @@ -package uk.co.neviyn.observations.auth; - -import io.dropwizard.auth.Authenticator; -import io.dropwizard.auth.basic.BasicCredentials; -import java.util.Optional; -import lombok.AllArgsConstructor; -import uk.co.neviyn.observations.core.User; - -@AllArgsConstructor -public class SimpleAuthenticator implements Authenticator { - - private final String adminPassword; - - @Override - public Optional authenticate(BasicCredentials credentials) { - if (adminPassword.equals(credentials.getPassword())) { - return Optional.of(new User(credentials.getUsername())); - } - return Optional.empty(); - } -} \ No newline at end of file diff --git a/backend/src/main/java/uk/co/neviyn/observations/core/Observation.java b/backend/src/main/java/uk/co/neviyn/observations/core/Observation.java deleted file mode 100644 index 366ef30..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/core/Observation.java +++ /dev/null @@ -1,86 +0,0 @@ -package uk.co.neviyn.observations.core; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import java.util.List; -import java.util.Set; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import org.joda.time.DateTime; - -@Entity -@Table(name = "OBSERVATION") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class Observation implements Serializable { - - @NonNull - @JsonProperty - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private long id; - - @ManyToOne - @JoinColumn(name = "site_id", nullable = false) - @JsonIgnore - @EqualsAndHashCode.Exclude - private Site site; - - @ManyToMany(mappedBy = "observations") - @JsonIgnore - @EqualsAndHashCode.Exclude - private Set tutors; - - @NonNull - @JsonProperty - private String observed; - - @NonNull - @JsonProperty - private String whom; - - @NonNull - @JsonProperty - private TrainingType type; - - @NonNull - @JsonProperty - private float monitoring; - @NonNull - @JsonProperty - private float control; - @NonNull - @JsonProperty - private float conservatism; - @NonNull - @JsonProperty - private float teamwork; - @NonNull - @JsonProperty - private float knowledge; - - @NonNull - @JsonProperty - @ElementCollection - private List observations; - - @NonNull - @JsonProperty - private DateTime date; -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/core/ObservationEntry.java b/backend/src/main/java/uk/co/neviyn/observations/core/ObservationEntry.java deleted file mode 100644 index c38137b..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/core/ObservationEntry.java +++ /dev/null @@ -1,32 +0,0 @@ -package uk.co.neviyn.observations.core; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import javax.persistence.Embeddable; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -@Data -@NoArgsConstructor -@AllArgsConstructor -@Embeddable -public class ObservationEntry implements Serializable { - - @NonNull - @JsonProperty - private String type; - - @NonNull - @JsonProperty - private int rating; - - @NonNull - @JsonProperty - private String strengths; - - @NonNull - @JsonProperty - private String improvements; -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/core/Site.java b/backend/src/main/java/uk/co/neviyn/observations/core/Site.java deleted file mode 100644 index f23618d..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/core/Site.java +++ /dev/null @@ -1,47 +0,0 @@ -package uk.co.neviyn.observations.core; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -@Entity -@Table(name = "SITE") -@Data -@NoArgsConstructor -@Builder -@AllArgsConstructor -public class Site implements Serializable { - - @NonNull - @JsonProperty - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private long id; - - @NonNull - @JsonProperty - private String name; - - @OneToMany(mappedBy = "site") - @JsonIgnore - @EqualsAndHashCode.Exclude - private Set tutors; - - @OneToMany(mappedBy = "site") - @JsonIgnore - @EqualsAndHashCode.Exclude - private Set observations; -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/core/TrainingType.java b/backend/src/main/java/uk/co/neviyn/observations/core/TrainingType.java deleted file mode 100644 index a799171..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/core/TrainingType.java +++ /dev/null @@ -1,5 +0,0 @@ -package uk.co.neviyn.observations.core; - -public enum TrainingType { - INITIAL, CONTINUING -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/core/Tutor.java b/backend/src/main/java/uk/co/neviyn/observations/core/Tutor.java deleted file mode 100644 index caf2b42..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/core/Tutor.java +++ /dev/null @@ -1,56 +0,0 @@ -package uk.co.neviyn.observations.core; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; -import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; - -@Entity -@Table(name = "TUTOR") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class Tutor implements Serializable { - - @NonNull - @JsonProperty - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private long id; - - @NonNull - @JsonProperty - private String name; - - @ManyToOne - @JoinColumn(name = "site_id", nullable = false) - @JsonIgnore - @EqualsAndHashCode.Exclude - private Site site; - - @ManyToMany - @JsonIgnore - @JoinTable( - name = "TUTOR_OBSERVATION", - joinColumns = { @JoinColumn(name = "tutor_id")}, - inverseJoinColumns = { @JoinColumn(name = "observation_id")} - ) - @EqualsAndHashCode.Exclude - private Set observations; -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/core/User.java b/backend/src/main/java/uk/co/neviyn/observations/core/User.java deleted file mode 100644 index a4afecf..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/core/User.java +++ /dev/null @@ -1,15 +0,0 @@ -package uk.co.neviyn.observations.core; - -import java.security.Principal; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@AllArgsConstructor -@NoArgsConstructor -public class User implements Principal { - - private String name; - -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/dao/ObservationDao.java b/backend/src/main/java/uk/co/neviyn/observations/dao/ObservationDao.java deleted file mode 100644 index 8896776..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/dao/ObservationDao.java +++ /dev/null @@ -1,104 +0,0 @@ -package uk.co.neviyn.observations.dao; - -import io.dropwizard.hibernate.AbstractDAO; -import java.util.ArrayList; -import java.util.List; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; -import org.hibernate.SessionFactory; -import org.hibernate.query.Query; -import org.joda.time.DateTime; -import uk.co.neviyn.observations.api.AverageStats; -import uk.co.neviyn.observations.core.Observation; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.Tutor; - -public class ObservationDao extends AbstractDAO { - public ObservationDao(SessionFactory sessionFactory) { - super(sessionFactory); - } - - public Observation get(long id) { - return super.get(id); - } - - public Observation persist(Observation observation) { - return super.persist(observation); - } - - public List listAll() { - return currentSession().createQuery("from Observation", Observation.class).list(); - } - - public List filteredList(Site site, Tutor tutor, DateTime startDate, DateTime endDate, String whom) { - final CriteriaBuilder builder = currentSession().getCriteriaBuilder(); - CriteriaQuery criteriaQuery = builder.createQuery(Observation.class); - Root root = criteriaQuery.from(Observation.class); - List predicates = new ArrayList<>(); - if (site != null) { - predicates.add(builder.equal(root.get("site"), site)); - } - if (tutor != null) { - predicates.add(builder.equal(root.join("tutors"), tutor)); - } - if (startDate != null) { - predicates.add(builder.greaterThanOrEqualTo(root.get("date"), startDate)); - } - if (endDate != null) { - predicates.add(builder.lessThanOrEqualTo(root.get("date"), endDate)); - } - if (whom != null) { - predicates.add(builder.equal(root.get("whom"), whom)); - } - if (!predicates.isEmpty()) { - criteriaQuery.having(predicates.toArray(new Predicate[0])); - } - Query query = currentSession().createQuery(criteriaQuery); - System.out.println(query.getQueryString()); - return query.getResultList(); - } - - /** - * Generate the average observation stats with data constraints. - * - * @param site Restrict to a site. - * @param tutor Restrict to a tutor. - * @param startDate Restrict to after a certain date. - * @param endDate Restrict to before a certain date. - * @param whom Restrict to a particular person/group who was observed. - * @return Average observation scores per day. - */ - public List averageStats(Site site, Tutor tutor, DateTime startDate, DateTime endDate, String whom) { - CriteriaBuilder builder = currentSession().getCriteriaBuilder(); - CriteriaQuery criteriaQuery = builder.createQuery(AverageStats.class); - Root root = criteriaQuery.from(Observation.class); - criteriaQuery.multiselect(builder.avg(root.get("monitoring")), builder.avg(root.get("control")), - builder.avg(root.get("conservatism")), builder.avg(root.get("teamwork")), builder.avg(root.get("knowledge")), - root.get("date")); - criteriaQuery.groupBy(root.get("date")); - List predicates = new ArrayList<>(); - if (site != null) { - predicates.add(builder.equal(root.get("site"), site)); - } - if (tutor != null) { - predicates.add(builder.equal(root.join("tutors"), tutor)); - } - if (startDate != null) { - predicates.add(builder.greaterThanOrEqualTo(root.get("date"), startDate)); - } - if (endDate != null) { - predicates.add(builder.lessThanOrEqualTo(root.get("date"), endDate)); - } - if (whom != null) { - predicates.add(builder.equal(root.get("whom"), whom)); - } - if (!predicates.isEmpty()) { - criteriaQuery.having(predicates.toArray(new Predicate[0])); - } - Query query = currentSession().createQuery(criteriaQuery); - System.out.println(query.getQueryString()); - return query.getResultList(); - } -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/dao/SiteDao.java b/backend/src/main/java/uk/co/neviyn/observations/dao/SiteDao.java deleted file mode 100644 index 1173929..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/dao/SiteDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package uk.co.neviyn.observations.dao; - -import io.dropwizard.hibernate.AbstractDAO; -import java.util.List; -import org.hibernate.SessionFactory; -import uk.co.neviyn.observations.core.Site; - -public class SiteDao extends AbstractDAO { - public SiteDao(SessionFactory sessionFactory) { - super(sessionFactory); - } - - public List listAll() { - return currentSession().createQuery("from Site", Site.class).list(); - } - - public Site get(long id) { - return super.get(id); - } - - public Site persist(Site site) { - return super.persist(site); - } -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/dao/TutorDao.java b/backend/src/main/java/uk/co/neviyn/observations/dao/TutorDao.java deleted file mode 100644 index 376c61b..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/dao/TutorDao.java +++ /dev/null @@ -1,24 +0,0 @@ -package uk.co.neviyn.observations.dao; - -import io.dropwizard.hibernate.AbstractDAO; -import java.util.List; -import org.hibernate.SessionFactory; -import uk.co.neviyn.observations.core.Tutor; - -public class TutorDao extends AbstractDAO { - public TutorDao(SessionFactory sessionFactory) { - super(sessionFactory); - } - - public Tutor get(long id) { - return super.get(id); - } - - public List listAll() { - return currentSession().createQuery("from Tutor", Tutor.class).list(); - } - - public Tutor persist(Tutor tutor) { - return super.persist(tutor); - } -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/resources/ObservationResource.java b/backend/src/main/java/uk/co/neviyn/observations/resources/ObservationResource.java deleted file mode 100644 index 50d19db..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/resources/ObservationResource.java +++ /dev/null @@ -1,143 +0,0 @@ -package uk.co.neviyn.observations.resources; - -import io.dropwizard.hibernate.UnitOfWork; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import javax.validation.constraints.NotNull; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import uk.co.neviyn.observations.api.AverageStatsChartJs; -import uk.co.neviyn.observations.api.NewObservation; -import uk.co.neviyn.observations.core.Observation; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.TrainingType; -import uk.co.neviyn.observations.core.Tutor; -import uk.co.neviyn.observations.dao.ObservationDao; -import uk.co.neviyn.observations.dao.SiteDao; -import uk.co.neviyn.observations.dao.TutorDao; - -@RequiredArgsConstructor -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Path("/observation") -@Slf4j -public class ObservationResource { - - private final ObservationDao dao; - private final TutorDao tutorDao; - private final SiteDao siteDao; - - /** - * Create a new Observation. - * - * @param newObservation New observation data. - * @return ID of newly created observation. - */ - @POST - @UnitOfWork - public long add(@NotNull NewObservation newObservation) { - log.info(newObservation.toString()); - final DateTime submissionDate = LocalDate.now().toDateTimeAtStartOfDay(); - Set tutors = new HashSet<>(); - for (long l : newObservation.getTutorIds()) { - tutors.add(tutorDao.get(l)); - } - final Site site = siteDao.get(newObservation.getSiteId()); - Observation observation = Observation.builder().site(site).tutors(tutors).observed(newObservation.getObserved()) - .type(TrainingType.valueOf(newObservation.getType())).monitoring(newObservation.getMonitoring()) - .control(newObservation.getControl()).conservatism(newObservation.getConservatism()) - .teamwork(newObservation.getTeamwork()).knowledge(newObservation.getKnowledge()) - .observations(newObservation.getRawData()).date(submissionDate).whom(newObservation.getWhom()).build(); - for (Tutor t : tutors) { - t.getObservations().add(observation); - } - observation = dao.persist(observation); - log.info("Created observation with ID " + observation.getId()); - return observation.getId(); - } - - @GET - @UnitOfWork - public List observations(@QueryParam("site") Integer siteId, @QueryParam("tutor") Integer tutorId, - @QueryParam("startDate") String startDate, @QueryParam("endDate") String endDate, - @QueryParam("whom") String whom) { - Site site = null; - Tutor tutor = null; - DateTime start = null; - DateTime end = null; - try { - site = siteDao.get(siteId); - } catch (Exception e) { - log.warn("Couldn't get site with ID " + siteId); - } - try { - tutor = tutorDao.get(tutorId); - } catch (Exception e) { - log.warn("Couldn't get tutor with ID " + tutorId); - } - try { - start = DateTime.parse(startDate); - } catch (Exception e) { - log.warn("Couldn't get a valid date from " + startDate); - } - try { - end = DateTime.parse(endDate); - } catch (Exception e) { - log.warn("Couldn't get a valid date from " + endDate); - } - return dao.filteredList(site, tutor, start, end, whom); - } - - /** - * Get a Chart.js compatible llist of average observation scores grouped by day. - * - * @param siteId Only observations for site. - * @param tutorId Only observations for tutor. - * @param startDate Only observations after startDate. - * @param endDate Only observations before endDate. - * @param whom Only observations of whom. - * @return Chart.js stats object. - */ - @Path("/average") - @GET - @UnitOfWork - public AverageStatsChartJs averageObservationScores(@QueryParam("site") Integer siteId, - @QueryParam("tutor") Integer tutorId, @QueryParam("startDate") String startDate, - @QueryParam("endDate") String endDate, @QueryParam("whom") String whom) { - Site site = null; - Tutor tutor = null; - DateTime start = null; - DateTime end = null; - try { - site = siteDao.get(siteId); - } catch (Exception e) { - log.warn("Couldn't get site with ID " + siteId); - } - try { - tutor = tutorDao.get(tutorId); - } catch (Exception e) { - log.warn("Couldn't get tutor with ID " + tutorId); - } - try { - start = DateTime.parse(startDate); - } catch (Exception e) { - log.warn("Couldn't get a valid date from " + startDate); - } - try { - end = DateTime.parse(endDate); - } catch (Exception e) { - log.warn("Couldn't get a valid date from " + endDate); - } - return new AverageStatsChartJs(dao.averageStats(site, tutor, start, end, whom)); - } -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/resources/SiteResource.java b/backend/src/main/java/uk/co/neviyn/observations/resources/SiteResource.java deleted file mode 100644 index 6a99e9c..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/resources/SiteResource.java +++ /dev/null @@ -1,68 +0,0 @@ -package uk.co.neviyn.observations.resources; - -import io.dropwizard.auth.Auth; -import io.dropwizard.hibernate.UnitOfWork; -import java.util.List; -import java.util.stream.Collectors; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import uk.co.neviyn.observations.api.SelectOption; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.User; -import uk.co.neviyn.observations.dao.SiteDao; - -@RequiredArgsConstructor -@Produces(MediaType.APPLICATION_JSON) -@Path("/site") -@Slf4j -public class SiteResource { - - private final SiteDao dao; - - /** - * Add a new Site. - * @param user Authorization account. - * @param name Name of Site to add. - * @return Newly created site object. - */ - @POST - @UnitOfWork - public Site add(@Auth User user, String name) { - Site site = dao.persist(Site.builder().name(name).build()); - log.info("Created site '" + site.getName() + "' with id " + site.getId()); - return site; - } - - /** - * List all known Sites. - * @return List of all Sites. - */ - @Path("/all") - @GET - @UnitOfWork - public List> allSites() { - return dao.listAll().stream().map(x -> - new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList() - ); - } - - /** - * A List of all the Tutors registered to Site. - * @param id ID of site. - * @return List of Tutors, compatible with a HTML select object. - */ - @Path("/{id}/tutors") - @GET - @UnitOfWork - public List> getSiteTutors(@PathParam("id") long id) { - return dao.get(id).getTutors().stream().map(x -> - new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList() - ); - } -} diff --git a/backend/src/main/java/uk/co/neviyn/observations/resources/TutorResource.java b/backend/src/main/java/uk/co/neviyn/observations/resources/TutorResource.java deleted file mode 100644 index fd75eb5..0000000 --- a/backend/src/main/java/uk/co/neviyn/observations/resources/TutorResource.java +++ /dev/null @@ -1,91 +0,0 @@ -package uk.co.neviyn.observations.resources; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.dropwizard.auth.Auth; -import io.dropwizard.hibernate.UnitOfWork; -import java.util.List; -import java.util.Set; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import lombok.AllArgsConstructor; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import uk.co.neviyn.observations.core.Observation; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.Tutor; -import uk.co.neviyn.observations.core.User; -import uk.co.neviyn.observations.dao.SiteDao; -import uk.co.neviyn.observations.dao.TutorDao; - -@RequiredArgsConstructor -@Produces(MediaType.APPLICATION_JSON) -@Path("/tutor") -@Slf4j -public class TutorResource { - - private final TutorDao dao; - private final SiteDao siteDao; - - /** - * Create a new Tutor. - * @param user Authorization account. - * @param newTutor Details of new Tutor. - * @return Newly created Tutor object. - */ - @POST - @UnitOfWork - public Tutor add(@Auth User user, NewTutor newTutor) { - final Site site = siteDao.get(newTutor.siteId); - final Tutor tutor = Tutor.builder().name(newTutor.name).site(site).build(); - site.getTutors().add(tutor); - log.info("Created tutor '" + tutor.getName() + "' with id " - + tutor.getId() + " at site " + site.getId()); - return dao.persist(tutor); - } - - /** - * Get a List of all Tutors. - * @return List of all Tutors. - */ - @Path("/all") - @GET - @UnitOfWork - public List allTutors() { - List tutors = dao.listAll(); - if (tutors != null && !tutors.isEmpty()) { - return tutors; - } - throw new WebApplicationException("No tutors found!", Response.Status.NOT_FOUND); - } - - - /** - * Get a list of all observations by a tutor. - * @param id Tutor ID. - * @return List of tutors' observations. - */ - @Path("/{id}/observations") - @GET - @UnitOfWork - public Set getTutorObservation(@PathParam("id") long id) { - return dao.get(id).getObservations(); - } - - @AllArgsConstructor - @NoArgsConstructor - static class NewTutor { - @JsonProperty - long siteId; - @NonNull - @JsonProperty - String name; - } -} diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Api.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Api.kt new file mode 100644 index 0000000..c5662e9 --- /dev/null +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Api.kt @@ -0,0 +1,59 @@ +package uk.co.neviyn.observationdatabase + +import org.joda.time.LocalDate + +data class NameValue( + val text: String, + val value: Long +) + +data class NewSite( + val name: String +) + +data class NewTutor( + val name: String, + val siteId: Long +) + +data class SimpleObservation( + val date: LocalDate, + val type: TrainingType, + val observed: String, + val whom: String, + val entries: List + ){ + constructor(observation: Observation) : this(observation.date, observation.type, + observation.observed, observation.whom, observation.entries) +} + +data class NewObservation( + val site: Long, + val type: TrainingType, + val observed: String, + val whom: String, + val entries: List, + val tutors: List +) + +data class ObservationsRequest( + val site: Long?, + val tutor: Long?, + val whom: String?, + val startDate: LocalDate, + val endDate: LocalDate +) + +data class ChartData( + val labels: List, + val datasets: List +) + +data class ChartDataset( + val label: String, + val backgroundColor: String, + val borderColor: String, + val data: List +){ + constructor(label: String, color: String, data: List): this(label, color, color, data) +} \ No newline at end of file diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Controller.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Controller.kt new file mode 100644 index 0000000..ded4713 --- /dev/null +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Controller.kt @@ -0,0 +1,149 @@ +package uk.co.neviyn.observationdatabase + +import org.joda.time.LocalDate +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.web.bind.annotation.* +import javax.validation.Valid + +@RestController +@RequestMapping("/api") +class Controller { + + @Autowired + lateinit var siteRepository: SiteRepository + @Autowired + lateinit var tutorRepository: TutorRepository + @Autowired + lateinit var observationRepository: ObservationRepository + + @GetMapping("/site") + fun getAllSites(): List = siteRepository.findAll().map { NameValue(it.name, it.id) } + + + @PostMapping("/site") + fun addSite(@Valid @RequestBody newSite: NewSite): NameValue { + val site = siteRepository.save(Site(name = newSite.name)) + return NameValue(site.name, site.id) + } + + @GetMapping("/site/{id}/tutors") + fun getTutorsForSite(@PathVariable(value = "id") id: Long): List = + siteRepository.findById(id).map { site -> + site.tutors.map { NameValue(it.name, it.id) } + }.get() + + @GetMapping + fun getAllTutors(): List = tutorRepository.findAll().map { NameValue(it.name, it.id) } + + @PostMapping("/tutor") + fun addTutor(@Valid @RequestBody newTutor: NewTutor): NameValue? { + var nameValue: NameValue? = null + siteRepository.findById(newTutor.siteId).ifPresent { + val tutor = tutorRepository.save(Tutor(name = newTutor.name, site = it)) + it.tutors.add(tutor) + siteRepository.save(it) + nameValue = NameValue(tutor.name, tutor.id) + } + return nameValue + } + + @GetMapping("/tutor/{id}/observations") + fun getObservationsForTutor(@PathVariable(value = "id") id: Long): List = + tutorRepository.findById(id).map { tutor -> + tutor.observations.map { SimpleObservation(it) } + }.get() + + @PostMapping("/observation") + fun addObservation(@Valid @RequestBody newObservation: NewObservation): Long { + val site = siteRepository.findById(newObservation.site).get() + val tutors = tutorRepository.findAllById(newObservation.tutors).toSet() + val overallScores = newObservation.entries.asSequence().groupBy { it.type } + .map { entry -> entry.key to entry.value.asSequence().mapNotNull { it.rating }.average() } + .map { it.first to if(it.second > 0) it.second else null }.toList() + .toMap() + var observation = Observation( + site = site, + date = LocalDate.now(), + type = newObservation.type, + observed = newObservation.observed, + whom = newObservation.whom, + monitoring = overallScores[RatingCategory.MONITORING], + conservatism = overallScores[RatingCategory.CONSERVATISM], + control = overallScores[RatingCategory.CONTROL], + teamwork = overallScores[RatingCategory.TEAMWORK], + knowledge = overallScores[RatingCategory.KNOWLEDGE], + entries = newObservation.entries, + tutors = tutors + ) + observation = observationRepository.save(observation) + tutors.forEach { + it.observations.add(observation) + tutorRepository.save(it) + } + return observation.id + } + + @GetMapping("/observations") + fun getObservations(@Valid @RequestBody observationsRequest: ObservationsRequest): List? { + if (observationsRequest.tutor != null) { + val tutor = tutorRepository.findById(observationsRequest.tutor).get() + return if (observationsRequest.whom == null) { + observationRepository.findByTutorsAndDateBetween(tutor = tutor, + startDate = observationsRequest.startDate, + endDate = observationsRequest.endDate) + } else { + observationRepository.findByTutorsAndWhomAndDateBetween(tutor = tutor, + whom = observationsRequest.whom, + startDate = observationsRequest.startDate, + endDate = observationsRequest.endDate) + } + } + if (observationsRequest.site != null) { + val site = siteRepository.findById(observationsRequest.site).get() + return if (observationsRequest.whom == null) { + observationRepository.findBySiteAndDateBetween(site = site, + startDate = observationsRequest.startDate, + endDate = observationsRequest.endDate) + } else { + observationRepository.findBySiteAndWhomAndDateBetween(site = site, + whom = observationsRequest.whom, + startDate = observationsRequest.startDate, + endDate = observationsRequest.endDate) + } + } + return null + } + + @GetMapping("/observations/chartdata") + fun getObservationsChartData(@Valid @RequestBody observationsRequest: ObservationsRequest): ChartData? { + val data = getObservations(observationsRequest) ?: return null + val groupedData = data.asSequence().groupBy { it.date }.map{ entry -> AverageData( + entry.value.asSequence().mapNotNull { it.monitoring }.average(), + entry.value.asSequence().mapNotNull { it.control }.average(), + entry.value.asSequence().mapNotNull { it.conservatism }.average(), + entry.value.asSequence().mapNotNull { it.teamwork }.average(), + entry.value.asSequence().mapNotNull { it.knowledge }.average(), + entry.key + )}.toList() + val dates = groupedData.map { it.date.toString("yyyy-MM-dd") } + return ChartData( + labels = dates, + datasets = listOf( + ChartDataset("Monitoring", "#F90", groupedData.map { it.monitoring }), + ChartDataset("Control", "#3F0", groupedData.map { it.control }), + ChartDataset("Conservatism", "#33F", groupedData.map { it.conservatism }), + ChartDataset("Teamwork", "#FF0", groupedData.map { it.teamwork }), + ChartDataset("Knowledge", "#000", groupedData.map { it.knowledge }) + ) + ) + } +} + +data class AverageData( + val monitoring: Double, + val control: Double, + val conservatism: Double, + val teamwork: Double, + val knowledge: Double, + val date: LocalDate +) \ No newline at end of file diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt new file mode 100644 index 0000000..27e7310 --- /dev/null +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Entity.kt @@ -0,0 +1,81 @@ +package uk.co.neviyn.observationdatabase + +import com.fasterxml.jackson.annotation.JsonProperty +import org.joda.time.LocalDate +import javax.persistence.* + +@Entity +data class Site( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long = 0, + val name: String){ + @OneToMany(fetch = FetchType.LAZY) + val tutors: MutableSet = mutableSetOf() +} + +@Entity +data class Tutor( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long = 0, + val name: String, + @ManyToOne(fetch = FetchType.LAZY) + val site: Site +){ + @ManyToMany + @JoinTable(name = "tutor_observations", + joinColumns = [JoinColumn(name =" tutor_id", referencedColumnName = "id")], + inverseJoinColumns = [JoinColumn(name = "observation_id", referencedColumnName = "id")]) + val observations: MutableSet = mutableSetOf() +} + +enum class TrainingType { + INITIAL, CONTINUING +} + +enum class RatingCategory { + MONITORING, CONTROL, CONSERVATISM, TEAMWORK, KNOWLEDGE +} + +@Entity +data class Observation( + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + val id: Long = 0, + @ManyToOne + val site: Site, + @Column(nullable = false) + val date: LocalDate, + @Column(nullable = false) + val type: TrainingType, + @Column(nullable = false) + val observed: String, + @Column(nullable = false) + val whom: String, + val monitoring: Double?, + val control: Double?, + val conservatism: Double?, + val teamwork: Double?, + val knowledge: Double?, + @ElementCollection + val entries: List, + @ManyToMany(mappedBy = "observations") + val tutors: Set +) + +@Embeddable +data class Entry( + @Column(nullable = false) + @JsonProperty + val type: RatingCategory, + @Column(nullable = false) + @JsonProperty + val rating: Int, + @Column(nullable = false) + @JsonProperty + val strengths: String, + @Column(nullable = false) + @JsonProperty + val improvements: String +) \ No newline at end of file diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/ObservationDatabaseApplication.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/ObservationDatabaseApplication.kt new file mode 100644 index 0000000..db87127 --- /dev/null +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/ObservationDatabaseApplication.kt @@ -0,0 +1,11 @@ +package uk.co.neviyn.observationdatabase + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + +@SpringBootApplication +class ObservationDatabaseApplication + +fun main(args: Array) { + runApplication(*args) +} diff --git a/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Repository.kt b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Repository.kt new file mode 100644 index 0000000..81bcea9 --- /dev/null +++ b/backend/src/main/kotlin/uk/co/neviyn/observationdatabase/Repository.kt @@ -0,0 +1,23 @@ +package uk.co.neviyn.observationdatabase + +import org.joda.time.LocalDate +import org.springframework.data.jpa.repository.JpaSpecificationExecutor +import org.springframework.data.repository.CrudRepository +import org.springframework.stereotype.Repository + +@Repository +interface SiteRepository: CrudRepository + +@Repository +interface TutorRepository: CrudRepository + +@Repository +interface ObservationRepository: CrudRepository, JpaSpecificationExecutor { + fun findBySiteAndDateBetween(site: Site, startDate: LocalDate, endDate: LocalDate): List + + fun findByTutorsAndDateBetween(tutor: Tutor, startDate: LocalDate, endDate: LocalDate): List + + fun findBySiteAndWhomAndDateBetween(site: Site, whom: String, startDate: LocalDate, endDate: LocalDate): List + + fun findByTutorsAndWhomAndDateBetween(tutor: Tutor, whom: String, startDate: LocalDate, endDate: LocalDate): List +} \ No newline at end of file diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties new file mode 100644 index 0000000..dcc84e6 --- /dev/null +++ b/backend/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.jpa.properties.jadira.usertype.autoRegisterUserTypes = true \ No newline at end of file diff --git a/backend/src/main/resources/banner.txt b/backend/src/main/resources/banner.txt deleted file mode 100644 index 029d6b9..0000000 --- a/backend/src/main/resources/banner.txt +++ /dev/null @@ -1,7 +0,0 @@ - - ____ __ __ _ - / __ \/ / ___ ___ _____ _____ _/ /_(_)__ ___ ___ -/ /_/ / _ \(_- siteDao.persist(site)); - } - - @Test - public void persistAndGet() { - Observation insert = testRule.inTransaction(() -> dao.persist(observation)); - assertNotNull(insert); - assertTrue(insert.getId() > 0); - assertNotNull(dao.get(insert.getId())); - } - - @Test - public void listAll() { - int numberOfObservations = 5; - testRule.inTransaction(() -> { - for (int i = 0; i < numberOfObservations; i++) { - // Make actual copies, otherwise they will merely overwrite. - dao.persist(SerializationUtils.clone(observation)); - } - }); - List observations = dao.listAll(); - assertNotNull(observations); - assertEquals(numberOfObservations, observations.size()); - } - - @Test - public void listAllWithNoObservations() { - List observations = dao.listAll(); - assertNotNull(observations); - assertEquals(0, observations.size()); - } - - @Test - public void averageStatsNoParam() { - Observation otherEntry = SerializationUtils.clone(observation); - otherEntry.setMonitoring(5); - otherEntry.setControl(5); - otherEntry.setConservatism(5); - otherEntry.setTeamwork(5); - Observation differentDay = SerializationUtils.clone(observation); - differentDay.setDate(DateTime.parse("2018-09-20")); - testRule.inTransaction(() -> { - dao.persist(observation); - dao.persist(otherEntry); - dao.persist(differentDay); - }); - List stats = dao.averageStats(null, null, null, null, null); - assertNotNull(stats); - assertEquals(2, stats.size()); - final AverageStats statObject = stats.get(0); - assertEquals(3, statObject.getMonitoring(), 0); - assertEquals(3.5, statObject.getControl(), 0); - assertEquals(4, statObject.getConservatism(), 0); - assertEquals(4.5, statObject.getTeamwork(), 0); - assertEquals(5, statObject.getKnowledge(), 0); - } - - @Test - public void averageStatsWithSite() { - Observation otherEntry = SerializationUtils.clone(observation); - otherEntry.setMonitoring(5); - otherEntry.setControl(5); - otherEntry.setConservatism(5); - otherEntry.setTeamwork(5); - Observation differentDay = SerializationUtils.clone(observation); - differentDay.setDate(DateTime.parse("2018-09-20")); - testRule.inTransaction(() -> { - dao.persist(observation); - dao.persist(otherEntry); - dao.persist(differentDay); - }); - List stats = dao.averageStats(site, null, null, null, null); - assertNotNull(stats); - assertEquals(2, stats.size()); - final AverageStats statObject = stats.get(0); - assertEquals(3, statObject.getMonitoring(), 0); - assertEquals(3.5, statObject.getControl(), 0); - assertEquals(4, statObject.getConservatism(), 0); - assertEquals(4.5, statObject.getTeamwork(), 0); - assertEquals(5, statObject.getKnowledge(), 0); - } - - @Test - public void averageStatsWithStartDate() { - Observation otherEntry = SerializationUtils.clone(observation); - otherEntry.setMonitoring(5); - otherEntry.setControl(5); - otherEntry.setConservatism(5); - otherEntry.setTeamwork(5); - Observation differentDay = SerializationUtils.clone(observation); - differentDay.setDate(DateTime.parse("2018-09-20")); - testRule.inTransaction(() -> { - dao.persist(observation); - dao.persist(otherEntry); - dao.persist(differentDay); - }); - List stats = dao.averageStats(null, null, DateTime.parse("2018-09-01").withTimeAtStartOfDay(), null, null); - assertNotNull(stats); - assertEquals(2, stats.size()); - // Change one observation to outside range - differentDay.setDate(DateTime.parse("2018-08-20")); - testRule.inTransaction(() -> { - dao.persist(differentDay); - }); - stats = dao.averageStats(null, null, DateTime.parse("2018-09-01").withTimeAtStartOfDay(), null, null); - assertNotNull(stats); - assertEquals(1, stats.size()); - } - - @Test - public void averageStatsWithEndDate() { - Observation otherEntry = SerializationUtils.clone(observation); - otherEntry.setMonitoring(5); - otherEntry.setControl(5); - otherEntry.setConservatism(5); - otherEntry.setTeamwork(5); - Observation differentDay = SerializationUtils.clone(observation); - differentDay.setDate(DateTime.parse("2018-09-20")); - testRule.inTransaction(() -> { - dao.persist(observation); - dao.persist(otherEntry); - dao.persist(differentDay); - }); - List stats = dao.averageStats(null, null, null, DateTime.parse("2018-10-01").withTimeAtStartOfDay(), null); - assertNotNull(stats); - assertEquals(2, stats.size()); - // Change one observation to outside range - differentDay.setDate(DateTime.parse("2018-10-20")); - testRule.inTransaction(() -> { - dao.persist(differentDay); - }); - stats = dao.averageStats(null, null, null, DateTime.parse("2018-10-01").withTimeAtStartOfDay(), null); - assertNotNull(stats); - assertEquals(1, stats.size()); - } - - @Test - public void averageStatsWithBothDate() { - Observation otherEntry = SerializationUtils.clone(observation); - otherEntry.setMonitoring(5); - otherEntry.setControl(5); - otherEntry.setConservatism(5); - otherEntry.setTeamwork(5); - otherEntry.setDate(DateTime.parse("2018-08-20")); - Observation differentDay = SerializationUtils.clone(observation); - differentDay.setDate(DateTime.parse("2018-10-20")); - testRule.inTransaction(() -> { - dao.persist(observation); - dao.persist(otherEntry); - dao.persist(differentDay); - }); - List stats = dao.averageStats(site, null, null, null, null); - assertNotNull(stats); - assertEquals(3, stats.size()); - stats = dao.averageStats(null, null, DateTime.parse("2018-09-01").withTimeAtStartOfDay(), DateTime.parse("2018-10-01").withTimeAtStartOfDay(), null); - assertNotNull(stats); - System.out.println(stats.toString()); - assertEquals(1, stats.size()); - } - - @Test - public void averageStatsWithWhom() { - Observation otherEntry = SerializationUtils.clone(observation); - otherEntry.setMonitoring(5); - otherEntry.setControl(5); - otherEntry.setConservatism(5); - otherEntry.setTeamwork(5); - Observation differentDay = SerializationUtils.clone(observation); - differentDay.setDate(DateTime.parse("2018-09-20")); - testRule.inTransaction(() -> { - dao.persist(observation); - dao.persist(otherEntry); - dao.persist(differentDay); - }); - List stats = dao.averageStats(null, null, null, null, "Group A"); - assertNotNull(stats); - assertEquals(2, stats.size()); - differentDay.setWhom("Group B"); - testRule.inTransaction(() -> { - dao.persist(differentDay); - }); - stats = dao.averageStats(null, null, null, null, "Group A"); - assertNotNull(stats); - assertEquals(1, stats.size()); - } -} \ No newline at end of file diff --git a/backend/src/test/java/uk/co/neviyn/observations/dao/SiteDaoTest.java b/backend/src/test/java/uk/co/neviyn/observations/dao/SiteDaoTest.java deleted file mode 100644 index aa6f89e..0000000 --- a/backend/src/test/java/uk/co/neviyn/observations/dao/SiteDaoTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package uk.co.neviyn.observations.dao; - -import org.junit.Before; -import org.junit.Test; -import uk.co.neviyn.observations.core.Site; - -import java.util.List; - -import static org.junit.Assert.*; - -public class SiteDaoTest extends DaoTestBase{ - - private SiteDao dao; - - @Before - public void setUp() { - dao = new SiteDao(testRule.getSessionFactory()); - } - - @Test - public void listAll() { - testRule.inTransaction(() -> { - dao.persist(Site.builder().name("Site A").build()); - dao.persist(Site.builder().name("Site B").build()); - dao.persist(Site.builder().name("Site C").build()); - }); - List result = dao.listAll(); - assertNotNull(result); - assertEquals(3, result.size()); - } - - @Test - public void listAllWithNoObservations() { - List sites = dao.listAll(); - assertNotNull(sites); - assertEquals(0, sites.size()); - } - - @Test - public void persistAndGet() { - Site insert = testRule.inTransaction(() -> dao.persist(Site.builder().name("Test Site").build())); - assertNotNull(insert); - assertTrue(insert.getId() > 0); - assertNotNull(dao.get(insert.getId())); - } -} \ No newline at end of file diff --git a/backend/src/test/java/uk/co/neviyn/observations/dao/TutorDaoTest.java b/backend/src/test/java/uk/co/neviyn/observations/dao/TutorDaoTest.java deleted file mode 100644 index 9786ae7..0000000 --- a/backend/src/test/java/uk/co/neviyn/observations/dao/TutorDaoTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package uk.co.neviyn.observations.dao; - -import org.junit.Before; -import org.junit.Test; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.Tutor; - -import java.util.List; - -import static org.junit.Assert.*; - -public class TutorDaoTest extends DaoTestBase{ - - private TutorDao dao; - private SiteDao siteDao; - private final Site site = Site.builder().name("Test site").build(); - - @Before - public void setUp() { - dao = new TutorDao(testRule.getSessionFactory()); - siteDao = new SiteDao(testRule.getSessionFactory()); - testRule.inTransaction(() -> siteDao.persist(site)); - } - - @Test - public void listAll() { - testRule.inTransaction(() -> { - dao.persist(Tutor.builder().name("Mr Test").site(site).build()); - dao.persist(Tutor.builder().name("Mr Test2").site(site).build()); - dao.persist(Tutor.builder().name("Mr Test3").site(site).build()); - }); - List result = dao.listAll(); - assertNotNull(result); - assertEquals(3, result.size()); - } - - @Test - public void listAllWithNoObservations() { - List tutors = dao.listAll(); - assertNotNull(tutors); - assertEquals(0, tutors.size()); - } - - @Test - public void persistAndGet() { - Tutor insert = testRule.inTransaction(() -> dao.persist(Tutor.builder().name("Mr Test").site(site).build())); - assertNotNull(insert); - assertTrue(insert.getId() > 0); - assertNotNull(dao.get(insert.getId())); - } -} \ No newline at end of file diff --git a/backend/src/test/java/uk/co/neviyn/observations/resources/ObservationResourceTest.java b/backend/src/test/java/uk/co/neviyn/observations/resources/ObservationResourceTest.java deleted file mode 100644 index 11b789f..0000000 --- a/backend/src/test/java/uk/co/neviyn/observations/resources/ObservationResourceTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package uk.co.neviyn.observations.resources; - -import io.dropwizard.testing.junit.ResourceTestRule; -import org.junit.After; -import org.junit.ClassRule; -import org.junit.Test; -import uk.co.neviyn.observations.api.NewObservation; -import uk.co.neviyn.observations.core.Observation; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.Tutor; -import uk.co.neviyn.observations.dao.ObservationDao; -import uk.co.neviyn.observations.dao.SiteDao; -import uk.co.neviyn.observations.dao.TutorDao; - -import javax.ws.rs.client.Entity; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - -import static org.mockito.Mockito.*; - -public class ObservationResourceTest { - - private static final ObservationDao dao = mock(ObservationDao.class); - private static final SiteDao siteDao = mock(SiteDao.class); - private static final TutorDao tutorDao = mock(TutorDao.class); - - @ClassRule - public static final ResourceTestRule resources = ResourceTestRule.builder() - .addResource(new ObservationResource(dao, tutorDao, siteDao)) - .build(); - - @After - public void tearDown() { - reset(dao); - reset(siteDao); - reset(tutorDao); - } - - @Test - public void add() { - final Site testSite = Site.builder().id(1).name("Test Site").build(); - final List tutors = Arrays.asList(Tutor.builder().id(1).name("Mr A").observations(new HashSet<>()).build(), Tutor.builder().id(2).name("Mr B").observations(new HashSet<>()).build()); - when(siteDao.get(1)).thenReturn(testSite); - when(tutorDao.get(1)).thenReturn(tutors.get(0)); - when(tutorDao.get(2)).thenReturn(tutors.get(1)); - resources.target("/observation").request().post(Entity.json(NewObservation.builder().type("INITIAL") - .conservatism(1f).control(2f).knowledge(3f).monitoring(4f).teamwork(5f).siteId(1).tutorIds(Arrays.asList(1L, 2L)) - .observed("").whom("Group A").rawData(new ArrayList<>()).build())); - verify(dao, times(1)).persist(any(Observation.class)); - } - - @Test - public void averageObservationScores() { - } - - @Test - public void averageStatsChartJs() { - } - - @Test - public void averageObservationScoresForSite() { - } - - @Test - public void averageObservationScoresForSiteChartJs() { - } -} \ No newline at end of file diff --git a/backend/src/test/java/uk/co/neviyn/observations/resources/SiteResourceTest.java b/backend/src/test/java/uk/co/neviyn/observations/resources/SiteResourceTest.java deleted file mode 100644 index 2b92632..0000000 --- a/backend/src/test/java/uk/co/neviyn/observations/resources/SiteResourceTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package uk.co.neviyn.observations.resources; - -import io.dropwizard.auth.AuthDynamicFeature; -import io.dropwizard.auth.AuthValueFactoryProvider; -import io.dropwizard.auth.basic.BasicCredentialAuthFilter; -import io.dropwizard.testing.junit.ResourceTestRule; -import org.junit.After; -import org.junit.ClassRule; -import org.junit.Test; -import uk.co.neviyn.observations.api.SelectOption; -import uk.co.neviyn.observations.auth.SimpleAuthenticator; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.Tutor; -import uk.co.neviyn.observations.core.User; -import uk.co.neviyn.observations.dao.SiteDao; - -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.GenericType; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.*; - -public class SiteResourceTest { - - private static final SiteDao dao = mock(SiteDao.class); - private final String httpAuth = "Basic dGVzdDpURVNUUFc="; - - @ClassRule - public static final ResourceTestRule resources = ResourceTestRule.builder() - .addResource(new AuthDynamicFeature( - new BasicCredentialAuthFilter.Builder() - .setAuthenticator(new SimpleAuthenticator("TESTPW")) - .setRealm("SECURITY") - .buildAuthFilter() - )) - .addProvider(new AuthValueFactoryProvider.Binder<>(User.class)) - .addResource(new SiteResource(dao)) - .build(); - - @After - public void tearDown() { - reset(dao); - } - - @Test - public void add() { - resources.target("/site").request().header("Authorization", httpAuth).post(Entity.json("New Site")); - verify(dao, times(1)).persist(Site.builder().name("New Site").tutors(new HashSet<>()).build()); - } - - @Test - public void allSites() { - when(dao.listAll()).thenReturn(Arrays.asList(Site.builder().id(1).name("Site 1").build(), Site.builder().id(2).name("Site 2").build())); - List> sites = resources.target("/site/all").request().get(new GenericType>>() { - }); - assertNotNull(sites); - assertEquals(2, sites.size()); - } - - @Test - public void getSiteTutors() { - Set tutors = new HashSet<>(Arrays.asList(Tutor.builder().id(1).name("Test 1").build(), Tutor.builder().id(2).name("Test 2").build())); - when(dao.get(1)).thenReturn(Site.builder().id(1).name("Site").tutors(tutors).build()); - List> result = resources.target("/site/1/tutors").request().get(new GenericType>>() { - }); - assertNotNull(result); - assertEquals(2, result.size()); - } -} \ No newline at end of file diff --git a/backend/src/test/java/uk/co/neviyn/observations/resources/TutorResourceTest.java b/backend/src/test/java/uk/co/neviyn/observations/resources/TutorResourceTest.java deleted file mode 100644 index a2ed6ed..0000000 --- a/backend/src/test/java/uk/co/neviyn/observations/resources/TutorResourceTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package uk.co.neviyn.observations.resources; - -import io.dropwizard.auth.AuthDynamicFeature; -import io.dropwizard.auth.AuthValueFactoryProvider; -import io.dropwizard.auth.basic.BasicCredentialAuthFilter; -import io.dropwizard.testing.junit.ResourceTestRule; -import org.junit.After; -import org.junit.ClassRule; -import org.junit.Test; -import uk.co.neviyn.observations.auth.SimpleAuthenticator; -import uk.co.neviyn.observations.core.Site; -import uk.co.neviyn.observations.core.Tutor; -import uk.co.neviyn.observations.core.User; -import uk.co.neviyn.observations.dao.SiteDao; -import uk.co.neviyn.observations.dao.TutorDao; - -import javax.ws.rs.client.Entity; -import javax.ws.rs.core.GenericType; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.*; - -public class TutorResourceTest { - - private static final TutorDao dao = mock(TutorDao.class); - private static final SiteDao siteDao = mock(SiteDao.class); - private final String httpAuth = "Basic dGVzdDpURVNUUFc="; - - @ClassRule - public static final ResourceTestRule resources = ResourceTestRule.builder() - .addResource(new AuthDynamicFeature( - new BasicCredentialAuthFilter.Builder() - .setAuthenticator(new SimpleAuthenticator("TESTPW")) - .setRealm("SECURITY") - .buildAuthFilter() - )) - .addProvider(new AuthValueFactoryProvider.Binder<>(User.class)) - .addResource(new TutorResource(dao, siteDao)) - .build(); - - @After - public void tearDown() { - reset(dao); - reset(siteDao); - } - - @Test - public void add() { - final Site testSite = Site.builder().id(1).name("Test Site").tutors(new HashSet<>()).build(); - when(siteDao.get(1)).thenReturn(testSite); - resources.target("/tutor").request().header("Authorization", httpAuth).post(Entity.json(new TutorResource.NewTutor(1, "Mr X"))); - verify(dao, times(1)).persist(Tutor.builder().name("Mr X").site(testSite).build()); - } - - @Test - public void allTutors() { - List tutors = Arrays.asList(Tutor.builder().id(1).name("Mr A").build(), Tutor.builder().id(2).name("Mr B").build()); - when(dao.listAll()).thenReturn(tutors); - List result = resources.target("/tutor/all").request().get(new GenericType>() { - }); - for (Tutor t : result) { - assertTrue(tutors.contains(t)); - } - } -} \ No newline at end of file diff --git a/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/ObservationdatabaseApplicationTests.kt b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/ObservationdatabaseApplicationTests.kt new file mode 100644 index 0000000..804f8d4 --- /dev/null +++ b/backend/src/test/kotlin/uk/co/neviyn/observationdatabase/ObservationdatabaseApplicationTests.kt @@ -0,0 +1,16 @@ +package uk.co.neviyn.observationdatabase + +import org.junit.Test +import org.junit.runner.RunWith +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.junit4.SpringRunner + +@RunWith(SpringRunner::class) +@SpringBootTest +class ObservationdatabaseApplicationTests { + + @Test + fun contextLoads() { + } + +} diff --git a/backend/src/test/resources/fixtures/NewObservation.json b/backend/src/test/resources/fixtures/NewObservation.json deleted file mode 100644 index 4d80c4d..0000000 --- a/backend/src/test/resources/fixtures/NewObservation.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "siteId":1, - "tutorIds":[1,2,3], - "observed":"A random thing made for testing.", - "whom": "Group A", - "type":"INITIAL", - "monitoring":1, - "control":2, - "conservatism":3, - "teamwork":4, - "knowledge":5, - "rawData":[{"type":"MONITORING","rating":5,"strengths":"some","improvements":"another sum"}] -} \ No newline at end of file diff --git a/backend/src/test/resources/fixtures/Observation.json b/backend/src/test/resources/fixtures/Observation.json deleted file mode 100644 index 5b505de..0000000 --- a/backend/src/test/resources/fixtures/Observation.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "id":0, - "observed":"Just a test observation", - "whom": "Group A", - "type":"INITIAL", - "monitoring":1, - "control":2, - "conservatism":3, - "teamwork":4, - "knowledge":5, - "observations":[{ - "type": "MONITORING", - "rating":5, - "strengths":"some", - "improvements":"another sum" - }], - "date":"2018-09-18T00:00:00.000Z" -} \ No newline at end of file diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 1e0b548..113e542 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -92,7 +92,7 @@ export default { mounted() { this.resetStore(); Vue.axios - .get("/site/all") + .get("/site") .then(response => { this.siteOptions = response.data; this.loaded = true; diff --git a/frontend/src/views/NewSite.vue b/frontend/src/views/NewSite.vue index 59128ca..b6b06de 100644 --- a/frontend/src/views/NewSite.vue +++ b/frontend/src/views/NewSite.vue @@ -40,10 +40,10 @@ export default { var form = document.getElementById("submission-form"); if (form.checkValidity()) { Vue.axios - .post("/site", this.siteName) + .post("/site", { 'name':this.siteName }) .then(response => { this.alertVariant = "success"; - this.alertText = "Successfully added " + response.data.name; + this.alertText = "Successfully added " + response.data.text; this.showAlert(); }) .catch(error => { diff --git a/frontend/src/views/NewTutor.vue b/frontend/src/views/NewTutor.vue index 1989fff..a0beef5 100644 --- a/frontend/src/views/NewTutor.vue +++ b/frontend/src/views/NewTutor.vue @@ -38,7 +38,7 @@ export default { }, mounted() { Vue.axios - .get("/site/all") + .get("/site") .then(response => { this.siteOptions = response.data; }) @@ -67,12 +67,12 @@ export default { if (form.checkValidity()) { Vue.axios .post("/tutor", { - siteId: this.siteSelection, - name: this.tutorName + 'siteId': this.siteSelection, + 'name': this.tutorName }) .then(response => { this.alertVariant = "success"; - this.alertText = "Successfully added " + response.data.name; + this.alertText = "Successfully added " + response.data.text; this.showAlert(); }) .catch(error => { diff --git a/frontend/src/views/Observation.vue b/frontend/src/views/Observation.vue index 5db9c8e..6e9479b 100644 --- a/frontend/src/views/Observation.vue +++ b/frontend/src/views/Observation.vue @@ -199,17 +199,12 @@ export default { if (form.checkValidity()) { Vue.axios .post("/observation", { - siteId: this.site, - tutorIds: this.tutors, + site: this.site, + tutors: this.tutors, observed: this.description, whom: this.whom, type: this.type, - monitoring: this.totals[0], - control: this.totals[1], - conservatism: this.totals[2], - teamwork: this.totals[3], - knowledge: this.totals[4], - rawData: JSON.parse(JSON.stringify(this.observations)) + entries: JSON.parse(JSON.stringify(this.observations)) }) .then(function(response) { console.log(response); diff --git a/frontend/src/views/Stats.vue b/frontend/src/views/Stats.vue index 7427684..3c5318e 100644 --- a/frontend/src/views/Stats.vue +++ b/frontend/src/views/Stats.vue @@ -103,14 +103,12 @@ export default { methods: { getFilteredAverage: function() { Vue.axios - .get("/observation/average", { - params: { + .get("/observations/chartdata", { site: this.siteSelection, tutor: this.tutorSelection, startDate: moment(this.startDate).format("YYYY-MM-DD"), endDate: moment(this.endDate).format("YYYY-MM-DD"), whom: this.whom - } }) .then(response => { this.chartData = response.data; diff --git a/frontend/src/views/ViewObservations.vue b/frontend/src/views/ViewObservations.vue index 1e319ce..2763222 100644 --- a/frontend/src/views/ViewObservations.vue +++ b/frontend/src/views/ViewObservations.vue @@ -26,22 +26,31 @@ - - -

Category: {{ observation.type }}

-

Rating: {{ observation.rating }}

-
- - - - - - - - - - -
+ + + +

{{ observation.date }}-{{ observation.type }}/{{ observation.observed }}-{{ obsevation.whom }}

+
+
+ + + +

{{ entry.type }}

+

{{ entry.rating }}

+
+ + + + + + + + + + +
+
+
@@ -78,14 +87,12 @@ export default { methods: { getFiltered: function() { Vue.axios - .get("/observation", { - params: { + .get("/observations", { site: this.siteSelection, tutor: this.tutorSelection, startDate: moment(this.startDate).format("YYYY-MM-DD"), endDate: moment(this.endDate).format("YYYY-MM-DD"), whom: this.whom - } }) .then(response => { this.chartData = response.data; @@ -96,12 +103,12 @@ export default { this.$refs.errorModal.show(); }); }, - changeStartDate: function(e) { - this.startDate = e.date; - }, - changeEndDate: function(e) { - this.endDate = e.date; - } + changeStartDate: function(e) { + this.startDate = e.date; + }, + changeEndDate: function(e) { + this.endDate = e.date; + } } };