Merge pull request #3 from andrewlalis/data_import
Merge current working branch to master
This commit is contained in:
commit
2a205b5dc0
|
@ -1,3 +1,4 @@
|
||||||
.idea/*
|
.idea/*
|
||||||
*.iml
|
*.iml
|
||||||
target/*
|
target/*
|
||||||
|
javadoc/*
|
|
@ -0,0 +1,105 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
viewBox="0 0 64.000001 64.000001"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="TAA.svg"
|
||||||
|
inkscape:export-filename="/home/andrew/Programming/Projects/Teaching_Assistant_Assistant/src/main/resources/static/images/logo.png"
|
||||||
|
inkscape:export-xdpi="360"
|
||||||
|
inkscape:export-ydpi="360">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.2"
|
||||||
|
inkscape:cx="24.365199"
|
||||||
|
inkscape:cy="32.206088"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1030"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-988.36216)">
|
||||||
|
<rect
|
||||||
|
style="opacity:1;fill:#008000;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
id="rect4136"
|
||||||
|
width="60"
|
||||||
|
height="60"
|
||||||
|
x="1"
|
||||||
|
y="991.36218"
|
||||||
|
ry="16" />
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot4138"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
transform="matrix(2.0532963,0,0,2.0532963,-37.008,965.44742)"><flowRegion
|
||||||
|
id="flowRegion4140"><rect
|
||||||
|
id="rect4142"
|
||||||
|
width="18.125"
|
||||||
|
height="26.249994"
|
||||||
|
x="27.5"
|
||||||
|
y="9.8928566" /></flowRegion><flowPara
|
||||||
|
id="flowPara4144"
|
||||||
|
style="fill:#ffffff;fill-opacity:1">T</flowPara></flowRoot> <flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot4154"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
transform="matrix(1.3900147,0,0,1.3900147,-2.1586653,998.49896)"><flowRegion
|
||||||
|
id="flowRegion4156"><rect
|
||||||
|
id="rect4158"
|
||||||
|
width="18.125"
|
||||||
|
height="26.249994"
|
||||||
|
x="27.5"
|
||||||
|
y="9.8928566" /></flowRegion><flowPara
|
||||||
|
id="flowPara4160"
|
||||||
|
style="fill:#ffffff;fill-opacity:1">A</flowPara></flowRoot> <flowRoot
|
||||||
|
transform="matrix(1.3900147,0,0,1.3900147,-29.448313,998.49896)"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="flowRoot4162"
|
||||||
|
xml:space="preserve"><flowRegion
|
||||||
|
id="flowRegion4164"><rect
|
||||||
|
y="9.8928566"
|
||||||
|
x="27.5"
|
||||||
|
height="26.249994"
|
||||||
|
width="18.125"
|
||||||
|
id="rect4166" /></flowRegion><flowPara
|
||||||
|
style="fill:#ffffff;fill-opacity:1"
|
||||||
|
id="flowPara4168">A</flowPara></flowRoot> </g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
|
@ -1,25 +1,13 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant;
|
package nl.andrewlalis.teaching_assistant_assistant;
|
||||||
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.PersonRepository;
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeamRepository;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.boot.CommandLineRunner;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class TeachingAssistantAssistantApplication implements CommandLineRunner {
|
public class TeachingAssistantAssistantApplication implements CommandLineRunner {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
CourseRepository courseRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
TeamRepository teamRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
PersonRepository personRepository;
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(TeachingAssistantAssistantApplication.class, args);
|
SpringApplication.run(TeachingAssistantAssistantApplication.class, args);
|
||||||
}
|
}
|
||||||
|
@ -27,5 +15,6 @@ public class TeachingAssistantAssistantApplication implements CommandLineRunner
|
||||||
@Override
|
@Override
|
||||||
public void run(String... args) throws Exception {
|
public void run(String... args) throws Exception {
|
||||||
System.out.println("Running startup...");
|
System.out.println("Running startup...");
|
||||||
|
System.out.println(new BCryptPasswordEncoder().encode("test"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.config;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.security.UserDetailsService;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security configuration for the TAA application.
|
||||||
|
*
|
||||||
|
* This configuration makes use of the custom user details service provided by the application for database-persistent
|
||||||
|
* user accounts.
|
||||||
|
*
|
||||||
|
* Login, logout, and registration pages are set so that all users, authenticated and unauthenticated, may access them,
|
||||||
|
* while actual site content is only visible to authenticated users.
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
|
protected WebSecurityConfig(UserDetailsService userDetailsService) {
|
||||||
|
this.userDetailsService = userDetailsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth.userDetailsService(this.userDetailsService)
|
||||||
|
.passwordEncoder(passwordEncoder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.csrf().disable() // So that we can GET the logout page.
|
||||||
|
|
||||||
|
.authorizeRequests() // Let anyone view the login and logout pages, as well as various registration pages.
|
||||||
|
.antMatchers("/login*", "/logout*", "/register*", "/register/**")
|
||||||
|
.permitAll()
|
||||||
|
.and()
|
||||||
|
|
||||||
|
.authorizeRequests()
|
||||||
|
.antMatchers("/css/**", "/images/**", "/javascript/**")
|
||||||
|
.permitAll()
|
||||||
|
.and()
|
||||||
|
|
||||||
|
.authorizeRequests() // Only logged in users should be able to see site content.
|
||||||
|
.antMatchers("/**").hasRole("user")
|
||||||
|
.anyRequest().hasRole("user")
|
||||||
|
.and()
|
||||||
|
|
||||||
|
.formLogin()
|
||||||
|
.loginPage("/login")
|
||||||
|
.permitAll()
|
||||||
|
.loginProcessingUrl("/login")
|
||||||
|
.defaultSuccessUrl("/", true)
|
||||||
|
.failureUrl("/login?error")
|
||||||
|
.and()
|
||||||
|
|
||||||
|
.logout()
|
||||||
|
.permitAll()
|
||||||
|
.clearAuthentication(true)
|
||||||
|
.invalidateHttpSession(true)
|
||||||
|
.logoutUrl("/logout")
|
||||||
|
.logoutSuccessUrl("/login")
|
||||||
|
.deleteCookies("JSESSIONID");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Spring Security to use a specific password encoder.
|
||||||
|
* @return The password encoder to use.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,11 +12,11 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||||
* Controller for the list of courses in the system.
|
* Controller for the list of courses in the system.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class Courses {
|
public class CoursesController extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
protected Courses(CourseRepository courseRepository) {
|
protected CoursesController(CourseRepository courseRepository) {
|
||||||
this.courseRepository = courseRepository;
|
this.courseRepository = courseRepository;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the login page, visible to all users.
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
private final Logger logger = LogManager.getLogger(LoginController.class);
|
||||||
|
|
||||||
|
@GetMapping("/login")
|
||||||
|
public String get() {
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.dto.NewUserRegistrationDTO;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the registration page which is used for the creation of new accounts.
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class RegisterController {
|
||||||
|
|
||||||
|
private final Logger logger = LogManager.getLogger(RegisterController.class);
|
||||||
|
|
||||||
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
private static final String[] personTypes = {
|
||||||
|
"Student",
|
||||||
|
"Teaching Assistant",
|
||||||
|
"Professor",
|
||||||
|
"Administrator"
|
||||||
|
};
|
||||||
|
|
||||||
|
protected RegisterController(CourseRepository courseRepository) {
|
||||||
|
this.courseRepository = courseRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/register")
|
||||||
|
public String get(Model model) {
|
||||||
|
model.addAttribute("newUserRegistration", new NewUserRegistrationDTO(Arrays.asList(personTypes), this.courseRepository.findAll()));
|
||||||
|
return "register";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/register")
|
||||||
|
public String post(@ModelAttribute NewUserRegistrationDTO newUserRegistration) {
|
||||||
|
logger.info("Received new registration: " + newUserRegistration);
|
||||||
|
|
||||||
|
return "redirect:/login";
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,18 +2,13 @@ package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class RootController {
|
public class RootController extends UserPageController {
|
||||||
|
|
||||||
@RequestMapping(
|
@GetMapping("/")
|
||||||
path = "/",
|
|
||||||
produces = "text/html"
|
|
||||||
)
|
|
||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
model.addAttribute("name", "JOHN");
|
return "index";
|
||||||
return "index.html";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for operations dealing with the global collection of students, not particular to one course.
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class StudentsController extends UserPageController {
|
||||||
|
|
||||||
|
private StudentRepository studentRepository;
|
||||||
|
|
||||||
|
protected StudentsController(StudentRepository studentRepository) {
|
||||||
|
this.studentRepository = studentRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of all students.
|
||||||
|
* @param model The view model.
|
||||||
|
* @return The template for displaying a list of students.
|
||||||
|
*/
|
||||||
|
@GetMapping("/students")
|
||||||
|
public String get(Model model) {
|
||||||
|
model.addAttribute("students", this.studentRepository.findAll());
|
||||||
|
return "students";
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,13 +13,16 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the list of teaching assistants in the system.
|
||||||
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class TeachingAssistants {
|
public class TeachingAssistantsController extends UserPageController {
|
||||||
|
|
||||||
private TeachingAssistantRepository teachingAssistantRepository;
|
private TeachingAssistantRepository teachingAssistantRepository;
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
protected TeachingAssistants(TeachingAssistantRepository teachingAssistantRepository, CourseRepository courseRepository) {
|
protected TeachingAssistantsController(TeachingAssistantRepository teachingAssistantRepository, CourseRepository courseRepository) {
|
||||||
this.teachingAssistantRepository = teachingAssistantRepository;
|
this.teachingAssistantRepository = teachingAssistantRepository;
|
||||||
this.courseRepository = courseRepository;
|
this.courseRepository = courseRepository;
|
||||||
}
|
}
|
|
@ -1,17 +0,0 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class TestController {
|
|
||||||
|
|
||||||
@GetMapping("/test")
|
|
||||||
public String test (@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
|
|
||||||
model.addAttribute("name", name);
|
|
||||||
return "test";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.security.User;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.security.UserDetails;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract controller which simplifies the definition of controllers for pages that require a user to be signed in.
|
||||||
|
*/
|
||||||
|
public abstract class UserPageController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shortcut to get the current authenticated user.
|
||||||
|
* @param auth The spring authentication.
|
||||||
|
* @return The user that's logged in.
|
||||||
|
*/
|
||||||
|
@ModelAttribute("user")
|
||||||
|
protected User getUser(Authentication auth) {
|
||||||
|
UserDetails userDetails = (UserDetails) auth.getPrincipal();
|
||||||
|
return userDetails.getUser();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
@ -13,7 +14,7 @@ import java.util.Optional;
|
||||||
* Controller for the course entity, that is, one individual course.
|
* Controller for the course entity, that is, one individual course.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class CourseEntity {
|
public class CourseEntity extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
@ -7,7 +8,7 @@ import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class CreateCourse {
|
public class CreateCourse extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ public class CreateCourse {
|
||||||
|
|
||||||
@GetMapping("/courses/create")
|
@GetMapping("/courses/create")
|
||||||
public String get(Model model) {
|
public String get(Model model) {
|
||||||
Course course = new Course("no name", "no code");
|
Course course = new Course(null, null);
|
||||||
model.addAttribute("course", course);
|
model.addAttribute("course", course);
|
||||||
return "courses/create";
|
return "courses/create";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.util.sample_data.CourseGenerator;
|
import nl.andrewlalis.teaching_assistant_assistant.util.sample_data.CourseGenerator;
|
||||||
|
@ -10,7 +11,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class Generate {
|
public class Generate extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
@ -22,7 +23,7 @@ import java.util.Optional;
|
||||||
* Controller for importing students from a CSV sheet.
|
* Controller for importing students from a CSV sheet.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class ImportStudents {
|
public class ImportStudents extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
|
@ -18,7 +19,7 @@ import java.util.Optional;
|
||||||
* Controller for exporting team information into readable files.
|
* Controller for exporting team information into readable files.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class ExportStudentTeams {
|
public class ExportStudentTeams extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
@ -79,10 +80,17 @@ public class ExportStudentTeams {
|
||||||
|
|
||||||
private byte[] getContactInfo(Course course) {
|
private byte[] getContactInfo(Course course) {
|
||||||
StringBuilder sb = new StringBuilder("Student Team Contact Details\n");
|
StringBuilder sb = new StringBuilder("Student Team Contact Details\n");
|
||||||
|
sb.append("--------------------------------------------\n");
|
||||||
|
sb.append("Student Number, Name, Email, Github Username\n");
|
||||||
|
sb.append("--------------------------------------------\n");
|
||||||
for (StudentTeam team : course.getStudentTeams()) {
|
for (StudentTeam team : course.getStudentTeams()) {
|
||||||
sb.append("2019_Team_").append(team.getId()).append(": ");
|
sb.append("Team ").append(team.getId()).append(":\n");
|
||||||
for (Student student : team.getStudents()) {
|
for (Student student : team.getStudents()) {
|
||||||
sb.append(student.getFullName()).append(" (").append(student.getEmailAddress()).append("), ");
|
sb.append("\t - s").append(student.getStudentNumber())
|
||||||
|
.append(", ").append(student.getFullName())
|
||||||
|
.append(", ").append(student.getEmailAddress())
|
||||||
|
.append(", ").append(student.getGithubUsername())
|
||||||
|
.append('\n');
|
||||||
}
|
}
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
@ -15,7 +16,7 @@ import java.io.IOException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class GenerateRepositories {
|
public class GenerateRepositories extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
private StudentTeamRepository studentTeamRepository;
|
private StudentTeamRepository studentTeamRepository;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
@ -20,7 +21,7 @@ import java.util.Optional;
|
||||||
* TODO: Implement this functionality automatically.
|
* TODO: Implement this functionality automatically.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class MergeSingleTeams {
|
public class MergeSingleTeams extends UserPageController {
|
||||||
|
|
||||||
private Logger logger = LogManager.getLogger(MergeSingleTeams.class);
|
private Logger logger = LogManager.getLogger(MergeSingleTeams.class);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
|
@ -20,7 +21,7 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class StudentTeamEntity {
|
public class StudentTeamEntity extends UserPageController {
|
||||||
|
|
||||||
private StudentTeamRepository studentTeamRepository;
|
private StudentTeamRepository studentTeamRepository;
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
@ -15,7 +16,7 @@ import java.util.Optional;
|
||||||
* Updates branch protection for all student repositories in a given course.
|
* Updates branch protection for all student repositories in a given course.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class UpdateBranchProtection {
|
public class UpdateBranchProtection extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.students;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.students;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
@ -17,7 +18,7 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class InviteAllToRepository {
|
public class InviteAllToRepository extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
|
||||||
|
@ -14,7 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class AssignToStudentTeams {
|
public class AssignToStudentTeams extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
|
||||||
|
@ -15,7 +16,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class CreateTeachingAssistantTeam {
|
public class CreateTeachingAssistantTeam extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
private TeachingAssistantRepository teachingAssistantRepository;
|
private TeachingAssistantRepository teachingAssistantRepository;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.teaching_assistant_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
@ -12,7 +13,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class TeachingAssistantTeamEntity {
|
public class TeachingAssistantTeamEntity extends UserPageController {
|
||||||
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
private TeachingAssistantTeamRepository teachingAssistantTeamRepository;
|
private TeachingAssistantTeamRepository teachingAssistantTeamRepository;
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* Contains all page and action controllers which respond to requests on the website.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Each class defined here should therefore be annotated with Spring's <code>@Controller</code> annotation, and
|
||||||
|
* define one or more methods annotated with a <code>@RequestMapping</code> (or any convenience shortcut) to respond
|
||||||
|
* to requests to the controller.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
|
@ -0,0 +1,19 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.register;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the registration form for new students.
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class StudentRegisterController {
|
||||||
|
|
||||||
|
@GetMapping("/register/student")
|
||||||
|
public String get() {
|
||||||
|
|
||||||
|
|
||||||
|
return "/register/student";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.students;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.services.StudentService;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
@ -14,30 +15,28 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for operations dealing with the global collection of students, not particular to one course.
|
* Controller for creating a new student.
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class Students {
|
public class StudentCreateController extends UserPageController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constant which defines what value is returned if the user says that the newly created student should not be
|
||||||
|
* part of a course.
|
||||||
|
*/
|
||||||
private static final String NO_COURSE = "NO_COURSE_SELECTED";
|
private static final String NO_COURSE = "NO_COURSE_SELECTED";
|
||||||
|
|
||||||
private StudentRepository studentRepository;
|
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
|
private StudentService studentService;
|
||||||
|
|
||||||
protected Students(StudentRepository studentRepository, CourseRepository courseRepository) {
|
protected StudentCreateController(CourseRepository courseRepository, StudentService studentService) {
|
||||||
this.studentRepository = studentRepository;
|
|
||||||
this.courseRepository = courseRepository;
|
this.courseRepository = courseRepository;
|
||||||
}
|
this.studentService = studentService;
|
||||||
|
|
||||||
@GetMapping("/students")
|
|
||||||
public String get(Model model) {
|
|
||||||
model.addAttribute("students", this.studentRepository.findAll());
|
|
||||||
return "students";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/students/create")
|
@GetMapping("/students/create")
|
||||||
public String getCreate(Model model) {
|
public String getCreate(Model model) {
|
||||||
model.addAttribute("student", new Student("First Name", "Last Name", "Email Address", "Github Username", 1234567));
|
model.addAttribute("student", new Student(null, null, null, null, 1234567));
|
||||||
model.addAttribute("courses", this.courseRepository.findAll());
|
model.addAttribute("courses", this.courseRepository.findAll());
|
||||||
|
|
||||||
return "students/create";
|
return "students/create";
|
||||||
|
@ -49,20 +48,16 @@ public class Students {
|
||||||
)
|
)
|
||||||
public String postCreate(
|
public String postCreate(
|
||||||
@ModelAttribute Student newStudent,
|
@ModelAttribute Student newStudent,
|
||||||
@RequestParam(value = "course_code", required = false) String courseCode
|
@RequestParam(value = "course_code", required = false, defaultValue = NO_COURSE) String courseCode
|
||||||
) {
|
) {
|
||||||
this.studentRepository.save(newStudent);
|
Optional<Course> optionalCourse = this.courseRepository.findByCode(courseCode);
|
||||||
|
Course course = null;
|
||||||
if (courseCode != null && !courseCode.equals(NO_COURSE)) {
|
if (optionalCourse.isPresent()) {
|
||||||
Optional<Course> optionalCourse = this.courseRepository.findByCode(courseCode);
|
course = optionalCourse.get();
|
||||||
optionalCourse.ifPresent(course -> {
|
|
||||||
course.addParticipant(newStudent);
|
|
||||||
newStudent.assignToCourse(course);
|
|
||||||
this.courseRepository.save(course);
|
|
||||||
this.studentRepository.save(newStudent);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.studentService.createStudent(newStudent, course);
|
||||||
|
|
||||||
return "redirect:/students";
|
return "redirect:/students";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,85 +0,0 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.students;
|
|
||||||
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.Team;
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeamRepository;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class StudentEntity {
|
|
||||||
|
|
||||||
private StudentRepository studentRepository;
|
|
||||||
private TeamRepository teamRepository;
|
|
||||||
private CourseRepository courseRepository;
|
|
||||||
|
|
||||||
protected StudentEntity(StudentRepository studentRepository, TeamRepository teamRepository, CourseRepository courseRepository) {
|
|
||||||
this.studentRepository = studentRepository;
|
|
||||||
this.teamRepository = teamRepository;
|
|
||||||
this.courseRepository = courseRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/students/{id}")
|
|
||||||
public String get(@PathVariable long id, Model model) {
|
|
||||||
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
|
||||||
optionalStudent.ifPresent(student -> model.addAttribute("student", student));
|
|
||||||
return "students/entity";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/students/{id}/edit")
|
|
||||||
public String getEdit(@PathVariable long id, Model model) {
|
|
||||||
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
|
||||||
optionalStudent.ifPresent(student -> model.addAttribute("student", student));
|
|
||||||
return "students/entity/edit";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(
|
|
||||||
value = "/students/{id}/edit",
|
|
||||||
consumes = "application/x-www-form-urlencoded"
|
|
||||||
)
|
|
||||||
public String post(@ModelAttribute Student editedStudent, @PathVariable long id) {
|
|
||||||
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
|
||||||
optionalStudent.ifPresent(student -> {
|
|
||||||
student.setFirstName(editedStudent.getFirstName());
|
|
||||||
student.setLastName(editedStudent.getLastName());
|
|
||||||
student.setEmailAddress(editedStudent.getEmailAddress());
|
|
||||||
student.setGithubUsername(editedStudent.getGithubUsername());
|
|
||||||
student.setStudentNumber(editedStudent.getStudentNumber());
|
|
||||||
this.studentRepository.save(student);
|
|
||||||
});
|
|
||||||
|
|
||||||
return "redirect:/students/{id}";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/students/{id}/remove")
|
|
||||||
public String getRemove(@PathVariable long id) {
|
|
||||||
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
|
||||||
optionalStudent.ifPresent(student -> {
|
|
||||||
|
|
||||||
for (Team team : student.getTeams()) {
|
|
||||||
team.removeMember(student);
|
|
||||||
student.removeFromAssignedTeam(team);
|
|
||||||
this.teamRepository.save(team);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Course course : student.getCourses()) {
|
|
||||||
course.removeParticipant(student);
|
|
||||||
student.removeFromAssignedCourse(course);
|
|
||||||
this.courseRepository.save(course);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.studentRepository.delete(student);
|
|
||||||
});
|
|
||||||
|
|
||||||
return "redirect:/students";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.students;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for a single student entity.
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class StudentEntityController extends UserPageController {
|
||||||
|
|
||||||
|
private StudentRepository studentRepository;
|
||||||
|
|
||||||
|
protected StudentEntityController(StudentRepository studentRepository) {
|
||||||
|
this.studentRepository = studentRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/students/{id}")
|
||||||
|
public String get(@PathVariable long id, Model model) {
|
||||||
|
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
||||||
|
optionalStudent.ifPresent(student -> model.addAttribute("student", student));
|
||||||
|
return "students/entity";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.students.entity;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.services.StudentService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for editing a student entity.
|
||||||
|
*/
|
||||||
|
@Controller("/students/{id}/edit")
|
||||||
|
public class StudentEntityEditController extends UserPageController {
|
||||||
|
|
||||||
|
private StudentRepository studentRepository;
|
||||||
|
private StudentService studentService;
|
||||||
|
|
||||||
|
protected StudentEntityEditController(StudentRepository studentRepository, StudentService studentService) {
|
||||||
|
this.studentRepository = studentRepository;
|
||||||
|
this.studentService = studentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data of the student whose information is going to be edited, and add that to the model to be rendered.
|
||||||
|
* @param id The id of the student to edit.
|
||||||
|
* @param model The view model.
|
||||||
|
* @return The edit template which will be populated with the student's data.
|
||||||
|
*/
|
||||||
|
@GetMapping("/students/{id}/edit")
|
||||||
|
public String getEdit(@PathVariable long id, Model model) {
|
||||||
|
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
||||||
|
optionalStudent.ifPresent(student -> model.addAttribute("student", student));
|
||||||
|
return "students/entity/edit";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives edited data about a student and saves it.
|
||||||
|
* @param editedStudent A temporary <code>Student</code> object containing the edited information.
|
||||||
|
* @param id The id of the student to edit the information of.
|
||||||
|
* @return A redirect to the entity page for the student whose information was just edited.
|
||||||
|
*/
|
||||||
|
@PostMapping(
|
||||||
|
value = "/students/{id}/edit",
|
||||||
|
consumes = "application/x-www-form-urlencoded"
|
||||||
|
)
|
||||||
|
public String post(@ModelAttribute Student editedStudent, @PathVariable long id) {
|
||||||
|
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
||||||
|
optionalStudent.ifPresent(student -> this.studentService.editStudent(student, editedStudent));
|
||||||
|
|
||||||
|
return "redirect:/students/{id}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.students.entity;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.services.StudentService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for removing a student from the application.
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class StudentEntityRemoveController {
|
||||||
|
|
||||||
|
private StudentService studentService;
|
||||||
|
private StudentRepository studentRepository;
|
||||||
|
|
||||||
|
protected StudentEntityRemoveController(StudentService studentService, StudentRepository studentRepository) {
|
||||||
|
this.studentService = studentService;
|
||||||
|
this.studentRepository = studentRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/students/{id}/remove")
|
||||||
|
public String getRemove(@PathVariable long id) {
|
||||||
|
Optional<Student> optionalStudent = this.studentRepository.findById(id);
|
||||||
|
optionalStudent.ifPresent(student -> this.studentService.removeStudent(student));
|
||||||
|
|
||||||
|
return "redirect:/students";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package nl.andrewlalis.teaching_assistant_assistant.controllers.teaching_assistants;
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.teaching_assistants;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.controllers.UserPageController;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantRepository;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
@ -9,12 +10,15 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for a single teaching assistant entity.
|
||||||
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class TeachingAssistantEntity {
|
public class TeachingAssistantEntityController extends UserPageController {
|
||||||
|
|
||||||
private TeachingAssistantRepository teachingAssistantRepository;
|
private TeachingAssistantRepository teachingAssistantRepository;
|
||||||
|
|
||||||
protected TeachingAssistantEntity(TeachingAssistantRepository teachingAssistantRepository) {
|
protected TeachingAssistantEntityController(TeachingAssistantRepository teachingAssistantRepository) {
|
||||||
this.teachingAssistantRepository = teachingAssistantRepository;
|
this.teachingAssistantRepository = teachingAssistantRepository;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,23 +6,39 @@ import javax.persistence.*;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The basic entity properties which any entity in this system should have: an id and a creation timestamp. Every entity
|
* An abstract object from which all persistent objects in this application should extend.
|
||||||
* in this system should extend from BasicEntity.
|
* <p>
|
||||||
|
* The basic entity properties which any entity in this system should have: an {@code id} and a creation timestamp.
|
||||||
|
* Every entity in this system should extend from BasicEntity.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Every single entity in this system therefore is identified uniquely by a Long primary key, although it may also
|
||||||
|
* be identified by other codes or attributes defined in such an entity. For example, the {@link Course} object has
|
||||||
|
* a unique code, which can also be used to select a course.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
@MappedSuperclass
|
@MappedSuperclass
|
||||||
public abstract class BasicEntity {
|
public abstract class BasicEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The primary key for any basic entity.
|
||||||
|
*/
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(
|
@GeneratedValue(
|
||||||
strategy = GenerationType.IDENTITY
|
strategy = GenerationType.IDENTITY
|
||||||
)
|
)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date at which this basic entity was created.
|
||||||
|
*/
|
||||||
@Temporal(
|
@Temporal(
|
||||||
value = TemporalType.TIMESTAMP
|
value = TemporalType.TIMESTAMP
|
||||||
)
|
)
|
||||||
@CreationTimestamp
|
@CreationTimestamp
|
||||||
@Column
|
@Column(nullable = false)
|
||||||
private Date createdOn;
|
private Date createdOn;
|
||||||
|
|
||||||
protected BasicEntity() {}
|
protected BasicEntity() {}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.dto;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data transfer object to aid in the registration of a new authenticated user. This object therefore contains all the
|
||||||
|
* data that potential users enter prior to the actual creation of a new user.
|
||||||
|
*/
|
||||||
|
public class NewUserRegistrationDTO {
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
private String emailAddress;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String passwordConfirm;
|
||||||
|
|
||||||
|
private String selectedPersonType;
|
||||||
|
|
||||||
|
private List<String> availablePersonTypes;
|
||||||
|
|
||||||
|
private Iterable<Course> availableCourses;
|
||||||
|
|
||||||
|
public NewUserRegistrationDTO(List<String> availablePersonTypes, Iterable<Course> availableCourses) {
|
||||||
|
this.availablePersonTypes = availablePersonTypes;
|
||||||
|
this.availableCourses = availableCourses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPasswordConfirm() {
|
||||||
|
return passwordConfirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordConfirm(String passwordConfirm) {
|
||||||
|
this.passwordConfirm = passwordConfirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmailAddress() {
|
||||||
|
return emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailAddress(String emailAddress) {
|
||||||
|
this.emailAddress = emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAvailablePersonTypes() {
|
||||||
|
return availablePersonTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<Course> getAvailableCourses() {
|
||||||
|
return availableCourses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSelectedPersonType() {
|
||||||
|
return this.selectedPersonType;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Contains all persistent entities that make up the core data model for the application.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* All model objects should ultimately extend from {@link nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity}
|
||||||
|
* and define new attributes as necessary for use.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* From BasicEntity it is implied that all entities contained herein can be identified uniquely by at least a
|
||||||
|
* <code>Long id</code>.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model;
|
|
@ -3,6 +3,7 @@ package nl.andrewlalis.teaching_assistant_assistant.model.people;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity;
|
import nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.Team;
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.Team;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.security.User;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -10,6 +11,11 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents any person (teaching assistant, student, or other) that exists in this application.
|
* Represents any person (teaching assistant, student, or other) that exists in this application.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* A Person may belong to many {@link Team}s and may also belong to many {@link Course}s, irrespective of Team
|
||||||
|
* involvement.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "people")
|
@Table(name = "people")
|
||||||
|
@ -18,15 +24,27 @@ import java.util.List;
|
||||||
)
|
)
|
||||||
public abstract class Person extends BasicEntity {
|
public abstract class Person extends BasicEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The person's first name.
|
||||||
|
*/
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String firstName;
|
private String firstName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The person's last name.
|
||||||
|
*/
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String lastName;
|
private String lastName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The person's email address.
|
||||||
|
*/
|
||||||
@Column
|
@Column
|
||||||
private String emailAddress;
|
private String emailAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The person's github username.
|
||||||
|
*/
|
||||||
@Column
|
@Column
|
||||||
private String githubUsername;
|
private String githubUsername;
|
||||||
|
|
||||||
|
@ -51,6 +69,16 @@ public abstract class Person extends BasicEntity {
|
||||||
)
|
)
|
||||||
private List<Course> courses;
|
private List<Course> courses;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authenticated user belonging to this person.
|
||||||
|
*/
|
||||||
|
@OneToOne(
|
||||||
|
fetch = FetchType.LAZY,
|
||||||
|
optional = true,
|
||||||
|
mappedBy = "person"
|
||||||
|
)
|
||||||
|
private User user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor for JPA.
|
* Default constructor for JPA.
|
||||||
*/
|
*/
|
||||||
|
@ -74,12 +102,20 @@ public abstract class Person extends BasicEntity {
|
||||||
this.githubUsername = githubUsername;
|
this.githubUsername = githubUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns this person to a team.
|
||||||
|
* @param team The team to assign to.
|
||||||
|
*/
|
||||||
public void assignToTeam(Team team) {
|
public void assignToTeam(Team team) {
|
||||||
if (!this.teams.contains(team)) {
|
if (!this.teams.contains(team)) {
|
||||||
this.teams.add(team);
|
this.teams.add(team);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes this person from a team.
|
||||||
|
* @param team The team to remove from.
|
||||||
|
*/
|
||||||
public void removeFromAssignedTeam(Team team) {
|
public void removeFromAssignedTeam(Team team) {
|
||||||
this.teams.remove(team);
|
this.teams.remove(team);
|
||||||
}
|
}
|
||||||
|
@ -142,6 +178,14 @@ public abstract class Person extends BasicEntity {
|
||||||
return this.teams;
|
return this.teams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if two Persons are equal. They are considered equal when all of the basic identifying information
|
* Determines if two Persons are equal. They are considered equal when all of the basic identifying information
|
||||||
* about the person is the same, regardless of case.
|
* about the person is the same, regardless of case.
|
||||||
|
|
|
@ -9,9 +9,11 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A group consisting of one or more members. Child classes should define P as a sub class of Person to define custom
|
* A group consisting of one or more members that belongs to a {@link Course}.
|
||||||
* behavior if needed.
|
*
|
||||||
* @param <P> The type of members this group contains.
|
* <p>
|
||||||
|
* Any Team contains a collection of {@link Person} objects, each representing a member of the team.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance(
|
@Inheritance(
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.repositories;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.security.Role;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The repository for all roles to which users may be assigned.
|
||||||
|
*/
|
||||||
|
public interface RoleRepository extends CrudRepository<Role, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to find a role by the given name.
|
||||||
|
* @return An optional Role that has the given name.
|
||||||
|
*/
|
||||||
|
public Optional<Role> findByName(String name);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.repositories;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.security.User;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
Optional<User> findByUsername(String username);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
/**
|
||||||
|
* A collection of {@link org.springframework.data.repository.CrudRepository} repositories that are used to access key
|
||||||
|
* components of the {@code nl.andrewlalis.teaching_assistant_assistant.model} package.
|
||||||
|
*/
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.repositories;
|
|
@ -0,0 +1,43 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.security;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.ManyToMany;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a role that a user has, which gives the user access to certain resources.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class Role extends BasicEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of this role.
|
||||||
|
*/
|
||||||
|
@Column(nullable = false, unique = true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of users with this role.
|
||||||
|
*/
|
||||||
|
@ManyToMany(mappedBy = "roles")
|
||||||
|
private List<User> users;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<User> getUsers() {
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsers(List<User> users) {
|
||||||
|
this.users = users;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.security;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Person;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a user of the website with some credentials.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class User extends BasicEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A unique username for the user.
|
||||||
|
*/
|
||||||
|
@Column(nullable = false, unique = true)
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The password for this user.
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not this user has been activated.
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private boolean activated = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not this user has been locked (no more access).
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private boolean locked = false;
|
||||||
|
|
||||||
|
@ManyToMany(
|
||||||
|
fetch = FetchType.EAGER
|
||||||
|
)
|
||||||
|
@JoinTable(
|
||||||
|
name = "user_roles",
|
||||||
|
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
|
||||||
|
)
|
||||||
|
private List<Role> roles;
|
||||||
|
|
||||||
|
@OneToOne
|
||||||
|
@JoinColumn(
|
||||||
|
name = "person_id",
|
||||||
|
nullable = true,
|
||||||
|
referencedColumnName = "id"
|
||||||
|
)
|
||||||
|
private Person person;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return this.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return this.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person getPerson() {
|
||||||
|
return this.person;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActivated() {
|
||||||
|
return activated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivated(boolean activated) {
|
||||||
|
this.activated = activated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocked() {
|
||||||
|
return locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocked(boolean locked) {
|
||||||
|
this.locked = locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Role> getRoles() {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRoles(List<Role> roles) {
|
||||||
|
this.roles = roles;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.security;
|
||||||
|
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TAA-specific implementation of Spring's UserDetails interface to supply user authentication data.
|
||||||
|
*/
|
||||||
|
public class UserDetails implements org.springframework.security.core.userdetails.UserDetails {
|
||||||
|
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
protected UserDetails(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
List<Role> roles = this.user.getRoles();
|
||||||
|
List<GrantedAuthority> authorities = new ArrayList<>();
|
||||||
|
for (Role role : roles) {
|
||||||
|
authorities.add(new SimpleGrantedAuthority(role.getName()));
|
||||||
|
}
|
||||||
|
return authorities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return this.user.getPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return this.user.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked() {
|
||||||
|
return !this.user.isLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return this.user.isActivated();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.model.security;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.UserRepository;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom user details service to supply database persistent user information to Spring Security.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
|
||||||
|
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
protected UserDetailsService(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
Optional<User> optionalUser = this.userRepository.findByUsername(username);
|
||||||
|
optionalUser.orElseThrow(() -> new UsernameNotFoundException("Username not found."));
|
||||||
|
|
||||||
|
return new nl.andrewlalis.teaching_assistant_assistant.model.security.UserDetails(optionalUser.get());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.services;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.Team;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeamRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with manipulation and various operations on individual students or groups of students (not teams).
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class StudentService {
|
||||||
|
|
||||||
|
private StudentRepository studentRepository;
|
||||||
|
private CourseRepository courseRepository;
|
||||||
|
private TeamRepository teamRepository;
|
||||||
|
|
||||||
|
protected StudentService (StudentRepository studentRepository, CourseRepository courseRepository, TeamRepository teamRepository) {
|
||||||
|
this.studentRepository = studentRepository;
|
||||||
|
this.courseRepository = courseRepository;
|
||||||
|
this.teamRepository = teamRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new student and assigns them to a course, if provided.
|
||||||
|
* @param student An unsaved student model.
|
||||||
|
* @param course The course to assign the student to. This may be null.
|
||||||
|
*/
|
||||||
|
public void createStudent(Student student, Course course) {
|
||||||
|
if (course != null) {
|
||||||
|
course.addParticipant(student);
|
||||||
|
student.assignToCourse(course);
|
||||||
|
this.courseRepository.save(course); // This cascades to save the student as well.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits a students' data. More specifically, updates the provided <code>student</code> with the attributes found
|
||||||
|
* in the provided <code>editedStudent</code> object.
|
||||||
|
* @param student The student to update.
|
||||||
|
* @param editedStudent A model containing updated attributes to assign to the given student.
|
||||||
|
*/
|
||||||
|
public void editStudent(Student student, Student editedStudent) {
|
||||||
|
student.setFirstName(editedStudent.getFirstName());
|
||||||
|
student.setLastName(editedStudent.getLastName());
|
||||||
|
student.setStudentNumber(editedStudent.getStudentNumber());
|
||||||
|
student.setEmailAddress(editedStudent.getEmailAddress());
|
||||||
|
student.setGithubUsername(editedStudent.getGithubUsername());
|
||||||
|
this.studentRepository.save(student);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a student from the application completely.
|
||||||
|
* @param student The student to remove.
|
||||||
|
*/
|
||||||
|
public void removeStudent(Student student) {
|
||||||
|
List<Team> teams = student.getTeams();
|
||||||
|
for (Team team : teams) {
|
||||||
|
team.removeMember(student);
|
||||||
|
student.removeFromAssignedTeam(team);
|
||||||
|
this.teamRepository.save(team);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Course> courses = student.getCourses();
|
||||||
|
for (Course course : courses) {
|
||||||
|
course.removeParticipant(student);
|
||||||
|
student.removeFromAssignedCourse(course);
|
||||||
|
this.courseRepository.save(course);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.studentRepository.delete(student);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -50,7 +50,7 @@ public class StudentTeamService {
|
||||||
StudentTeam newTeam = new StudentTeam(course);
|
StudentTeam newTeam = new StudentTeam(course);
|
||||||
course.addStudentTeam(newTeam);
|
course.addStudentTeam(newTeam);
|
||||||
this.courseRepository.save(course);
|
this.courseRepository.save(course);
|
||||||
logger.info("Created new team: " + newTeam.getId());
|
logger.info("Created new team.");
|
||||||
|
|
||||||
return newTeam;
|
return newTeam;
|
||||||
}
|
}
|
||||||
|
@ -185,13 +185,19 @@ public class StudentTeamService {
|
||||||
s.removeFromAssignedTeam(team);
|
s.removeFromAssignedTeam(team);
|
||||||
team.removeMember(s);
|
team.removeMember(s);
|
||||||
this.studentRepository.save(s);
|
this.studentRepository.save(s);
|
||||||
|
|
||||||
|
logger.debug("Removed student " + s.getFullName() + " from team " + team.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the TA team assignment.
|
// Remove the TA team assignment.
|
||||||
TeachingAssistantTeam teachingAssistantTeam = team.getAssignedTeachingAssistantTeam();
|
TeachingAssistantTeam teachingAssistantTeam = team.getAssignedTeachingAssistantTeam();
|
||||||
teachingAssistantTeam.removeAssignedStudentTeam(team);
|
if (teachingAssistantTeam != null) {
|
||||||
|
teachingAssistantTeam.removeAssignedStudentTeam(team);
|
||||||
|
this.teachingAssistantTeamRepository.save(teachingAssistantTeam);
|
||||||
|
logger.debug("Removed team " + team.getId() + " from Teaching Assistant Team " + teachingAssistantTeam.getId() + " assigned teams list.");
|
||||||
|
}
|
||||||
|
|
||||||
team.setAssignedTeachingAssistantTeam(null);
|
team.setAssignedTeachingAssistantTeam(null);
|
||||||
this.teachingAssistantTeamRepository.save(teachingAssistantTeam);
|
|
||||||
|
|
||||||
// Remove the repository from the course and delete it.
|
// Remove the repository from the course and delete it.
|
||||||
course.removeStudentTeam(team);
|
course.removeStudentTeam(team);
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,17 +1,9 @@
|
||||||
.footer_bar {
|
body {
|
||||||
background-color: darkslategray;
|
padding-bottom: 110px;
|
||||||
color: whitesmoke;
|
|
||||||
height: 30px;
|
|
||||||
padding-top: 20px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: -1; /* Make this footer appear above all other things. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.third {
|
.footer {
|
||||||
width: 33%;
|
background-color: darkslategray;
|
||||||
display: inline-block;
|
color: whitesmoke;
|
||||||
text-align: center;
|
height: 100px;
|
||||||
}
|
}
|
|
@ -1,45 +1,13 @@
|
||||||
body {
|
.header {
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
background-color: whitesmoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_bar {
|
|
||||||
background-color: green;
|
background-color: green;
|
||||||
width: 100%;
|
|
||||||
color: whitesmoke;
|
color: whitesmoke;
|
||||||
padding-bottom: 20px;
|
|
||||||
padding-top: 20px;
|
|
||||||
height: 30px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header_title {
|
.header a {
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
width: 25%;
|
|
||||||
display: inline;
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_link_list {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
width: 75%;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_link_list li {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header_link_list a {
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
background-color: darkgreen;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header_link_list a:hover {
|
.header a:hover {
|
||||||
background-color: darkgray;
|
color: lightgray;
|
||||||
}
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
body {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page_row {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login_form {
|
||||||
|
background-color: green;
|
||||||
|
color: white;
|
||||||
|
width: 50%;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login_form_row {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login_form label {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login_form input {
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login_form input[type=submit]:hover {
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
|
@ -1,52 +1,7 @@
|
||||||
/* Set the font for the whole website here. */
|
/*.btn-primary {*/
|
||||||
body {
|
/* background-color: green;*/
|
||||||
font-family: sans-serif;
|
/*}*/
|
||||||
}
|
|
||||||
|
|
||||||
.content_container {
|
/*.btn-primary:hover {*/
|
||||||
width: 50%;
|
/* background-color: darkgreen;*/
|
||||||
margin-left: auto;
|
/*}*/
|
||||||
margin-right: auto;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 16px;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar_container {
|
|
||||||
width: 20%;
|
|
||||||
height: 100%;
|
|
||||||
position: fixed;
|
|
||||||
top: 70px;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar_block {
|
|
||||||
margin: 20px 0 20px 0;
|
|
||||||
padding: 20px;
|
|
||||||
background-color: green;
|
|
||||||
color: whitesmoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar_block a {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar_block a:hover {
|
|
||||||
color: lightgreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
table, th, td {
|
|
||||||
border: 1px solid black;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page_row {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
File diff suppressed because one or more lines are too long
|
@ -1,39 +1,27 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Courses', content=~{::#content}, actions=~{::#actions})}" lang="en">
|
||||||
<head>
|
|
||||||
<title>Courses</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>Courses</h1>
|
<a class="btn btn-primary m-1" th:href="@{/courses/create}">Create New Course</a>
|
||||||
<hr>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li th:each="course: ${courses}">
|
|
||||||
<h2><a th:href="@{/courses/{code}(code=${course.getCode()})}" th:text="${course.getName()}"></a></h2>
|
|
||||||
<ul>
|
|
||||||
<li>Code: <span th:text="${course.getCode()}"></span></li>
|
|
||||||
<li>Created on: <span th:text="${course.getCreatedOn()}"></span></li>
|
|
||||||
<li>Students: <span th:text="${course.getStudents().size()}"></span></li>
|
|
||||||
<li>Teaching Assistants: <span th:text="${course.getTeachingAssistants().size()}"></span></li>
|
|
||||||
<li>Student Teams: <span th:text="${course.getStudentTeams().size()}"></span></li>
|
|
||||||
<li>Teaching Assistant Teams: <span th:text="${course.getTeachingAssistantTeams().size()}"></span></li>
|
|
||||||
<li>Number of Active Students (in a team): <span th:text="${course.getNumberOfStudentsInTeams()}"></span></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
<div id="content" class="container-fluid">
|
||||||
<div class="sidebar_block">
|
<div class="col-sm-12 col-md-6 offset-3">
|
||||||
<a href="/courses/create">Create new course</a>
|
<div class="list-group">
|
||||||
</div>
|
<a th:each="course: ${courses}" class="list-group-item list-group-item-action flex-column align-items-start" th:href="@{/courses/{code}(code=${course.getCode()})}">
|
||||||
<div class="sidebar_block">
|
<div class="d-flex w-100 justify-content-between">
|
||||||
Do something else
|
<h4 class="mb-1" th:text="${course.getName()}"></h4>
|
||||||
</div>
|
<small th:text="${course.getCode()}"></small>
|
||||||
<div class="sidebar_block">
|
</div>
|
||||||
Click this link!
|
<ul>
|
||||||
|
<li><span class="badge badge-primary" th:text="${course.getStudentTeams().size()}"></span> Student Teams</li>
|
||||||
|
<li><span class="badge badge-primary" th:text="${course.getNumberOfStudentsInTeams()}"></span> Active Students</li>
|
||||||
|
<li><span class="badge badge-primary" th:text="${course.getTeachingAssistants().size()}"></span> Teaching Assistants</li>
|
||||||
|
</ul>
|
||||||
|
<small>Created on <span th:text="${course.getCreatedOn()}"></span></small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,43 +1,35 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Create New Course', content=~{::#content})}" lang="en">
|
||||||
<head>
|
|
||||||
<title>Create a Course</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Create New Course</h1>
|
<form th:action="@{/courses}" th:object="${course}" method="post">
|
||||||
|
<div class="form-group">
|
||||||
<form action="#" th:action="@{/courses}" th:object="${course}" method="post">
|
<label for="course_name_input">Name</label>
|
||||||
<div class="page_row">
|
<input id="course_name_input" type="text" class="form-control" th:field="*{name}" required/>
|
||||||
<label for="course_name_input">Name:</label>
|
|
||||||
<input id="course_name_input" type="text" th:field="*{name}" required/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-group">
|
||||||
<label for="course_code_input">Code:</label>
|
<label for="course_code_input">Code</label>
|
||||||
<input id="course_code_input" type="text" th:field="*{code}" required/>
|
<input id="course_code_input" type="text" class="form-control" th:field="*{code}" required/>
|
||||||
|
<small class="form-text text-muted">Unique identifying code for this course.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-group">
|
||||||
<label for="course_github_organization_name_input">Github Organization:</label>
|
<label for="course_github_organization_name_input">Github Organization</label>
|
||||||
<input id="course_github_organization_name_input" type="text" th:field="*{githubOrganizationName}" required/>
|
<input id="course_github_organization_name_input" type="text" class="form-control" th:field="*{githubOrganizationName}" required/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-group">
|
||||||
<label for="course_github_api_key_input">Github API Key:</label>
|
<label for="course_github_api_key_input">Github API Key</label>
|
||||||
<input id="course_github_api_key_input" type="text" th:field="*{apiKey}" required/>
|
<input id="course_github_api_key_input" type="text" class="form-control" th:field="*{apiKey}" required/>
|
||||||
|
<small class="form-text text-muted">Needed to manage student repositories.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<input class="btn btn-primary" type="submit" value="Create"/>
|
||||||
<button type="submit">Submit</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,40 +1,35 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title=${course.getName()}, content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title th:text="${course.getName()}"></title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1><span th:text="${course.getName()}"></span> (Code: <span th:text="${course.getCode()}"></span>)</h1>
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/import_students(code=${course.getCode()})}">Import Students From CSV</a>
|
||||||
<hr>
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/import_teaching_assistants(code=${course.getCode()})}">Import Teaching Assistants From CSV</a>
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
Github Organization: <a th:href="@{${'https://www.github.com/' + course.getGithubOrganizationName()}}" th:text="${course.getGithubOrganizationName()}"></a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a th:href="@{/courses/{code}/teaching_assistant_teams(code=${course.getCode()})}">Teaching Assistant Teams</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a th:href="@{/courses/{code}/student_teams(code=${course.getCode()})}">Student Teams</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a th:href="@{/courses/{code}/students(code=${course.getCode()})}">All Students</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a th:href="@{/courses/{code}/teaching_assistants(code=${course.getCode()})}">All Teaching Assistants</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
<div id="content" class="row justify-content-center">
|
||||||
<div class="sidebar_block">
|
<div class="col-sm-12 col-md-6">
|
||||||
<a th:href="@{/courses/{code}/import_students(code=${course.getCode()})}">Import students from CSV</a>
|
<div class="list-group">
|
||||||
</div>
|
<a class="list-group-item list-group-item-action" th:href="@{${'https://www.github.com/' + course.getGithubOrganizationName()}}">
|
||||||
<div class="sidebar_block">
|
Github Organization: <span th:text="${course.getGithubOrganizationName()}"></span>
|
||||||
<a th:disabled="true" th:href="@{/courses/{code}/import_teaching_assistants(code=${course.getCode()})}">Import teaching assistants from CSV</a>
|
</a>
|
||||||
|
<a class="list-group-item list-group-item-action d-flex justify-content-between align-items-center" th:href="@{/courses/{code}/teaching_assistant_teams(code=${course.getCode()})}">
|
||||||
|
Teaching Assistant Teams
|
||||||
|
<span class="badge badge-primary" th:text="${course.getTeachingAssistantTeams().size()}"></span>
|
||||||
|
</a>
|
||||||
|
<a class="list-group-item list-group-item-action d-flex justify-content-between align-items-center" th:href="@{/courses/{code}/student_teams(code=${course.getCode()})}">
|
||||||
|
Student Teams
|
||||||
|
<span class="badge badge-primary" th:text="${course.getStudentTeams().size()}"></span>
|
||||||
|
</a>
|
||||||
|
<a class="list-group-item list-group-item-action d-flex justify-content-between align-items-center" th:href="@{/courses/{code}/students(code=${course.getCode()})}">
|
||||||
|
Students
|
||||||
|
<span class="badge badge-primary" th:text="${course.getStudents().size()}"></span>
|
||||||
|
</a>
|
||||||
|
<a class="list-group-item list-group-item-action d-flex justify-content-between align-items-center" th:href="@{/courses/{code}/teaching_assistants(code=${course.getCode()})}">
|
||||||
|
Teaching Assistants
|
||||||
|
<span class="badge badge-primary" th:text="${course.getTeachingAssistants().size()}"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar_content})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Import Students From CSV', content=~{::#content})}">
|
||||||
<head>
|
<head>
|
||||||
<title>Import Students via CSV</title>
|
<title>Import Students via CSV</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Import Students from CSV File</h1>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Use this form to import student data from a CSV which has been generated by a Google form. As of right now, the column headers are hard-coded, but in the future it will be possible to dynamically import data from any CSV file by custom header format definitions.
|
Use this form to import student data from a CSV which has been generated by a Google form. As of right now, the column headers are hard-coded, but in the future it will be possible to dynamically import data from any CSV file by custom header format definitions.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post" action="#" enctype="multipart/form-data" th:action="@{/courses/{code}/import_students(code=${course.getCode()})}">
|
<form method="post" enctype="multipart/form-data" th:action="@{/courses/{code}/import_students(code=${course.getCode()})}">
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="file_input">File:</label>
|
<label for="file_input">File:</label>
|
||||||
<input id="file_input" type="file" name="file" accept="text/csv"/>
|
<input id="file_input" type="file" name="file" accept="text/csv"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -26,9 +24,5 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar_content">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,18 +1,33 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Student Teams for ' + ${course.getCode()}, content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Student Teams</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>Student Teams for <span th:text="${course.getName()}"></span></h1>
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/student_teams/generate_repositories(code=${course.getCode()})}">
|
||||||
|
Generate Repositories
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/student_teams/branch_protection_update(code=${course.getCode()})}">
|
||||||
|
Update Branch Protection
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/student_teams/export(code=${course.getCode()})}">
|
||||||
|
Export
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/student_teams/export_contact_info(code=${course.getCode()})}">
|
||||||
|
Export Team Contact Details
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/student_teams/create(code=${course.getCode()})}">
|
||||||
|
Create New Student Team
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/student_teams/merge_single_teams(code=${course.getCode()})}">
|
||||||
|
Merge Single Teams
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content" class="row justify-content-center">
|
||||||
<div th:if="${course.getStudentTeams().isEmpty()}">
|
<div th:if="${course.getStudentTeams().isEmpty()}">
|
||||||
<p>No student teams.</p>
|
<p>No student teams.</p>
|
||||||
</div>
|
</div>
|
||||||
<table>
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Team</th>
|
<th>Team</th>
|
||||||
<th>Students</th>
|
<th>Students</th>
|
||||||
|
@ -53,26 +68,5 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/generate_repositories(code=${course.getCode()})}">Generate Repositories</a>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/branch_protection_update(code=${course.getCode()})}">Update Branch Protection</a>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/export(code=${course.getCode()})}">Export</a>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/export_contact_info(code=${course.getCode()})}">Export Team Contact Details</a>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/create(code=${course.getCode()})}">Create New Student Team</a>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/merge_single_teams(code=${course.getCode()})}">Merge Single Teams</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,28 +1,19 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Create Student Team', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<title>Create Student Team</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Create a New Student Team</h1>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Creates a new student team for the <span th:text="${course.getName()}"></span> course, without any assigned TA team or student members.
|
Creates a new student team for the <span th:text="${course.getName()}"></span> course, without any assigned TA team or student members.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form action="#" th:action="@{/courses/{code}/student_teams/create(code=${course.getCode()})}" enctype="application/x-www-form-urlencoded" method="post">
|
<form th:action="@{/courses/{code}/student_teams/create(code=${course.getCode()})}" enctype="application/x-www-form-urlencoded" method="post">
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<button type="submit">Submit</button>
|
<input type="submit" value="Submit" class="btn btn-primary"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,14 +1,39 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Student Team ' + ${student_team.getId()}, content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Student Team</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>Student Team <span th:text="${student_team.getId()}"></span></h1>
|
<th:block th:if="${student_team.getGithubRepositoryName() == null && student_team.getAssignedTeachingAssistantTeam() != null}">
|
||||||
|
<a
|
||||||
|
class="btn btn-primary m-1"
|
||||||
|
th:href="@{/courses/{code}/student_teams/{id}/generate_repository
|
||||||
|
(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}"
|
||||||
|
>Generate Repository</a>
|
||||||
|
</th:block>
|
||||||
|
<th:block th:if="${student_team.getGithubRepositoryName() != null}">
|
||||||
|
<a
|
||||||
|
class="btn btn-primary m-1"
|
||||||
|
th:href="@{/courses/{code}/student_teams/{id}/delete_repository
|
||||||
|
(code=${student_team.getCourse().getCode()}, id=${student_team.getAssignedTeachingAssistantTeam().getId()})}"
|
||||||
|
>Archive Repository</a>
|
||||||
|
</th:block>
|
||||||
|
<a
|
||||||
|
class="btn btn-primary m-1"
|
||||||
|
th:href="@{/courses/{code}/student_teams/{id}/add_student(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}">
|
||||||
|
Add Student To Team
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="btn btn-primary m-1"
|
||||||
|
th:href="@{/courses/{code}/student_teams/{id}/assign_teaching_assistant_team(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}">
|
||||||
|
Assign Teaching Assistant Team
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="btn btn-primary m-1"
|
||||||
|
th:href="@{/courses/{code}/student_teams/{id}/remove(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}">Remove This Team</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content" class="row justify-content-center">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Github Repository:
|
Github Repository:
|
||||||
|
@ -43,39 +68,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
<div id="sidebar">
|
||||||
<div class="sidebar_block" th:if="${student_team.getGithubRepositoryName() == null && student_team.getAssignedTeachingAssistantTeam() != null}">
|
<div class="sidebar_block" >
|
||||||
<a
|
|
||||||
th:href="@{/courses/{code}/student_teams/{id}/generate_repository
|
|
||||||
(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}"
|
|
||||||
>Generate Repository</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sidebar_block" th:if="${student_team.getGithubRepositoryName() != null}">
|
<div class="sidebar_block" >
|
||||||
<a
|
|
||||||
th:href="@{/courses/{code}/student_teams/{id}/delete_repository
|
|
||||||
(code=${student_team.getCourse().getCode()}, id=${student_team.getAssignedTeachingAssistantTeam().getId()})}"
|
|
||||||
>Archive Repository</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/{id}/add_student(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}">
|
|
||||||
Add Student To Team
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/{id}/assign_teaching_assistant_team(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}">
|
|
||||||
Assign Teaching Assistant Team
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/student_teams/{id}/remove(code=${student_team.getCourse().getCode()}, id=${student_team.getId()})}">Remove This Team</a>
|
|
||||||
<p>
|
|
||||||
Removes this team permanently, and archives the repository.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,28 +1,22 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Add Student To Team', content=~{::#content})}" lang="en">
|
||||||
<head>
|
|
||||||
<title>Add Student To Team</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Add a Student to Team <span th:text="${student_team.getId()}"></span></h1>
|
|
||||||
|
|
||||||
<form
|
<form
|
||||||
action="#"
|
|
||||||
th:action="@{/courses/{code}/student_teams/{id}/add_student(code=${course.getCode()}, id=${student_team.getId()})}"
|
th:action="@{/courses/{code}/student_teams/{id}/add_student(code=${course.getCode()}, id=${student_team.getId()})}"
|
||||||
enctype="application/x-www-form-urlencoded"
|
enctype="application/x-www-form-urlencoded"
|
||||||
method="post"
|
method="post"
|
||||||
>
|
>
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="student_select">Select a Student to Add:</label>
|
<label for="student_select">Select a Student to Add:</label>
|
||||||
<select id="student_select" name="student_id" required>
|
<select id="student_select" name="student_id" class="form-control" required>
|
||||||
<option th:each="student: ${eligible_students}" th:value="${student.getId()}" th:text="${student.getFullName()}"></option>
|
<option th:each="student: ${eligible_students}" th:value="${student.getId()}" th:text="${student.getFullName()}"></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<button type="submit">Submit</button>
|
<input type="submit" class="btn btn-primary" value="Submit"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,22 +1,16 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Assign Teaching Assistant Team', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<title>Assign Teaching Assistant Team</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Assign a Teaching Assistant Team to Student Team <span th:text="${student_team.getId()}"></span></h1>
|
|
||||||
|
|
||||||
<form
|
<form
|
||||||
action="#"
|
|
||||||
th:action="@{/courses/{code}/student_teams/{id}/assign_teaching_assistant_team(code=${course.getCode()}, id=${student_team.getId()})}"
|
th:action="@{/courses/{code}/student_teams/{id}/assign_teaching_assistant_team(code=${course.getCode()}, id=${student_team.getId()})}"
|
||||||
enctype="application/x-www-form-urlencoded"
|
enctype="application/x-www-form-urlencoded"
|
||||||
method="post"
|
method="post"
|
||||||
>
|
>
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="ta_team_select">Select a Team:</label>
|
<label for="ta_team_select">Select a Team:</label>
|
||||||
<select id="ta_team_select" name="teaching_assistant_team_id">
|
<select id="ta_team_select" name="teaching_assistant_team_id" class="form-control">
|
||||||
<option value="-1">None</option>
|
<option value="-1">None</option>
|
||||||
<option
|
<option
|
||||||
th:each="team: ${course.getTeachingAssistantTeams()}" th:value="${team.getId()}"
|
th:each="team: ${course.getTeachingAssistantTeams()}" th:value="${team.getId()}"
|
||||||
|
@ -25,8 +19,8 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<button type="submit">Submit</button>
|
<input type="submit" value="Submit" class="btn btn-primary"/>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Generate Repositories', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Generate Repositories</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Generate Repositories for all Student Teams in <span th:text="${course.getName()}"></span></h1>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Be careful, this may take a little while...
|
Generate Repositories for all Student Teams in <span th:text="${course.getName()}"></span>. Be careful, this may take a little while...
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form
|
<form
|
||||||
|
@ -23,9 +18,5 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,15 +1,16 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Students in ' + ${course.getCode()}, content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Students</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>Students in <span th:text="${course.getName()}"></span></h1>
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/students/invite_all(code=${course.getCode()})}">
|
||||||
|
Invite All Students To Repository
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table>
|
<div id="content">
|
||||||
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Student</th>
|
<th>Student</th>
|
||||||
<th>Student Number</th>
|
<th>Student Number</th>
|
||||||
|
@ -25,11 +26,5 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/students/invite_all(code=${course.getCode()})}">Invite All Students To Repository</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h1>Invite All Students in <span th:text="${course.getName()}"></span> to Repository</h1>
|
<h1>Invite All Students in <span th:text="${course.getName()}"></span> to Repository</h1>
|
||||||
|
<!-- TODO: Upgrade the basic method by which students gain access to the repository. Follow instructions from Github. -->
|
||||||
<p>
|
<p>
|
||||||
Be careful, this may take a little while...
|
Be careful, this may take a little while...
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -1,30 +1,53 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Teaching Assistants for ' + ${course.getCode()}, content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Teaching Assistant Teams</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>Teaching Assistant Teams for <span th:text="${course.getName()}"></span></h1>
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/teaching_assistant_teams/create(code=${course.getCode()})}">
|
||||||
|
Create Teaching Assistant Team
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/teaching_assistant_teams/assign_to_student_teams(code=${course.getCode()})}">
|
||||||
|
Assign Teams to Student Teams
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content" class="row justify-content-center">
|
||||||
<div th:if="${course.getTeachingAssistantTeams().isEmpty()}">
|
<div th:if="${course.getTeachingAssistantTeams().isEmpty()}">
|
||||||
<p>No teaching assistant teams.</p>
|
<p>No teaching assistant teams.</p>
|
||||||
</div>
|
</div>
|
||||||
<table>
|
<table class="table table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>Team</th>
|
||||||
|
<th>Teaching Assistants</th>
|
||||||
|
<th>Github Team</th>
|
||||||
|
<th>Assigned Student Teams</th>
|
||||||
|
<th>Delete</th>
|
||||||
|
</tr>
|
||||||
<tr th:each="taTeam: ${course.getTeachingAssistantTeams()}">
|
<tr th:each="taTeam: ${course.getTeachingAssistantTeams()}">
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a th:href="@{/courses/{code}/teaching_assistant_teams/{team_id}
|
||||||
th:href="@{/courses/{code}/teaching_assistant_teams/{team_id}
|
|
||||||
(code=${course.getCode()}, team_id=${taTeam.getId()})}">
|
(code=${course.getCode()}, team_id=${taTeam.getId()})}">
|
||||||
Teaching Assistant Team <span th:text="${taTeam.getId()}"></span>
|
Teaching Assistant Team <span th:text="${taTeam.getId()}"></span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td th:each="ta: ${taTeam.getTeachingAssistants()}">
|
<td>
|
||||||
<span th:text="${ta.getFullName()}"></span>
|
<div th:each="ta: ${taTeam.getTeachingAssistants()}">
|
||||||
|
<a th:href="@{/teaching_assistants/{id}(id=${ta.getId()})}" th:text="${ta.getFullName()}"></a><br>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a
|
||||||
|
th:href="'https://www.github.com/orgs/' + ${course.getGithubOrganizationName()} + '/teams/' + ${taTeam.getGithubTeamName().toLowerCase()}"
|
||||||
|
th:text="${taTeam.getGithubTeamName()}"
|
||||||
|
target="_blank"
|
||||||
|
></a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div th:each="studentTeam: ${taTeam.getAssignedStudentTeams()}">
|
||||||
|
<a th:href="@{/courses/{code}/student_teams/{id}(code=${course.getCode()}, id=${studentTeam.getId()})}" th:text="'Student Team ' + ${studentTeam.getId()}"></a>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td th:text="${taTeam.getGithubTeamName()}"></td>
|
|
||||||
<td>
|
<td>
|
||||||
<a th:href="@{/courses/{code}/teaching_assistant_teams/{team_id}/delete
|
<a th:href="@{/courses/{code}/teaching_assistant_teams/{team_id}/delete
|
||||||
(code=${course.getCode()}, team_id=${taTeam.getId()})}">
|
(code=${course.getCode()}, team_id=${taTeam.getId()})}">
|
||||||
|
@ -35,14 +58,5 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/teaching_assistant_teams/create(code=${course.getCode()})}">Create Teaching Assistant Team</a>
|
|
||||||
</div>
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/teaching_assistant_teams/assign_to_student_teams(code=${course.getCode()})}">Assign Teams to Student Teams</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,11 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Assign To Student Teams', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<title>Assign To Student Teams</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<form action="#" th:action="@{/courses/{code}/teaching_assistant_teams/assign_to_student_teams(code=${course.getCode()})}" enctype="application/x-www-form-urlencoded" method="post">
|
<form action="#" th:action="@{/courses/{code}/teaching_assistant_teams/assign_to_student_teams(code=${course.getCode()})}" enctype="application/x-www-form-urlencoded" method="post">
|
||||||
<label for="seed_input">Random Seed:</label>
|
<label for="seed_input">Random Seed:</label>
|
||||||
<input id="seed_input" type="number" name="seed" value="0" required/>
|
<input id="seed_input" type="number" name="seed" value="0" required/>
|
||||||
|
@ -13,9 +10,5 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,25 +1,25 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Create Teaching Assistant Team', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<title>Create Teaching Assistant Team</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<form action="#" th:action="@{/courses/{code}/teaching_assistant_teams(code=${course.getCode()})}" enctype="application/x-www-form-urlencoded" method="post">
|
<div class="col-sm-12 col-md-6">
|
||||||
<label for="ta_team_github_team_name">Github team name:</label>
|
<form action="#" th:action="@{/courses/{code}/teaching_assistant_teams(code=${course.getCode()})}" enctype="application/x-www-form-urlencoded" method="post">
|
||||||
<input id="ta_team_github_team_name" type="text" name="github_team_name"/>
|
<div class="form-row">
|
||||||
|
<label for="ta_team_github_team_name">Github team name:</label>
|
||||||
|
<input id="ta_team_github_team_name" type="text" name="github_team_name" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<label for="ta_team_member_1">Select the first Team Member:</label>
|
<div class="form-row">
|
||||||
<select id="ta_team_member_1" name="id_1">
|
<label for="ta_team_member_1">Select the first Team Member:</label>
|
||||||
<option th:each="ta: ${course.getTeachingAssistants()}" th:value="${ta.getId()}" th:text="${ta.getFullName()}"></option>
|
<select id="ta_team_member_1" name="id_1" class="form-control">
|
||||||
</select>
|
<option th:each="ta: ${course.getTeachingAssistants()}" th:value="${ta.getId()}" th:text="${ta.getFullName()}"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="submit">Submit</button>
|
<input type="submit" value="Submit" class="btn btn-primary"/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Teaching Assistant Team ' + ${teachingAssistantTeam.getId()}, content=~{::#content})}">
|
||||||
<head>
|
<head>
|
||||||
<title>Teaching Assistant Team</title>
|
<title>Teaching Assistant Team</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Teaching Assistant Team <span th:text="${teachingAssistantTeam.getId()}"></span> for <span th:text="${course.getName()}"></span></h1>
|
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Github Team Name: <code th:text="${teachingAssistantTeam.getGithubTeamName()}"></code>
|
Github Team Name: <code th:text="${teachingAssistantTeam.getGithubTeamName()}"></code>
|
||||||
|
@ -35,9 +33,5 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,14 +1,18 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Teaching Assistants for ' + ${course.getCode()}, content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
|
||||||
<title>Teaching Assistants</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>Teaching Assistants for <span th:text="${course.getName()}"></span></h1>
|
<a class="btn btn-primary m-1" th:href="@{/courses/{code}/teaching_assistants/create(code=${course.getCode()})}">Add Teaching Assistant</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table>
|
<div id="content">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>Teaching Assistant</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Id</th>
|
||||||
|
</tr>
|
||||||
<tr th:each="teachingAssistant: ${course.getTeachingAssistants()}">
|
<tr th:each="teachingAssistant: ${course.getTeachingAssistants()}">
|
||||||
<td>
|
<td>
|
||||||
<a th:href="@{/teaching_assistants/{id}(id=${teachingAssistant.getId()})}"><span th:text="${teachingAssistant.getFullName()}"></span></a>
|
<a th:href="@{/teaching_assistants/{id}(id=${teachingAssistant.getId()})}"><span th:text="${teachingAssistant.getFullName()}"></span></a>
|
||||||
|
@ -19,11 +23,5 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/courses/{code}/teaching_assistants/create(code=${course.getCode()})}">Add Teaching Assistant</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -5,19 +5,32 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<footer th:fragment="footer" class="footer_bar">
|
<footer th:fragment="footer" class="container-fluid footer fixed-bottom">
|
||||||
<!-- <link rel="stylesheet" href="../../../resources/static/css/footer.css" th:href="@{/css/footer.css}"/>-->
|
<link rel="stylesheet" th:href="@{/css/footer.css}" type="text/css"/>
|
||||||
|
|
||||||
<!-- <div class="third">-->
|
|
||||||
<!-- First third of footer-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div class="third">-->
|
|
||||||
<!-- Middle of footer-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div class="third">-->
|
|
||||||
<!-- Right side of footer.-->
|
|
||||||
<!-- </div>-->
|
|
||||||
|
|
||||||
|
<div class="row text-center">
|
||||||
|
<div class="col-sm-12 col-md-4">
|
||||||
|
<h5>Quick Links</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-4">
|
||||||
|
<h5>More links</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12 col-md-4">
|
||||||
|
<h5>Yet more links</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
Social media icons go here.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 text-center">
|
||||||
|
<p class="h6">
|
||||||
|
© 2019 Andrew Lalis, all rights reserved.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -7,15 +7,36 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
||||||
<nav th:fragment="header" class="header_bar">
|
<nav th:fragment="header" class="navbar navbar-expand navbar- header">
|
||||||
<link rel="stylesheet" href="../../../resources/static/css/header.css" th:href="@{/css/header.css}"/>
|
<link rel="stylesheet" th:href="@{/css/header.css}"/>
|
||||||
<h1 class="header_title">Teaching Assistant Assistant</h1>
|
|
||||||
<ul class="header_link_list">
|
<a class="navbar-brand" href="/">
|
||||||
<li><a href="/" th:href="@{/}">Home</a>
|
<img src="/../resources/static/images/logo.png" th:src="@{/images/logo.png}" class="d-inline-block align-top" alt="" width="30" height="30"/>
|
||||||
<li><a href="/courses" th:href="@{/courses}">Courses</a>
|
Teaching Assistant Assistant
|
||||||
<li><a href="/students" th:href="@{/students}">Students</a></li>
|
</a>
|
||||||
<li><a href="/teaching_assistants" th:href="@{/teaching_assistants}">Teaching Assistants</a></li>
|
<div class="collapse navbar-collapse">
|
||||||
</ul>
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" th:href="@{/}">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" th:href="@{/courses}">Courses</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" th:href="@{/students}">Students</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" th:href="@{/teaching_assistants}">
|
||||||
|
Teaching Assistants
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" th:href="@{/logout}">
|
||||||
|
Log out (Logged in as <span th:text="${user.getPerson().getFullName()}"></span>)
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Home', content=~{::#content})}" lang="en">
|
||||||
<head>
|
|
||||||
<title>Homepage</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="container-fluid">
|
||||||
<p>
|
<div class="row justify-content-center">
|
||||||
Welcome to the home page. To find the courses in this application please follow the link to <a th:href="@{/courses}">courses</a>.
|
<div class="col-6">
|
||||||
</p>
|
<h3>Welcome to the Teaching Assistant Assistant, <span th:text="${user.getPerson().getFullName()}"></span>.</h3>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="sidebar">
|
<p>
|
||||||
<div class="sidebar_block">
|
To find the courses in this application please follow the link to <a th:href="@{/courses}">courses</a>.
|
||||||
This is an example sidebar block.
|
</p>
|
||||||
</div>
|
|
||||||
<div id="generate_courses_block" class="sidebar_block">
|
<p>
|
||||||
<a href="/courses/generate">Click here to generate test data.</a>
|
This application makes it easy to sift through lots of student groups that are usually handled manually in some
|
||||||
</div>
|
spreadsheet. By integrating all data into one web application it is possible to access the information you need
|
||||||
<div class="sidebar_block">
|
faster, and make coordinated changes without fear of introducing inconsistencies or errors.
|
||||||
Another sidebar block with a lot more text in it, so that the text should properly wrap to the next lines if needed.
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,45 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" th:fragment="layout (title, content, sidebar_content)" xmlns:th="http://www.thymeleaf.org">
|
<html lang="en" th:fragment="layout (title, content)" xmlns:th="http://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title th:replace="${title}">basic_page</title>
|
<title th:text="${title}">basic_page</title>
|
||||||
|
|
||||||
|
<link rel="icon" th:href="@{/images/favicon.ico}"/>
|
||||||
|
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"/>
|
||||||
|
<script th:src="@{/javascript/bootstrap.bundle.min.js}"></script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../../../resources/static/css/style.css" th:href="@{/css/style.css}" />
|
<link rel="stylesheet" href="../../../resources/static/css/style.css" th:href="@{/css/style.css}" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div th:replace="~{fragments/header :: header}"></div>
|
<!-- Only show the header if the user is authenticated. -->
|
||||||
|
<header th:if="${user != null}">
|
||||||
|
<div th:replace="~{fragments/header :: header}"></div>
|
||||||
|
</header>
|
||||||
|
|
||||||
<div class="content_container">
|
<div class="content_container container-fluid">
|
||||||
<div th:replace="${content}">
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1 class="text-center" th:text="${title}"></h1>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- If the page controller specifies some actions, add them here as cards. -->
|
||||||
|
<th:block th:if="${actions != null}">
|
||||||
|
<div th:include="${actions}" class="row justify-content-center mb-2">
|
||||||
|
</div>
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<div th:replace="${content}" class="row">
|
||||||
<p>
|
<p>
|
||||||
Basic page content block.
|
Basic page content block.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sidebar_container">
|
|
||||||
<div th:replace="${sidebar_content}">
|
|
||||||
<p>
|
|
||||||
Basic page sidebar block.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div th:replace="~{fragments/footer :: footer}"></div>
|
<div th:replace="~{fragments/footer :: footer}"></div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Login', content=~{::#content})}" lang="en">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<section id="content" class="container">
|
||||||
|
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="alert alert-danger" th:if="${param.error}">
|
||||||
|
Invalid username or password!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-success" th:if="${param.logout}">
|
||||||
|
You have been logged out!
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<p>
|
||||||
|
Please log in to access to the world's most advanced course organization tool ever created. With the ability to manipulate large groups of students with ease, you might actually enjoy teaching a course.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<form th:action="@{/login}" method="post">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username_input">Username</label>
|
||||||
|
<input id="username_input" class="form-control" type="text" name="username"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password_input">Password</label>
|
||||||
|
<input id="password_input" class="form-control" type="password" name="password"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input class="btn btn-primary" type="submit" value="Login"/>
|
||||||
|
|
||||||
|
<a class="btn btn-secondary btn-sm" th:href="@{/register}">Don't have an account? Sign up here!</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Register', content=~{::#content})}" lang="en">
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<section id="content" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<p>
|
||||||
|
Here you can register to create a new account to access the information provided by this application, whether you are a professor, teaching assistant, or student. After filling out this submission form, you'll receive an email with a link to verify that you are who you say you are, after which your account will be activated.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<h3>I am a ...</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col text-center">
|
||||||
|
<a class="btn btn-primary" th:href="@{/register/student}">Student</a>
|
||||||
|
</div>
|
||||||
|
<div class="col text-center">
|
||||||
|
<a class="btn btn-primary" th:href="@{/register/teaching_assistant}">Teaching Assistant</a>
|
||||||
|
</div>
|
||||||
|
<div class="col text-center">
|
||||||
|
<a class="btn btn-primary" th:href="@{/register/administrator}">Administrator</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Register as a New Student', content=~{::#content})}" lang="en">
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<section id="content" class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<p>
|
||||||
|
To register as a student, please fill out the form below. Make sure to double-check that all information is entered is accurate.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Where the form asks for a <em>Registration Code</em>, please provide the code that has been given to you by your lecturers. This code ensures that you'll join the right course.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col">
|
||||||
|
<form action="/register/student" method="post" enctype="application/x-www-form-urlencoded">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>
|
||||||
|
Registration Code:
|
||||||
|
<input type="text" name="registration_code" class="form-control">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,15 +1,17 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Students', content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Students</title>
|
<title>Students</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>All Students</h1>
|
<a class="btn btn-primary m-1" th:href="@{/students/create}">Create Student</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table>
|
<div id="content" class="row">
|
||||||
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Student</th>
|
<th>Student</th>
|
||||||
<th>Student Number</th>
|
<th>Student Number</th>
|
||||||
|
@ -44,11 +46,5 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/students/create}">Create Student</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,59 +1,66 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Create New Student', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<title>Create a Student</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Create New Student</h1>
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<form th:action="@{/students/create}" th:object="${student}" method="post" enctype="application/x-www-form-urlencoded">
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="col">
|
||||||
|
<label for="student_first_name_input">First Name</label>
|
||||||
|
<input id="student_first_name_input" class="form-control" type="text" th:field="*{firstName}" placeholder="Elon" required />
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<label for="student_last_name_input">Last Name</label>
|
||||||
|
<input id="student_last_name_input" class="form-control" type="text" th:field="*{lastName}" placeholder="Musk" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form action="#" th:action="@{/students/create}" th:object="${student}" method="post" enctype="application/x-www-form-urlencoded">
|
<div class="form-row">
|
||||||
<div class="page_row">
|
<div class="col">
|
||||||
<label for="student_first_name_input">First Name:</label>
|
<label for="student_email_input">Email Address</label>
|
||||||
<input id="student_first_name_input" type="text" th:field="*{firstName}" required />
|
<input id="student_email_input" class="form-control" type="email" th:field="*{emailAddress}" placeholder="me@example.com" required />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="student_last_name_input">Last Name:</label>
|
<div class="col">
|
||||||
<input id="student_last_name_input" type="text" th:field="*{lastName}" required />
|
<label for="student_github_username_input">Github Username</label>
|
||||||
</div>
|
<input id="student_github_username_input" class="form-control" type="text" th:field="*{githubUsername}" placeholder="username" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="student_email_input">Email Address:</label>
|
<div class="col">
|
||||||
<input id="student_email_input" type="email" th:field="*{emailAddress}" required />
|
<label for="student_number_input">Student Number</label>
|
||||||
</div>
|
<input id="student_number_input" class="form-control" type="number" th:field="*{studentNumber}" value="" placeholder="1234567" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="student_github_username_input">Github Username:</label>
|
<div class="col">
|
||||||
<input id="student_github_username_input" type="text" th:field="*{githubUsername}" required />
|
<label for="student_course_select">Add this student to a course?</label>
|
||||||
</div>
|
<select id="student_course_select" class="form-control" name="course_code">
|
||||||
|
<option value="NO_COURSE_SELECTED">None</option>
|
||||||
|
<option
|
||||||
|
th:each="course: ${courses}"
|
||||||
|
th:value="${course.getCode()}"
|
||||||
|
th:text="${course.getName()}"
|
||||||
|
></option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted">This can also be done later at this student's page.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row mt-1">
|
||||||
<label for="student_number_input">Student Number:</label>
|
<div class="col">
|
||||||
<input id="student_number_input" type="number" th:field="*{studentNumber}" required />
|
<input class="btn btn-primary" type="submit" value="Submit" />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
</form>
|
||||||
<label for="student_course_select">Select a course to add the student to:</label>
|
</div>
|
||||||
<select id="student_course_select" name="course_code">
|
|
||||||
<option value="NO_COURSE_SELECTED">None</option>
|
|
||||||
<option
|
|
||||||
th:each="course: ${courses}"
|
|
||||||
th:value="${course.getCode()}"
|
|
||||||
th:text="${course.getName()}"
|
|
||||||
></option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="page_row">
|
|
||||||
<button type="submit">Submit</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title=${student.getFullName()}, content=~{::#content}, actions=~{::#actions})}">
|
||||||
<head>
|
|
||||||
<title>Student</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="actions">
|
||||||
<h1>Student: <span th:text="${student.getFullName()}"></span></h1>
|
<a class="btn btn-primary m-1" th:href="@{/students/{id}/edit(id=${student.getId()})}">Edit</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content" class="row">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Student Number: <code th:text="${student.getStudentNumber()}"></code>
|
Student Number: <code th:text="${student.getStudentNumber()}"></code>
|
||||||
|
@ -29,11 +29,5 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
<div class="sidebar_block">
|
|
||||||
<a th:href="@{/students/{id}/edit(id=${student.getId()})}">Edit</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,53 +1,44 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Edit Student', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<title>Edit Student</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Edit Student: <span th:text="${student.getFullName()}"></span></h1>
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<form
|
||||||
|
th:action="@{/students/{id}/edit(id=${student.getId()})}" th:object="${student}"
|
||||||
|
method="post"
|
||||||
|
>
|
||||||
|
|
||||||
<form
|
<div class="form-row">
|
||||||
action="#"
|
<label for="first_name_input">First Name:</label>
|
||||||
th:action="@{/students/{id}/edit(id=${student.getId()})}" th:object="${student}"
|
<input id="first_name_input" type="text" th:field="*{firstName}" required />
|
||||||
method="post"
|
</div>
|
||||||
>
|
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="first_name_input">First Name:</label>
|
<label for="last_name_input">Last Name:</label>
|
||||||
<input id="first_name_input" type="text" th:field="*{firstName}" required />
|
<input id="last_name_input" type="text" th:field="*{lastName}" required />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="last_name_input">Last Name:</label>
|
<label for="email_input">Email Address:</label>
|
||||||
<input id="last_name_input" type="text" th:field="*{lastName}" required />
|
<input id="email_input" type="email" th:field="*{emailAddress}" required />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="email_input">Email Address:</label>
|
<label for="github_username_input">Github Username:</label>
|
||||||
<input id="email_input" type="email" th:field="*{emailAddress}" required />
|
<input id="github_username_input" type="text" th:field="*{githubUsername}" required />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
<div class="form-row">
|
||||||
<label for="github_username_input">Github Username:</label>
|
<label for="student_number_input">Student Number:</label>
|
||||||
<input id="github_username_input" type="text" th:field="*{githubUsername}" required />
|
<input id="student_number_input" type="number" th:field="*{studentNumber}" required />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="page_row">
|
|
||||||
<label for="student_number_input">Student Number:</label>
|
|
||||||
<input id="student_number_input" type="number" th:field="*{studentNumber}" required />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="page_row">
|
|
||||||
<button type="submit">Submit</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,22 +1,28 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title='Teaching Assistants', content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Teaching Assistants</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h1>All Teaching Assistants</h1>
|
<table class="table">
|
||||||
|
<tr>
|
||||||
<table>
|
<th>Teaching Assistant</th>
|
||||||
|
<th>Github Username</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Courses</th>
|
||||||
|
<th>Delete</th>
|
||||||
|
</tr>
|
||||||
<tr th:each="teachingAssistant: ${teaching_assistants}">
|
<tr th:each="teachingAssistant: ${teaching_assistants}">
|
||||||
<td>
|
<td>
|
||||||
<a th:href="@{/teaching_assistants/{id}(id=${teachingAssistant.getId()})}"><span th:text="${teachingAssistant.getFullName()}"></span></a>
|
<a th:href="@{/teaching_assistants/{id}(id=${teachingAssistant.getId()})}"><span th:text="${teachingAssistant.getFullName()}"></span></a>
|
||||||
</td>
|
</td>
|
||||||
<td th:text="${teachingAssistant.getGithubUsername()}"></td>
|
<td th:text="${teachingAssistant.getGithubUsername()}"></td>
|
||||||
<td th:text="${teachingAssistant.getEmailAddress()}"></td>
|
<td th:text="${teachingAssistant.getEmailAddress()}"></td>
|
||||||
<td th:text="${teachingAssistant.getId()}"></td>
|
<td>
|
||||||
|
<div th:each="course: ${teachingAssistant.getCourses()}">
|
||||||
|
<a th:href="@{/courses/{code}(code=${course.getCode()})}" th:text="${course.getName()}"></a><br>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a th:href="@{/teaching_assistants/{id}/delete(id=${teachingAssistant.getId()})}">Delete</a>
|
<a th:href="@{/teaching_assistants/{id}/delete(id=${teachingAssistant.getId()})}">Delete</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -24,9 +30,5 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,33 +1,21 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (title=${teachingAssistant.getFullName()}, content=~{::#content})}">
|
||||||
<head>
|
|
||||||
<title>Teaching Assistant</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content" class="row justify-content-center">
|
||||||
<h1>Teaching Assistant: <span th:text="${teachingAssistant.getFullName()}"></span></h1>
|
<div class="col-sm-12 col-md-6">
|
||||||
|
<div class="list-group">
|
||||||
<ul>
|
<a class="list-group-item list-group-item-action" th:text="'Email: ' + ${teachingAssistant.getEmailAddress()}" th:href="'mailto: ' + ${teachingAssistant.getEmailAddress()}"></a>
|
||||||
<li>
|
<a class="list-group-item list-group-item-action" th:text="'Github Username: ' + ${teachingAssistant.getGithubUsername()}" th:href="'https://www.github.com/' + ${teachingAssistant.getGithubUsername()}" target="_blank"></a>
|
||||||
Email: <code th:text="${teachingAssistant.getEmailAddress()}"></code>
|
<div class="list-group-item">
|
||||||
</li>
|
<h5>Courses</h5>
|
||||||
<li>
|
<div th:each="course: ${teachingAssistant.getCourses()}">
|
||||||
Github Username: <code th:text="${teachingAssistant.getGithubUsername()}"></code>
|
<a class="list-group-item-action" th:text="${course.getName()}" th:href="@{/courses/{code}(code=${course.getCode()})}"></a><br>
|
||||||
</li>
|
</div>
|
||||||
<li>
|
</div>
|
||||||
Courses:
|
</div>
|
||||||
<ul>
|
</div>
|
||||||
<li th:each="course: ${teachingAssistant.getCourses()}">
|
|
||||||
<a th:href="@{/courses/{code}(code=${course.getCode()})}"><span th:text="${course.getName()}"></span></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="sidebar">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
|
||||||
<head>
|
|
||||||
<title>Test Controller Page</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<p th:text="'Hello, ' + ${name} + '!'"></p>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue