merge visibility and grouptype + merge createorga and createstudent + adapt to changes + finish create refactor
This commit is contained in:
@ -3,12 +3,12 @@ package mops.gruppen2.controller;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
||||
import mops.gruppen2.domain.Group;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.User;
|
||||
import mops.gruppen2.service.CsvService;
|
||||
import mops.gruppen2.service.GroupService;
|
||||
import mops.gruppen2.service.IdService;
|
||||
import mops.gruppen2.service.ProjectionService;
|
||||
import mops.gruppen2.service.ValidationService;
|
||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@ -24,7 +24,6 @@ import javax.annotation.security.RolesAllowed;
|
||||
import static mops.gruppen2.service.ControllerService.getGroupType;
|
||||
import static mops.gruppen2.service.ControllerService.getParent;
|
||||
import static mops.gruppen2.service.ControllerService.getUserLimit;
|
||||
import static mops.gruppen2.service.ControllerService.getVisibility;
|
||||
|
||||
@SuppressWarnings("SameReturnValue")
|
||||
@Log4j2
|
||||
@ -41,66 +40,42 @@ public class GroupCreationController {
|
||||
this.projectionService = projectionService;
|
||||
}
|
||||
|
||||
@RolesAllowed({"ROLE_orga", "ROLE_student"})
|
||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||
@GetMapping("/create")
|
||||
public String getCreate(KeycloakAuthenticationToken token,
|
||||
Model model) {
|
||||
|
||||
model.addAttribute("lectures", projectionService.projectLectures());
|
||||
|
||||
if (token.getAccount().getRoles().contains("orga")) {
|
||||
return "create_orga";
|
||||
}
|
||||
|
||||
return "create_student";
|
||||
return "create";
|
||||
}
|
||||
|
||||
@RolesAllowed("ROLE_orga")
|
||||
@PostMapping("/create/orga")
|
||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||
@PostMapping("/create")
|
||||
@CacheEvict(value = "groups", allEntries = true)
|
||||
public String postCreateOrga(KeycloakAuthenticationToken token,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("description") String description,
|
||||
@RequestParam("visibility") boolean isPrivate,
|
||||
@RequestParam("lecture") boolean isLecture,
|
||||
@RequestParam("maxInfiniteUsers") boolean isInfinite,
|
||||
@RequestParam("userMaximum") long userLimit,
|
||||
@RequestParam("parent") String parent,
|
||||
@RequestParam("type") String type,
|
||||
@RequestParam(value = "parent", defaultValue = "") String parent,
|
||||
@RequestParam("limit") String limit,
|
||||
@RequestParam("userlimit") long userLimit,
|
||||
@RequestParam(value = "file", required = false) MultipartFile file) {
|
||||
|
||||
User user = new User(token);
|
||||
Group group = groupService.createGroup(user,
|
||||
title,
|
||||
description,
|
||||
getVisibility(isPrivate),
|
||||
getGroupType(isLecture),
|
||||
getUserLimit(isInfinite, userLimit),
|
||||
getParent(parent, isLecture));
|
||||
|
||||
groupService.addUsersToGroup(CsvService.readCsvFile(file), group, user);
|
||||
|
||||
return "redirect:/gruppen2/details/" + IdService.uuidToString(group.getId());
|
||||
}
|
||||
|
||||
@RolesAllowed("ROLE_studentin")
|
||||
@PostMapping("/create/student")
|
||||
@CacheEvict(value = "groups", allEntries = true)
|
||||
public String postCreateStudent(KeycloakAuthenticationToken token,
|
||||
@RequestParam("title") String title,
|
||||
@RequestParam("description") String description,
|
||||
@RequestParam("visibility") boolean isPrivate,
|
||||
@RequestParam("maxInfiniteUsers") boolean isInfinite,
|
||||
@RequestParam("userMaximum") long userLimit,
|
||||
@RequestParam("parent") String parent) {
|
||||
ValidationService.validateGroupType(token, type);
|
||||
|
||||
User user = new User(token);
|
||||
Group group = groupService.createGroup(user,
|
||||
title,
|
||||
description,
|
||||
getVisibility(isPrivate),
|
||||
GroupType.SIMPLE,
|
||||
getUserLimit(isInfinite, userLimit),
|
||||
getParent(parent, false));
|
||||
getGroupType(type),
|
||||
getUserLimit(limit, userLimit),
|
||||
getParent(parent, type));
|
||||
|
||||
// ROLE_studentin kann kein CSV importieren
|
||||
if (token.getAccount().getRoles().contains("orga")) {
|
||||
groupService.addUsersToGroup(CsvService.readCsvFile(file), group, user);
|
||||
}
|
||||
|
||||
return "redirect:/gruppen2/details/" + IdService.uuidToString(group.getId());
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import mops.gruppen2.domain.Account;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.Role;
|
||||
import mops.gruppen2.domain.User;
|
||||
import mops.gruppen2.domain.Visibility;
|
||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
@ -27,10 +26,9 @@ public class ModelAttributeControllerAdvice {
|
||||
// Add enums
|
||||
model.addAttribute("member", Role.MEMBER);
|
||||
model.addAttribute("admin", Role.ADMIN);
|
||||
model.addAttribute("public", Visibility.PUBLIC);
|
||||
model.addAttribute("private", Visibility.PRIVATE);
|
||||
model.addAttribute("public", GroupType.PUBLIC);
|
||||
model.addAttribute("private", GroupType.PRIVATE);
|
||||
model.addAttribute("lecture", GroupType.LECTURE);
|
||||
model.addAttribute("simple", GroupType.SIMPLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package mops.gruppen2.controller;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
||||
import mops.gruppen2.domain.Group;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.User;
|
||||
import mops.gruppen2.domain.Visibility;
|
||||
import mops.gruppen2.service.InviteService;
|
||||
import mops.gruppen2.service.ProjectionService;
|
||||
import mops.gruppen2.service.SearchService;
|
||||
@ -74,7 +74,7 @@ public class SearchAndInviteController {
|
||||
model.addAttribute("group", group);
|
||||
|
||||
// Gruppe öffentlich
|
||||
if (group.getVisibility() == Visibility.PUBLIC) {
|
||||
if (group.getType() == GroupType.PUBLIC) {
|
||||
return "redirect:/gruppen2/details/" + group.getId();
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,6 @@ public class Group {
|
||||
|
||||
//TODO: Single Type for Public/Private/Lecture?
|
||||
private GroupType type;
|
||||
private Visibility visibility;
|
||||
|
||||
private String title;
|
||||
private String description;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package mops.gruppen2.domain;
|
||||
|
||||
public enum GroupType {
|
||||
SIMPLE,
|
||||
PUBLIC,
|
||||
PRIVATE,
|
||||
LECTURE
|
||||
}
|
||||
|
6
src/main/java/mops/gruppen2/domain/Limit.java
Normal file
6
src/main/java/mops/gruppen2/domain/Limit.java
Normal file
@ -0,0 +1,6 @@
|
||||
package mops.gruppen2.domain;
|
||||
|
||||
public enum Limit {
|
||||
INFINITE,
|
||||
LOCKED
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package mops.gruppen2.domain;
|
||||
|
||||
public enum Visibility {
|
||||
PUBLIC,
|
||||
PRIVATE
|
||||
}
|
@ -6,7 +6,6 @@ import lombok.ToString;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.domain.Group;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.Visibility;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -16,15 +15,13 @@ import java.util.UUID;
|
||||
@Log4j2
|
||||
public class CreateGroupEvent extends Event {
|
||||
|
||||
private Visibility groupVisibility;
|
||||
private UUID groupParent;
|
||||
private GroupType groupType;
|
||||
|
||||
public CreateGroupEvent(UUID groupId, String userId, UUID parent, GroupType type, Visibility visibility) {
|
||||
public CreateGroupEvent(UUID groupId, String userId, UUID parent, GroupType type) {
|
||||
super(groupId, userId);
|
||||
groupParent = parent;
|
||||
groupType = type;
|
||||
groupVisibility = visibility;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -32,7 +29,6 @@ public class CreateGroupEvent extends Event {
|
||||
group.setId(groupId);
|
||||
group.setParent(groupParent);
|
||||
group.setType(groupType);
|
||||
group.setVisibility(groupVisibility);
|
||||
|
||||
log.trace("\t\t\t\t\tNeue Gruppe: {}", group.toString());
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ public class DeleteGroupEvent extends Event {
|
||||
group.getMembers().clear();
|
||||
group.setTitle(null);
|
||||
group.setDescription(null);
|
||||
group.setVisibility(null);
|
||||
group.setType(null);
|
||||
group.setParent(null);
|
||||
group.setUserLimit(0L);
|
||||
|
@ -2,7 +2,8 @@ package mops.gruppen2.service;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.Visibility;
|
||||
import mops.gruppen2.domain.Limit;
|
||||
import net.bytebuddy.description.modifier.Visibility;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -18,27 +19,27 @@ public final class ControllerService {
|
||||
return isPrivate ? Visibility.PRIVATE : Visibility.PUBLIC;
|
||||
}
|
||||
|
||||
public static GroupType getGroupType(boolean isLecture) {
|
||||
return isLecture ? GroupType.LECTURE : GroupType.SIMPLE;
|
||||
public static GroupType getGroupType(String type) {
|
||||
return GroupType.valueOf(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wenn die maximale Useranzahl unendlich ist, wird das Maximum auf 100000 gesetzt.
|
||||
* Praktisch gibt es also maximal 100000 Nutzer pro Gruppe.
|
||||
*
|
||||
* @param isInfinite Gibt an, ob es unendlich viele User geben soll
|
||||
* @param userLimit Das Maximum an Usern, falls es eins gibt
|
||||
* @param limit Gibt an, ob es unendlich viele User geben soll
|
||||
* @param userLimit Das Maximum an Usern, falls es eins gibt
|
||||
*
|
||||
* @return Maximum an Usern
|
||||
*/
|
||||
public static long getUserLimit(boolean isInfinite, long userLimit) {
|
||||
return isInfinite ? Long.MAX_VALUE : userLimit;
|
||||
public static long getUserLimit(String limit, long userLimit) {
|
||||
return Limit.valueOf(limit) == Limit.INFINITE ? Long.MAX_VALUE : userLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die UUID des Parents, falls vorhanden.
|
||||
*/
|
||||
public static UUID getParent(String parent, boolean isLecture) {
|
||||
return isLecture ? IdService.emptyUUID() : IdService.stringToUUID(parent);
|
||||
public static UUID getParent(String parent, String type) {
|
||||
return GroupType.valueOf(type) == GroupType.LECTURE ? IdService.emptyUUID() : IdService.stringToUUID(parent);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import mops.gruppen2.domain.Group;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.Role;
|
||||
import mops.gruppen2.domain.User;
|
||||
import mops.gruppen2.domain.Visibility;
|
||||
import mops.gruppen2.domain.event.AddUserEvent;
|
||||
import mops.gruppen2.domain.event.CreateGroupEvent;
|
||||
import mops.gruppen2.domain.event.DeleteGroupEvent;
|
||||
@ -51,7 +50,6 @@ public class GroupService {
|
||||
public Group createGroup(User user,
|
||||
String title,
|
||||
String description,
|
||||
Visibility visibility,
|
||||
GroupType groupType,
|
||||
long userLimit,
|
||||
UUID parent) {
|
||||
@ -59,8 +57,7 @@ public class GroupService {
|
||||
// Regeln:
|
||||
// isPrivate -> !isLecture
|
||||
// isLecture -> !isPrivate
|
||||
ValidationService.validateFlags(visibility, groupType);
|
||||
Group group = createGroup(user, parent, groupType, visibility);
|
||||
Group group = createGroup(user, parent, groupType);
|
||||
|
||||
// Die Reihenfolge ist wichtig, da der ausführende User Admin sein muss
|
||||
addUser(user, group);
|
||||
@ -133,12 +130,11 @@ public class GroupService {
|
||||
/**
|
||||
* Erzeugt eine Gruppe, speichert diese und gibt diese zurück.
|
||||
*/
|
||||
private Group createGroup(User user, UUID parent, GroupType groupType, Visibility visibility) {
|
||||
private Group createGroup(User user, UUID parent, GroupType groupType) {
|
||||
Event event = new CreateGroupEvent(UUID.randomUUID(),
|
||||
user.getId(),
|
||||
parent,
|
||||
groupType,
|
||||
visibility);
|
||||
groupType);
|
||||
Group group = new Group();
|
||||
event.apply(group);
|
||||
|
||||
|
@ -4,7 +4,6 @@ import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.domain.Group;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.User;
|
||||
import mops.gruppen2.domain.Visibility;
|
||||
import mops.gruppen2.domain.event.Event;
|
||||
import mops.gruppen2.domain.exception.EventException;
|
||||
import mops.gruppen2.domain.exception.GroupNotFoundException;
|
||||
@ -131,7 +130,7 @@ public class ProjectionService {
|
||||
List<Group> groups = projectGroups(events);
|
||||
|
||||
return groups.stream()
|
||||
.filter(group -> group.getVisibility() == Visibility.PUBLIC)
|
||||
.filter(group -> group.getType() == GroupType.PUBLIC)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,13 @@ import lombok.extern.log4j.Log4j2;
|
||||
import mops.gruppen2.domain.Group;
|
||||
import mops.gruppen2.domain.GroupType;
|
||||
import mops.gruppen2.domain.User;
|
||||
import mops.gruppen2.domain.Visibility;
|
||||
import mops.gruppen2.domain.exception.BadParameterException;
|
||||
import mops.gruppen2.domain.exception.GroupFullException;
|
||||
import mops.gruppen2.domain.exception.NoAccessException;
|
||||
import mops.gruppen2.domain.exception.NoAdminAfterActionException;
|
||||
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
|
||||
import mops.gruppen2.domain.exception.UserNotFoundException;
|
||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static mops.gruppen2.domain.Role.ADMIN;
|
||||
@ -127,12 +127,6 @@ public final class ValidationService {
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateFlags(Visibility visibility, GroupType groupType) {
|
||||
if (visibility == Visibility.PRIVATE && groupType == GroupType.LECTURE) {
|
||||
throw new BadParameterException("Eine Veranstaltung kann nicht privat sein!");
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateUserLimit(long userLimit, Group group) {
|
||||
if (userLimit < 1) {
|
||||
throw new BadParameterException("Das Userlimit muss größer als 1 sein!");
|
||||
@ -142,4 +136,11 @@ public final class ValidationService {
|
||||
throw new BadParameterException("Das Userlimit kann nicht unter der momentanen Mitgliederanzahl sein!");
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateGroupType(KeycloakAuthenticationToken token, String type) {
|
||||
if (!token.getAccount().getRoles().contains("orga")
|
||||
&& GroupType.valueOf(type) == GroupType.LECTURE) {
|
||||
throw new BadParameterException("Eine Veranstaltung kann nur von ORGA erstellt werden.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
171
src/main/resources/templates/create.html
Normal file
171
src/main/resources/templates/create.html
Normal file
@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" xmlns:th="http://www.thymeleaf.org" th:replace="~{mopslayout :: html(
|
||||
name='Gruppenbildung',
|
||||
title='Neue Gruppe',
|
||||
headcontent=~{fragments/general :: headcontent(style='none')},
|
||||
navigation=~{fragments/general :: nav(current='create')},
|
||||
bodycontent=~{:: bodycontent})}">
|
||||
|
||||
<body>
|
||||
|
||||
<main th:fragment="bodycontent">
|
||||
<div class="container-fluid">
|
||||
|
||||
<h1 class="def-cursor">Neue Gruppe</h1>
|
||||
|
||||
<div class="content">
|
||||
<h3 class="def-cursor">Eigenschaften:</h3>
|
||||
|
||||
<form enctype="multipart/form-data" method="post" th:action="@{/gruppen2/create}">
|
||||
|
||||
<div class="content-text">
|
||||
<!--Gruppentitel-->
|
||||
<div class="input-group mb-2">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Gruppentitel:</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" th:name="title" required>
|
||||
</div>
|
||||
|
||||
<!--Gruppenbeschreibung-->
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Beschreibung:</span>
|
||||
</div>
|
||||
<textarea class="form-control" th:name="description" required></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--TODO: Enter AsciiDoc Description-->
|
||||
|
||||
<div class="content-text-in">
|
||||
<!--Gruppentyp-->
|
||||
<label for="grouptype">Gruppentyp:</label>
|
||||
<div class="btn-toolbar row mb-2" id="grouptype">
|
||||
<div class="btn-group btn-group-toggle col-sm-4" data-toggle="buttons">
|
||||
<label class="btn btn-secondary active" onclick="enableParent()">
|
||||
<input type="radio" name="type" value="PRIVATE" checked> Privat
|
||||
</label>
|
||||
<label class="btn btn-secondary" onclick="enableParent()">
|
||||
<input type="radio" name="type" value="PUBLIC"> Öffentlich
|
||||
</label>
|
||||
<label class="btn btn-secondary" onclick="disableParent()"
|
||||
th:if="${account.getRoles().contains('orga')}">
|
||||
<input type="radio" name="type" value="LECTURE"> Veranstaltung
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="input-group col-sm-8">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Gehört zu:</span>
|
||||
</div>
|
||||
<select class="custom-select" id="parentselect" name="parent">
|
||||
<option value="" selected>Keiner</option>
|
||||
<option th:each="lecture : ${lectures}" th:value="${lecture.getId()}"
|
||||
th:text="${lecture.getTitle()}"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Benutzerlimit-->
|
||||
<label for="userlimit">Teilnehmeranzahl:</label>
|
||||
<div class="btn-toolbar row" id="userlimit">
|
||||
<div class="btn-group btn-group-toggle col-sm-4" data-toggle="buttons">
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="limit" value="INFINITE" checked>
|
||||
Unbegrenzt
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="limit" value="LOCKED"> Begrenzt
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="input-group col-sm-8">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Limit:</span>
|
||||
</div>
|
||||
<input type="number" class="form-control" th:name="userlimit" value="1"
|
||||
min="1" max="100000" required>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text text-monospace">Teilnehmer</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-text" th:if="${account.getRoles().contains('orga')}">
|
||||
<!--CSV-->
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">CSV:</span>
|
||||
</div>
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" id="file" th:name="file">
|
||||
<label class="custom-file-label" for="file">Datei auswählen</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Submit-->
|
||||
<button class="btn btn-primary btn-block" type="submit">Gruppe Erstellen</button>
|
||||
|
||||
<!--<div class="custom-control custom-checkbox" id="privateCheckbox">
|
||||
<!–DUMMY–>
|
||||
<input type="hidden" id="visibilityDummy" name="visibility" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="visibility" onchange="$('#visibilityDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="visibility">Privat</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-checkbox" id="lectureCheckbox">
|
||||
<!–DUMMY–>
|
||||
<input type="hidden" id="lectureDummy" name="lecture" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="lecture" onchange="$('#lectureDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="lecture">Veranstaltung</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group mt-3" id="lectureParent">
|
||||
<label for="parent">Veranstaltungszugehörigkeit</label>
|
||||
<select class="form-control" id="parent" th:name="parent">
|
||||
<option value="" selected>--Keine--</option>
|
||||
<option th:each="lecture : ${lectures}" name="parent" th:value="${lecture.getId()}" th:text="${lecture.getTitle()}"></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-checkbox">
|
||||
<!–DUMMY–>
|
||||
<input type="hidden" id="maxInfiniteUsersDummy" name="maxInfiniteUsers" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="maxInfiniteUsers"
|
||||
onchange="$('#maxInfiniteUsersDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="maxInfiniteUsers">Anzahl
|
||||
unbegrenzt</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group mt-3" id="userMaximum">
|
||||
<label for="userMax">Teilnehmeranzahl</label>
|
||||
<input class="form-control" id="userMax" th:name="userMaximum" type="number" min="1" max="100000" value="1">
|
||||
</div>-->
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Add the following code if you want the name of the file appear on select
|
||||
$(".custom-file-input").on("change", function () {
|
||||
const fileName = $(this).val().split("\\").pop();
|
||||
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
|
||||
});
|
||||
|
||||
function disableParent() {
|
||||
$('#parentselect').prop('disabled', true);
|
||||
}
|
||||
|
||||
function enableParent() {
|
||||
$('#parentselect').prop('disabled', false);
|
||||
}
|
||||
</script>
|
||||
|
||||
</main>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,183 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de" xmlns:th="http://www.thymeleaf.org" th:replace="~{mopslayout :: html(
|
||||
name='Gruppenbildung',
|
||||
title='Neue Gruppe',
|
||||
headcontent=~{fragments/general :: headcontent},
|
||||
navigation=~{fragments/general :: nav(current='create')},
|
||||
bodycontent=~{:: bodycontent})}">
|
||||
|
||||
<body>
|
||||
|
||||
<main th:fragment="bodycontent">
|
||||
<div class="container-fluid">
|
||||
|
||||
<h1 class="def-cursor">Neue Gruppe</h1>
|
||||
|
||||
<div class="content p-2 mt-3">
|
||||
<form enctype="multipart/form-data" method="post" th:action="@{/gruppen2/create/orga}">
|
||||
|
||||
<!--Gruppentitel-->
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Gruppentitel:</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" th:name="title" required>
|
||||
</div>
|
||||
|
||||
<!--Gruppenbeschreibung-->
|
||||
<div class="input-group mb-5">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Beschreibung:</span>
|
||||
</div>
|
||||
<textarea class="form-control" th:name="description" required></textarea>
|
||||
</div>
|
||||
|
||||
<!--TODO: Enter AsciiDoc Description-->
|
||||
|
||||
<!--Gruppentyp-->
|
||||
<label for="grouptype">Gruppentyp:</label>
|
||||
<div class="btn-toolbar row mb-3" id="grouptype">
|
||||
<div class="btn-group btn-group-toggle col-sm-4" data-toggle="buttons">
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="type" id="type_private" checked> Privat
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="type" id="type_public"> Öffentlich
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="type" id="type_lecture"> Veranstaltung
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="input-group col-sm-8">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Gehört zu:</span>
|
||||
</div>
|
||||
<select class="custom-select" id="parent" name="parent">
|
||||
<option value="" selected>Keiner</option>
|
||||
<option th:each="lecture : ${lectures}" th:value="${lecture.getId()}"
|
||||
name="parent" th:text="${lecture.getTitle()}"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Benutzerlimit-->
|
||||
<label for="userlimit">Teilnehmeranzahl:</label>
|
||||
<div class="btn-toolbar row mb-5" id="userlimit">
|
||||
<div class="btn-group btn-group-toggle col-sm-4" data-toggle="buttons">
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="limit" id="limit_no" checked> Unbegrenzt
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="limit" id="limit_yes"> Begrenzt
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="input-group col-sm-8">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">Limit:</span>
|
||||
</div>
|
||||
<input type="number" class="form-control" th:name="userlimit" value="1"
|
||||
min="1" max="100000" required>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text text-monospace">Teilnehmer</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--CSV-->
|
||||
<div class="input-group mb-5">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text text-monospace">CSV:</span>
|
||||
</div>
|
||||
<div class="custom-file">
|
||||
<input class="custom-file-input" id="file" th:name="file" type="file">
|
||||
<label class="custom-file-label" for="file">Choose file</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Submit-->
|
||||
<div class="form-group">
|
||||
<button class="btn btn-primary btn-block" type="submit">Erstellen</button>
|
||||
</div>
|
||||
|
||||
<!--<div class="custom-control custom-checkbox" id="privateCheckbox">
|
||||
<!–DUMMY–>
|
||||
<input type="hidden" id="visibilityDummy" name="visibility" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="visibility" onchange="$('#visibilityDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="visibility">Privat</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-checkbox" id="lectureCheckbox">
|
||||
<!–DUMMY–>
|
||||
<input type="hidden" id="lectureDummy" name="lecture" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="lecture" onchange="$('#lectureDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="lecture">Veranstaltung</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group mt-3" id="lectureParent">
|
||||
<label for="parent">Veranstaltungszugehörigkeit</label>
|
||||
<select class="form-control" id="parent" th:name="parent">
|
||||
<option value="" selected>--Keine--</option>
|
||||
<option th:each="lecture : ${lectures}" name="parent" th:value="${lecture.getId()}" th:text="${lecture.getTitle()}"></option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-checkbox">
|
||||
<!–DUMMY–>
|
||||
<input type="hidden" id="maxInfiniteUsersDummy" name="maxInfiniteUsers" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="maxInfiniteUsers"
|
||||
onchange="$('#maxInfiniteUsersDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="maxInfiniteUsers">Anzahl
|
||||
unbegrenzt</label>
|
||||
</div>
|
||||
|
||||
<div class="form-group mt-3" id="userMaximum">
|
||||
<label for="userMax">Teilnehmeranzahl</label>
|
||||
<input class="form-control" id="userMax" th:name="userMaximum" type="number" min="1" max="100000" value="1">
|
||||
</div>-->
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Add the following code if you want the name of the file appear on select
|
||||
$(".custom-file-input").on("change", function () {
|
||||
const fileName = $(this).val().split("\\").pop();
|
||||
$(this).siblings(".custom-file-label").addClass("selected").html(fileName);
|
||||
});
|
||||
|
||||
// Collapse lectureParent if lecture
|
||||
$(document).ready(function () {
|
||||
$('#lecture').change(function () {
|
||||
$('#parent').prop('disable', function (i, v) { return !v; });
|
||||
});
|
||||
});
|
||||
|
||||
// Collapse provateCheckbox if lecture
|
||||
$(document).ready(function () {
|
||||
$('#lecture').change(function () {
|
||||
$('#visibility').prop('disabled', function (i, v) { return !v; });
|
||||
});
|
||||
});
|
||||
|
||||
// Collapse lectureCheckbox if private
|
||||
$(document).ready(function () {
|
||||
$('#visibility').change(function () {
|
||||
$('#lecture').prop('disabled', function (i, v) { return !v; });
|
||||
});
|
||||
});
|
||||
|
||||
// Collapse userMaximum if infinite
|
||||
$(document).ready(function () {
|
||||
$('#maxInfiniteUsers').change(function () {
|
||||
$('#userMax').prop('readonly', function (i, v) { return !v; });
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</main>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,95 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org"
|
||||
th:replace="~{mopslayout :: html(name='Gruppenbildung', headcontent=~{:: headcontent}, navigation=~{:: navigation}, bodycontent=~{:: bodycontent})}"
|
||||
xmlns="http://www.w3.org/1999/html">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Gruppenerstellung</title>
|
||||
<th:block th:fragment="headcontent">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
||||
rel="stylesheet">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
|
||||
</th:block>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navigation navigation-secondary" is="mops-navigation" th:fragment="navigation">
|
||||
<ul>
|
||||
<li>
|
||||
<a th:href="@{/gruppen2}">Gruppen</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a th:href="@{/gruppen2/create}">Erstellen</a>
|
||||
</li>
|
||||
<li>
|
||||
<a th:href="@{/gruppen2/search}">Suche</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<main th:fragment="bodycontent">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<h1>Gruppenerstellung</h1>
|
||||
<form method="post" th:action="@{/gruppen2/create/student}">
|
||||
<div class="shadow-sm p-2"
|
||||
style=" border: 10px solid aliceblue; border-radius: 5px; background: aliceblue;">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="titel">Titel</label>
|
||||
<input class="form-control" id="titel" required th:name="title" type="text">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description">Beschreibung</label>
|
||||
<textarea class="form-control" id="description" required rows="3" th:name="description"></textarea>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<!--DUMMY-->
|
||||
<input type="hidden" id="maxInfiniteUsersDummy" name="maxInfiniteUsers" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="maxInfiniteUsers" onchange="$('#maxInfiniteUsersDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="maxInfiniteUsers">Anzahl
|
||||
unbegrenzt</label>
|
||||
</div>
|
||||
<div class="form-group mt-3" id="userMaximum">
|
||||
<label for="userMax">Teilnehmeranzahl</label>
|
||||
<input class="form-control" th:name="userMaximum"
|
||||
type="number" min="1" max="10000" id="userMax">
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<!--DUMMY-->
|
||||
<input type="hidden" id="visibilityDummy" name="visibility" value="0"/>
|
||||
<input class="custom-control-input" type="checkbox" id="visibility" onchange="$('#visibilityDummy').val(this.checked ? 1 : 0)"/>
|
||||
<label class="custom-control-label" for="visibility">Privat</label>
|
||||
</div>
|
||||
<div class="form-group" id="lectureParent">
|
||||
<label for="parent">Veranstaltungszugehörigkeit</label>
|
||||
<select class="form-control" id="parent" name="parent">
|
||||
<option value="" selected>--Keine--</option>
|
||||
<option th:each="lecture : ${lectures}" th:name="parent" th:value="${lecture.getId()}" th:text="${lecture.getTitle()}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group pt-4">
|
||||
<button class="btn btn-primary"
|
||||
style="background: #52a1eb; border-style: none;"
|
||||
type="submit">Erstellen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('#maxInfiniteUsers').change(function () {
|
||||
$('#userMaximum').fadeToggle();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
@ -3,11 +3,12 @@
|
||||
<html lang="de" xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<!--Stylesheets, Javascript etc.-->
|
||||
<th:block th:fragment="headcontent">
|
||||
<th:block th:fragment="headcontent(style)">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
|
||||
<link th:href="@{/style.css}" rel="stylesheet"/>
|
||||
<link th:unless="${style == 'none'}" th:href="@{${style}}" rel="stylesheet"/>
|
||||
</th:block>
|
||||
|
||||
<!--Left navigation bar-->
|
||||
|
@ -5,9 +5,9 @@
|
||||
<!--Grouptype Badges-->
|
||||
<th:block th:fragment="badges">
|
||||
<span class="badge badge-pill private float-right"
|
||||
th:if='${group.getVisibility() == private}'>Privat</span>
|
||||
<span class="badge badge-pill public float-right" th:if="${group.getVisibility() == public}"
|
||||
th:unless="${group.getType() == lecture}">Öffentlich</span>
|
||||
th:if='${group.getType() == private}'>Privat</span>
|
||||
<span class="badge badge-pill public float-right"
|
||||
th:if="${group.getType() == public}">Öffentlich</span>
|
||||
<span class="badge badge-pill lecture float-right"
|
||||
th:if='${group.getType() == lecture}'>Veranstaltung</span>
|
||||
|
||||
|
Reference in New Issue
Block a user