GUI improvements
This commit is contained in:
parent
8ea0def877
commit
25485b1fd4
28 changed files with 7160 additions and 6921 deletions
|
@ -1,136 +1,137 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl;
|
package ch.ethz.seb.sebserver.gbl;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.eclipse.swt.graphics.RGB;
|
import org.eclipse.swt.graphics.RGB;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
||||||
|
|
||||||
/** Global Constants used in SEB Server web-service as well as in web-gui component */
|
/** Global Constants used in SEB Server web-service as well as in web-gui component */
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
|
|
||||||
public static final String DEFAULT_LANG_CODE = "en";
|
public static final String DEFAULT_LANG_CODE = "en";
|
||||||
public static final String DEFAULT_TIME_ZONE_CODE = "UTC";
|
public static final String DEFAULT_TIME_ZONE_CODE = "UTC";
|
||||||
|
public static final String TOOLTIP_TEXT_KEY_SUFFIX = ".tooltip";
|
||||||
public static final int SEB_FILE_HEADER_SIZE = 4;
|
|
||||||
public static final int JN_CRYPTOR_ITERATIONS = 10000;
|
public static final int SEB_FILE_HEADER_SIZE = 4;
|
||||||
public static final int JN_CRYPTOR_VERSION_HEADER_SIZE = 1;
|
public static final int JN_CRYPTOR_ITERATIONS = 10000;
|
||||||
|
public static final int JN_CRYPTOR_VERSION_HEADER_SIZE = 1;
|
||||||
public static final String TRUE_STRING = Boolean.TRUE.toString();
|
|
||||||
public static final String FALSE_STRING = Boolean.FALSE.toString();
|
public static final String TRUE_STRING = Boolean.TRUE.toString();
|
||||||
|
public static final String FALSE_STRING = Boolean.FALSE.toString();
|
||||||
public static final long SECOND_IN_MILLIS = 1000;
|
|
||||||
public static final long MINUTE_IN_MILLIS = 60 * SECOND_IN_MILLIS;
|
public static final long SECOND_IN_MILLIS = 1000;
|
||||||
public static final long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS;
|
public static final long MINUTE_IN_MILLIS = 60 * SECOND_IN_MILLIS;
|
||||||
public static final long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS;
|
public static final long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS;
|
||||||
|
public static final long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS;
|
||||||
public static final Character CARRIAGE_RETURN = '\n';
|
|
||||||
public static final Character CURLY_BRACE_OPEN = '{';
|
public static final Character CARRIAGE_RETURN = '\n';
|
||||||
public static final Character CURLY_BRACE_CLOSE = '}';
|
public static final Character CURLY_BRACE_OPEN = '{';
|
||||||
public static final Character SQUARE_BRACE_OPEN = '[';
|
public static final Character CURLY_BRACE_CLOSE = '}';
|
||||||
public static final Character SQUARE_BRACE_CLOSE = ']';
|
public static final Character SQUARE_BRACE_OPEN = '[';
|
||||||
public static final Character COLON = ':';
|
public static final Character SQUARE_BRACE_CLOSE = ']';
|
||||||
public static final Character SEMICOLON = ';';
|
public static final Character COLON = ':';
|
||||||
public static final Character PERCENTAGE = '%';
|
public static final Character SEMICOLON = ';';
|
||||||
public static final Character SLASH = '/';
|
public static final Character PERCENTAGE = '%';
|
||||||
public static final Character BACKSLASH = '\\';
|
public static final Character SLASH = '/';
|
||||||
public static final Character QUOTE = '\'';
|
public static final Character BACKSLASH = '\\';
|
||||||
public static final Character DOUBLE_QUOTE = '"';
|
public static final Character QUOTE = '\'';
|
||||||
public static final Character COMMA = ',';
|
public static final Character DOUBLE_QUOTE = '"';
|
||||||
public static final Character PIPE = '|';
|
public static final Character COMMA = ',';
|
||||||
public static final Character AMPERSAND = '&';
|
public static final Character PIPE = '|';
|
||||||
public static final Character EQUALITY_SIGN = '=';
|
public static final Character AMPERSAND = '&';
|
||||||
public static final Character LIST_SEPARATOR_CHAR = COMMA;
|
public static final Character EQUALITY_SIGN = '=';
|
||||||
public static final Character COMPLEX_VALUE_SEPARATOR = COLON;
|
public static final Character LIST_SEPARATOR_CHAR = COMMA;
|
||||||
|
public static final Character COMPLEX_VALUE_SEPARATOR = COLON;
|
||||||
public static final String NULL = "null";
|
|
||||||
public static final String PERCENTAGE_STRING = Constants.PERCENTAGE.toString();
|
public static final String NULL = "null";
|
||||||
public static final String LIST_SEPARATOR = COMMA.toString();
|
public static final String PERCENTAGE_STRING = Constants.PERCENTAGE.toString();
|
||||||
public static final String EMBEDDED_LIST_SEPARATOR = PIPE.toString();
|
public static final String LIST_SEPARATOR = COMMA.toString();
|
||||||
public static final String NO_NAME = "NONE";
|
public static final String EMBEDDED_LIST_SEPARATOR = PIPE.toString();
|
||||||
public static final String EMPTY_NOTE = "--";
|
public static final String NO_NAME = "NONE";
|
||||||
public static final String FORM_URL_ENCODED_SEPARATOR = AMPERSAND.toString();
|
public static final String EMPTY_NOTE = "--";
|
||||||
public static final String FORM_URL_ENCODED_NAME_VALUE_SEPARATOR = EQUALITY_SIGN.toString();
|
public static final String FORM_URL_ENCODED_SEPARATOR = AMPERSAND.toString();
|
||||||
public static final String URL_PORT_SEPARATOR = COLON.toString();
|
public static final String FORM_URL_ENCODED_NAME_VALUE_SEPARATOR = EQUALITY_SIGN.toString();
|
||||||
public static final String URL_ADDRESS_SEPARATOR = COLON.toString() + SLASH.toString() + SLASH.toString();
|
public static final String URL_PORT_SEPARATOR = COLON.toString();
|
||||||
public static final String URL_PATH_SEPARATOR = SLASH.toString();
|
public static final String URL_ADDRESS_SEPARATOR = COLON.toString() + SLASH.toString() + SLASH.toString();
|
||||||
|
public static final String URL_PATH_SEPARATOR = SLASH.toString();
|
||||||
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
|
||||||
public static final String TIME_ZONE_OFFSET_TAIL_FORMAT = "|ZZ";
|
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||||
|
public static final String TIME_ZONE_OFFSET_TAIL_FORMAT = "|ZZ";
|
||||||
//public static final String DEFAULT_DIPLAY_DATE_TIME_FORMAT = "MM-dd-yyyy HH:mm:ss";
|
|
||||||
public static final String DEFAULT_DISPLAY_DATE_FORMAT = "MM-dd-yyyy";
|
//public static final String DEFAULT_DIPLAY_DATE_TIME_FORMAT = "MM-dd-yyyy HH:mm:ss";
|
||||||
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
|
public static final String DEFAULT_DISPLAY_DATE_FORMAT = "MM-dd-yyyy";
|
||||||
|
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
|
||||||
public static final DateTimeFormatter STANDARD_DATE_TIME_FORMATTER = DateTimeFormat
|
|
||||||
.forPattern(DEFAULT_DATE_TIME_FORMAT)
|
public static final DateTimeFormatter STANDARD_DATE_TIME_FORMATTER = DateTimeFormat
|
||||||
.withZoneUTC();
|
.forPattern(DEFAULT_DATE_TIME_FORMAT)
|
||||||
|
.withZoneUTC();
|
||||||
public static final String XML_VERSION_HEADER =
|
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>";
|
public static final String XML_VERSION_HEADER =
|
||||||
public static final String XML_DOCTYPE_HEADER =
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?>";
|
||||||
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
|
public static final String XML_DOCTYPE_HEADER =
|
||||||
public static final String XML_PLIST_START_V1 =
|
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
|
||||||
"<plist version=\"1.0\">";
|
public static final String XML_PLIST_START_V1 =
|
||||||
public static final String XML_PLIST_END =
|
"<plist version=\"1.0\">";
|
||||||
"</plist>";
|
public static final String XML_PLIST_END =
|
||||||
public static final String XML_DICT_START =
|
"</plist>";
|
||||||
"<dict>";
|
public static final String XML_DICT_START =
|
||||||
public static final String XML_DICT_END =
|
"<dict>";
|
||||||
"</dict>";
|
public static final String XML_DICT_END =
|
||||||
|
"</dict>";
|
||||||
public static final String XML_PLIST_NAME = "plist";
|
|
||||||
public static final String XML_PLIST_DICT_NAME = "dict";
|
public static final String XML_PLIST_NAME = "plist";
|
||||||
public static final String XML_PLIST_ARRAY_NAME = "array";
|
public static final String XML_PLIST_DICT_NAME = "dict";
|
||||||
public static final String XML_PLIST_KEY_NAME = "key";
|
public static final String XML_PLIST_ARRAY_NAME = "array";
|
||||||
public static final String XML_PLIST_BOOLEAN_TRUE = "true";
|
public static final String XML_PLIST_KEY_NAME = "key";
|
||||||
public static final String XML_PLIST_BOOLEAN_FALSE = "false";
|
public static final String XML_PLIST_BOOLEAN_TRUE = "true";
|
||||||
public static final String XML_PLIST_STRING = "string";
|
public static final String XML_PLIST_BOOLEAN_FALSE = "false";
|
||||||
public static final String XML_PLIST_DATA = "data";
|
public static final String XML_PLIST_STRING = "string";
|
||||||
public static final String XML_PLIST_INTEGER = "integer";
|
public static final String XML_PLIST_DATA = "data";
|
||||||
|
public static final String XML_PLIST_INTEGER = "integer";
|
||||||
public static final String OAUTH2_GRANT_TYPE_PASSWORD = "password";
|
|
||||||
public static final String OAUTH2_CLIENT_SECRET = "client_secret";
|
public static final String OAUTH2_GRANT_TYPE_PASSWORD = "password";
|
||||||
public static final String OAUTH2_GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
|
public static final String OAUTH2_CLIENT_SECRET = "client_secret";
|
||||||
public static final String OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials";
|
public static final String OAUTH2_GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
|
||||||
public static final String OAUTH2_SCOPE_READ = "read";
|
public static final String OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials";
|
||||||
public static final String OAUTH2_SCOPE_WRITE = "write";
|
public static final String OAUTH2_SCOPE_READ = "read";
|
||||||
|
public static final String OAUTH2_SCOPE_WRITE = "write";
|
||||||
public static final int RWT_MOUSE_BUTTON_1 = 1;
|
|
||||||
public static final int RWT_MOUSE_BUTTON_2 = 2;
|
public static final int RWT_MOUSE_BUTTON_1 = 1;
|
||||||
public static final int RWT_MOUSE_BUTTON_3 = 3;
|
public static final int RWT_MOUSE_BUTTON_2 = 2;
|
||||||
|
public static final int RWT_MOUSE_BUTTON_3 = 3;
|
||||||
public static final int GZIP_HEADER_LENGTH = 4;
|
|
||||||
public static final int GZIP_ID1 = 0x1F;
|
public static final int GZIP_HEADER_LENGTH = 4;
|
||||||
public static final int GZIP_ID2 = 0x8B;
|
public static final int GZIP_ID1 = 0x1F;
|
||||||
public static final int GZIP_CM = 8;
|
public static final int GZIP_ID2 = 0x8B;
|
||||||
|
public static final int GZIP_CM = 8;
|
||||||
public static final RGB WHITE_RGB = new RGB(255, 255, 255);
|
|
||||||
public static final RGB BLACK_RGB = new RGB(0, 0, 0);
|
public static final RGB WHITE_RGB = new RGB(255, 255, 255);
|
||||||
|
public static final RGB BLACK_RGB = new RGB(0, 0, 0);
|
||||||
public static final TypeReference<Collection<APIMessage>> TYPE_REFERENCE_API_MESSAGE =
|
|
||||||
new TypeReferenceAPIMessage();
|
public static final TypeReference<Collection<APIMessage>> TYPE_REFERENCE_API_MESSAGE =
|
||||||
public static final ParameterizedTypeReference<Collection<Privilege>> TYPE_REFERENCE_PRIVILEGES =
|
new TypeReferenceAPIMessage();
|
||||||
new TypeReferencePrivileges();
|
public static final ParameterizedTypeReference<Collection<Privilege>> TYPE_REFERENCE_PRIVILEGES =
|
||||||
|
new TypeReferencePrivileges();
|
||||||
public static final class TypeReferenceAPIMessage extends TypeReference<Collection<APIMessage>> {
|
|
||||||
}
|
public static final class TypeReferenceAPIMessage extends TypeReference<Collection<APIMessage>> {
|
||||||
|
}
|
||||||
public static final class TypeReferencePrivileges extends ParameterizedTypeReference<Collection<Privilege>> {
|
|
||||||
}
|
public static final class TypeReferencePrivileges extends ParameterizedTypeReference<Collection<Privilege>> {
|
||||||
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,360 +1,361 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.model.user;
|
package ch.ethz.seb.sebserver.gbl.model.user;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.constraints.Email;
|
import javax.validation.constraints.Email;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER;
|
import ch.ethz.seb.sebserver.gbl.model.Domain.USER;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
|
||||||
/** The user info domain model contains primary user information
|
/** The user info domain model contains primary user information
|
||||||
*
|
*
|
||||||
* This domain model is annotated and fully serializable and deserializable
|
* This domain model is annotated and fully serializable and deserializable
|
||||||
* to and from JSON within the Jackson library.
|
* to and from JSON within the Jackson library.
|
||||||
*
|
*
|
||||||
* This domain model is immutable and thread-save */
|
* This domain model is immutable and thread-save */
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public final class UserInfo implements UserAccount, Serializable {
|
public final class UserInfo implements UserAccount, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 2526446136264377808L;
|
private static final long serialVersionUID = 2526446136264377808L;
|
||||||
|
|
||||||
public static final String FILTER_ATTR_USER_NAME = "username";
|
public static final String FILTER_ATTR_USER_NAME = "username";
|
||||||
public static final String FILTER_ATTR_EMAIL = "email";
|
public static final String FILTER_ATTR_EMAIL = "email";
|
||||||
public static final String FILTER_ATTR_LANGUAGE = "language";
|
public static final String FILTER_ATTR_LANGUAGE = "language";
|
||||||
public static final String FILTER_ATTR_ROLE = "role";
|
public static final String FILTER_ATTR_ROLE = "role";
|
||||||
|
|
||||||
/** The user's UUID */
|
/** The user's UUID */
|
||||||
@JsonProperty(USER.ATTR_UUID)
|
@JsonProperty(USER.ATTR_UUID)
|
||||||
public final String uuid;
|
public final String uuid;
|
||||||
|
|
||||||
/** The foreign key identifier to the institution where the User belongs to */
|
/** The foreign key identifier to the institution where the User belongs to */
|
||||||
@NotNull
|
@NotNull(message = "user:institutionId:notNull")
|
||||||
@JsonProperty(USER.ATTR_INSTITUTION_ID)
|
@JsonProperty(USER.ATTR_INSTITUTION_ID)
|
||||||
public final Long institutionId;
|
public final Long institutionId;
|
||||||
|
|
||||||
@JsonProperty(USER.ATTR_CREATION_DATE)
|
@JsonProperty(USER.ATTR_CREATION_DATE)
|
||||||
public final DateTime creationDate;
|
public final DateTime creationDate;
|
||||||
|
|
||||||
/** First name of the user */
|
/** First name of the user */
|
||||||
@NotNull(message = "user:name:notNull")
|
@NotNull(message = "user:name:notNull")
|
||||||
@Size(min = 3, max = 255, message = "user:name:size:{min}:{max}:${validatedValue}")
|
@Size(max = 255, message = "user:name:size:{min}:{max}:${validatedValue}")
|
||||||
@JsonProperty(USER.ATTR_NAME)
|
@JsonProperty(USER.ATTR_NAME)
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
/** Surname of the user */
|
/** Surname of the user */
|
||||||
@Size(max = 255, message = "user:surname:size:{min}:{max}:${validatedValue}")
|
@NotNull(message = "user:surname:notNull")
|
||||||
@JsonProperty(USER.ATTR_SURNAME)
|
@Size(max = 255, message = "user:surname:size:{min}:{max}:${validatedValue}")
|
||||||
public final String surname;
|
@JsonProperty(USER.ATTR_SURNAME)
|
||||||
|
public final String surname;
|
||||||
/** The internal user name */
|
|
||||||
@NotNull(message = "user:username:notNull")
|
/** The internal user name */
|
||||||
@Size(min = 3, max = 255, message = "user:username:size:{min}:{max}:${validatedValue}")
|
@NotNull(message = "user:username:notNull")
|
||||||
@JsonProperty(USER.ATTR_USERNAME)
|
@Size(min = 3, max = 255, message = "user:username:size:{min}:{max}:${validatedValue}")
|
||||||
public final String username;
|
@JsonProperty(USER.ATTR_USERNAME)
|
||||||
|
public final String username;
|
||||||
/** E-mail address of the user */
|
|
||||||
@Email(message = "user:email:email:_:_:${validatedValue}")
|
/** E-mail address of the user */
|
||||||
@JsonProperty(USER.ATTR_EMAIL)
|
@Email(message = "user:email:email:_:_:${validatedValue}")
|
||||||
public final String email;
|
@JsonProperty(USER.ATTR_EMAIL)
|
||||||
|
public final String email;
|
||||||
/** Indicates whether this user is still active or not */
|
|
||||||
@NotNull
|
/** Indicates whether this user is still active or not */
|
||||||
@JsonProperty(USER.ATTR_ACTIVE)
|
@NotNull
|
||||||
public final Boolean active;
|
@JsonProperty(USER.ATTR_ACTIVE)
|
||||||
|
public final Boolean active;
|
||||||
/** The users locale */
|
|
||||||
@NotNull(message = "user:language:notNull")
|
/** The users locale */
|
||||||
@JsonProperty(USER.ATTR_LANGUAGE)
|
@NotNull(message = "user:language:notNull")
|
||||||
public final Locale language;
|
@JsonProperty(USER.ATTR_LANGUAGE)
|
||||||
|
public final Locale language;
|
||||||
/** The users time zone */
|
|
||||||
@NotNull(message = "user:timeZone:notNull")
|
/** The users time zone */
|
||||||
@JsonProperty(USER.ATTR_TIMEZONE)
|
@NotNull(message = "user:timeZone:notNull")
|
||||||
public final DateTimeZone timeZone;
|
@JsonProperty(USER.ATTR_TIMEZONE)
|
||||||
|
public final DateTimeZone timeZone;
|
||||||
/** The users roles in a unmodifiable set. Is never null */
|
|
||||||
@NotNull(message = "user:userRoles:notNull")
|
/** The users roles in a unmodifiable set. Is never null */
|
||||||
@NotEmpty(message = "user:userRoles:notNull")
|
@NotNull(message = "user:userRoles:notNull")
|
||||||
@JsonProperty(USER_ROLE.REFERENCE_NAME)
|
@NotEmpty(message = "user:userRoles:notNull")
|
||||||
public final Set<String> roles;
|
@JsonProperty(USER_ROLE.REFERENCE_NAME)
|
||||||
|
public final Set<String> roles;
|
||||||
@JsonCreator
|
|
||||||
public UserInfo(
|
@JsonCreator
|
||||||
@JsonProperty(USER.ATTR_UUID) final String uuid,
|
public UserInfo(
|
||||||
@JsonProperty(USER.ATTR_INSTITUTION_ID) final Long institutionId,
|
@JsonProperty(USER.ATTR_UUID) final String uuid,
|
||||||
@JsonProperty(USER.ATTR_CREATION_DATE) final DateTime creationDate,
|
@JsonProperty(USER.ATTR_INSTITUTION_ID) final Long institutionId,
|
||||||
@JsonProperty(USER.ATTR_NAME) final String name,
|
@JsonProperty(USER.ATTR_CREATION_DATE) final DateTime creationDate,
|
||||||
@JsonProperty(USER.ATTR_SURNAME) final String surname,
|
@JsonProperty(USER.ATTR_NAME) final String name,
|
||||||
@JsonProperty(USER.ATTR_USERNAME) final String username,
|
@JsonProperty(USER.ATTR_SURNAME) final String surname,
|
||||||
@JsonProperty(USER.ATTR_EMAIL) final String email,
|
@JsonProperty(USER.ATTR_USERNAME) final String username,
|
||||||
@JsonProperty(USER.ATTR_ACTIVE) final Boolean active,
|
@JsonProperty(USER.ATTR_EMAIL) final String email,
|
||||||
@JsonProperty(USER.ATTR_LANGUAGE) final Locale language,
|
@JsonProperty(USER.ATTR_ACTIVE) final Boolean active,
|
||||||
@JsonProperty(USER.ATTR_TIMEZONE) final DateTimeZone timeZone,
|
@JsonProperty(USER.ATTR_LANGUAGE) final Locale language,
|
||||||
@JsonProperty(USER_ROLE.REFERENCE_NAME) final Set<String> roles) {
|
@JsonProperty(USER.ATTR_TIMEZONE) final DateTimeZone timeZone,
|
||||||
|
@JsonProperty(USER_ROLE.REFERENCE_NAME) final Set<String> roles) {
|
||||||
this.uuid = uuid;
|
|
||||||
this.institutionId = institutionId;
|
this.uuid = uuid;
|
||||||
this.creationDate = creationDate;
|
this.institutionId = institutionId;
|
||||||
this.name = name;
|
this.creationDate = creationDate;
|
||||||
this.surname = surname;
|
this.name = name;
|
||||||
this.username = username;
|
this.surname = surname;
|
||||||
this.email = email;
|
this.username = username;
|
||||||
this.active = BooleanUtils.isTrue(active);
|
this.email = email;
|
||||||
this.language = language;
|
this.active = BooleanUtils.isTrue(active);
|
||||||
this.timeZone = timeZone;
|
this.language = language;
|
||||||
this.roles = Utils.immutableSetOf(roles);
|
this.timeZone = timeZone;
|
||||||
}
|
this.roles = Utils.immutableSetOf(roles);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public EntityType entityType() {
|
@Override
|
||||||
return EntityType.USER;
|
public EntityType entityType() {
|
||||||
}
|
return EntityType.USER;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getModelId() {
|
@Override
|
||||||
return this.uuid;
|
public String getModelId() {
|
||||||
}
|
return this.uuid;
|
||||||
|
}
|
||||||
public String getUuid() {
|
|
||||||
return this.uuid;
|
public String getUuid() {
|
||||||
}
|
return this.uuid;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public DateTime getCreationDate() {
|
@Override
|
||||||
return this.creationDate;
|
public DateTime getCreationDate() {
|
||||||
}
|
return this.creationDate;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Long getInstitutionId() {
|
@Override
|
||||||
return this.institutionId;
|
public Long getInstitutionId() {
|
||||||
}
|
return this.institutionId;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getOwnerId() {
|
@Override
|
||||||
return this.uuid;
|
public String getOwnerId() {
|
||||||
}
|
return this.uuid;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getName() {
|
@Override
|
||||||
return this.name;
|
public String getName() {
|
||||||
}
|
return this.name;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getSurname() {
|
@Override
|
||||||
return this.surname;
|
public String getSurname() {
|
||||||
}
|
return this.surname;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getUsername() {
|
@Override
|
||||||
return this.username;
|
public String getUsername() {
|
||||||
}
|
return this.username;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getEmail() {
|
@Override
|
||||||
return this.email;
|
public String getEmail() {
|
||||||
}
|
return this.email;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Boolean getActive() {
|
@Override
|
||||||
return this.active;
|
public Boolean getActive() {
|
||||||
}
|
return this.active;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public boolean isActive() {
|
@Override
|
||||||
return this.active;
|
public boolean isActive() {
|
||||||
}
|
return this.active;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Locale getLanguage() {
|
@Override
|
||||||
return this.language;
|
public Locale getLanguage() {
|
||||||
}
|
return this.language;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public DateTimeZone getTimeZone() {
|
@Override
|
||||||
return this.timeZone;
|
public DateTimeZone getTimeZone() {
|
||||||
}
|
return this.timeZone;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Set<String> getRoles() {
|
@Override
|
||||||
return this.roles;
|
public Set<String> getRoles() {
|
||||||
}
|
return this.roles;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
@JsonIgnore
|
@Override
|
||||||
public EnumSet<UserRole> getUserRoles() {
|
@JsonIgnore
|
||||||
return EnumSet.copyOf(
|
public EnumSet<UserRole> getUserRoles() {
|
||||||
getRoles().stream()
|
return EnumSet.copyOf(
|
||||||
.map(r -> UserRole.valueOf(r))
|
getRoles().stream()
|
||||||
.collect(Collectors.toList()));
|
.map(UserRole::valueOf)
|
||||||
}
|
.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
public boolean hasRole(final UserRole userRole) {
|
|
||||||
if (userRole == null) {
|
public boolean hasRole(final UserRole userRole) {
|
||||||
return false;
|
if (userRole == null) {
|
||||||
}
|
return false;
|
||||||
return this.roles.contains(userRole.name());
|
}
|
||||||
}
|
return this.roles.contains(userRole.name());
|
||||||
|
}
|
||||||
public boolean hasAnyRole(final UserRole... userRole) {
|
|
||||||
if (userRole == null) {
|
public boolean hasAnyRole(final UserRole... userRole) {
|
||||||
return false;
|
if (userRole == null) {
|
||||||
}
|
return false;
|
||||||
return CollectionUtils.containsAny(getUserRoles(), Arrays.asList(userRole));
|
}
|
||||||
}
|
return CollectionUtils.containsAny(getUserRoles(), Arrays.asList(userRole));
|
||||||
|
}
|
||||||
@JsonIgnore
|
|
||||||
@Override
|
@JsonIgnore
|
||||||
public EntityKey getEntityKey() {
|
@Override
|
||||||
if (StringUtils.isBlank(this.uuid)) {
|
public EntityKey getEntityKey() {
|
||||||
return null;
|
if (StringUtils.isBlank(this.uuid)) {
|
||||||
}
|
return null;
|
||||||
return new EntityKey(this.uuid, entityType());
|
}
|
||||||
}
|
return new EntityKey(this.uuid, entityType());
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
@Override
|
||||||
final int prime = 31;
|
public int hashCode() {
|
||||||
int result = 1;
|
final int prime = 31;
|
||||||
result = prime * result + ((this.uuid == null) ? 0 : this.uuid.hashCode());
|
int result = 1;
|
||||||
return result;
|
result = prime * result + ((this.uuid == null) ? 0 : this.uuid.hashCode());
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public boolean equals(final Object obj) {
|
@Override
|
||||||
if (this == obj)
|
public boolean equals(final Object obj) {
|
||||||
return true;
|
if (this == obj)
|
||||||
if (obj == null)
|
return true;
|
||||||
return false;
|
if (obj == null)
|
||||||
if (getClass() != obj.getClass())
|
return false;
|
||||||
return false;
|
if (getClass() != obj.getClass())
|
||||||
final UserInfo other = (UserInfo) obj;
|
return false;
|
||||||
if (this.uuid == null) {
|
final UserInfo other = (UserInfo) obj;
|
||||||
if (other.uuid != null)
|
if (this.uuid == null) {
|
||||||
return false;
|
if (other.uuid != null)
|
||||||
} else if (!this.uuid.equals(other.uuid))
|
return false;
|
||||||
return false;
|
} else if (!this.uuid.equals(other.uuid))
|
||||||
return true;
|
return false;
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String toString() {
|
@Override
|
||||||
final StringBuilder builder = new StringBuilder();
|
public String toString() {
|
||||||
builder.append("UserInfo [uuid=");
|
final StringBuilder builder = new StringBuilder();
|
||||||
builder.append(this.uuid);
|
builder.append("UserInfo [uuid=");
|
||||||
builder.append(", institutionId=");
|
builder.append(this.uuid);
|
||||||
builder.append(this.institutionId);
|
builder.append(", institutionId=");
|
||||||
builder.append(", creationDate=");
|
builder.append(this.institutionId);
|
||||||
builder.append(this.creationDate);
|
builder.append(", creationDate=");
|
||||||
builder.append(", name=");
|
builder.append(this.creationDate);
|
||||||
builder.append(this.name);
|
builder.append(", name=");
|
||||||
builder.append(", surname=");
|
builder.append(this.name);
|
||||||
builder.append(this.surname);
|
builder.append(", surname=");
|
||||||
builder.append(", username=");
|
builder.append(this.surname);
|
||||||
builder.append(this.username);
|
builder.append(", username=");
|
||||||
builder.append(", email=");
|
builder.append(this.username);
|
||||||
builder.append(this.email);
|
builder.append(", email=");
|
||||||
builder.append(", active=");
|
builder.append(this.email);
|
||||||
builder.append(this.active);
|
builder.append(", active=");
|
||||||
builder.append(", language=");
|
builder.append(this.active);
|
||||||
builder.append(this.language);
|
builder.append(", language=");
|
||||||
builder.append(", timeZone=");
|
builder.append(this.language);
|
||||||
builder.append(this.timeZone);
|
builder.append(", timeZone=");
|
||||||
builder.append(", roles=");
|
builder.append(this.timeZone);
|
||||||
builder.append(this.roles);
|
builder.append(", roles=");
|
||||||
builder.append("]");
|
builder.append(this.roles);
|
||||||
return builder.toString();
|
builder.append("]");
|
||||||
}
|
return builder.toString();
|
||||||
|
}
|
||||||
/** Use this to create a copy of a given UserInfo instance.
|
|
||||||
*
|
/** Use this to create a copy of a given UserInfo instance.
|
||||||
* @param userInfo UserInfo instance to copy
|
*
|
||||||
* @return copied UserInfo instance */
|
* @param userInfo UserInfo instance to copy
|
||||||
public static final UserInfo of(final UserInfo userInfo) {
|
* @return copied UserInfo instance */
|
||||||
return new UserInfo(
|
public static UserInfo of(final UserInfo userInfo) {
|
||||||
userInfo.getUuid(),
|
return new UserInfo(
|
||||||
userInfo.getInstitutionId(),
|
userInfo.getUuid(),
|
||||||
userInfo.creationDate,
|
userInfo.getInstitutionId(),
|
||||||
userInfo.getName(),
|
userInfo.creationDate,
|
||||||
userInfo.getUsername(),
|
userInfo.getName(),
|
||||||
userInfo.getSurname(),
|
userInfo.getUsername(),
|
||||||
userInfo.getEmail(),
|
userInfo.getSurname(),
|
||||||
userInfo.getActive(),
|
userInfo.getEmail(),
|
||||||
userInfo.getLanguage(),
|
userInfo.getActive(),
|
||||||
userInfo.getTimeZone(),
|
userInfo.getLanguage(),
|
||||||
userInfo.roles);
|
userInfo.getTimeZone(),
|
||||||
}
|
userInfo.roles);
|
||||||
|
}
|
||||||
/** Use this to create a copy of a given UserInfo by overriding available arguments.
|
|
||||||
*
|
/** Use this to create a copy of a given UserInfo by overriding available arguments.
|
||||||
* @param userInfo UserInfo instance to copy
|
*
|
||||||
* @param name new name or null if the name of given userInfo should be taken
|
* @param userInfo UserInfo instance to copy
|
||||||
* @param surname new surname or null if the name of given userInfo should be taken
|
* @param name new name or null if the name of given userInfo should be taken
|
||||||
* @param username new username or null if the username of given userInfo should be taken
|
* @param surname new surname or null if the name of given userInfo should be taken
|
||||||
* @param email new email or null if the email of given userInfo should be taken
|
* @param username new username or null if the username of given userInfo should be taken
|
||||||
* @param language new language or null if the language of given userInfo should be taken
|
* @param email new email or null if the email of given userInfo should be taken
|
||||||
* @param timeZone new timeZone or null if the timeZone of given userInfo should be taken
|
* @param language new language or null if the language of given userInfo should be taken
|
||||||
* @param roles new timeZone or null if the roles of given userInfo should be taken
|
* @param timeZone new timeZone or null if the timeZone of given userInfo should be taken
|
||||||
* @return copied UserInfo instance with the given attributes */
|
* @param roles new timeZone or null if the roles of given userInfo should be taken
|
||||||
public static final UserInfo of(
|
* @return copied UserInfo instance with the given attributes */
|
||||||
final UserInfo userInfo,
|
public static UserInfo of(
|
||||||
final String name,
|
final UserInfo userInfo,
|
||||||
final String username,
|
final String name,
|
||||||
final String surname,
|
final String username,
|
||||||
final String email,
|
final String surname,
|
||||||
final Locale language,
|
final String email,
|
||||||
final DateTimeZone timeZone,
|
final Locale language,
|
||||||
final String... roles) {
|
final DateTimeZone timeZone,
|
||||||
|
final String... roles) {
|
||||||
return new UserInfo(
|
|
||||||
userInfo.getUuid(),
|
return new UserInfo(
|
||||||
userInfo.getInstitutionId(),
|
userInfo.getUuid(),
|
||||||
userInfo.creationDate,
|
userInfo.getInstitutionId(),
|
||||||
(name != null) ? name : userInfo.getName(),
|
userInfo.creationDate,
|
||||||
(surname != null) ? surname : userInfo.getSurname(),
|
(name != null) ? name : userInfo.getName(),
|
||||||
(username != null) ? username : userInfo.getUsername(),
|
(surname != null) ? surname : userInfo.getSurname(),
|
||||||
(email != null) ? email : userInfo.getEmail(),
|
(username != null) ? username : userInfo.getUsername(),
|
||||||
userInfo.getActive(),
|
(email != null) ? email : userInfo.getEmail(),
|
||||||
(language != null) ? language : userInfo.getLanguage(),
|
userInfo.getActive(),
|
||||||
(timeZone != null) ? timeZone : userInfo.getTimeZone(),
|
(language != null) ? language : userInfo.getLanguage(),
|
||||||
(roles != null) ? new HashSet<>(Arrays.asList(roles)) : userInfo.roles);
|
(timeZone != null) ? timeZone : userInfo.getTimeZone(),
|
||||||
}
|
(roles != null) ? new HashSet<>(Arrays.asList(roles)) : userInfo.roles);
|
||||||
|
}
|
||||||
public static final UserInfo withEMail(final UserInfo userInfo, final String email) {
|
|
||||||
return of(userInfo, null, null, null, email, null, null, (String[]) null);
|
public static UserInfo withEMail(final UserInfo userInfo, final String email) {
|
||||||
}
|
return of(userInfo, null, null, null, email, null, null, (String[]) null);
|
||||||
|
}
|
||||||
public static final UserInfo withRoles(final UserInfo userInfo, final String... roles) {
|
|
||||||
return of(userInfo, null, null, null, null, null, null, roles);
|
public static UserInfo withRoles(final UserInfo userInfo, final String... roles) {
|
||||||
}
|
return of(userInfo, null, null, null, null, null, null, roles);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,284 +1,285 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.model.user;
|
package ch.ethz.seb.sebserver.gbl.model.user;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.constraints.Email;
|
import javax.validation.constraints.Email;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER;
|
import ch.ethz.seb.sebserver.gbl.model.Domain.USER;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public final class UserMod implements UserAccount {
|
public final class UserMod implements UserAccount {
|
||||||
|
|
||||||
@JsonProperty(USER.ATTR_UUID)
|
@JsonProperty(USER.ATTR_UUID)
|
||||||
public final String uuid;
|
public final String uuid;
|
||||||
|
|
||||||
/** The foreign key identifier to the institution where the User belongs to */
|
/** The foreign key identifier to the institution where the User belongs to */
|
||||||
@NotNull(message = "user:institutionId:notNull")
|
@NotNull(message = "user:institutionId:notNull")
|
||||||
@JsonProperty(USER.ATTR_INSTITUTION_ID)
|
@JsonProperty(USER.ATTR_INSTITUTION_ID)
|
||||||
public final Long institutionId;
|
public final Long institutionId;
|
||||||
|
|
||||||
/** first (or full) name of the user */
|
/** first (or full) name of the user */
|
||||||
@NotNull(message = "user:name:notNull")
|
@NotNull(message = "user:name:notNull")
|
||||||
@Size(min = 3, max = 255, message = "user:name:size:{min}:{max}:${validatedValue}")
|
@Size(max = 255, message = "user:name:size:{min}:{max}:${validatedValue}")
|
||||||
@JsonProperty(USER.ATTR_NAME)
|
@JsonProperty(USER.ATTR_NAME)
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
/** surname of the user */
|
/** surname of the user */
|
||||||
@Size(max = 255, message = "user:surname:size:{min}:{max}:${validatedValue}")
|
@NotNull(message = "user:surname:notNull")
|
||||||
@JsonProperty(USER.ATTR_SURNAME)
|
@Size(max = 255, message = "user:surname:size:{min}:{max}:${validatedValue}")
|
||||||
public final String surname;
|
@JsonProperty(USER.ATTR_SURNAME)
|
||||||
|
public final String surname;
|
||||||
/** The internal user name */
|
|
||||||
@NotNull(message = "user:username:notNull")
|
/** The internal user name */
|
||||||
@Size(min = 3, max = 255, message = "user:username:size:{min}:{max}:${validatedValue}")
|
@NotNull(message = "user:username:notNull")
|
||||||
@JsonProperty(USER.ATTR_USERNAME)
|
@Size(min = 3, max = 255, message = "user:username:size:{min}:{max}:${validatedValue}")
|
||||||
public final String username;
|
@JsonProperty(USER.ATTR_USERNAME)
|
||||||
|
public final String username;
|
||||||
/** E-mail address of the user */
|
|
||||||
@Email(message = "user:email:email:_:_:${validatedValue}")
|
/** E-mail address of the user */
|
||||||
@JsonProperty(USER.ATTR_EMAIL)
|
@Email(message = "user:email:email:_:_:${validatedValue}")
|
||||||
public final String email;
|
@JsonProperty(USER.ATTR_EMAIL)
|
||||||
|
public final String email;
|
||||||
/** The users locale */
|
|
||||||
@NotNull(message = "user:language:notNull")
|
/** The users locale */
|
||||||
@JsonProperty(USER.ATTR_LANGUAGE)
|
@NotNull(message = "user:language:notNull")
|
||||||
public final Locale language;
|
@JsonProperty(USER.ATTR_LANGUAGE)
|
||||||
|
public final Locale language;
|
||||||
/** The users time zone */
|
|
||||||
@NotNull(message = "user:timeZone:notNull")
|
/** The users time zone */
|
||||||
@JsonProperty(USER.ATTR_TIMEZONE)
|
@NotNull(message = "user:timeZone:notNull")
|
||||||
public final DateTimeZone timeZone;
|
@JsonProperty(USER.ATTR_TIMEZONE)
|
||||||
|
public final DateTimeZone timeZone;
|
||||||
/** The users roles in a unmodifiable set */
|
|
||||||
@NotNull(message = "user:userRoles:notNull")
|
/** The users roles in a unmodifiable set */
|
||||||
@NotEmpty(message = "user:userRoles:notNull")
|
@NotNull(message = "user:userRoles:notNull")
|
||||||
@JsonProperty(USER_ROLE.REFERENCE_NAME)
|
@NotEmpty(message = "user:userRoles:notNull")
|
||||||
public final Set<String> roles;
|
@JsonProperty(USER_ROLE.REFERENCE_NAME)
|
||||||
|
public final Set<String> roles;
|
||||||
@NotNull(message = "user:newPassword:notNull")
|
|
||||||
@Size(min = 8, max = 255, message = "user:newPassword:size:{min}:{max}:${validatedValue}")
|
@NotNull(message = "user:newPassword:notNull")
|
||||||
@JsonProperty(PasswordChange.ATTR_NAME_NEW_PASSWORD)
|
@Size(min = 8, max = 255, message = "user:newPassword:size:{min}:{max}:${validatedValue}")
|
||||||
private final CharSequence newPassword;
|
@JsonProperty(PasswordChange.ATTR_NAME_NEW_PASSWORD)
|
||||||
|
private final CharSequence newPassword;
|
||||||
@NotNull(message = "user:confirmNewPassword:notNull")
|
|
||||||
@JsonProperty(PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD)
|
@NotNull(message = "user:confirmNewPassword:notNull")
|
||||||
private final CharSequence confirmNewPassword;
|
@JsonProperty(PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD)
|
||||||
|
private final CharSequence confirmNewPassword;
|
||||||
@JsonCreator
|
|
||||||
public UserMod(
|
@JsonCreator
|
||||||
@JsonProperty(USER.ATTR_UUID) final String uuid,
|
public UserMod(
|
||||||
@JsonProperty(USER.ATTR_INSTITUTION_ID) final Long institutionId,
|
@JsonProperty(USER.ATTR_UUID) final String uuid,
|
||||||
@JsonProperty(USER.ATTR_NAME) final String name,
|
@JsonProperty(USER.ATTR_INSTITUTION_ID) final Long institutionId,
|
||||||
@JsonProperty(USER.ATTR_SURNAME) final String surname,
|
@JsonProperty(USER.ATTR_NAME) final String name,
|
||||||
@JsonProperty(USER.ATTR_USERNAME) final String username,
|
@JsonProperty(USER.ATTR_SURNAME) final String surname,
|
||||||
@JsonProperty(PasswordChange.ATTR_NAME_NEW_PASSWORD) final CharSequence newPassword,
|
@JsonProperty(USER.ATTR_USERNAME) final String username,
|
||||||
@JsonProperty(PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD) final CharSequence confirmNewPassword,
|
@JsonProperty(PasswordChange.ATTR_NAME_NEW_PASSWORD) final CharSequence newPassword,
|
||||||
@JsonProperty(USER.ATTR_EMAIL) final String email,
|
@JsonProperty(PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD) final CharSequence confirmNewPassword,
|
||||||
@JsonProperty(USER.ATTR_LANGUAGE) final Locale language,
|
@JsonProperty(USER.ATTR_EMAIL) final String email,
|
||||||
@JsonProperty(USER.ATTR_TIMEZONE) final DateTimeZone timeZone,
|
@JsonProperty(USER.ATTR_LANGUAGE) final Locale language,
|
||||||
@JsonProperty(USER_ROLE.REFERENCE_NAME) final Set<String> roles) {
|
@JsonProperty(USER.ATTR_TIMEZONE) final DateTimeZone timeZone,
|
||||||
|
@JsonProperty(USER_ROLE.REFERENCE_NAME) final Set<String> roles) {
|
||||||
this.uuid = uuid;
|
|
||||||
this.institutionId = institutionId;
|
this.uuid = uuid;
|
||||||
this.newPassword = newPassword;
|
this.institutionId = institutionId;
|
||||||
this.confirmNewPassword = confirmNewPassword;
|
this.newPassword = newPassword;
|
||||||
this.name = name;
|
this.confirmNewPassword = confirmNewPassword;
|
||||||
this.surname = surname;
|
this.name = name;
|
||||||
this.username = username;
|
this.surname = surname;
|
||||||
this.email = email;
|
this.username = username;
|
||||||
this.language = (language != null) ? language : Locale.ENGLISH;
|
this.email = email;
|
||||||
this.timeZone = (timeZone != null) ? timeZone : DateTimeZone.UTC;
|
this.language = (language != null) ? language : Locale.ENGLISH;
|
||||||
this.roles = (roles != null)
|
this.timeZone = (timeZone != null) ? timeZone : DateTimeZone.UTC;
|
||||||
? Collections.unmodifiableSet(roles)
|
this.roles = (roles != null)
|
||||||
: Collections.emptySet();
|
? Collections.unmodifiableSet(roles)
|
||||||
}
|
: Collections.emptySet();
|
||||||
|
}
|
||||||
public UserMod(final String modelId, final POSTMapper postAttrMapper) {
|
|
||||||
this.uuid = modelId;
|
public UserMod(final String modelId, final POSTMapper postAttrMapper) {
|
||||||
this.institutionId = postAttrMapper.getLong(USER.ATTR_INSTITUTION_ID);
|
this.uuid = modelId;
|
||||||
this.newPassword = postAttrMapper.getString(PasswordChange.ATTR_NAME_NEW_PASSWORD);
|
this.institutionId = postAttrMapper.getLong(USER.ATTR_INSTITUTION_ID);
|
||||||
this.confirmNewPassword = postAttrMapper.getString(PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD);
|
this.newPassword = postAttrMapper.getString(PasswordChange.ATTR_NAME_NEW_PASSWORD);
|
||||||
this.name = postAttrMapper.getString(USER.ATTR_NAME);
|
this.confirmNewPassword = postAttrMapper.getString(PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD);
|
||||||
this.surname = postAttrMapper.getString(USER.ATTR_SURNAME);
|
this.name = postAttrMapper.getString(USER.ATTR_NAME);
|
||||||
this.username = postAttrMapper.getString(USER.ATTR_USERNAME);
|
this.surname = postAttrMapper.getString(USER.ATTR_SURNAME);
|
||||||
this.email = postAttrMapper.getString(USER.ATTR_EMAIL);
|
this.username = postAttrMapper.getString(USER.ATTR_USERNAME);
|
||||||
this.language = postAttrMapper.getLocale(USER.ATTR_LANGUAGE);
|
this.email = postAttrMapper.getString(USER.ATTR_EMAIL);
|
||||||
this.timeZone = postAttrMapper.getDateTimeZone(USER.ATTR_TIMEZONE);
|
this.language = postAttrMapper.getLocale(USER.ATTR_LANGUAGE);
|
||||||
this.roles = postAttrMapper.getStringSet(USER_ROLE.REFERENCE_NAME);
|
this.timeZone = postAttrMapper.getDateTimeZone(USER.ATTR_TIMEZONE);
|
||||||
}
|
this.roles = postAttrMapper.getStringSet(USER_ROLE.REFERENCE_NAME);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getModelId() {
|
@Override
|
||||||
return this.uuid;
|
public String getModelId() {
|
||||||
}
|
return this.uuid;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public EntityType entityType() {
|
@Override
|
||||||
return EntityType.USER;
|
public EntityType entityType() {
|
||||||
}
|
return EntityType.USER;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Long getInstitutionId() {
|
@Override
|
||||||
return this.institutionId;
|
public Long getInstitutionId() {
|
||||||
}
|
return this.institutionId;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public DateTime getCreationDate() {
|
@Override
|
||||||
return null;
|
public DateTime getCreationDate() {
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getOwnerId() {
|
@Override
|
||||||
return this.uuid;
|
public String getOwnerId() {
|
||||||
}
|
return this.uuid;
|
||||||
|
}
|
||||||
public CharSequence getNewPassword() {
|
|
||||||
return this.newPassword;
|
public CharSequence getNewPassword() {
|
||||||
}
|
return this.newPassword;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getName() {
|
@Override
|
||||||
return this.name;
|
public String getName() {
|
||||||
}
|
return this.name;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getSurname() {
|
@Override
|
||||||
return this.surname;
|
public String getSurname() {
|
||||||
}
|
return this.surname;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getUsername() {
|
@Override
|
||||||
return this.username;
|
public String getUsername() {
|
||||||
}
|
return this.username;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String getEmail() {
|
@Override
|
||||||
return this.email;
|
public String getEmail() {
|
||||||
}
|
return this.email;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Locale getLanguage() {
|
@Override
|
||||||
return this.language;
|
public Locale getLanguage() {
|
||||||
}
|
return this.language;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public DateTimeZone getTimeZone() {
|
@Override
|
||||||
return this.timeZone;
|
public DateTimeZone getTimeZone() {
|
||||||
}
|
return this.timeZone;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Set<String> getRoles() {
|
@Override
|
||||||
return this.roles;
|
public Set<String> getRoles() {
|
||||||
}
|
return this.roles;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
@JsonIgnore
|
@Override
|
||||||
public EnumSet<UserRole> getUserRoles() {
|
@JsonIgnore
|
||||||
final List<UserRole> roles = getRoles()
|
public EnumSet<UserRole> getUserRoles() {
|
||||||
.stream()
|
final List<UserRole> roles = getRoles()
|
||||||
.map(r -> UserRole.valueOf(r))
|
.stream()
|
||||||
.collect(Collectors.toList());
|
.map(r -> UserRole.valueOf(r))
|
||||||
if (roles.isEmpty()) {
|
.collect(Collectors.toList());
|
||||||
return EnumSet.noneOf(UserRole.class);
|
if (roles.isEmpty()) {
|
||||||
}
|
return EnumSet.noneOf(UserRole.class);
|
||||||
return EnumSet.copyOf(roles);
|
}
|
||||||
}
|
return EnumSet.copyOf(roles);
|
||||||
|
}
|
||||||
public CharSequence getRetypedNewPassword() {
|
|
||||||
return this.confirmNewPassword;
|
public CharSequence getRetypedNewPassword() {
|
||||||
}
|
return this.confirmNewPassword;
|
||||||
|
}
|
||||||
public boolean passwordChangeRequest() {
|
|
||||||
return this.newPassword != null;
|
public boolean passwordChangeRequest() {
|
||||||
}
|
return this.newPassword != null;
|
||||||
|
}
|
||||||
public boolean newPasswordMatch() {
|
|
||||||
return passwordChangeRequest() && this.newPassword.equals(this.confirmNewPassword);
|
public boolean newPasswordMatch() {
|
||||||
}
|
return passwordChangeRequest() && this.newPassword.equals(this.confirmNewPassword);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Boolean getActive() {
|
@Override
|
||||||
return false;
|
public Boolean getActive() {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public boolean isActive() {
|
@Override
|
||||||
return false;
|
public boolean isActive() {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
@JsonIgnore
|
|
||||||
@Override
|
@JsonIgnore
|
||||||
public EntityKey getEntityKey() {
|
@Override
|
||||||
if (StringUtils.isBlank(this.uuid)) {
|
public EntityKey getEntityKey() {
|
||||||
return null;
|
if (StringUtils.isBlank(this.uuid)) {
|
||||||
}
|
return null;
|
||||||
return new EntityKey(this.uuid, entityType());
|
}
|
||||||
}
|
return new EntityKey(this.uuid, entityType());
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public String toString() {
|
@Override
|
||||||
final StringBuilder builder = new StringBuilder();
|
public String toString() {
|
||||||
builder.append("UserMod [uuid=");
|
final StringBuilder builder = new StringBuilder();
|
||||||
builder.append(this.uuid);
|
builder.append("UserMod [uuid=");
|
||||||
builder.append(", institutionId=");
|
builder.append(this.uuid);
|
||||||
builder.append(this.institutionId);
|
builder.append(", institutionId=");
|
||||||
builder.append(", name=");
|
builder.append(this.institutionId);
|
||||||
builder.append(this.name);
|
builder.append(", name=");
|
||||||
builder.append(", surname=");
|
builder.append(this.name);
|
||||||
builder.append(this.surname);
|
builder.append(", surname=");
|
||||||
builder.append(", username=");
|
builder.append(this.surname);
|
||||||
builder.append(this.username);
|
builder.append(", username=");
|
||||||
builder.append(", email=");
|
builder.append(this.username);
|
||||||
builder.append(this.email);
|
builder.append(", email=");
|
||||||
builder.append(", language=");
|
builder.append(this.email);
|
||||||
builder.append(this.language);
|
builder.append(", language=");
|
||||||
builder.append(", timeZone=");
|
builder.append(this.language);
|
||||||
builder.append(this.timeZone);
|
builder.append(", timeZone=");
|
||||||
builder.append(", roles=");
|
builder.append(this.timeZone);
|
||||||
builder.append(this.roles);
|
builder.append(", roles=");
|
||||||
builder.append(", newPassword=");
|
builder.append(this.roles);
|
||||||
builder.append(this.newPassword);
|
builder.append(", newPassword=");
|
||||||
builder.append(", confirmNewPassword=");
|
builder.append(this.newPassword);
|
||||||
builder.append(this.confirmNewPassword);
|
builder.append(", confirmNewPassword=");
|
||||||
builder.append("]");
|
builder.append(this.confirmNewPassword);
|
||||||
return builder.toString();
|
builder.append("]");
|
||||||
}
|
return builder.toString();
|
||||||
|
}
|
||||||
public static UserMod createNew(final Long institutionId) {
|
|
||||||
return new UserMod(
|
public static UserMod createNew(final Long institutionId) {
|
||||||
UUID.randomUUID().toString(),
|
return new UserMod(
|
||||||
institutionId,
|
UUID.randomUUID().toString(),
|
||||||
null, null, null, null, null, null, null, null, null);
|
institutionId,
|
||||||
}
|
null, null, null, null, null, null, null, null, null);
|
||||||
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,70 +1,79 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.util;
|
package ch.ethz.seb.sebserver.gbl.util;
|
||||||
|
|
||||||
/** A tuple of two elements of the same type */
|
/** A tuple of two elements of the same type */
|
||||||
public class Tuple<T> {
|
public class Tuple<T> {
|
||||||
|
|
||||||
/** The first element of the tuple */
|
/** The first element of the tuple */
|
||||||
public final T _1;
|
public final T _1;
|
||||||
/** The second element of the tuple */
|
/** The second element of the tuple */
|
||||||
public final T _2;
|
public final T _2;
|
||||||
|
|
||||||
public Tuple(final T _1, final T _2) {
|
public Tuple(final T _1, final T _2) {
|
||||||
super();
|
super();
|
||||||
this._1 = _1;
|
this._1 = _1;
|
||||||
this._2 = _2;
|
this._2 = _2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T get_1() {
|
public T get_1() {
|
||||||
return this._1;
|
return this._1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T get_2() {
|
public T get_2() {
|
||||||
return this._2;
|
return this._2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SuppressWarnings("unchecked")
|
||||||
public int hashCode() {
|
public <TT extends Tuple<T>> TT adaptTo(Class<TT> type) {
|
||||||
final int prime = 31;
|
if (type.equals(this.getClass())) {
|
||||||
int result = 1;
|
return (TT) this;
|
||||||
result = prime * result + ((this._1 == null) ? 0 : this._1.hashCode());
|
}
|
||||||
result = prime * result + ((this._2 == null) ? 0 : this._2.hashCode());
|
|
||||||
return result;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public int hashCode() {
|
||||||
if (this == obj)
|
final int prime = 31;
|
||||||
return true;
|
int result = 1;
|
||||||
if (obj == null)
|
result = prime * result + ((this._1 == null) ? 0 : this._1.hashCode());
|
||||||
return false;
|
result = prime * result + ((this._2 == null) ? 0 : this._2.hashCode());
|
||||||
if (getClass() != obj.getClass())
|
return result;
|
||||||
return false;
|
}
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
final Tuple other = (Tuple) obj;
|
@Override
|
||||||
if (this._1 == null) {
|
public boolean equals(final Object obj) {
|
||||||
if (other._1 != null)
|
if (this == obj)
|
||||||
return false;
|
return true;
|
||||||
} else if (!this._1.equals(other._1))
|
if (obj == null)
|
||||||
return false;
|
return false;
|
||||||
if (this._2 == null) {
|
if (getClass() != obj.getClass())
|
||||||
if (other._2 != null)
|
return false;
|
||||||
return false;
|
@SuppressWarnings("rawtypes")
|
||||||
} else if (!this._2.equals(other._2))
|
final Tuple other = (Tuple) obj;
|
||||||
return false;
|
if (this._1 == null) {
|
||||||
return true;
|
if (other._1 != null)
|
||||||
}
|
return false;
|
||||||
|
} else if (!this._1.equals(other._1))
|
||||||
@Override
|
return false;
|
||||||
public String toString() {
|
if (this._2 == null) {
|
||||||
return "( " + this._1 + ", " + this._2 + ")";
|
if (other._2 != null)
|
||||||
}
|
return false;
|
||||||
|
} else if (!this._2.equals(other._2))
|
||||||
}
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "( " + this._1 + ", " + this._2 + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
41
src/main/java/ch/ethz/seb/sebserver/gbl/util/Tuple3.java
Normal file
41
src/main/java/ch/ethz/seb/sebserver/gbl/util/Tuple3.java
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.gbl.util;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/** A tuple of three elements of the same type */
|
||||||
|
public class Tuple3<T> extends Tuple<T> {
|
||||||
|
|
||||||
|
/** The third element of the tuple */
|
||||||
|
public final T _3;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
Tuple3<?> tuple3 = (Tuple3<?>) o;
|
||||||
|
return Objects.equals(_3, tuple3._3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), _3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tuple3(T _1, T _2, T _3) {
|
||||||
|
super(_1, _2);
|
||||||
|
this._3 = _3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T get_3() {
|
||||||
|
return _3;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,253 +1,257 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttribute;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
@Lazy
|
|
||||||
@Component
|
@Lazy
|
||||||
@GuiProfile
|
@Component
|
||||||
public class ConfigTemplateAttributeForm implements TemplateComposer {
|
@GuiProfile
|
||||||
|
public class ConfigTemplateAttributeForm implements TemplateComposer {
|
||||||
private static final LocTextKey FORM_TITLE =
|
|
||||||
new LocTextKey("sebserver.configtemplate.attr.form.title");
|
private static final LocTextKey FORM_TITLE =
|
||||||
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
new LocTextKey("sebserver.configtemplate.attr.form.title");
|
||||||
new LocTextKey("sebserver.configtemplate.attr.form.name");
|
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
private static final LocTextKey FORM_TYPE_TEXT_KEY =
|
new LocTextKey("sebserver.configtemplate.attr.form.name");
|
||||||
new LocTextKey("sebserver.configtemplate.attr.form.type");
|
private static final LocTextKey FORM_TYPE_TEXT_KEY =
|
||||||
private static final LocTextKey FORM_VIEW_TEXT_KEY =
|
new LocTextKey("sebserver.configtemplate.attr.form.type");
|
||||||
new LocTextKey("sebserver.configtemplate.attr.form.view");
|
private static final LocTextKey FORM_VIEW_TEXT_KEY =
|
||||||
private static final LocTextKey FORM_GROUP_TEXT_KEY =
|
new LocTextKey("sebserver.configtemplate.attr.form.view");
|
||||||
new LocTextKey("sebserver.configtemplate.attr.form.group");
|
private static final LocTextKey FORM_GROUP_TEXT_KEY =
|
||||||
private static final LocTextKey FORM_VALUE_TEXT_KEY =
|
new LocTextKey("sebserver.configtemplate.attr.form.group");
|
||||||
new LocTextKey("sebserver.configtemplate.attr.form.value");
|
private static final LocTextKey FORM_VALUE_TEXT_KEY =
|
||||||
|
new LocTextKey("sebserver.configtemplate.attr.form.value");
|
||||||
private final PageService pageService;
|
private static final LocTextKey FORM_VALUE_TOOLTIP_TEXT_KEY =
|
||||||
private final RestService restService;
|
new LocTextKey("sebserver.configtemplate.attr.form.value" + Constants.TOOLTIP_TEXT_KEY_SUFFIX);
|
||||||
private final CurrentUser currentUser;
|
|
||||||
private final ResourceService resourceService;
|
private final PageService pageService;
|
||||||
private final ExamConfigurationService examConfigurationService;
|
private final RestService restService;
|
||||||
|
private final CurrentUser currentUser;
|
||||||
protected ConfigTemplateAttributeForm(
|
private final ResourceService resourceService;
|
||||||
final PageService pageService,
|
private final ExamConfigurationService examConfigurationService;
|
||||||
final RestService restService,
|
|
||||||
final CurrentUser currentUser,
|
protected ConfigTemplateAttributeForm(
|
||||||
final ExamConfigurationService examConfigurationService) {
|
final PageService pageService,
|
||||||
|
final RestService restService,
|
||||||
this.pageService = pageService;
|
final CurrentUser currentUser,
|
||||||
this.restService = restService;
|
final ExamConfigurationService examConfigurationService) {
|
||||||
this.currentUser = currentUser;
|
|
||||||
this.resourceService = pageService.getResourceService();
|
this.pageService = pageService;
|
||||||
this.examConfigurationService = examConfigurationService;
|
this.restService = restService;
|
||||||
|
this.currentUser = currentUser;
|
||||||
}
|
this.resourceService = pageService.getResourceService();
|
||||||
|
this.examConfigurationService = examConfigurationService;
|
||||||
@Override
|
|
||||||
public void compose(final PageContext pageContext) {
|
}
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
|
||||||
|
@Override
|
||||||
final EntityKey attributeKey = pageContext.getEntityKey();
|
public void compose(final PageContext pageContext) {
|
||||||
final EntityKey templateKey = pageContext.getParentEntityKey();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final Long templateId = Long.valueOf(templateKey.modelId);
|
|
||||||
|
final EntityKey attributeKey = pageContext.getEntityKey();
|
||||||
try {
|
final EntityKey templateKey = pageContext.getParentEntityKey();
|
||||||
|
final Long templateId = Long.valueOf(templateKey.modelId);
|
||||||
final ConfigurationNode template = this.restService
|
|
||||||
.getBuilder(GetExamConfigNode.class)
|
try {
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, templateKey.modelId)
|
|
||||||
.call()
|
final ConfigurationNode template = this.restService
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
.getBuilder(GetExamConfigNode.class)
|
||||||
.getOrThrow();
|
.withURIVariable(API.PARAM_MODEL_ID, templateKey.modelId)
|
||||||
|
.call()
|
||||||
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(template);
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
||||||
final boolean modifyGrant = entityGrant.m();
|
.getOrThrow();
|
||||||
|
|
||||||
// the attribute
|
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(template);
|
||||||
final TemplateAttribute attribute = this.restService.getBuilder(GetTemplateAttribute.class)
|
final boolean modifyGrant = entityGrant.m();
|
||||||
.withURIVariable(API.PARAM_PARENT_MODEL_ID, templateKey.modelId)
|
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, attributeKey.modelId)
|
// the attribute
|
||||||
.call()
|
final TemplateAttribute attribute = this.restService.getBuilder(GetTemplateAttribute.class)
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
.withURIVariable(API.PARAM_PARENT_MODEL_ID, templateKey.modelId)
|
||||||
.getOrThrow();
|
.withURIVariable(API.PARAM_MODEL_ID, attributeKey.modelId)
|
||||||
|
.call()
|
||||||
// the follow-up configuration
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
||||||
final Configuration configuration = this.restService.getBuilder(GetConfigurations.class)
|
.getOrThrow();
|
||||||
.withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, templateKey.getModelId())
|
|
||||||
.withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING)
|
// the follow-up configuration
|
||||||
.call()
|
final Configuration configuration = this.restService.getBuilder(GetConfigurations.class)
|
||||||
.map(Utils::toSingleton)
|
.withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, templateKey.getModelId())
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION, error))
|
.withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING)
|
||||||
.getOrThrow();
|
.call()
|
||||||
|
.map(Utils::toSingleton)
|
||||||
// the default page layout with title
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION, error))
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
.getOrThrow();
|
||||||
pageContext.getParent(),
|
|
||||||
FORM_TITLE);
|
// the default page layout with title
|
||||||
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
final PageContext formContext = pageContext.copyOf(content);
|
pageContext.getParent(),
|
||||||
|
FORM_TITLE);
|
||||||
final boolean hasView = attribute.getOrientation() != null;
|
|
||||||
|
final PageContext formContext = pageContext.copyOf(content);
|
||||||
this.pageService.formBuilder(formContext)
|
|
||||||
.readonly(true) // TODO change this for next version
|
final boolean hasView = attribute.getOrientation() != null;
|
||||||
.addField(FormBuilder.text(
|
|
||||||
Domain.CONFIGURATION_ATTRIBUTE.ATTR_NAME,
|
this.pageService.formBuilder(formContext)
|
||||||
FORM_NAME_TEXT_KEY,
|
.readonly(true) // TODO change this for next version
|
||||||
attribute::getName))
|
.addField(FormBuilder.text(
|
||||||
.addField(FormBuilder.text(
|
Domain.CONFIGURATION_ATTRIBUTE.ATTR_NAME,
|
||||||
Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE,
|
FORM_NAME_TEXT_KEY,
|
||||||
FORM_TYPE_TEXT_KEY,
|
attribute::getName))
|
||||||
() -> this.resourceService.getAttributeTypeName(attribute)))
|
.addField(FormBuilder.text(
|
||||||
.addFieldIf(
|
Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE,
|
||||||
() -> hasView,
|
FORM_TYPE_TEXT_KEY,
|
||||||
() -> FormBuilder.singleSelection(
|
() -> this.resourceService.getAttributeTypeName(attribute)))
|
||||||
Domain.ORIENTATION.ATTR_VIEW_ID,
|
.addFieldIf(
|
||||||
FORM_VIEW_TEXT_KEY,
|
() -> hasView,
|
||||||
attribute.getViewModelId(),
|
() -> FormBuilder.singleSelection(
|
||||||
() -> this.resourceService.getViewResources(templateKey.modelId)))
|
Domain.ORIENTATION.ATTR_VIEW_ID,
|
||||||
.addFieldIf(
|
FORM_VIEW_TEXT_KEY,
|
||||||
() -> hasView,
|
attribute.getViewModelId(),
|
||||||
() -> FormBuilder.text(
|
() -> this.resourceService.getViewResources(templateKey.modelId)))
|
||||||
Domain.ORIENTATION.ATTR_GROUP_ID,
|
.addFieldIf(
|
||||||
FORM_GROUP_TEXT_KEY,
|
() -> hasView,
|
||||||
attribute.getGroupId()))
|
() -> FormBuilder.text(
|
||||||
.build();
|
Domain.ORIENTATION.ATTR_GROUP_ID,
|
||||||
|
FORM_GROUP_TEXT_KEY,
|
||||||
final Composite valSpace = new Composite(content, SWT.NONE);
|
attribute.getGroupId()))
|
||||||
valSpace.setLayout(new GridLayout());
|
.build();
|
||||||
valSpace.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
|
||||||
|
final Composite valSpace = new Composite(content, SWT.NONE);
|
||||||
widgetFactory.labelLocalized(
|
valSpace.setLayout(new GridLayout());
|
||||||
valSpace,
|
valSpace.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||||
CustomVariant.TEXT_H2,
|
|
||||||
FORM_VALUE_TEXT_KEY);
|
widgetFactory.label(content, StringUtils.EMPTY);
|
||||||
|
widgetFactory.labelLocalized(
|
||||||
widgetFactory.labelSeparator(valSpace);
|
valSpace,
|
||||||
|
CustomVariant.TEXT_H3,
|
||||||
final Composite grid = new Composite(valSpace, SWT.NONE);
|
FORM_VALUE_TEXT_KEY,
|
||||||
grid.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
FORM_VALUE_TOOLTIP_TEXT_KEY);
|
||||||
grid.setLayout(new GridLayout(6, true));
|
widgetFactory.labelSeparator(valSpace);
|
||||||
|
|
||||||
final PageContext valueContext = formContext.copyOf(grid);
|
final Composite grid = new Composite(valSpace, SWT.NONE);
|
||||||
|
grid.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||||
final Orientation defaultOrientation = getDefaultOrientation(attribute);
|
grid.setLayout(new GridLayout(6, true));
|
||||||
final AttributeMapping attributeMapping = this.examConfigurationService
|
|
||||||
.getAttributes(attribute, defaultOrientation)
|
final PageContext valueContext = formContext.copyOf(grid);
|
||||||
.getOrThrow();
|
|
||||||
final ViewContext viewContext = this.examConfigurationService.createViewContext(
|
final Orientation defaultOrientation = getDefaultOrientation(attribute);
|
||||||
valueContext,
|
final AttributeMapping attributeMapping = this.examConfigurationService
|
||||||
configuration,
|
.getAttributes(attribute, defaultOrientation)
|
||||||
new View(-1L, "template", 10, 0, templateId),
|
.getOrThrow();
|
||||||
attributeMapping,
|
final ViewContext viewContext = this.examConfigurationService.createViewContext(
|
||||||
1, false);
|
valueContext,
|
||||||
|
configuration,
|
||||||
final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder(
|
new View(-1L, "template", 10, 0, templateId),
|
||||||
attribute.getConfigAttribute(),
|
attributeMapping,
|
||||||
defaultOrientation);
|
1, false);
|
||||||
|
|
||||||
final InputField createInputField = inputFieldBuilder.createInputField(
|
final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder(
|
||||||
grid,
|
attribute.getConfigAttribute(),
|
||||||
attribute.getConfigAttribute(),
|
defaultOrientation);
|
||||||
viewContext);
|
|
||||||
|
final InputField createInputField = inputFieldBuilder.createInputField(
|
||||||
viewContext.registerInputField(createInputField);
|
grid,
|
||||||
|
attribute.getConfigAttribute(),
|
||||||
this.examConfigurationService.initInputFieldValues(
|
viewContext);
|
||||||
configuration.id,
|
|
||||||
Arrays.asList(viewContext));
|
viewContext.registerInputField(createInputField);
|
||||||
|
|
||||||
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
this.examConfigurationService.initInputFieldValues(
|
||||||
|
configuration.id,
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_SET_DEFAULT)
|
Collections.singletonList(viewContext));
|
||||||
.withEntityKey(attributeKey)
|
|
||||||
.withParentEntityKey(templateKey)
|
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
||||||
.withExec(this.examConfigurationService::resetToDefaults)
|
|
||||||
.ignoreMoveAwayFromEdit()
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_SET_DEFAULT)
|
||||||
.publishIf(() -> modifyGrant)
|
.withEntityKey(attributeKey)
|
||||||
|
.withParentEntityKey(templateKey)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_REMOVE_VIEW)
|
.withExec(this.examConfigurationService::resetToDefaults)
|
||||||
.withEntityKey(attributeKey)
|
.ignoreMoveAwayFromEdit()
|
||||||
.withParentEntityKey(templateKey)
|
.publishIf(() -> modifyGrant)
|
||||||
.withExec(this.examConfigurationService::removeFromView)
|
|
||||||
.ignoreMoveAwayFromEdit()
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_REMOVE_VIEW)
|
||||||
.publishIf(() -> modifyGrant && hasView)
|
.withEntityKey(attributeKey)
|
||||||
|
.withParentEntityKey(templateKey)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_ATTACH_DEFAULT_VIEW)
|
.withExec(this.examConfigurationService::removeFromView)
|
||||||
.withEntityKey(attributeKey)
|
.ignoreMoveAwayFromEdit()
|
||||||
.withParentEntityKey(templateKey)
|
.publishIf(() -> modifyGrant && hasView)
|
||||||
.withExec(this.examConfigurationService::attachToDefaultView)
|
|
||||||
.ignoreMoveAwayFromEdit()
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_ATTACH_DEFAULT_VIEW)
|
||||||
.publishIf(() -> modifyGrant && !hasView)
|
.withEntityKey(attributeKey)
|
||||||
|
.withParentEntityKey(templateKey)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_EDIT_TEMPLATE)
|
.withExec(this.examConfigurationService::attachToDefaultView)
|
||||||
.withEntityKey(templateKey)
|
.ignoreMoveAwayFromEdit()
|
||||||
.ignoreMoveAwayFromEdit()
|
.publishIf(() -> modifyGrant && !hasView)
|
||||||
.publish();
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_FORM_EDIT_TEMPLATE)
|
||||||
} catch (final Exception e) {
|
.withEntityKey(templateKey)
|
||||||
pageContext.notifyUnexpectedError(e);
|
.ignoreMoveAwayFromEdit()
|
||||||
}
|
.publish();
|
||||||
}
|
|
||||||
|
} catch (final Exception e) {
|
||||||
private Orientation getDefaultOrientation(final TemplateAttribute attribute) {
|
pageContext.notifyUnexpectedError(e);
|
||||||
return new Orientation(
|
}
|
||||||
-1L,
|
}
|
||||||
attribute.getConfigAttribute().id,
|
|
||||||
attribute.templateId,
|
private Orientation getDefaultOrientation(final TemplateAttribute attribute) {
|
||||||
null,
|
return new Orientation(
|
||||||
null,
|
-1L,
|
||||||
0,
|
attribute.getConfigAttribute().id,
|
||||||
0,
|
attribute.templateId,
|
||||||
2,
|
null,
|
||||||
1,
|
null,
|
||||||
TitleOrientation.NONE);
|
0,
|
||||||
}
|
0,
|
||||||
|
2,
|
||||||
}
|
1,
|
||||||
|
TitleOrientation.NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,348 +1,362 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttributePage;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetTemplateAttributePage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class ConfigTemplateForm implements TemplateComposer {
|
public class ConfigTemplateForm implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey FORM_TITLE_NEW =
|
private static final LocTextKey FORM_TITLE_NEW =
|
||||||
new LocTextKey("sebserver.configtemplate.form.title.new");
|
new LocTextKey("sebserver.configtemplate.form.title.new");
|
||||||
private static final LocTextKey FORM_TITLE =
|
private static final LocTextKey FORM_TITLE =
|
||||||
new LocTextKey("sebserver.configtemplate.form.title");
|
new LocTextKey("sebserver.configtemplate.form.title");
|
||||||
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.form.name");
|
new LocTextKey("sebserver.configtemplate.form.name");
|
||||||
private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.form.description");
|
new LocTextKey("sebserver.configtemplate.form.description");
|
||||||
private static final LocTextKey ATTRIBUTES_LIST_TITLE_TEXT_KEY =
|
private static final LocTextKey ATTRIBUTES_LIST_TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.attrs.list.title");
|
new LocTextKey("sebserver.configtemplate.attrs.list.title");
|
||||||
private static final LocTextKey ATTRIBUTES_LIST_NAME_TEXT_KEY =
|
private static final LocTextKey ATTRIBUTES_LIST_TITLE_TOOLTIP_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.attrs.list.name");
|
new LocTextKey("sebserver.configtemplate.attrs.list.title" + Constants.TOOLTIP_TEXT_KEY_SUFFIX);
|
||||||
private static final LocTextKey ATTRIBUTES_LIST_VIEW_TEXT_KEY =
|
private static final LocTextKey ATTRIBUTES_LIST_NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.attrs.list.view");
|
new LocTextKey("sebserver.configtemplate.attrs.list.name");
|
||||||
private static final LocTextKey ATTRIBUTES_LIST_GROUP_TEXT_KEY =
|
private static final LocTextKey ATTRIBUTES_LIST_VIEW_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.attrs.list.group");
|
new LocTextKey("sebserver.configtemplate.attrs.list.view");
|
||||||
private static final LocTextKey ATTRIBUTES_LIST_TYPE_TEXT_KEY =
|
private static final LocTextKey ATTRIBUTES_LIST_GROUP_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.attrs.list.type");
|
new LocTextKey("sebserver.configtemplate.attrs.list.group");
|
||||||
private static final LocTextKey EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY =
|
private static final LocTextKey ATTRIBUTES_LIST_TYPE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.attr.info.pleaseSelect");
|
new LocTextKey("sebserver.configtemplate.attrs.list.type");
|
||||||
|
private static final LocTextKey EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY =
|
||||||
private final PageService pageService;
|
new LocTextKey("sebserver.configtemplate.attr.info.pleaseSelect");
|
||||||
private final RestService restService;
|
|
||||||
private final CurrentUser currentUser;
|
private final PageService pageService;
|
||||||
private final I18nSupport i18nSupport;
|
private final RestService restService;
|
||||||
private final ResourceService resourceService;
|
private final CurrentUser currentUser;
|
||||||
private final ExamConfigurationService examConfigurationService;
|
private final I18nSupport i18nSupport;
|
||||||
|
private final ResourceService resourceService;
|
||||||
private final TableFilterAttribute nameFilter =
|
private final ExamConfigurationService examConfigurationService;
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, TemplateAttribute.FILTER_ATTR_NAME);
|
|
||||||
private final TableFilterAttribute groupFilter =
|
private final TableFilterAttribute nameFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, TemplateAttribute.FILTER_ATTR_GROUP);
|
new TableFilterAttribute(CriteriaType.TEXT, TemplateAttribute.FILTER_ATTR_NAME);
|
||||||
|
private final TableFilterAttribute groupFilter =
|
||||||
protected ConfigTemplateForm(
|
new TableFilterAttribute(CriteriaType.TEXT, TemplateAttribute.FILTER_ATTR_GROUP);
|
||||||
final PageService pageService,
|
|
||||||
final RestService restService,
|
protected ConfigTemplateForm(
|
||||||
final CurrentUser currentUser,
|
final PageService pageService,
|
||||||
final ExamConfigurationService examConfigurationService) {
|
final RestService restService,
|
||||||
|
final CurrentUser currentUser,
|
||||||
this.pageService = pageService;
|
final ExamConfigurationService examConfigurationService) {
|
||||||
this.restService = restService;
|
|
||||||
this.currentUser = currentUser;
|
this.pageService = pageService;
|
||||||
this.i18nSupport = pageService.getI18nSupport();
|
this.restService = restService;
|
||||||
this.resourceService = pageService.getResourceService();
|
this.currentUser = currentUser;
|
||||||
this.examConfigurationService = examConfigurationService;
|
this.i18nSupport = pageService.getI18nSupport();
|
||||||
|
this.resourceService = pageService.getResourceService();
|
||||||
}
|
this.examConfigurationService = examConfigurationService;
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public void compose(final PageContext pageContext) {
|
|
||||||
|
@Override
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
public void compose(final PageContext pageContext) {
|
||||||
final ResourceService resourceService = this.pageService.getResourceService();
|
|
||||||
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final UserInfo user = this.currentUser.get();
|
final ResourceService resourceService = this.pageService.getResourceService();
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
|
||||||
final boolean isNew = entityKey == null;
|
final UserInfo user = this.currentUser.get();
|
||||||
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
// get data or create new. Handle error if happen
|
final boolean isNew = entityKey == null;
|
||||||
final ConfigurationNode examConfig = (isNew)
|
|
||||||
? ConfigurationNode.createNewTemplate(user.institutionId)
|
// get data or create new. Handle error if happen
|
||||||
: this.restService
|
final ConfigurationNode examConfig = (isNew)
|
||||||
.getBuilder(GetExamConfigNode.class)
|
? ConfigurationNode.createNewTemplate(user.institutionId)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
: this.restService
|
||||||
.call()
|
.getBuilder(GetExamConfigNode.class)
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
.getOrThrow();
|
.call()
|
||||||
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
||||||
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig);
|
.getOrThrow();
|
||||||
final boolean writeGrant = entityGrant.w();
|
|
||||||
final boolean modifyGrant = entityGrant.m();
|
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig);
|
||||||
final boolean isReadonly = pageContext.isReadonly();
|
final boolean writeGrant = entityGrant.w();
|
||||||
|
final boolean modifyGrant = entityGrant.m();
|
||||||
// new PageContext with actual EntityKey
|
final boolean isReadonly = pageContext.isReadonly();
|
||||||
final PageContext formContext = pageContext
|
|
||||||
.withEntityKey(examConfig.getEntityKey());
|
// new PageContext with actual EntityKey
|
||||||
|
final PageContext formContext = pageContext
|
||||||
// the default page layout with interactive title
|
.withEntityKey(examConfig.getEntityKey());
|
||||||
final LocTextKey titleKey = (isNew)
|
|
||||||
? FORM_TITLE_NEW
|
// the default page layout with interactive title
|
||||||
: FORM_TITLE;
|
final LocTextKey titleKey = (isNew)
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
? FORM_TITLE_NEW
|
||||||
formContext.getParent(),
|
: FORM_TITLE;
|
||||||
titleKey);
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
|
formContext.getParent(),
|
||||||
// The SebClientConfig form
|
titleKey);
|
||||||
final FormHandle<ConfigurationNode> formHandle = this.pageService.formBuilder(
|
|
||||||
formContext.copyOf(content))
|
// The SebClientConfig form
|
||||||
.readonly(isReadonly)
|
final FormHandle<ConfigurationNode> formHandle = this.pageService.formBuilder(
|
||||||
.putStaticValueIf(() -> !isNew,
|
formContext.copyOf(content))
|
||||||
Domain.CONFIGURATION_NODE.ATTR_ID,
|
.readonly(isReadonly)
|
||||||
examConfig.getModelId())
|
.putStaticValueIf(() -> !isNew,
|
||||||
.putStaticValue(
|
Domain.CONFIGURATION_NODE.ATTR_ID,
|
||||||
Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID,
|
examConfig.getModelId())
|
||||||
String.valueOf(examConfig.getInstitutionId()))
|
.putStaticValue(
|
||||||
.putStaticValue(
|
Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID,
|
||||||
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
String.valueOf(examConfig.getInstitutionId()))
|
||||||
ConfigurationType.TEMPLATE.name())
|
.putStaticValue(
|
||||||
.putStaticValue(
|
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
||||||
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
ConfigurationType.TEMPLATE.name())
|
||||||
ConfigurationStatus.IN_USE.name())
|
.putStaticValue(
|
||||||
.addField(FormBuilder.text(
|
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
||||||
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
ConfigurationStatus.IN_USE.name())
|
||||||
FORM_NAME_TEXT_KEY,
|
.addField(FormBuilder.text(
|
||||||
examConfig.name))
|
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
||||||
.addField(FormBuilder.text(
|
FORM_NAME_TEXT_KEY,
|
||||||
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
examConfig.name)
|
||||||
FORM_DESCRIPTION_TEXT_KEY,
|
.mandatory(!isReadonly))
|
||||||
examConfig.description)
|
.addField(FormBuilder.text(
|
||||||
.asArea())
|
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
||||||
|
FORM_DESCRIPTION_TEXT_KEY,
|
||||||
.buildFor((isNew)
|
examConfig.description)
|
||||||
? this.restService.getRestCall(NewExamConfig.class)
|
.asArea())
|
||||||
: this.restService.getRestCall(SaveExamConfig.class));
|
|
||||||
|
.buildFor((isNew)
|
||||||
final PageActionBuilder pageActionBuilder = this.pageService
|
? this.restService.getRestCall(NewExamConfig.class)
|
||||||
.pageActionBuilder(formContext.clearEntityKeys());
|
: this.restService.getRestCall(SaveExamConfig.class));
|
||||||
|
|
||||||
if (isReadonly) {
|
final PageActionBuilder pageActionBuilder = this.pageService
|
||||||
|
.pageActionBuilder(formContext.clearEntityKeys());
|
||||||
widgetFactory.label(content, "");
|
|
||||||
widgetFactory.labelLocalizedTitle(
|
if (isReadonly) {
|
||||||
content,
|
|
||||||
ATTRIBUTES_LIST_TITLE_TEXT_KEY);
|
widgetFactory.label(content, StringUtils.EMPTY);
|
||||||
|
widgetFactory.labelLocalized(
|
||||||
final TableFilterAttribute viewFilter = new TableFilterAttribute(
|
content,
|
||||||
CriteriaType.SINGLE_SELECTION,
|
WidgetFactory.CustomVariant.TEXT_H3,
|
||||||
TemplateAttribute.FILTER_ATTR_VIEW,
|
ATTRIBUTES_LIST_TITLE_TEXT_KEY,
|
||||||
() -> this.resourceService.getViewResources(entityKey.modelId));
|
ATTRIBUTES_LIST_TITLE_TOOLTIP_TEXT_KEY);
|
||||||
final TableFilterAttribute typeFilter = new TableFilterAttribute(
|
widgetFactory.labelSeparator(content);
|
||||||
CriteriaType.SINGLE_SELECTION,
|
|
||||||
TemplateAttribute.FILTER_ATTR_TYPE,
|
final TableFilterAttribute viewFilter = new TableFilterAttribute(
|
||||||
() -> this.resourceService.getAttributeTypeResources());
|
CriteriaType.SINGLE_SELECTION,
|
||||||
|
TemplateAttribute.FILTER_ATTR_VIEW,
|
||||||
final EntityTable<TemplateAttribute> attrTable =
|
() -> this.resourceService.getViewResources(entityKey.modelId));
|
||||||
this.pageService.entityTableBuilder(
|
final TableFilterAttribute typeFilter = new TableFilterAttribute(
|
||||||
Domain.CONFIGURATION_NODE.TYPE_NAME + "_Template",
|
CriteriaType.SINGLE_SELECTION,
|
||||||
this.restService.getRestCall(GetTemplateAttributePage.class))
|
TemplateAttribute.FILTER_ATTR_TYPE,
|
||||||
.withRestCallAdapter(restCall -> restCall.withURIVariable(
|
this.resourceService::getAttributeTypeResources);
|
||||||
API.PARAM_PARENT_MODEL_ID,
|
|
||||||
entityKey.modelId))
|
final EntityTable<TemplateAttribute> attrTable =
|
||||||
.withPaging(15)
|
this.pageService.entityTableBuilder(
|
||||||
.withColumn(new ColumnDefinition<>(
|
Domain.CONFIGURATION_NODE.TYPE_NAME + "_Template",
|
||||||
Domain.CONFIGURATION_ATTRIBUTE.ATTR_NAME,
|
this.restService.getRestCall(GetTemplateAttributePage.class))
|
||||||
ATTRIBUTES_LIST_NAME_TEXT_KEY,
|
.withRestCallAdapter(restCall -> restCall.withURIVariable(
|
||||||
this::getAttributeName)
|
API.PARAM_PARENT_MODEL_ID,
|
||||||
.withFilter(this.nameFilter)
|
entityKey.modelId))
|
||||||
.sortable()
|
.withPaging(15)
|
||||||
.widthProportion(3))
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withColumn(new ColumnDefinition<TemplateAttribute>(
|
Domain.CONFIGURATION_ATTRIBUTE.ATTR_NAME,
|
||||||
Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE,
|
ATTRIBUTES_LIST_NAME_TEXT_KEY,
|
||||||
ATTRIBUTES_LIST_TYPE_TEXT_KEY,
|
this::getAttributeName)
|
||||||
resourceService::getAttributeTypeName)
|
.withFilter(this.nameFilter)
|
||||||
.withFilter(typeFilter)
|
.sortable()
|
||||||
.sortable()
|
.widthProportion(3))
|
||||||
.widthProportion(1))
|
.withColumn(new ColumnDefinition<TemplateAttribute>(
|
||||||
.withColumn(new ColumnDefinition<>(
|
Domain.CONFIGURATION_ATTRIBUTE.ATTR_TYPE,
|
||||||
Domain.ORIENTATION.ATTR_VIEW_ID,
|
ATTRIBUTES_LIST_TYPE_TEXT_KEY,
|
||||||
ATTRIBUTES_LIST_VIEW_TEXT_KEY,
|
resourceService::getAttributeTypeName)
|
||||||
resourceService.getViewNameFunction(entityKey.modelId))
|
.withFilter(typeFilter)
|
||||||
.withFilter(viewFilter)
|
.sortable()
|
||||||
.sortable()
|
.widthProportion(1))
|
||||||
.widthProportion(1))
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withColumn(new ColumnDefinition<>(
|
Domain.ORIENTATION.ATTR_VIEW_ID,
|
||||||
Domain.ORIENTATION.ATTR_GROUP_ID,
|
ATTRIBUTES_LIST_VIEW_TEXT_KEY,
|
||||||
ATTRIBUTES_LIST_GROUP_TEXT_KEY,
|
resourceService.getViewNameFunction(entityKey.modelId))
|
||||||
TemplateAttribute::getGroupId)
|
.withFilter(viewFilter)
|
||||||
.withFilter(this.groupFilter)
|
.sortable()
|
||||||
.sortable()
|
.widthProportion(1))
|
||||||
.widthProportion(1))
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withDefaultAction(pageActionBuilder
|
Domain.ORIENTATION.ATTR_GROUP_ID,
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT)
|
ATTRIBUTES_LIST_GROUP_TEXT_KEY,
|
||||||
.withParentEntityKey(entityKey)
|
TemplateAttribute::getGroupId)
|
||||||
.create())
|
.withFilter(this.groupFilter)
|
||||||
.compose(pageContext.copyOf(content));
|
.sortable()
|
||||||
|
.widthProportion(1))
|
||||||
pageActionBuilder
|
.withDefaultAction(pageActionBuilder
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT)
|
.withParentEntityKey(entityKey)
|
||||||
.withParentEntityKey(entityKey)
|
.create())
|
||||||
.withSelect(
|
|
||||||
attrTable::getSelection,
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
PageAction::applySingleSelectionAsEntityKey,
|
pageContext,
|
||||||
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT,
|
||||||
.publishIf(() -> attrTable.hasAnyContent())
|
ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_SET_DEFAULT,
|
||||||
|
ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_REMOVE_VIEW,
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_SET_DEFAULT)
|
ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_ATTACH_DEFAULT_VIEW))
|
||||||
.withParentEntityKey(entityKey)
|
|
||||||
.withSelect(
|
.compose(pageContext.copyOf(content));
|
||||||
attrTable::getSelection,
|
|
||||||
action -> this.resetToDefaults(action, attrTable),
|
pageActionBuilder
|
||||||
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
|
||||||
.noEventPropagation()
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_EDIT)
|
||||||
.publishIf(() -> attrTable.hasAnyContent())
|
.withParentEntityKey(entityKey)
|
||||||
|
.withSelect(
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_REMOVE_VIEW)
|
attrTable::getSelection,
|
||||||
.withParentEntityKey(entityKey)
|
PageAction::applySingleSelectionAsEntityKey,
|
||||||
.withSelect(
|
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
||||||
attrTable::getSelection,
|
.publishIf(attrTable::hasAnyContent, false)
|
||||||
action -> this.removeFormView(action, attrTable),
|
|
||||||
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_SET_DEFAULT)
|
||||||
.noEventPropagation()
|
.withParentEntityKey(entityKey)
|
||||||
.publishIf(() -> attrTable.hasAnyContent())
|
.withSelect(
|
||||||
|
attrTable::getSelection,
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_ATTACH_DEFAULT_VIEW)
|
action -> this.resetToDefaults(action, attrTable),
|
||||||
.withParentEntityKey(entityKey)
|
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
||||||
.withSelect(
|
.noEventPropagation()
|
||||||
attrTable::getSelection,
|
.publishIf(attrTable::hasAnyContent, false)
|
||||||
action -> this.attachView(action, attrTable),
|
|
||||||
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_REMOVE_VIEW)
|
||||||
.noEventPropagation()
|
.withParentEntityKey(entityKey)
|
||||||
.publishIf(() -> attrTable.hasAnyContent());
|
.withSelect(
|
||||||
}
|
attrTable::getSelection,
|
||||||
|
action -> this.removeFormView(action, attrTable),
|
||||||
pageActionBuilder
|
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
||||||
|
.noEventPropagation()
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_NEW)
|
.publishIf(attrTable::hasAnyContent, false)
|
||||||
.publishIf(() -> writeGrant && isReadonly)
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_ATTR_LIST_ATTACH_DEFAULT_VIEW)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_MODIFY)
|
.withParentEntityKey(entityKey)
|
||||||
.withEntityKey(entityKey)
|
.withSelect(
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
attrTable::getSelection,
|
||||||
|
action -> this.attachView(action, attrTable),
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CREATE_CONFIG)
|
EMPTY_ATTRIBUTE_SELECTION_TEXT_KEY)
|
||||||
.withEntityKey(entityKey)
|
.noEventPropagation()
|
||||||
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
.publishIf(attrTable::hasAnyContent, false);
|
||||||
this.pageService,
|
}
|
||||||
pageContext
|
|
||||||
.withAttribute(
|
pageActionBuilder
|
||||||
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
|
||||||
Constants.TRUE_STRING)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_NEW)
|
||||||
.withAttribute(
|
.publishIf(() -> writeGrant && isReadonly)
|
||||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
|
||||||
Constants.FALSE_STRING)))
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_MODIFY)
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
.withEntityKey(entityKey)
|
||||||
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_SAVE)
|
|
||||||
.withEntityKey(entityKey)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CREATE_CONFIG)
|
||||||
.withExec(formHandle::processFormSave)
|
.withEntityKey(entityKey)
|
||||||
.ignoreMoveAwayFromEdit()
|
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
||||||
.publishIf(() -> !isReadonly)
|
this.pageService,
|
||||||
|
pageContext
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CANCEL_MODIFY)
|
.withAttribute(
|
||||||
.withEntityKey(entityKey)
|
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
||||||
.withExec(this.pageService.backToCurrentFunction())
|
Constants.TRUE_STRING)
|
||||||
.publishIf(() -> !isReadonly);
|
.withAttribute(
|
||||||
|
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||||
}
|
Constants.FALSE_STRING)))
|
||||||
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
private String getAttributeName(final TemplateAttribute attribute) {
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_SAVE)
|
||||||
final String name = this.i18nSupport.getText(
|
.withEntityKey(entityKey)
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.getName(),
|
.withExec(formHandle::processFormSave)
|
||||||
"");
|
.ignoreMoveAwayFromEdit()
|
||||||
if (StringUtils.isNotBlank(name)) {
|
.publishIf(() -> !isReadonly)
|
||||||
return attribute.getName() + " (" + name + ")";
|
|
||||||
} else {
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_CANCEL_MODIFY)
|
||||||
return attribute.getName();
|
.withEntityKey(entityKey)
|
||||||
}
|
.withExec(this.pageService.backToCurrentFunction())
|
||||||
}
|
.publishIf(() -> !isReadonly);
|
||||||
|
|
||||||
private final PageAction resetToDefaults(
|
}
|
||||||
final PageAction action,
|
|
||||||
final EntityTable<TemplateAttribute> attrTable) {
|
private String getAttributeName(final TemplateAttribute attribute) {
|
||||||
|
|
||||||
final PageAction resetToDefaults = this.examConfigurationService.resetToDefaults(action);
|
final String name = this.i18nSupport.getText(
|
||||||
// reload the list
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.getName(),
|
||||||
attrTable.applyFilter();
|
"");
|
||||||
return resetToDefaults;
|
if (StringUtils.isNotBlank(name)) {
|
||||||
}
|
return attribute.getName() + " (" + name + ")";
|
||||||
|
} else {
|
||||||
private final PageAction removeFormView(
|
return attribute.getName();
|
||||||
final PageAction action,
|
}
|
||||||
final EntityTable<TemplateAttribute> attrTable) {
|
}
|
||||||
|
|
||||||
final PageAction removeFormView = this.examConfigurationService.removeFromView(action);
|
private PageAction resetToDefaults(
|
||||||
// reload the list
|
final PageAction action,
|
||||||
attrTable.applyFilter();
|
final EntityTable<TemplateAttribute> attrTable) {
|
||||||
return removeFormView;
|
|
||||||
}
|
final PageAction resetToDefaults = this.examConfigurationService.resetToDefaults(action);
|
||||||
|
// reload the list
|
||||||
private final PageAction attachView(
|
attrTable.applyFilter();
|
||||||
final PageAction action,
|
return resetToDefaults;
|
||||||
final EntityTable<TemplateAttribute> attrTable) {
|
}
|
||||||
|
|
||||||
final PageAction attachView = this.examConfigurationService.attachToDefaultView(action);
|
private PageAction removeFormView(
|
||||||
// reload the list
|
final PageAction action,
|
||||||
attrTable.applyFilter();
|
final EntityTable<TemplateAttribute> attrTable) {
|
||||||
return attachView;
|
|
||||||
}
|
final PageAction removeFormView = this.examConfigurationService.removeFromView(action);
|
||||||
|
// reload the list
|
||||||
}
|
attrTable.applyFilter();
|
||||||
|
return removeFormView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PageAction attachView(
|
||||||
|
final PageAction action,
|
||||||
|
final EntityTable<TemplateAttribute> attrTable) {
|
||||||
|
|
||||||
|
final PageAction attachView = this.examConfigurationService.attachToDefaultView(action);
|
||||||
|
// reload the list
|
||||||
|
attrTable.applyFilter();
|
||||||
|
return attachView;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,155 +1,159 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodePage;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodePage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class ConfigTemplateList implements TemplateComposer {
|
public class ConfigTemplateList implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION =
|
||||||
new LocTextKey("sebserver.examconfig.list.action.no.modify.privilege");
|
new LocTextKey("sebserver.examconfig.list.action.no.modify.privilege");
|
||||||
private static final LocTextKey TITLE_TEMPLATE_TEXT_KEY =
|
private static final LocTextKey TITLE_TEMPLATE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.list.title");
|
new LocTextKey("sebserver.configtemplate.list.title");
|
||||||
private static final LocTextKey EMPTY_TEMPLATE_LIST_TEXT_KEY =
|
private static final LocTextKey EMPTY_TEMPLATE_LIST_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.list.empty");
|
new LocTextKey("sebserver.configtemplate.list.empty");
|
||||||
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.column.institution");
|
new LocTextKey("sebserver.examconfig.list.column.institution");
|
||||||
private static final LocTextKey NAME_TEXT_KEY =
|
private static final LocTextKey NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.column.name");
|
new LocTextKey("sebserver.examconfig.list.column.name");
|
||||||
private static final LocTextKey DESCRIPTION_TEXT_KEY =
|
private static final LocTextKey DESCRIPTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.column.description");
|
new LocTextKey("sebserver.examconfig.list.column.description");
|
||||||
private static final LocTextKey EMPTY_TEMPLATE_SELECTION_TEXT_KEY =
|
private static final LocTextKey EMPTY_TEMPLATE_SELECTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.configtemplate.info.pleaseSelect");
|
new LocTextKey("sebserver.configtemplate.info.pleaseSelect");
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final ResourceService resourceService;
|
private final ResourceService resourceService;
|
||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
|
|
||||||
private final TableFilterAttribute institutionFilter;
|
private final TableFilterAttribute institutionFilter;
|
||||||
private final TableFilterAttribute nameFilter =
|
private final TableFilterAttribute nameFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
||||||
private final TableFilterAttribute descFilter =
|
private final TableFilterAttribute descFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, ConfigurationNode.FILTER_ATTR_DESCRIPTION);
|
new TableFilterAttribute(CriteriaType.TEXT, ConfigurationNode.FILTER_ATTR_DESCRIPTION);
|
||||||
|
|
||||||
protected ConfigTemplateList(
|
protected ConfigTemplateList(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser,
|
final CurrentUser currentUser,
|
||||||
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.resourceService = pageService.getResourceService();
|
this.resourceService = pageService.getResourceService();
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
|
|
||||||
this.institutionFilter = new TableFilterAttribute(
|
this.institutionFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
Entity.FILTER_ATTR_INSTITUTION,
|
Entity.FILTER_ATTR_INSTITUTION,
|
||||||
this.resourceService::institutionResource);
|
this.resourceService::institutionResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
TITLE_TEMPLATE_TEXT_KEY);
|
TITLE_TEMPLATE_TEXT_KEY);
|
||||||
|
|
||||||
final boolean isSEBAdmin = this.currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
final boolean isSEBAdmin = this.currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||||
final PageActionBuilder pageActionBuilder =
|
final PageActionBuilder pageActionBuilder =
|
||||||
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
||||||
|
|
||||||
final EntityTable<ConfigurationNode> templateTable =
|
final EntityTable<ConfigurationNode> templateTable =
|
||||||
this.pageService.entityTableBuilder(
|
this.pageService.entityTableBuilder(
|
||||||
TITLE_TEMPLATE_TEXT_KEY.name,
|
TITLE_TEMPLATE_TEXT_KEY.name,
|
||||||
this.restService.getRestCall(GetExamConfigNodePage.class))
|
this.restService.getRestCall(GetExamConfigNodePage.class))
|
||||||
.withStaticFilter(
|
.withStaticFilter(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
||||||
ConfigurationType.TEMPLATE.name())
|
ConfigurationType.TEMPLATE.name())
|
||||||
.withEmptyMessage(EMPTY_TEMPLATE_LIST_TEXT_KEY)
|
.withEmptyMessage(EMPTY_TEMPLATE_LIST_TEXT_KEY)
|
||||||
.withPaging(this.pageSize)
|
.withPaging(this.pageSize)
|
||||||
.withColumnIf(
|
.withColumnIf(
|
||||||
() -> isSEBAdmin,
|
() -> isSEBAdmin,
|
||||||
() -> new ColumnDefinition<>(
|
() -> new ColumnDefinition<>(
|
||||||
Domain.LMS_SETUP.ATTR_INSTITUTION_ID,
|
Domain.LMS_SETUP.ATTR_INSTITUTION_ID,
|
||||||
INSTITUTION_TEXT_KEY,
|
INSTITUTION_TEXT_KEY,
|
||||||
this.resourceService::localizedExamConfigInstitutionName)
|
this.resourceService::localizedExamConfigInstitutionName)
|
||||||
.withFilter(this.institutionFilter)
|
.withFilter(this.institutionFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
||||||
NAME_TEXT_KEY,
|
NAME_TEXT_KEY,
|
||||||
ConfigurationNode::getName)
|
ConfigurationNode::getName)
|
||||||
.withFilter(this.nameFilter)
|
.withFilter(this.nameFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
||||||
DESCRIPTION_TEXT_KEY,
|
DESCRIPTION_TEXT_KEY,
|
||||||
ConfigurationNode::getDescription)
|
ConfigurationNode::getDescription)
|
||||||
.withFilter(this.descFilter)
|
.withFilter(this.descFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withDefaultAction(pageActionBuilder
|
.withDefaultAction(pageActionBuilder
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST)
|
||||||
.create())
|
.create())
|
||||||
.compose(pageContext.copyOf(content));
|
|
||||||
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
final GrantCheck examConfigGrant = this.currentUser.grantCheck(EntityType.CONFIGURATION_NODE);
|
pageContext,
|
||||||
pageActionBuilder
|
ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST,
|
||||||
// Exam Configuration template actions...
|
ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_MODIFY_FROM_LIST))
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_NEW)
|
|
||||||
.publishIf(examConfigGrant::iw)
|
.compose(pageContext.copyOf(content));
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST)
|
final GrantCheck examConfigGrant = this.currentUser.grantCheck(EntityType.CONFIGURATION_NODE);
|
||||||
.withSelect(templateTable::getSelection, PageAction::applySingleSelectionAsEntityKey,
|
pageActionBuilder
|
||||||
EMPTY_TEMPLATE_SELECTION_TEXT_KEY)
|
// Exam Configuration template actions...
|
||||||
.publishIf(() -> templateTable.hasAnyContent())
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_NEW)
|
||||||
|
.publishIf(examConfigGrant::iw)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_MODIFY_FROM_LIST)
|
|
||||||
.withSelect(
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_VIEW_FROM_LIST)
|
||||||
templateTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
.withSelect(templateTable::getSelection, PageAction::applySingleSelectionAsEntityKey,
|
||||||
PageAction::applySingleSelectionAsEntityKey, EMPTY_TEMPLATE_SELECTION_TEXT_KEY)
|
EMPTY_TEMPLATE_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> examConfigGrant.im() && templateTable.hasAnyContent());
|
.publishIf(templateTable::hasAnyContent, false)
|
||||||
|
|
||||||
}
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_TEMPLATE_MODIFY_FROM_LIST)
|
||||||
|
.withSelect(
|
||||||
}
|
templateTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION),
|
||||||
|
PageAction::applySingleSelectionAsEntityKey, EMPTY_TEMPLATE_SELECTION_TEXT_KEY)
|
||||||
|
.publishIf(() -> examConfigGrant.im() && templateTable.hasAnyContent(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,172 +1,167 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.DefaultPageLayout;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.DefaultPageLayout;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.DeactivateInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class InstitutionForm implements TemplateComposer {
|
public class InstitutionForm implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey TITLE_TEXT_KEY =
|
private static final LocTextKey TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.form.title");
|
new LocTextKey("sebserver.institution.form.title");
|
||||||
private static final LocTextKey NEW_TITLE_TEXT_KEY =
|
private static final LocTextKey NEW_TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.form.title.new");
|
new LocTextKey("sebserver.institution.form.title.new");
|
||||||
|
|
||||||
private static final LocTextKey FORM_LOGO_IMAGE_TEXT_KEY =
|
private static final LocTextKey FORM_LOGO_IMAGE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.form.logoImage");
|
new LocTextKey("sebserver.institution.form.logoImage");
|
||||||
private static final LocTextKey FORM_URL_SUFFIX_TEXT_KEY =
|
private static final LocTextKey FORM_URL_SUFFIX_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.form.urlSuffix");
|
new LocTextKey("sebserver.institution.form.urlSuffix");
|
||||||
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.form.name");
|
new LocTextKey("sebserver.institution.form.name");
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
|
|
||||||
protected InstitutionForm(
|
protected InstitutionForm(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser) {
|
final CurrentUser currentUser) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
|
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
final boolean isNew = entityKey == null;
|
final boolean isNew = entityKey == null;
|
||||||
// get data or create new. Handle error if happen
|
// get data or create new. Handle error if happen
|
||||||
final Institution institution = (isNew)
|
final Institution institution = (isNew)
|
||||||
? Institution.createNew()
|
? Institution.createNew()
|
||||||
: this.restService
|
: this.restService
|
||||||
.getBuilder(GetInstitution.class)
|
.getBuilder(GetInstitution.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
.call()
|
.call()
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.INSTITUTION, error))
|
.onError(error -> pageContext.notifyLoadError(EntityType.INSTITUTION, error))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final EntityGrantCheck instGrant = this.currentUser.entityGrantCheck(institution);
|
final EntityGrantCheck instGrant = this.currentUser.entityGrantCheck(institution);
|
||||||
final boolean writeGrant = instGrant.w();
|
final boolean writeGrant = instGrant.w();
|
||||||
final boolean modifyGrant = instGrant.m();
|
final boolean modifyGrant = instGrant.m();
|
||||||
final boolean isReadonly = pageContext.isReadonly();
|
final boolean isReadonly = pageContext.isReadonly();
|
||||||
|
|
||||||
// new PageContext with actual EntityKey
|
// new PageContext with actual EntityKey
|
||||||
final PageContext formContext = pageContext.withEntityKey(institution.getEntityKey());
|
final PageContext formContext = pageContext.withEntityKey(institution.getEntityKey());
|
||||||
|
|
||||||
// the default page layout with interactive title
|
// the default page layout with interactive title
|
||||||
final LocTextKey titleKey = isNew
|
final LocTextKey titleKey = isNew
|
||||||
? NEW_TITLE_TEXT_KEY
|
? NEW_TITLE_TEXT_KEY
|
||||||
: TITLE_TEXT_KEY;
|
: TITLE_TEXT_KEY;
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
formContext.getParent(),
|
formContext.getParent(),
|
||||||
titleKey);
|
titleKey);
|
||||||
|
|
||||||
// The Institution form
|
// The Institution form
|
||||||
final FormHandle<Institution> formHandle = this.pageService.formBuilder(
|
final FormHandle<Institution> formHandle = this.pageService.formBuilder(
|
||||||
formContext.copyOf(content))
|
formContext.copyOf(content))
|
||||||
.readonly(isReadonly)
|
.readonly(isReadonly)
|
||||||
.putStaticValueIf(() -> !isNew,
|
.putStaticValueIf(() -> !isNew,
|
||||||
Domain.INSTITUTION.ATTR_ID,
|
Domain.INSTITUTION.ATTR_ID,
|
||||||
institution.getModelId())
|
institution.getModelId())
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
Domain.INSTITUTION.ATTR_NAME,
|
Domain.INSTITUTION.ATTR_NAME,
|
||||||
FORM_NAME_TEXT_KEY,
|
FORM_NAME_TEXT_KEY,
|
||||||
institution.name)
|
institution.name)
|
||||||
.mandatory(!isReadonly))
|
.mandatory(!isReadonly))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
Domain.INSTITUTION.ATTR_URL_SUFFIX,
|
Domain.INSTITUTION.ATTR_URL_SUFFIX,
|
||||||
FORM_URL_SUFFIX_TEXT_KEY,
|
FORM_URL_SUFFIX_TEXT_KEY,
|
||||||
institution.urlSuffix))
|
institution.urlSuffix))
|
||||||
.addField(FormBuilder.imageUpload(
|
.addField(FormBuilder.imageUpload(
|
||||||
Domain.INSTITUTION.ATTR_LOGO_IMAGE,
|
Domain.INSTITUTION.ATTR_LOGO_IMAGE,
|
||||||
FORM_LOGO_IMAGE_TEXT_KEY,
|
FORM_LOGO_IMAGE_TEXT_KEY,
|
||||||
institution.logoImage)
|
institution.logoImage)
|
||||||
.withMaxWidth(DefaultPageLayout.LOGO_IMAGE_MAX_WIDTH)
|
.withMaxWidth(DefaultPageLayout.LOGO_IMAGE_MAX_WIDTH)
|
||||||
.withMaxHeight(DefaultPageLayout.LOGO_IMAGE_MAX_HEIGHT))
|
.withMaxHeight(DefaultPageLayout.LOGO_IMAGE_MAX_HEIGHT))
|
||||||
.buildFor((isNew)
|
.buildFor((isNew)
|
||||||
? this.restService.getRestCall(NewInstitution.class)
|
? this.restService.getRestCall(NewInstitution.class)
|
||||||
: this.restService.getRestCall(SaveInstitution.class));
|
: this.restService.getRestCall(SaveInstitution.class));
|
||||||
|
|
||||||
// propagate content actions to action-pane
|
// propagate content actions to action-pane
|
||||||
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
||||||
|
|
||||||
.newAction(ActionDefinition.INSTITUTION_NEW)
|
.newAction(ActionDefinition.INSTITUTION_NEW)
|
||||||
.publishIf(() -> writeGrant && isReadonly)
|
.publishIf(() -> writeGrant && isReadonly)
|
||||||
|
|
||||||
// Removed as discussed in SEBSERV-52
|
.newAction(ActionDefinition.INSTITUTION_MODIFY)
|
||||||
// .newAction(ActionDefinition.USER_ACCOUNT_NEW)
|
.withEntityKey(entityKey)
|
||||||
// .withParentEntityKey(entityKey)
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
// .publishIf(() -> userWriteGrant && isReadonly && institution.isActive())
|
|
||||||
|
.newAction(ActionDefinition.INSTITUTION_DEACTIVATE)
|
||||||
.newAction(ActionDefinition.INSTITUTION_MODIFY)
|
.withEntityKey(entityKey)
|
||||||
.withEntityKey(entityKey)
|
.withSimpleRestCall(this.restService, DeactivateInstitution.class)
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
.withConfirm(this.pageService.confirmDeactivation(institution))
|
||||||
|
.publishIf(() -> writeGrant && isReadonly && institution.isActive())
|
||||||
.newAction(ActionDefinition.INSTITUTION_DEACTIVATE)
|
|
||||||
.withEntityKey(entityKey)
|
.newAction(ActionDefinition.INSTITUTION_ACTIVATE)
|
||||||
.withSimpleRestCall(this.restService, DeactivateInstitution.class)
|
.withEntityKey(entityKey)
|
||||||
.withConfirm(this.pageService.confirmDeactivation(institution))
|
.withSimpleRestCall(this.restService, ActivateInstitution.class)
|
||||||
.publishIf(() -> writeGrant && isReadonly && institution.isActive())
|
.publishIf(() -> writeGrant && isReadonly && !institution.isActive())
|
||||||
|
|
||||||
.newAction(ActionDefinition.INSTITUTION_ACTIVATE)
|
.newAction(ActionDefinition.INSTITUTION_SAVE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withSimpleRestCall(this.restService, ActivateInstitution.class)
|
.withExec(formHandle::processFormSave)
|
||||||
.publishIf(() -> writeGrant && isReadonly && !institution.isActive())
|
.ignoreMoveAwayFromEdit()
|
||||||
|
.publishIf(() -> !isReadonly)
|
||||||
.newAction(ActionDefinition.INSTITUTION_SAVE)
|
|
||||||
.withEntityKey(entityKey)
|
.newAction(ActionDefinition.INSTITUTION_SAVE_AND_ACTIVATE)
|
||||||
.withExec(formHandle::processFormSave)
|
.withEntityKey(entityKey)
|
||||||
.ignoreMoveAwayFromEdit()
|
.withExec(formHandle::saveAndActivate)
|
||||||
.publishIf(() -> !isReadonly)
|
.ignoreMoveAwayFromEdit()
|
||||||
|
.publishIf(() -> !isReadonly && !institution.isActive())
|
||||||
.newAction(ActionDefinition.INSTITUTION_SAVE_AND_ACTIVATE)
|
|
||||||
.withEntityKey(entityKey)
|
.newAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY)
|
||||||
.withExec(formHandle::saveAndActivate)
|
.withEntityKey(entityKey)
|
||||||
.ignoreMoveAwayFromEdit()
|
.withExec(this.pageService.backToCurrentFunction())
|
||||||
.publishIf(() -> !isReadonly && !institution.isActive())
|
.publishIf(() -> !isReadonly);
|
||||||
|
}
|
||||||
.newAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY)
|
|
||||||
.withEntityKey(entityKey)
|
}
|
||||||
.withExec(this.pageService.backToCurrentFunction())
|
|
||||||
.publishIf(() -> !isReadonly);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,158 +1,158 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionPage;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionPage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class InstitutionList implements TemplateComposer {
|
public class InstitutionList implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
|
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.list.empty");
|
new LocTextKey("sebserver.institution.list.empty");
|
||||||
private static final LocTextKey TITLE_TEXT_KEY =
|
private static final LocTextKey TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.list.title");
|
new LocTextKey("sebserver.institution.list.title");
|
||||||
private static final LocTextKey NAME_TEXT_KEY =
|
private static final LocTextKey NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.list.column.name");
|
new LocTextKey("sebserver.institution.list.column.name");
|
||||||
private static final LocTextKey URL_TEXT_KEY =
|
private static final LocTextKey URL_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.list.column.urlSuffix");
|
new LocTextKey("sebserver.institution.list.column.urlSuffix");
|
||||||
private static final LocTextKey ACTIVE_TEXT_KEY =
|
private static final LocTextKey ACTIVE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.list.column.active");
|
new LocTextKey("sebserver.institution.list.column.active");
|
||||||
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.institution.info.pleaseSelect");
|
new LocTextKey("sebserver.institution.info.pleaseSelect");
|
||||||
|
|
||||||
private final TableFilterAttribute nameFilter =
|
private final TableFilterAttribute nameFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
||||||
private final TableFilterAttribute urlSuffixFilter =
|
private final TableFilterAttribute urlSuffixFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, Institution.FILTER_ATTR_URL_SUFFIX);
|
new TableFilterAttribute(CriteriaType.TEXT, Institution.FILTER_ATTR_URL_SUFFIX);
|
||||||
private final TableFilterAttribute activityFilter;
|
private final TableFilterAttribute activityFilter;
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
|
|
||||||
protected InstitutionList(
|
protected InstitutionList(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser,
|
final CurrentUser currentUser,
|
||||||
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
|
|
||||||
this.activityFilter = new TableFilterAttribute(
|
this.activityFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
Institution.FILTER_ATTR_ACTIVE,
|
Institution.FILTER_ATTR_ACTIVE,
|
||||||
StringUtils.EMPTY,
|
StringUtils.EMPTY,
|
||||||
this.pageService.getResourceService()::activityResources);
|
this.pageService.getResourceService()::activityResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final Composite content = this.pageService.getWidgetFactory().defaultPageLayout(
|
final Composite content = this.pageService.getWidgetFactory().defaultPageLayout(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
TITLE_TEXT_KEY);
|
TITLE_TEXT_KEY);
|
||||||
|
|
||||||
final PageActionBuilder pageActionBuilder =
|
final PageActionBuilder pageActionBuilder =
|
||||||
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
||||||
|
|
||||||
// table
|
// table
|
||||||
final EntityTable<Institution> table =
|
final EntityTable<Institution> table =
|
||||||
this.pageService.entityTableBuilder(this.restService.getRestCall(GetInstitutionPage.class))
|
this.pageService.entityTableBuilder(this.restService.getRestCall(GetInstitutionPage.class))
|
||||||
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
|
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
|
||||||
.withPaging(this.pageSize)
|
.withPaging(this.pageSize)
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.INSTITUTION.ATTR_NAME,
|
Domain.INSTITUTION.ATTR_NAME,
|
||||||
NAME_TEXT_KEY,
|
NAME_TEXT_KEY,
|
||||||
Institution::getName)
|
Institution::getName)
|
||||||
.sortable()
|
.sortable()
|
||||||
.withFilter(this.nameFilter))
|
.withFilter(this.nameFilter))
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.INSTITUTION.ATTR_URL_SUFFIX,
|
Domain.INSTITUTION.ATTR_URL_SUFFIX,
|
||||||
URL_TEXT_KEY,
|
URL_TEXT_KEY,
|
||||||
Institution::getUrlSuffix)
|
Institution::getUrlSuffix)
|
||||||
.sortable()
|
.sortable()
|
||||||
.withFilter(this.urlSuffixFilter))
|
.withFilter(this.urlSuffixFilter))
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.INSTITUTION.ATTR_ACTIVE,
|
Domain.INSTITUTION.ATTR_ACTIVE,
|
||||||
ACTIVE_TEXT_KEY,
|
ACTIVE_TEXT_KEY,
|
||||||
this.pageService.getResourceService().<Institution> localizedActivityFunction())
|
this.pageService.getResourceService().<Institution> localizedActivityFunction())
|
||||||
.sortable()
|
.sortable()
|
||||||
.withFilter(this.activityFilter))
|
.withFilter(this.activityFilter))
|
||||||
.withDefaultAction(pageActionBuilder
|
.withDefaultAction(pageActionBuilder
|
||||||
.newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
|
.newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
|
||||||
.create())
|
.create())
|
||||||
.withSelectionListener(this.pageService.getSelectionPublisher(
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY,
|
ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY,
|
||||||
ActionDefinition.INSTITUTION_ACTIVATE,
|
ActionDefinition.INSTITUTION_ACTIVATE,
|
||||||
ActionDefinition.INSTITUTION_DEACTIVATE,
|
ActionDefinition.INSTITUTION_DEACTIVATE,
|
||||||
pageContext,
|
pageContext,
|
||||||
ActionDefinition.INSTITUTION_VIEW_FROM_LIST,
|
ActionDefinition.INSTITUTION_VIEW_FROM_LIST,
|
||||||
ActionDefinition.INSTITUTION_MODIFY_FROM_LIST,
|
ActionDefinition.INSTITUTION_MODIFY_FROM_LIST,
|
||||||
ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY))
|
ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY))
|
||||||
.compose(pageContext.copyOf(content));
|
.compose(pageContext.copyOf(content));
|
||||||
|
|
||||||
// propagate content actions to action-pane
|
// propagate content actions to action-pane
|
||||||
final GrantCheck instGrant = this.currentUser.grantCheck(EntityType.INSTITUTION);
|
final GrantCheck instGrant = this.currentUser.grantCheck(EntityType.INSTITUTION);
|
||||||
|
|
||||||
pageActionBuilder
|
pageActionBuilder
|
||||||
|
|
||||||
.newAction(ActionDefinition.INSTITUTION_NEW)
|
.newAction(ActionDefinition.INSTITUTION_NEW)
|
||||||
.publishIf(instGrant::w)
|
.publishIf(instGrant::w)
|
||||||
|
|
||||||
.newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
|
.newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
|
||||||
.withSelect(
|
.withSelect(
|
||||||
table::getSelection,
|
table::getSelection,
|
||||||
PageAction::applySingleSelectionAsEntityKey,
|
PageAction::applySingleSelectionAsEntityKey,
|
||||||
EMPTY_SELECTION_TEXT_KEY)
|
EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> table.hasAnyContent(), false)
|
.publishIf(table::hasAnyContent, false)
|
||||||
|
|
||||||
.newAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST)
|
.newAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST)
|
||||||
.withSelect(
|
.withSelect(
|
||||||
table::getSelection,
|
table::getSelection,
|
||||||
PageAction::applySingleSelectionAsEntityKey,
|
PageAction::applySingleSelectionAsEntityKey,
|
||||||
EMPTY_SELECTION_TEXT_KEY)
|
EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> instGrant.m() && table.hasAnyContent(), false)
|
.publishIf(() -> instGrant.m() && table.hasAnyContent(), false)
|
||||||
|
|
||||||
.newAction(ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY)
|
.newAction(ActionDefinition.INSTITUTION_TOGGLE_ACTIVITY)
|
||||||
.withExec(this.pageService.activationToggleActionFunction(table, EMPTY_SELECTION_TEXT_KEY))
|
.withExec(this.pageService.activationToggleActionFunction(table, EMPTY_SELECTION_TEXT_KEY))
|
||||||
.withConfirm(this.pageService.confirmDeactivation(table))
|
.withConfirm(this.pageService.confirmDeactivation(table))
|
||||||
.publishIf(() -> instGrant.m() && table.hasAnyContent(), false);
|
.publishIf(() -> instGrant.m() && table.hasAnyContent(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,205 +1,211 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.rap.rwt.client.service.UrlLauncher;
|
import org.eclipse.rap.rwt.client.service.UrlLauncher;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService;
|
import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.download.SebClientConfigDownload;
|
import ch.ethz.seb.sebserver.gui.service.remote.download.SebClientConfigDownload;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.ActivateClientConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.ActivateClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.DeactivateClientConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.DeactivateClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.NewClientConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.NewClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.SaveClientConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.SaveClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class SebClientConfigForm implements TemplateComposer {
|
public class SebClientConfigForm implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey FORM_TITLE_NEW =
|
private static final LocTextKey FORM_TITLE_NEW =
|
||||||
new LocTextKey("sebserver.clientconfig.form.title.new");
|
new LocTextKey("sebserver.clientconfig.form.title.new");
|
||||||
private static final LocTextKey FORM_TITLE =
|
private static final LocTextKey FORM_TITLE =
|
||||||
new LocTextKey("sebserver.clientconfig.form.title");
|
new LocTextKey("sebserver.clientconfig.form.title");
|
||||||
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.form.name");
|
new LocTextKey("sebserver.clientconfig.form.name");
|
||||||
private static final LocTextKey FORM_FALLBACK_URL_TEXT_KEY =
|
private static final LocTextKey FORM_FALLBACK_URL_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.form.fallback-url");
|
new LocTextKey("sebserver.clientconfig.form.fallback-url");
|
||||||
private static final LocTextKey FORM_DATE_TEXT_KEY =
|
private static final LocTextKey FORM_DATE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.form.date");
|
new LocTextKey("sebserver.clientconfig.form.date");
|
||||||
private static final LocTextKey FORM_ENCRYPT_SECRET_TEXT_KEY =
|
private static final LocTextKey FORM_ENCRYPT_SECRET_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.form.encryptSecret");
|
new LocTextKey("sebserver.clientconfig.form.encryptSecret");
|
||||||
private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY =
|
private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.form.encryptSecret.confirm");
|
new LocTextKey("sebserver.clientconfig.form.encryptSecret.confirm");
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final DownloadService downloadService;
|
private final DownloadService downloadService;
|
||||||
private final String downloadFileName;
|
private final String downloadFileName;
|
||||||
|
|
||||||
protected SebClientConfigForm(
|
protected SebClientConfigForm(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser,
|
final CurrentUser currentUser,
|
||||||
final DownloadService downloadService,
|
final DownloadService downloadService,
|
||||||
@Value("${sebserver.gui.seb.client.config.download.filename}") final String downloadFileName) {
|
@Value("${sebserver.gui.seb.client.config.download.filename}") final String downloadFileName) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.downloadService = downloadService;
|
this.downloadService = downloadService;
|
||||||
this.downloadFileName = downloadFileName;
|
this.downloadFileName = downloadFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final I18nSupport i18nSupport = this.pageService.getI18nSupport();
|
final I18nSupport i18nSupport = this.pageService.getI18nSupport();
|
||||||
|
|
||||||
final UserInfo user = this.currentUser.get();
|
final UserInfo user = this.currentUser.get();
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
||||||
|
|
||||||
final boolean isNew = entityKey == null;
|
final boolean isNew = entityKey == null;
|
||||||
|
|
||||||
// get data or create new. Handle error if happen
|
// get data or create new. Handle error if happen
|
||||||
final SebClientConfig clientConfig = (isNew)
|
final SebClientConfig clientConfig = (isNew)
|
||||||
? SebClientConfig.createNew((parentEntityKey != null)
|
? SebClientConfig.createNew((parentEntityKey != null)
|
||||||
? Long.valueOf(parentEntityKey.modelId)
|
? Long.valueOf(parentEntityKey.modelId)
|
||||||
: user.institutionId)
|
: user.institutionId)
|
||||||
: this.restService
|
: this.restService
|
||||||
.getBuilder(GetClientConfig.class)
|
.getBuilder(GetClientConfig.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
.call()
|
.call()
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.SEB_CLIENT_CONFIGURATION, error))
|
.onError(error -> pageContext.notifyLoadError(EntityType.SEB_CLIENT_CONFIGURATION, error))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(clientConfig);
|
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(clientConfig);
|
||||||
final boolean writeGrant = entityGrant.w();
|
final boolean writeGrant = entityGrant.w();
|
||||||
final boolean modifyGrant = entityGrant.m();
|
final boolean modifyGrant = entityGrant.m();
|
||||||
final boolean isReadonly = pageContext.isReadonly();
|
final boolean isReadonly = pageContext.isReadonly();
|
||||||
|
|
||||||
// new PageContext with actual EntityKey
|
// new PageContext with actual EntityKey
|
||||||
final PageContext formContext = pageContext.withEntityKey(clientConfig.getEntityKey());
|
final PageContext formContext = pageContext.withEntityKey(clientConfig.getEntityKey());
|
||||||
|
|
||||||
// the default page layout with interactive title
|
// the default page layout with interactive title
|
||||||
final LocTextKey titleKey = (isNew)
|
final LocTextKey titleKey = (isNew)
|
||||||
? FORM_TITLE_NEW
|
? FORM_TITLE_NEW
|
||||||
: FORM_TITLE;
|
: FORM_TITLE;
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
formContext.getParent(),
|
formContext.getParent(),
|
||||||
titleKey);
|
titleKey);
|
||||||
|
|
||||||
// The SebClientConfig form
|
// The SebClientConfig form
|
||||||
final FormHandle<SebClientConfig> formHandle = this.pageService.formBuilder(
|
final FormHandle<SebClientConfig> formHandle = this.pageService.formBuilder(
|
||||||
formContext.copyOf(content))
|
formContext.copyOf(content))
|
||||||
.readonly(isReadonly)
|
.readonly(isReadonly)
|
||||||
.putStaticValueIf(() -> !isNew,
|
.putStaticValueIf(() -> !isNew,
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ID,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ID,
|
||||||
clientConfig.getModelId())
|
clientConfig.getModelId())
|
||||||
.putStaticValue(
|
.putStaticValue(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_INSTITUTION_ID,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_INSTITUTION_ID,
|
||||||
String.valueOf(clientConfig.getInstitutionId()))
|
String.valueOf(clientConfig.getInstitutionId()))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME,
|
||||||
FORM_NAME_TEXT_KEY,
|
FORM_NAME_TEXT_KEY,
|
||||||
clientConfig.name))
|
clientConfig.name))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
SebClientConfig.ATTR_FALLBACK_START_URL,
|
SebClientConfig.ATTR_FALLBACK_START_URL,
|
||||||
FORM_FALLBACK_URL_TEXT_KEY,
|
FORM_FALLBACK_URL_TEXT_KEY,
|
||||||
clientConfig.fallbackStartURL))
|
clientConfig.fallbackStartURL))
|
||||||
.addFieldIf(() -> !isNew,
|
.addFieldIf(() -> !isNew,
|
||||||
() -> FormBuilder.text(
|
() -> FormBuilder.text(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_DATE,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_DATE,
|
||||||
FORM_DATE_TEXT_KEY,
|
FORM_DATE_TEXT_KEY,
|
||||||
i18nSupport.formatDisplayDateWithTimeZone(clientConfig.date))
|
i18nSupport.formatDisplayDateWithTimeZone(clientConfig.date))
|
||||||
.readonly(true))
|
.readonly(true))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET,
|
||||||
FORM_ENCRYPT_SECRET_TEXT_KEY)
|
FORM_ENCRYPT_SECRET_TEXT_KEY)
|
||||||
.asPasswordField())
|
.asPasswordField())
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
SebClientConfig.ATTR_CONFIRM_ENCRYPT_SECRET,
|
SebClientConfig.ATTR_CONFIRM_ENCRYPT_SECRET,
|
||||||
FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY)
|
FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY)
|
||||||
.asPasswordField())
|
.asPasswordField())
|
||||||
.buildFor((isNew)
|
.buildFor((isNew)
|
||||||
? this.restService.getRestCall(NewClientConfig.class)
|
? this.restService.getRestCall(NewClientConfig.class)
|
||||||
: this.restService.getRestCall(SaveClientConfig.class));
|
: this.restService.getRestCall(SaveClientConfig.class));
|
||||||
|
|
||||||
final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class);
|
final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class);
|
||||||
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_NEW)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_NEW)
|
||||||
.publishIf(() -> writeGrant && isReadonly)
|
.publishIf(() -> writeGrant && isReadonly)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_EXPORT)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_EXPORT)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(action -> {
|
.withExec(action -> {
|
||||||
final String downloadURL = this.downloadService.createDownloadURL(
|
final String downloadURL = this.downloadService.createDownloadURL(
|
||||||
entityKey.modelId,
|
entityKey.modelId,
|
||||||
SebClientConfigDownload.class,
|
SebClientConfigDownload.class,
|
||||||
this.downloadFileName);
|
this.downloadFileName);
|
||||||
urlLauncher.openURL(downloadURL);
|
urlLauncher.openURL(downloadURL);
|
||||||
return action;
|
return action;
|
||||||
})
|
})
|
||||||
.publishIf(() -> writeGrant && isReadonly && clientConfig.isActive())
|
.publishIf(() -> writeGrant && isReadonly && clientConfig.isActive())
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_DEACTIVATE)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_DEACTIVATE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withSimpleRestCall(this.restService, DeactivateClientConfig.class)
|
.withSimpleRestCall(this.restService, DeactivateClientConfig.class)
|
||||||
.withConfirm(this.pageService.confirmDeactivation(clientConfig))
|
.withConfirm(this.pageService.confirmDeactivation(clientConfig))
|
||||||
.publishIf(() -> writeGrant && isReadonly && clientConfig.isActive())
|
.publishIf(() -> writeGrant && isReadonly && clientConfig.isActive())
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_ACTIVATE)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_ACTIVATE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withSimpleRestCall(this.restService, ActivateClientConfig.class)
|
.withSimpleRestCall(this.restService, ActivateClientConfig.class)
|
||||||
.publishIf(() -> writeGrant && isReadonly && !clientConfig.isActive())
|
.publishIf(() -> writeGrant && isReadonly && !clientConfig.isActive())
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_SAVE)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_SAVE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(formHandle::processFormSave)
|
.withExec(formHandle::processFormSave)
|
||||||
.ignoreMoveAwayFromEdit()
|
.ignoreMoveAwayFromEdit()
|
||||||
.publishIf(() -> !isReadonly)
|
.publishIf(() -> !isReadonly)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_CANCEL_MODIFY)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_SAVE_AND_ACTIVATE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(this.pageService.backToCurrentFunction())
|
.withExec(formHandle::saveAndActivate)
|
||||||
.publishIf(() -> !isReadonly);
|
.ignoreMoveAwayFromEdit()
|
||||||
}
|
.publishIf(() -> !isReadonly && !clientConfig.isActive())
|
||||||
|
|
||||||
}
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_CANCEL_MODIFY)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
|
.withExec(this.pageService.backToCurrentFunction())
|
||||||
|
.publishIf(() -> !isReadonly);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,182 +1,199 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfigPage;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfigPage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class SebClientConfigList implements TemplateComposer {
|
public class SebClientConfigList implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
||||||
new LocTextKey("sebserver.clientconfig.list.action.no.modify.privilege");
|
new LocTextKey("sebserver.clientconfig.list.action.no.modify.privilege");
|
||||||
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
|
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.list.empty");
|
new LocTextKey("sebserver.clientconfig.list.empty");
|
||||||
private static final LocTextKey TITLE_TEXT_KEY =
|
private static final LocTextKey TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.list.title");
|
new LocTextKey("sebserver.clientconfig.list.title");
|
||||||
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.list.column.institution");
|
new LocTextKey("sebserver.clientconfig.list.column.institution");
|
||||||
private static final LocTextKey NAME_TEXT_KEY =
|
private static final LocTextKey NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.list.column.name");
|
new LocTextKey("sebserver.clientconfig.list.column.name");
|
||||||
private static final LocTextKey ACTIVE_TEXT_KEY =
|
private static final LocTextKey ACTIVE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.list.column.active");
|
new LocTextKey("sebserver.clientconfig.list.column.active");
|
||||||
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.info.pleaseSelect");
|
new LocTextKey("sebserver.clientconfig.info.pleaseSelect");
|
||||||
|
|
||||||
private final TableFilterAttribute institutionFilter;
|
private final TableFilterAttribute institutionFilter;
|
||||||
private final TableFilterAttribute nameFilter =
|
private final TableFilterAttribute nameFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
||||||
private final TableFilterAttribute dateFilter =
|
private final TableFilterAttribute dateFilter =
|
||||||
new TableFilterAttribute(
|
new TableFilterAttribute(
|
||||||
CriteriaType.DATE,
|
CriteriaType.DATE,
|
||||||
SebClientConfig.FILTER_ATTR_CREATION_DATE,
|
SebClientConfig.FILTER_ATTR_CREATION_DATE,
|
||||||
DateTime.now(DateTimeZone.UTC)
|
DateTime.now(DateTimeZone.UTC)
|
||||||
.minusYears(1)
|
.minusYears(1)
|
||||||
.toString(Constants.DEFAULT_DATE_TIME_FORMAT));
|
.toString(Constants.DEFAULT_DATE_TIME_FORMAT));
|
||||||
private final TableFilterAttribute activityFilter;
|
private final TableFilterAttribute activityFilter;
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final ResourceService resourceService;
|
private final ResourceService resourceService;
|
||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
|
|
||||||
protected SebClientConfigList(
|
protected SebClientConfigList(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser,
|
final CurrentUser currentUser,
|
||||||
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.resourceService = pageService.getResourceService();
|
this.resourceService = pageService.getResourceService();
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
|
|
||||||
this.institutionFilter = new TableFilterAttribute(
|
this.institutionFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
Entity.FILTER_ATTR_INSTITUTION,
|
Entity.FILTER_ATTR_INSTITUTION,
|
||||||
this.resourceService::institutionResource);
|
this.resourceService::institutionResource);
|
||||||
|
|
||||||
this.activityFilter = new TableFilterAttribute(
|
this.activityFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
UserInfo.FILTER_ATTR_ACTIVE,
|
UserInfo.FILTER_ATTR_ACTIVE,
|
||||||
this.resourceService::activityResources);
|
this.resourceService::activityResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
|
|
||||||
final I18nSupport i18nSupport = this.pageService.getI18nSupport();
|
final I18nSupport i18nSupport = this.pageService.getI18nSupport();
|
||||||
final Composite content = this.pageService.getWidgetFactory().defaultPageLayout(
|
final Composite content = this.pageService.getWidgetFactory().defaultPageLayout(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
TITLE_TEXT_KEY);
|
TITLE_TEXT_KEY);
|
||||||
|
|
||||||
final boolean isSEBAdmin = this.currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
final boolean isSEBAdmin = this.currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||||
final PageActionBuilder pageActionBuilder =
|
final PageActionBuilder pageActionBuilder =
|
||||||
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
||||||
|
|
||||||
// table
|
// table
|
||||||
final EntityTable<SebClientConfig> table =
|
final EntityTable<SebClientConfig> table =
|
||||||
this.pageService.entityTableBuilder(this.restService.getRestCall(GetClientConfigPage.class))
|
this.pageService.entityTableBuilder(this.restService.getRestCall(GetClientConfigPage.class))
|
||||||
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
|
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
|
||||||
.withPaging(this.pageSize)
|
.withPaging(this.pageSize)
|
||||||
.withColumnIf(
|
.withColumnIf(
|
||||||
() -> isSEBAdmin,
|
() -> isSEBAdmin,
|
||||||
() -> new ColumnDefinition<>(
|
() -> new ColumnDefinition<>(
|
||||||
Domain.LMS_SETUP.ATTR_INSTITUTION_ID,
|
Domain.LMS_SETUP.ATTR_INSTITUTION_ID,
|
||||||
INSTITUTION_TEXT_KEY,
|
INSTITUTION_TEXT_KEY,
|
||||||
clientConfigInstitutionNameFunction(this.resourceService))
|
clientConfigInstitutionNameFunction(this.resourceService))
|
||||||
.withFilter(this.institutionFilter))
|
.withFilter(this.institutionFilter))
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_NAME,
|
||||||
NAME_TEXT_KEY,
|
NAME_TEXT_KEY,
|
||||||
SebClientConfig::getName)
|
SebClientConfig::getName)
|
||||||
.withFilter(this.nameFilter)
|
.withFilter(this.nameFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_DATE,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_DATE,
|
||||||
new LocTextKey(
|
new LocTextKey(
|
||||||
"sebserver.clientconfig.list.column.date",
|
"sebserver.clientconfig.list.column.date",
|
||||||
i18nSupport.getUsersTimeZoneTitleSuffix()),
|
i18nSupport.getUsersTimeZoneTitleSuffix()),
|
||||||
SebClientConfig::getDate)
|
SebClientConfig::getDate)
|
||||||
.withFilter(this.dateFilter)
|
.withFilter(this.dateFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE,
|
||||||
ACTIVE_TEXT_KEY,
|
ACTIVE_TEXT_KEY,
|
||||||
this.pageService.getResourceService().<SebClientConfig> localizedActivityFunction())
|
this.pageService.getResourceService().<SebClientConfig> localizedActivityFunction())
|
||||||
.withFilter(this.activityFilter)
|
.withFilter(this.activityFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withDefaultAction(pageActionBuilder
|
.withDefaultAction(pageActionBuilder
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_VIEW_FROM_LIST)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_VIEW_FROM_LIST)
|
||||||
.create())
|
.create())
|
||||||
.compose(pageContext.copyOf(content));
|
|
||||||
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
final GrantCheck clientConfigGrant = this.currentUser.grantCheck(EntityType.SEB_CLIENT_CONFIGURATION);
|
ActionDefinition.SEB_CLIENT_CONFIG_TOGGLE_ACTIVITY,
|
||||||
|
ActionDefinition.SEB_CLIENT_CONFIG_ACTIVATE,
|
||||||
pageActionBuilder
|
ActionDefinition.SEB_CLIENT_CONFIG_DEACTIVATE,
|
||||||
|
pageContext,
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_NEW)
|
ActionDefinition.SEB_CLIENT_CONFIG_VIEW_FROM_LIST,
|
||||||
.publishIf(clientConfigGrant::iw)
|
ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST,
|
||||||
|
ActionDefinition.SEB_CLIENT_CONFIG_TOGGLE_ACTIVITY))
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_VIEW_FROM_LIST)
|
|
||||||
.withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
.compose(pageContext.copyOf(content));
|
||||||
.publishIf(() -> table.hasAnyContent())
|
|
||||||
|
final GrantCheck clientConfigGrant = this.currentUser.grantCheck(EntityType.SEB_CLIENT_CONFIGURATION);
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST)
|
|
||||||
.withSelect(
|
pageActionBuilder
|
||||||
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
|
||||||
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_NEW)
|
||||||
.publishIf(() -> clientConfigGrant.im() && table.hasAnyContent());
|
.publishIf(clientConfigGrant::iw)
|
||||||
|
|
||||||
}
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_VIEW_FROM_LIST)
|
||||||
|
.withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
||||||
private static Function<SebClientConfig, String> clientConfigInstitutionNameFunction(
|
.publishIf(table::hasAnyContent, false)
|
||||||
final ResourceService resourceService) {
|
|
||||||
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST)
|
||||||
return config -> resourceService.getInstitutionNameFunction()
|
.withSelect(
|
||||||
.apply(String.valueOf(config.institutionId));
|
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
||||||
}
|
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
||||||
|
.publishIf(() -> clientConfigGrant.im() && table.hasAnyContent(), false)
|
||||||
}
|
|
||||||
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_TOGGLE_ACTIVITY)
|
||||||
|
.withExec(this.pageService.activationToggleActionFunction(table, EMPTY_SELECTION_TEXT_KEY))
|
||||||
|
.withConfirm(this.pageService.confirmDeactivation(table))
|
||||||
|
.publishIf(() -> clientConfigGrant.im() && table.hasAnyContent(), false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Function<SebClientConfig, String> clientConfigInstitutionNameFunction(
|
||||||
|
final ResourceService resourceService) {
|
||||||
|
|
||||||
|
return config -> resourceService.getInstitutionNameFunction()
|
||||||
|
.apply(String.valueOf(config.institutionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,174 +1,178 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodePage;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodePage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class SebExamConfigList implements TemplateComposer {
|
public class SebExamConfigList implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
||||||
new LocTextKey("sebserver.examconfig.list.action.no.modify.privilege");
|
new LocTextKey("sebserver.examconfig.list.action.no.modify.privilege");
|
||||||
private static final LocTextKey EMPTY_CONFIG_LIST_TEXT_KEY =
|
private static final LocTextKey EMPTY_CONFIG_LIST_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.empty");
|
new LocTextKey("sebserver.examconfig.list.empty");
|
||||||
private static final LocTextKey TITLE_CONFIGURATION_TEXT_KEY =
|
private static final LocTextKey TITLE_CONFIGURATION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.title");
|
new LocTextKey("sebserver.examconfig.list.title");
|
||||||
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.column.institution");
|
new LocTextKey("sebserver.examconfig.list.column.institution");
|
||||||
private static final LocTextKey NAME_TEXT_KEY =
|
private static final LocTextKey NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.column.name");
|
new LocTextKey("sebserver.examconfig.list.column.name");
|
||||||
private static final LocTextKey DESCRIPTION_TEXT_KEY =
|
private static final LocTextKey DESCRIPTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.column.description");
|
new LocTextKey("sebserver.examconfig.list.column.description");
|
||||||
private static final LocTextKey STATUS_TEXT_KEY =
|
private static final LocTextKey STATUS_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.column.status");
|
new LocTextKey("sebserver.examconfig.list.column.status");
|
||||||
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.info.pleaseSelect");
|
new LocTextKey("sebserver.examconfig.info.pleaseSelect");
|
||||||
|
|
||||||
private final TableFilterAttribute institutionFilter;
|
private final TableFilterAttribute institutionFilter;
|
||||||
private final TableFilterAttribute nameFilter =
|
private final TableFilterAttribute nameFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
||||||
private final TableFilterAttribute descFilter =
|
private final TableFilterAttribute descFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, ConfigurationNode.FILTER_ATTR_DESCRIPTION);
|
new TableFilterAttribute(CriteriaType.TEXT, ConfigurationNode.FILTER_ATTR_DESCRIPTION);
|
||||||
private final TableFilterAttribute statusFilter;
|
private final TableFilterAttribute statusFilter;
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final ResourceService resourceService;
|
private final ResourceService resourceService;
|
||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
|
|
||||||
protected SebExamConfigList(
|
protected SebExamConfigList(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser,
|
final CurrentUser currentUser,
|
||||||
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.resourceService = pageService.getResourceService();
|
this.resourceService = pageService.getResourceService();
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
|
|
||||||
this.institutionFilter = new TableFilterAttribute(
|
this.institutionFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
Entity.FILTER_ATTR_INSTITUTION,
|
Entity.FILTER_ATTR_INSTITUTION,
|
||||||
this.resourceService::institutionResource);
|
this.resourceService::institutionResource);
|
||||||
|
|
||||||
this.statusFilter = new TableFilterAttribute(
|
this.statusFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
ConfigurationNode.FILTER_ATTR_STATUS,
|
ConfigurationNode.FILTER_ATTR_STATUS,
|
||||||
this.resourceService::examConfigStatusResources);
|
this.resourceService::examConfigStatusResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
TITLE_CONFIGURATION_TEXT_KEY);
|
TITLE_CONFIGURATION_TEXT_KEY);
|
||||||
|
|
||||||
final boolean isSEBAdmin = this.currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
final boolean isSEBAdmin = this.currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||||
final PageActionBuilder pageActionBuilder =
|
final PageActionBuilder pageActionBuilder =
|
||||||
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
||||||
|
|
||||||
// exam configuration table
|
// exam configuration table
|
||||||
final EntityTable<ConfigurationNode> configTable =
|
final EntityTable<ConfigurationNode> configTable =
|
||||||
this.pageService.entityTableBuilder(this.restService.getRestCall(GetExamConfigNodePage.class))
|
this.pageService.entityTableBuilder(this.restService.getRestCall(GetExamConfigNodePage.class))
|
||||||
.withStaticFilter(
|
.withStaticFilter(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
||||||
ConfigurationType.EXAM_CONFIG.name())
|
ConfigurationType.EXAM_CONFIG.name())
|
||||||
.withEmptyMessage(EMPTY_CONFIG_LIST_TEXT_KEY)
|
.withEmptyMessage(EMPTY_CONFIG_LIST_TEXT_KEY)
|
||||||
.withPaging(this.pageSize)
|
.withPaging(this.pageSize)
|
||||||
.withColumnIf(
|
.withColumnIf(
|
||||||
() -> isSEBAdmin,
|
() -> isSEBAdmin,
|
||||||
() -> new ColumnDefinition<>(
|
() -> new ColumnDefinition<>(
|
||||||
Domain.LMS_SETUP.ATTR_INSTITUTION_ID,
|
Domain.LMS_SETUP.ATTR_INSTITUTION_ID,
|
||||||
INSTITUTION_TEXT_KEY,
|
INSTITUTION_TEXT_KEY,
|
||||||
this.resourceService::localizedExamConfigInstitutionName)
|
this.resourceService::localizedExamConfigInstitutionName)
|
||||||
.withFilter(this.institutionFilter)
|
.withFilter(this.institutionFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
||||||
NAME_TEXT_KEY,
|
NAME_TEXT_KEY,
|
||||||
ConfigurationNode::getName)
|
ConfigurationNode::getName)
|
||||||
.withFilter(this.nameFilter)
|
.withFilter(this.nameFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
||||||
DESCRIPTION_TEXT_KEY,
|
DESCRIPTION_TEXT_KEY,
|
||||||
ConfigurationNode::getDescription)
|
ConfigurationNode::getDescription)
|
||||||
.withFilter(this.descFilter)
|
.withFilter(this.descFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withColumn(new ColumnDefinition<ConfigurationNode>(
|
.withColumn(new ColumnDefinition<ConfigurationNode>(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
||||||
STATUS_TEXT_KEY,
|
STATUS_TEXT_KEY,
|
||||||
this.resourceService::localizedExamConfigStatusName)
|
this.resourceService::localizedExamConfigStatusName)
|
||||||
.withFilter(this.statusFilter)
|
.withFilter(this.statusFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
.withDefaultAction(pageActionBuilder
|
.withDefaultAction(pageActionBuilder
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
|
||||||
.create())
|
.create())
|
||||||
.compose(pageContext.copyOf(content));
|
|
||||||
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
final GrantCheck examConfigGrant = this.currentUser.grantCheck(EntityType.CONFIGURATION_NODE);
|
pageContext,
|
||||||
pageActionBuilder
|
ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST,
|
||||||
// Exam Configuration actions...
|
ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST))
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
|
||||||
.publishIf(examConfigGrant::iw)
|
.compose(pageContext.copyOf(content));
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
|
final GrantCheck examConfigGrant = this.currentUser.grantCheck(EntityType.CONFIGURATION_NODE);
|
||||||
.withSelect(configTable::getSelection, PageAction::applySingleSelectionAsEntityKey,
|
pageActionBuilder
|
||||||
EMPTY_SELECTION_TEXT_KEY)
|
// Exam Configuration actions...
|
||||||
.publishIf(() -> configTable.hasAnyContent())
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
||||||
|
.publishIf(examConfigGrant::iw)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST)
|
|
||||||
.withSelect(
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST)
|
||||||
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
.withSelect(configTable::getSelection, PageAction::applySingleSelectionAsEntityKey,
|
||||||
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent())
|
.publishIf(configTable::hasAnyContent, false)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST)
|
||||||
.withExec(SebExamConfigImportPopup.importFunction(this.pageService, true))
|
.withSelect(
|
||||||
.noEventPropagation()
|
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
||||||
.publishIf(() -> examConfigGrant.im())
|
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
||||||
|
.publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent(), false)
|
||||||
;
|
|
||||||
}
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_NEW_CONFIG)
|
||||||
|
.withExec(SebExamConfigImportPopup.importFunction(this.pageService, true))
|
||||||
}
|
.noEventPropagation()
|
||||||
|
.publishIf(examConfigGrant::im);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,413 +1,423 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.HashSet;
|
||||||
import java.util.function.Function;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
|
||||||
import org.eclipse.rap.rwt.client.service.UrlLauncher;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.rap.rwt.client.service.UrlLauncher;
|
||||||
import org.eclipse.swt.widgets.Text;
|
import org.eclipse.swt.SWT;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.springframework.stereotype.Component;
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import org.springframework.stereotype.Component;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.download.SebExamConfigPlaintextDownload;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMappingNames;
|
import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMappingsPage;
|
import ch.ethz.seb.sebserver.gui.service.remote.download.SebExamConfigPlaintextDownload;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ExportConfigKey;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMappingNames;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMappingsPage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ExportConfigKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig;
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
@Lazy
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
@Component
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
@GuiProfile
|
|
||||||
public class SebExamConfigPropForm implements TemplateComposer {
|
@Lazy
|
||||||
|
@Component
|
||||||
static final LocTextKey FORM_TITLE_NEW =
|
@GuiProfile
|
||||||
new LocTextKey("sebserver.examconfig.form.title.new");
|
public class SebExamConfigPropForm implements TemplateComposer {
|
||||||
static final LocTextKey FORM_TITLE =
|
|
||||||
new LocTextKey("sebserver.examconfig.form.title");
|
static final LocTextKey FORM_TITLE_NEW =
|
||||||
static final LocTextKey FORM_NAME_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.title.new");
|
||||||
new LocTextKey("sebserver.examconfig.form.name");
|
static final LocTextKey FORM_TITLE =
|
||||||
static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.title");
|
||||||
new LocTextKey("sebserver.examconfig.form.description");
|
static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
static final LocTextKey FORM_HISTORY_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.name");
|
||||||
new LocTextKey("sebserver.examconfig.form.with-history");
|
static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
||||||
static final LocTextKey FORM_TEMPLATE_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.description");
|
||||||
new LocTextKey("sebserver.examconfig.form.template");
|
static final LocTextKey FORM_HISTORY_TEXT_KEY =
|
||||||
static final LocTextKey FORM_STATUS_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.with-history");
|
||||||
new LocTextKey("sebserver.examconfig.form.status");
|
static final LocTextKey FORM_TEMPLATE_TEXT_KEY =
|
||||||
static final LocTextKey FORM_IMPORT_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.template");
|
||||||
new LocTextKey("sebserver.examconfig.action.import-config");
|
static final LocTextKey FORM_STATUS_TEXT_KEY =
|
||||||
static final LocTextKey FORM_IMPORT_SELECT_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.status");
|
||||||
new LocTextKey("sebserver.examconfig.action.import-file-select");
|
static final LocTextKey FORM_IMPORT_TEXT_KEY =
|
||||||
static final LocTextKey FORM_IMPORT_PASSWORD_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.action.import-config");
|
||||||
new LocTextKey("sebserver.examconfig.action.import-file-password");
|
static final LocTextKey FORM_IMPORT_SELECT_TEXT_KEY =
|
||||||
static final LocTextKey CONFIG_KEY_TITLE_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.action.import-file-select");
|
||||||
new LocTextKey("sebserver.examconfig.form.config-key.title");
|
static final LocTextKey FORM_IMPORT_PASSWORD_TEXT_KEY =
|
||||||
static final LocTextKey FORM_IMPORT_CONFIRM_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.action.import-file-password");
|
||||||
new LocTextKey("sebserver.examconfig.action.import-config.confirm");
|
static final LocTextKey CONFIG_KEY_TITLE_TEXT_KEY =
|
||||||
static final LocTextKey FORM_ATTACHED_EXAMS_TITLE_TEXT_KEY =
|
new LocTextKey("sebserver.examconfig.form.config-key.title");
|
||||||
new LocTextKey("sebserver.examconfig.form.attched-to");
|
static final LocTextKey FORM_IMPORT_CONFIRM_TEXT_KEY =
|
||||||
|
new LocTextKey("sebserver.examconfig.action.import-config.confirm");
|
||||||
static final LocTextKey SAVE_CONFIRM_STATE_CHANGE_WHILE_ATTACHED =
|
static final LocTextKey FORM_ATTACHED_EXAMS_TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.action.state-change.confirm");
|
new LocTextKey("sebserver.examconfig.form.attached-to");
|
||||||
|
static final LocTextKey FORM_ATTACHED_EXAMS_TITLE_TOOLTIP_TEXT_KEY =
|
||||||
private final PageService pageService;
|
new LocTextKey("sebserver.examconfig.form.attached-to" + Constants.TOOLTIP_TEXT_KEY_SUFFIX);
|
||||||
private final RestService restService;
|
|
||||||
private final CurrentUser currentUser;
|
static final LocTextKey SAVE_CONFIRM_STATE_CHANGE_WHILE_ATTACHED =
|
||||||
private final DownloadService downloadService;
|
new LocTextKey("sebserver.examconfig.action.state-change.confirm");
|
||||||
private final String downloadFileName;
|
|
||||||
|
private final PageService pageService;
|
||||||
protected SebExamConfigPropForm(
|
private final RestService restService;
|
||||||
final PageService pageService,
|
private final CurrentUser currentUser;
|
||||||
final CurrentUser currentUser,
|
private final DownloadService downloadService;
|
||||||
final DownloadService downloadService,
|
private final String downloadFileName;
|
||||||
@Value("${sebserver.gui.seb.exam.config.download.filename}") final String downloadFileName) {
|
|
||||||
|
protected SebExamConfigPropForm(
|
||||||
this.pageService = pageService;
|
final PageService pageService,
|
||||||
this.restService = pageService.getRestService();
|
final CurrentUser currentUser,
|
||||||
this.currentUser = currentUser;
|
final DownloadService downloadService,
|
||||||
this.downloadService = downloadService;
|
@Value("${sebserver.gui.seb.exam.config.download.filename}") final String downloadFileName) {
|
||||||
this.downloadFileName = downloadFileName;
|
|
||||||
}
|
this.pageService = pageService;
|
||||||
|
this.restService = pageService.getRestService();
|
||||||
@Override
|
this.currentUser = currentUser;
|
||||||
public void compose(final PageContext pageContext) {
|
this.downloadService = downloadService;
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
this.downloadFileName = downloadFileName;
|
||||||
final ResourceService resourceService = this.pageService.getResourceService();
|
}
|
||||||
|
|
||||||
final UserInfo user = this.currentUser.get();
|
@Override
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
public void compose(final PageContext pageContext) {
|
||||||
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final boolean isNew = entityKey == null;
|
final ResourceService resourceService = this.pageService.getResourceService();
|
||||||
|
|
||||||
// get data or create new. Handle error if happen
|
final UserInfo user = this.currentUser.get();
|
||||||
final ConfigurationNode examConfig = (isNew)
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
? ConfigurationNode.createNewExamConfig(user.institutionId)
|
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
||||||
: this.restService
|
final boolean isNew = entityKey == null;
|
||||||
.getBuilder(GetExamConfigNode.class)
|
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
// get data or create new. Handle error if happen
|
||||||
.call()
|
final ConfigurationNode examConfig = (isNew)
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
? ConfigurationNode.createNewExamConfig(user.institutionId)
|
||||||
.getOrThrow();
|
: this.restService
|
||||||
|
.getBuilder(GetExamConfigNode.class)
|
||||||
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig);
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
final boolean writeGrant = entityGrant.w();
|
.call()
|
||||||
final boolean modifyGrant = entityGrant.m();
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
||||||
final boolean isReadonly = pageContext.isReadonly();
|
.getOrThrow();
|
||||||
final boolean isAttachedToExam = !isNew && this.restService
|
|
||||||
.getBuilder(GetExamConfigMappingNames.class)
|
final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig);
|
||||||
.withQueryParam(ExamConfigurationMap.FILTER_ATTR_CONFIG_ID, examConfig.getModelId())
|
final boolean writeGrant = entityGrant.w();
|
||||||
.call()
|
final boolean modifyGrant = entityGrant.m();
|
||||||
.map(names -> names != null && !names.isEmpty())
|
final boolean isReadonly = pageContext.isReadonly();
|
||||||
.getOr(Boolean.FALSE);
|
final boolean isAttachedToExam = !isNew && this.restService
|
||||||
|
.getBuilder(GetExamConfigMappingNames.class)
|
||||||
// new PageContext with actual EntityKey
|
.withQueryParam(ExamConfigurationMap.FILTER_ATTR_CONFIG_ID, examConfig.getModelId())
|
||||||
final PageContext formContext = pageContext.withEntityKey(examConfig.getEntityKey());
|
.call()
|
||||||
|
.map(names -> names != null && !names.isEmpty())
|
||||||
// the default page layout with interactive title
|
.getOr(Boolean.FALSE);
|
||||||
final LocTextKey titleKey = (isNew)
|
|
||||||
? FORM_TITLE_NEW
|
// new PageContext with actual EntityKey
|
||||||
: FORM_TITLE;
|
final PageContext formContext = pageContext.withEntityKey(examConfig.getEntityKey());
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
|
||||||
formContext.getParent(),
|
// the default page layout with interactive title
|
||||||
titleKey);
|
final LocTextKey titleKey = (isNew)
|
||||||
|
? FORM_TITLE_NEW
|
||||||
final List<Tuple<String>> examConfigTemplateResources = resourceService.getExamConfigTemplateResources();
|
: FORM_TITLE;
|
||||||
final FormHandle<ConfigurationNode> formHandle = this.pageService.formBuilder(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
formContext.copyOf(content))
|
formContext.getParent(),
|
||||||
.readonly(isReadonly)
|
titleKey);
|
||||||
.putStaticValueIf(() -> !isNew,
|
|
||||||
Domain.CONFIGURATION_NODE.ATTR_ID,
|
final List<Tuple<String>> examConfigTemplateResources = resourceService.getExamConfigTemplateResources();
|
||||||
examConfig.getModelId())
|
final FormHandle<ConfigurationNode> formHandle = this.pageService.formBuilder(
|
||||||
.putStaticValue(
|
formContext.copyOf(content))
|
||||||
Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID,
|
.readonly(isReadonly)
|
||||||
String.valueOf(examConfig.getInstitutionId()))
|
.putStaticValueIf(() -> !isNew,
|
||||||
.putStaticValue(
|
Domain.CONFIGURATION_NODE.ATTR_ID,
|
||||||
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
examConfig.getModelId())
|
||||||
ConfigurationType.EXAM_CONFIG.name())
|
.putStaticValue(
|
||||||
.addFieldIf(
|
Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID,
|
||||||
() -> !examConfigTemplateResources.isEmpty(),
|
String.valueOf(examConfig.getInstitutionId()))
|
||||||
() -> FormBuilder.singleSelection(
|
.putStaticValue(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_TEMPLATE_ID,
|
Domain.CONFIGURATION_NODE.ATTR_TYPE,
|
||||||
FORM_TEMPLATE_TEXT_KEY,
|
ConfigurationType.EXAM_CONFIG.name())
|
||||||
(parentEntityKey != null)
|
.addFieldIf(
|
||||||
? parentEntityKey.modelId
|
() -> !examConfigTemplateResources.isEmpty(),
|
||||||
: String.valueOf(examConfig.templateId),
|
() -> FormBuilder.singleSelection(
|
||||||
resourceService::getExamConfigTemplateResources)
|
Domain.CONFIGURATION_NODE.ATTR_TEMPLATE_ID,
|
||||||
.readonly(!isNew))
|
FORM_TEMPLATE_TEXT_KEY,
|
||||||
.addField(FormBuilder.text(
|
(parentEntityKey != null)
|
||||||
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
? parentEntityKey.modelId
|
||||||
FORM_NAME_TEXT_KEY,
|
: String.valueOf(examConfig.templateId),
|
||||||
examConfig.name))
|
resourceService::getExamConfigTemplateResources)
|
||||||
.addField(FormBuilder.text(
|
.readonly(!isNew))
|
||||||
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
.addField(FormBuilder.text(
|
||||||
FORM_DESCRIPTION_TEXT_KEY,
|
Domain.CONFIGURATION_NODE.ATTR_NAME,
|
||||||
examConfig.description)
|
FORM_NAME_TEXT_KEY,
|
||||||
.asArea())
|
examConfig.name)
|
||||||
|
.mandatory(!isReadonly))
|
||||||
.addField(FormBuilder.singleSelection(
|
.addField(FormBuilder.text(
|
||||||
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION,
|
||||||
FORM_STATUS_TEXT_KEY,
|
FORM_DESCRIPTION_TEXT_KEY,
|
||||||
examConfig.status.name(),
|
examConfig.description)
|
||||||
() -> resourceService.examConfigStatusResources(isAttachedToExam))
|
.asArea())
|
||||||
.withEmptyCellSeparation((isReadonly) ? false : true))
|
|
||||||
.buildFor((isNew)
|
.addField(FormBuilder.singleSelection(
|
||||||
? this.restService.getRestCall(NewExamConfig.class)
|
Domain.CONFIGURATION_NODE.ATTR_STATUS,
|
||||||
: this.restService.getRestCall(SaveExamConfig.class));
|
FORM_STATUS_TEXT_KEY,
|
||||||
|
examConfig.status.name(),
|
||||||
final boolean settingsReadonly = examConfig.status == ConfigurationStatus.IN_USE;
|
() -> resourceService.examConfigStatusResources(isAttachedToExam))
|
||||||
final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class);
|
.withEmptyCellSeparation(!isReadonly))
|
||||||
final PageContext actionContext = formContext.clearEntityKeys();
|
.buildFor((isNew)
|
||||||
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(actionContext);
|
? this.restService.getRestCall(NewExamConfig.class)
|
||||||
actionBuilder
|
: this.restService.getRestCall(SaveExamConfig.class));
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
final boolean settingsReadonly = examConfig.status == ConfigurationStatus.IN_USE;
|
||||||
.publishIf(() -> writeGrant && isReadonly)
|
final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class);
|
||||||
|
final PageContext actionContext = formContext.clearEntityKeys();
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_MODIFY)
|
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(actionContext);
|
||||||
.withEntityKey(entityKey)
|
actionBuilder
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW)
|
.publishIf(() -> writeGrant && isReadonly)
|
||||||
.withEntityKey(entityKey)
|
|
||||||
.publishIf(() -> isReadonly)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_MODIFY)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY)
|
|
||||||
.withEntityKey(entityKey)
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
.publishIf(() -> modifyGrant && isReadonly && !settingsReadonly)
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_EXPORT_PLAIN_XML)
|
.withEntityKey(entityKey)
|
||||||
.withEntityKey(entityKey)
|
.withAttribute(PageContext.AttributeKeys.READ_ONLY, String.valueOf(!modifyGrant))
|
||||||
.withExec(action -> {
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
final String downloadURL = this.downloadService.createDownloadURL(
|
|
||||||
entityKey.modelId,
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_EXPORT_PLAIN_XML)
|
||||||
SebExamConfigPlaintextDownload.class,
|
.withEntityKey(entityKey)
|
||||||
this.downloadFileName);
|
.withExec(action -> {
|
||||||
urlLauncher.openURL(downloadURL);
|
final String downloadURL = this.downloadService.createDownloadURL(
|
||||||
return action;
|
entityKey.modelId,
|
||||||
})
|
SebExamConfigPlaintextDownload.class,
|
||||||
.noEventPropagation()
|
this.downloadFileName);
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
urlLauncher.openURL(downloadURL);
|
||||||
|
return action;
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_GET_CONFIG_KEY)
|
})
|
||||||
.withEntityKey(entityKey)
|
.noEventPropagation()
|
||||||
.withExec(SebExamConfigPropForm.getConfigKeyFunction(this.pageService))
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
.noEventPropagation()
|
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_GET_CONFIG_KEY)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_EXISTING_CONFIG)
|
.withExec(SebExamConfigPropForm.getConfigKeyFunction(this.pageService))
|
||||||
.withEntityKey(entityKey)
|
.noEventPropagation()
|
||||||
.withExec(SebExamConfigImportPopup.importFunction(this.pageService, false))
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
.noEventPropagation()
|
|
||||||
.publishIf(() -> modifyGrant && isReadonly && !isAttachedToExam)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_IMPORT_TO_EXISTING_CONFIG)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG)
|
.withExec(SebExamConfigImportPopup.importFunction(this.pageService, false))
|
||||||
.withEntityKey(entityKey)
|
.noEventPropagation()
|
||||||
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
.publishIf(() -> modifyGrant && isReadonly && !isAttachedToExam)
|
||||||
this.pageService,
|
|
||||||
actionContext
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withAttribute(
|
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
||||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
this.pageService,
|
||||||
Constants.FALSE_STRING)
|
actionContext
|
||||||
.withAttribute(
|
.withEntityKey(entityKey)
|
||||||
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
.withAttribute(
|
||||||
Constants.FALSE_STRING)))
|
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||||
.noEventPropagation()
|
Constants.FALSE_STRING)
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
.withAttribute(
|
||||||
|
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
Constants.FALSE_STRING)))
|
||||||
.withEntityKey(entityKey)
|
.noEventPropagation()
|
||||||
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
this.pageService,
|
|
||||||
pageContext.withAttribute(
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
||||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
.withEntityKey(entityKey)
|
||||||
Constants.TRUE_STRING)))
|
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
||||||
.noEventPropagation()
|
this.pageService,
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
pageContext.withAttribute(
|
||||||
|
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_SAVE)
|
Constants.TRUE_STRING)))
|
||||||
.withEntityKey(entityKey)
|
.noEventPropagation()
|
||||||
.withExec(formHandle::processFormSave)
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
.ignoreMoveAwayFromEdit()
|
|
||||||
.withConfirm(() -> stateChangeConfirm(isAttachedToExam, formHandle))
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_SAVE)
|
||||||
.publishIf(() -> !isReadonly)
|
.withEntityKey(entityKey)
|
||||||
|
.withExec(formHandle::processFormSave)
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_CANCEL_MODIFY)
|
.ignoreMoveAwayFromEdit()
|
||||||
.withEntityKey(entityKey)
|
.withConfirm(() -> stateChangeConfirm(isAttachedToExam, formHandle))
|
||||||
.withExec(this.pageService.backToCurrentFunction())
|
.publishIf(() -> !isReadonly)
|
||||||
.publishIf(() -> !isReadonly);
|
|
||||||
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_CANCEL_MODIFY)
|
||||||
if (isAttachedToExam && isReadonly) {
|
.withEntityKey(entityKey)
|
||||||
|
.withExec(this.pageService.backToCurrentFunction())
|
||||||
widgetFactory.labelSeparator(content);
|
.publishIf(() -> !isReadonly);
|
||||||
widgetFactory.labelLocalized(
|
|
||||||
content,
|
if (isAttachedToExam && isReadonly) {
|
||||||
CustomVariant.TEXT_H3,
|
|
||||||
FORM_ATTACHED_EXAMS_TITLE_TEXT_KEY);
|
widgetFactory.label(content, StringUtils.EMPTY);
|
||||||
|
widgetFactory.labelLocalized(
|
||||||
final EntityTable<ExamConfigurationMap> table =
|
content,
|
||||||
this.pageService.entityTableBuilder(this.restService.getRestCall(GetExamConfigMappingsPage.class))
|
CustomVariant.TEXT_H3,
|
||||||
.withRestCallAdapter(restCall -> restCall.withQueryParam(
|
FORM_ATTACHED_EXAMS_TITLE_TEXT_KEY,
|
||||||
ExamConfigurationMap.FILTER_ATTR_CONFIG_ID, examConfig.getModelId()))
|
FORM_ATTACHED_EXAMS_TITLE_TOOLTIP_TEXT_KEY);
|
||||||
.withPaging(1)
|
widgetFactory.labelSeparator(content);
|
||||||
.hideNavigation()
|
|
||||||
.withRowDecorator(ExamList.decorateOnExamMapConsistency(this.pageService))
|
final EntityTable<ExamConfigurationMap> table =
|
||||||
|
this.pageService.entityTableBuilder(this.restService.getRestCall(GetExamConfigMappingsPage.class))
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withRestCallAdapter(restCall -> restCall.withQueryParam(
|
||||||
QuizData.QUIZ_ATTR_NAME,
|
ExamConfigurationMap.FILTER_ATTR_CONFIG_ID, examConfig.getModelId()))
|
||||||
ExamList.COLUMN_TITLE_NAME_KEY,
|
.withPaging(1)
|
||||||
ExamConfigurationMap::getExamName))
|
.hideNavigation()
|
||||||
|
.withRowDecorator(ExamList.decorateOnExamMapConsistency(this.pageService))
|
||||||
.withColumn(new ColumnDefinition<>(
|
|
||||||
QuizData.QUIZ_ATTR_START_TIME,
|
.withColumn(new ColumnDefinition<>(
|
||||||
new LocTextKey(
|
QuizData.QUIZ_ATTR_NAME,
|
||||||
ExamList.EXAM_LIST_COLUMN_STARTTIME,
|
ExamList.COLUMN_TITLE_NAME_KEY,
|
||||||
this.pageService.getI18nSupport().getUsersTimeZoneTitleSuffix()),
|
ExamConfigurationMap::getExamName))
|
||||||
ExamConfigurationMap::getExamStartTime))
|
|
||||||
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withColumn(new ColumnDefinition<ExamConfigurationMap>(
|
QuizData.QUIZ_ATTR_START_TIME,
|
||||||
Domain.EXAM.ATTR_TYPE,
|
new LocTextKey(
|
||||||
ExamList.COLUMN_TITLE_TYPE_KEY,
|
ExamList.EXAM_LIST_COLUMN_STARTTIME,
|
||||||
resourceService::localizedExamTypeName))
|
this.pageService.getI18nSupport().getUsersTimeZoneTitleSuffix()),
|
||||||
|
ExamConfigurationMap::getExamStartTime))
|
||||||
.withDefaultAction(this::showExamAction)
|
|
||||||
|
.withColumn(new ColumnDefinition<>(
|
||||||
.compose(pageContext.copyOf(content));
|
Domain.EXAM.ATTR_TYPE,
|
||||||
|
ExamList.COLUMN_TITLE_TYPE_KEY,
|
||||||
actionBuilder
|
resourceService::localizedExamTypeName))
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
|
.withDefaultAction(this::showExamAction)
|
||||||
.withExec(pageAction -> {
|
|
||||||
final ExamConfigurationMap selectedExamMapping = getSelectedExamMapping(table);
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
return pageAction.withEntityKey(
|
pageContext,
|
||||||
new EntityKey(selectedExamMapping.examId, EntityType.EXAM));
|
ActionDefinition.EXAM_VIEW_FROM_LIST))
|
||||||
})
|
|
||||||
.publishIf(table::hasAnyContent);
|
.compose(pageContext.copyOf(content));
|
||||||
}
|
|
||||||
}
|
actionBuilder
|
||||||
|
|
||||||
private PageAction showExamAction(final EntityTable<ExamConfigurationMap> table) {
|
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
|
||||||
return this.pageService.pageActionBuilder(table.getPageContext())
|
.withExec(pageAction -> {
|
||||||
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
|
final ExamConfigurationMap selectedExamMapping = getSelectedExamMapping(table);
|
||||||
.withSelectionSupplier(() -> {
|
return pageAction.withEntityKey(
|
||||||
final ExamConfigurationMap selectedROWData = getSelectedExamMapping(table);
|
new EntityKey(selectedExamMapping.examId, EntityType.EXAM));
|
||||||
return new HashSet<>(Arrays.asList(new EntityKey(selectedROWData.examId, EntityType.EXAM)));
|
})
|
||||||
})
|
.publishIf(table::hasAnyContent, false);
|
||||||
.withExec(PageAction::applySingleSelectionAsEntityKey)
|
}
|
||||||
.create();
|
}
|
||||||
}
|
|
||||||
|
private PageAction showExamAction(final EntityTable<ExamConfigurationMap> table) {
|
||||||
private ExamConfigurationMap getSelectedExamMapping(final EntityTable<ExamConfigurationMap> table) {
|
return this.pageService.pageActionBuilder(table.getPageContext())
|
||||||
final ExamConfigurationMap selectedROWData = table.getSingleSelectedROWData();
|
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
|
||||||
|
.withSelectionSupplier(() -> {
|
||||||
if (selectedROWData == null) {
|
final ExamConfigurationMap selectedROWData = getSelectedExamMapping(table);
|
||||||
throw new PageMessageException(ExamList.EMPTY_SELECTION_TEXT_KEY);
|
return new HashSet<>(Collections.singletonList(new EntityKey(selectedROWData.examId, EntityType.EXAM)));
|
||||||
}
|
})
|
||||||
return selectedROWData;
|
.withExec(PageAction::applySingleSelectionAsEntityKey)
|
||||||
}
|
.create();
|
||||||
|
}
|
||||||
private LocTextKey stateChangeConfirm(
|
|
||||||
final boolean isAttachedToExam,
|
private ExamConfigurationMap getSelectedExamMapping(final EntityTable<ExamConfigurationMap> table) {
|
||||||
final FormHandle<ConfigurationNode> formHandle) {
|
final ExamConfigurationMap selectedROWData = table.getSingleSelectedROWData();
|
||||||
|
|
||||||
if (isAttachedToExam) {
|
if (selectedROWData == null) {
|
||||||
final String fieldValue = formHandle
|
throw new PageMessageException(ExamList.EMPTY_SELECTION_TEXT_KEY);
|
||||||
.getForm()
|
}
|
||||||
.getFieldValue(Domain.CONFIGURATION_NODE.ATTR_STATUS);
|
return selectedROWData;
|
||||||
|
}
|
||||||
if (fieldValue != null) {
|
|
||||||
final ConfigurationStatus state = ConfigurationStatus.valueOf(fieldValue);
|
private LocTextKey stateChangeConfirm(
|
||||||
if (state != ConfigurationStatus.IN_USE) {
|
final boolean isAttachedToExam,
|
||||||
return SAVE_CONFIRM_STATE_CHANGE_WHILE_ATTACHED;
|
final FormHandle<ConfigurationNode> formHandle) {
|
||||||
}
|
|
||||||
}
|
if (isAttachedToExam) {
|
||||||
}
|
final String fieldValue = formHandle
|
||||||
|
.getForm()
|
||||||
return null;
|
.getFieldValue(Domain.CONFIGURATION_NODE.ATTR_STATUS);
|
||||||
}
|
|
||||||
|
if (fieldValue != null) {
|
||||||
public static Function<PageAction, PageAction> getConfigKeyFunction(final PageService pageService) {
|
final ConfigurationStatus state = ConfigurationStatus.valueOf(fieldValue);
|
||||||
final RestService restService = pageService.getResourceService().getRestService();
|
if (state != ConfigurationStatus.IN_USE) {
|
||||||
return action -> {
|
return SAVE_CONFIRM_STATE_CHANGE_WHILE_ATTACHED;
|
||||||
final ConfigKey configKey = restService.getBuilder(ExportConfigKey.class)
|
}
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, action.getEntityKey().modelId)
|
}
|
||||||
.call()
|
}
|
||||||
.getOrThrow();
|
|
||||||
|
return null;
|
||||||
final WidgetFactory widgetFactory = pageService.getWidgetFactory();
|
}
|
||||||
final ModalInputDialog<Void> dialog = new ModalInputDialog<>(
|
|
||||||
action.pageContext().getParent().getShell(),
|
public static Function<PageAction, PageAction> getConfigKeyFunction(final PageService pageService) {
|
||||||
widgetFactory);
|
final RestService restService = pageService.getResourceService().getRestService();
|
||||||
|
return action -> {
|
||||||
dialog.setDialogWidth(500);
|
final ConfigKey configKey = restService.getBuilder(ExportConfigKey.class)
|
||||||
|
.withURIVariable(API.PARAM_MODEL_ID, action.getEntityKey().modelId)
|
||||||
dialog.open(
|
.call()
|
||||||
CONFIG_KEY_TITLE_TEXT_KEY,
|
.getOrThrow();
|
||||||
action.pageContext(),
|
|
||||||
pc -> {
|
final WidgetFactory widgetFactory = pageService.getWidgetFactory();
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final ModalInputDialog<Void> dialog = new ModalInputDialog<>(
|
||||||
pc.getParent());
|
action.pageContext().getParent().getShell(),
|
||||||
|
widgetFactory);
|
||||||
widgetFactory.labelLocalized(
|
|
||||||
content,
|
dialog.setDialogWidth(500);
|
||||||
CustomVariant.TEXT_H3,
|
|
||||||
CONFIG_KEY_TITLE_TEXT_KEY);
|
dialog.open(
|
||||||
|
CONFIG_KEY_TITLE_TEXT_KEY,
|
||||||
final Text text = new Text(content, SWT.NONE);
|
action.pageContext(),
|
||||||
text.setEditable(false);
|
pc -> {
|
||||||
text.setText(configKey.key);
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
});
|
pc.getParent());
|
||||||
return action;
|
|
||||||
};
|
widgetFactory.labelLocalized(
|
||||||
}
|
content,
|
||||||
|
CustomVariant.TEXT_H3,
|
||||||
}
|
CONFIG_KEY_TITLE_TEXT_KEY);
|
||||||
|
|
||||||
|
final Text text = new Text(content, SWT.NONE);
|
||||||
|
text.setEditable(false);
|
||||||
|
text.setText(configKey.key);
|
||||||
|
});
|
||||||
|
return action;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,239 +1,238 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.TabFolder;
|
import org.eclipse.swt.widgets.TabFolder;
|
||||||
import org.eclipse.swt.widgets.TabItem;
|
import org.eclipse.swt.widgets.TabItem;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessageError;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessageError;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigHistory;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigHistory;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SebExamConfigUndo;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SebExamConfigUndo;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class SebExamConfigSettingsForm implements TemplateComposer {
|
public class SebExamConfigSettingsForm implements TemplateComposer {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SebExamConfigSettingsForm.class);
|
private static final Logger log = LoggerFactory.getLogger(SebExamConfigSettingsForm.class);
|
||||||
|
|
||||||
private static final String VIEW_TEXT_KEY_PREFIX =
|
private static final String VIEW_TEXT_KEY_PREFIX =
|
||||||
"sebserver.examconfig.props.form.views.";
|
"sebserver.examconfig.props.form.views.";
|
||||||
private static final String KEY_SAVE_TO_HISTORY_SUCCESS =
|
private static final String KEY_SAVE_TO_HISTORY_SUCCESS =
|
||||||
"sebserver.examconfig.action.saveToHistory.success";
|
"sebserver.examconfig.action.saveToHistory.success";
|
||||||
private static final String KEY_UNDO_SUCCESS =
|
private static final String KEY_UNDO_SUCCESS =
|
||||||
"sebserver.examconfig.action.undo.success";
|
"sebserver.examconfig.action.undo.success";
|
||||||
private static final LocTextKey TITLE_TEXT_KEY =
|
private static final LocTextKey TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.props.from.title");
|
new LocTextKey("sebserver.examconfig.props.from.title");
|
||||||
|
|
||||||
private static final LocTextKey MESSAGE_SAVE_INTEGRITY_VIOLATION =
|
private static final LocTextKey MESSAGE_SAVE_INTEGRITY_VIOLATION =
|
||||||
new LocTextKey("sebserver.examconfig.action.saveToHistory.integrity-violation");
|
new LocTextKey("sebserver.examconfig.action.saveToHistory.integrity-violation");
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final ExamConfigurationService examConfigurationService;
|
private final ExamConfigurationService examConfigurationService;
|
||||||
|
|
||||||
protected SebExamConfigSettingsForm(
|
protected SebExamConfigSettingsForm(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final CurrentUser currentUser,
|
final CurrentUser currentUser,
|
||||||
final ExamConfigurationService examConfigurationService) {
|
final ExamConfigurationService examConfigurationService) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.examConfigurationService = examConfigurationService;
|
this.examConfigurationService = examConfigurationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
|
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
|
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
TITLE_TEXT_KEY);
|
TITLE_TEXT_KEY);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
final ConfigurationNode configNode = this.restService.getBuilder(GetExamConfigNode.class)
|
final ConfigurationNode configNode = this.restService.getBuilder(GetExamConfigNode.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
.call()
|
.call()
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_NODE, error))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final Configuration configuration = this.restService.getBuilder(GetConfigurations.class)
|
final Configuration configuration = this.restService.getBuilder(GetConfigurations.class)
|
||||||
.withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, configNode.getModelId())
|
.withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, configNode.getModelId())
|
||||||
.withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING)
|
.withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING)
|
||||||
.call()
|
.call()
|
||||||
.map(Utils::toSingleton)
|
.map(Utils::toSingleton)
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION, error))
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION, error))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final AttributeMapping attributes = this.examConfigurationService
|
final AttributeMapping attributes = this.examConfigurationService
|
||||||
.getAttributes(configNode.templateId)
|
.getAttributes(configNode.templateId)
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_ATTRIBUTE, error))
|
.onError(error -> pageContext.notifyLoadError(EntityType.CONFIGURATION_ATTRIBUTE, error))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final boolean readonly = pageContext.isReadonly() || configNode.status == ConfigurationStatus.IN_USE;
|
final boolean readonly = pageContext.isReadonly() || configNode.status == ConfigurationStatus.IN_USE;
|
||||||
final List<View> views = this.examConfigurationService.getViews(attributes);
|
final List<View> views = this.examConfigurationService.getViews(attributes);
|
||||||
final TabFolder tabFolder = widgetFactory.tabFolderLocalized(content);
|
final TabFolder tabFolder = widgetFactory.tabFolderLocalized(content);
|
||||||
tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||||
|
|
||||||
final List<ViewContext> viewContexts = new ArrayList<>();
|
final List<ViewContext> viewContexts = new ArrayList<>();
|
||||||
for (final View view : views) {
|
for (final View view : views) {
|
||||||
final ViewContext viewContext = this.examConfigurationService.createViewContext(
|
final ViewContext viewContext = this.examConfigurationService.createViewContext(
|
||||||
pageContext,
|
pageContext,
|
||||||
configuration,
|
configuration,
|
||||||
view,
|
view,
|
||||||
attributes,
|
attributes,
|
||||||
20,
|
20,
|
||||||
readonly);
|
readonly);
|
||||||
viewContexts.add(viewContext);
|
viewContexts.add(viewContext);
|
||||||
|
|
||||||
final Composite viewGrid = this.examConfigurationService.createViewGrid(
|
final Composite viewGrid = this.examConfigurationService.createViewGrid(
|
||||||
tabFolder,
|
tabFolder,
|
||||||
viewContext);
|
viewContext);
|
||||||
|
|
||||||
final TabItem tabItem = widgetFactory.tabItemLocalized(
|
final TabItem tabItem = widgetFactory.tabItemLocalized(
|
||||||
tabFolder,
|
tabFolder,
|
||||||
new LocTextKey(VIEW_TEXT_KEY_PREFIX + view.name));
|
new LocTextKey(VIEW_TEXT_KEY_PREFIX + view.name));
|
||||||
tabItem.setControl(viewGrid);
|
tabItem.setControl(viewGrid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set selection if available
|
// set selection if available
|
||||||
final String viewIndex = pageContext.getAttribute("VIEW_INDEX");
|
final String viewIndex = pageContext.getAttribute("VIEW_INDEX");
|
||||||
if (StringUtils.isNotBlank(viewIndex)) {
|
if (StringUtils.isNotBlank(viewIndex)) {
|
||||||
try {
|
try {
|
||||||
tabFolder.setSelection(Integer.parseInt(viewIndex));
|
tabFolder.setSelection(Integer.parseInt(viewIndex));
|
||||||
} catch (final NumberFormatException e) {
|
} catch (final NumberFormatException e) {
|
||||||
log.warn("Failed to initialize view selection");
|
log.warn("Failed to initialize view selection");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.examConfigurationService.initInputFieldValues(configuration.id, viewContexts);
|
this.examConfigurationService.initInputFieldValues(configuration.id, viewContexts);
|
||||||
|
|
||||||
final GrantCheck examConfigGrant = this.currentUser.grantCheck(EntityType.CONFIGURATION_NODE);
|
final GrantCheck examConfigGrant = this.currentUser.grantCheck(EntityType.CONFIGURATION_NODE);
|
||||||
this.pageService.pageActionBuilder(pageContext.clearEntityKeys())
|
this.pageService.pageActionBuilder(pageContext.clearEntityKeys())
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE_TO_HISTORY)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE_TO_HISTORY)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(action -> {
|
.withExec(action -> {
|
||||||
this.restService.getBuilder(SaveExamConfigHistory.class)
|
this.restService.getBuilder(SaveExamConfigHistory.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, configuration.getModelId())
|
.withURIVariable(API.PARAM_MODEL_ID, configuration.getModelId())
|
||||||
.call()
|
.call()
|
||||||
.onError(t -> notifyErrorOnSave(t, pageContext));
|
.onError(t -> notifyErrorOnSave(t, pageContext));
|
||||||
return action.withAttribute(
|
return action.withAttribute(
|
||||||
"VIEW_INDEX",
|
"VIEW_INDEX",
|
||||||
String.valueOf(tabFolder.getSelectionIndex()));
|
String.valueOf(tabFolder.getSelectionIndex()));
|
||||||
})
|
})
|
||||||
.withSuccess(KEY_SAVE_TO_HISTORY_SUCCESS)
|
.withSuccess(KEY_SAVE_TO_HISTORY_SUCCESS)
|
||||||
.ignoreMoveAwayFromEdit()
|
.ignoreMoveAwayFromEdit()
|
||||||
.publishIf(() -> examConfigGrant.iw() && !readonly)
|
.publishIf(() -> examConfigGrant.iw() && !readonly)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_UNDO)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_UNDO)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(action -> {
|
.withExec(action -> {
|
||||||
this.restService.getBuilder(SebExamConfigUndo.class)
|
this.restService.getBuilder(SebExamConfigUndo.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, configuration.getModelId())
|
.withURIVariable(API.PARAM_MODEL_ID, configuration.getModelId())
|
||||||
.call()
|
.call()
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
return action.withAttribute(
|
return action.withAttribute(
|
||||||
"VIEW_INDEX",
|
"VIEW_INDEX",
|
||||||
String.valueOf(tabFolder.getSelectionIndex()));
|
String.valueOf(tabFolder.getSelectionIndex()));
|
||||||
})
|
})
|
||||||
.withSuccess(KEY_UNDO_SUCCESS)
|
.withSuccess(KEY_UNDO_SUCCESS)
|
||||||
.ignoreMoveAwayFromEdit()
|
.ignoreMoveAwayFromEdit()
|
||||||
.publishIf(() -> examConfigGrant.iw() && !readonly)
|
.publishIf(() -> examConfigGrant.iw() && !readonly)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
||||||
this.pageService,
|
this.pageService,
|
||||||
pageContext
|
pageContext
|
||||||
.withAttribute(
|
.withAttribute(
|
||||||
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
PageContext.AttributeKeys.COPY_AS_TEMPLATE,
|
||||||
Constants.TRUE_STRING)
|
Constants.TRUE_STRING)
|
||||||
.withAttribute(
|
.withAttribute(
|
||||||
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
PageContext.AttributeKeys.CREATE_FROM_TEMPLATE,
|
||||||
Constants.FALSE_STRING)))
|
Constants.FALSE_STRING)))
|
||||||
.noEventPropagation()
|
.noEventPropagation()
|
||||||
.publishIf(() -> examConfigGrant.iw())
|
.publishIf(examConfigGrant::iw)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.ignoreMoveAwayFromEdit()
|
.ignoreMoveAwayFromEdit()
|
||||||
.publish();
|
.publish();
|
||||||
|
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
pageContext.notifyUnexpectedError(e);
|
pageContext.notifyUnexpectedError(e);
|
||||||
throw e;
|
throw e;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.error("Unexpected error while trying to fetch exam configuration data and create views", e);
|
log.error("Unexpected error while trying to fetch exam configuration data and create views", e);
|
||||||
pageContext.notifyError(SebExamConfigPropForm.FORM_TITLE, e);
|
pageContext.notifyError(SebExamConfigPropForm.FORM_TITLE, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyErrorOnSave(final Exception error, final PageContext context) {
|
private void notifyErrorOnSave(final Exception error, final PageContext context) {
|
||||||
if (error instanceof APIMessageError) {
|
if (error instanceof APIMessageError) {
|
||||||
try {
|
try {
|
||||||
final List<APIMessage> errorMessages = ((APIMessageError) error).getErrorMessages();
|
final List<APIMessage> errorMessages = ((APIMessageError) error).getErrorMessages();
|
||||||
final APIMessage apiMessage = errorMessages.get(0);
|
final APIMessage apiMessage = errorMessages.get(0);
|
||||||
if (APIMessage.ErrorMessage.INTEGRITY_VALIDATION.isOf(apiMessage)) {
|
if (APIMessage.ErrorMessage.INTEGRITY_VALIDATION.isOf(apiMessage)) {
|
||||||
throw new PageMessageException(MESSAGE_SAVE_INTEGRITY_VIOLATION);
|
throw new PageMessageException(MESSAGE_SAVE_INTEGRITY_VIOLATION);
|
||||||
} else {
|
} else {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
} catch (final PageMessageException e) {
|
} catch (final PageMessageException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new RuntimeException(error);
|
throw new RuntimeException(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,143 +1,147 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.MessageBox;
|
import org.eclipse.swt.widgets.MessageBox;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
|
import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ChangePassword;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ChangePassword;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.Message;
|
import ch.ethz.seb.sebserver.gui.widget.Message;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
/** The form to change an User-Account password.
|
/** The form to change an User-Account password.
|
||||||
* If the current user is the owner of the User-Account the password is required and must
|
* If the current user is the owner of the User-Account the password is required and must
|
||||||
* match the users current password.
|
* match the users current password.
|
||||||
* If the current user is an administrator that has to reset another users password the
|
* If the current user is an administrator that has to reset another users password the
|
||||||
* password that is also required must match the administrators current password. */
|
* password that is also required must match the administrators current password.
|
||||||
public class UserAccountChangePasswordForm implements TemplateComposer {
|
**/
|
||||||
|
public class UserAccountChangePasswordForm implements TemplateComposer {
|
||||||
private static final String FORM_TITLE_KEY = "sebserver.useraccount.form.pwchange.title";
|
|
||||||
private static final LocTextKey FORM_PASSWORD_NEW_TEXT_KEY =
|
private static final String FORM_TITLE_KEY = "sebserver.useraccount.form.pwchange.title";
|
||||||
new LocTextKey("sebserver.useraccount.form.password.new");
|
private static final LocTextKey FORM_PASSWORD_NEW_TEXT_KEY =
|
||||||
private static final LocTextKey FORM_PASSWORD_NEW_CONFIRM_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.form.password.new");
|
||||||
new LocTextKey("sebserver.useraccount.form.password.new.confirm");
|
private static final LocTextKey FORM_PASSWORD_NEW_CONFIRM_TEXT_KEY =
|
||||||
private static final LocTextKey FORM_PASSWORD_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.form.password.new.confirm");
|
||||||
new LocTextKey("sebserver.useraccount.form.password");
|
private static final LocTextKey FORM_PASSWORD_TEXT_KEY =
|
||||||
|
new LocTextKey("sebserver.useraccount.form.password");
|
||||||
private final PageService pageService;
|
|
||||||
private final RestService restService;
|
private final PageService pageService;
|
||||||
private final CurrentUser currentUser;
|
private final RestService restService;
|
||||||
private final I18nSupport i18nSupport;
|
private final CurrentUser currentUser;
|
||||||
|
private final I18nSupport i18nSupport;
|
||||||
protected UserAccountChangePasswordForm(
|
|
||||||
final PageService pageService,
|
protected UserAccountChangePasswordForm(
|
||||||
final RestService restService,
|
final PageService pageService,
|
||||||
final CurrentUser currentUser) {
|
final RestService restService,
|
||||||
|
final CurrentUser currentUser) {
|
||||||
this.pageService = pageService;
|
|
||||||
this.restService = restService;
|
this.pageService = pageService;
|
||||||
this.currentUser = currentUser;
|
this.restService = restService;
|
||||||
this.i18nSupport = pageService.getI18nSupport();
|
this.currentUser = currentUser;
|
||||||
}
|
this.i18nSupport = pageService.getI18nSupport();
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void compose(final PageContext pageContext) {
|
@Override
|
||||||
|
public void compose(final PageContext pageContext) {
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
final UserInfo userInfo = this.restService
|
|
||||||
.getBuilder(GetUserAccount.class)
|
final UserInfo userInfo = this.restService
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
.getBuilder(GetUserAccount.class)
|
||||||
.call()
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.USER, error))
|
.call()
|
||||||
.getOrThrow();
|
.onError(error -> pageContext.notifyLoadError(EntityType.USER, error))
|
||||||
|
.getOrThrow();
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
|
||||||
pageContext.getParent(),
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
new LocTextKey(FORM_TITLE_KEY, userInfo.username));
|
pageContext.getParent(),
|
||||||
|
new LocTextKey(FORM_TITLE_KEY, userInfo.username));
|
||||||
final boolean ownAccount = this.currentUser.get().uuid.equals(entityKey.getModelId());
|
|
||||||
|
final boolean ownAccount = this.currentUser.get().uuid.equals(entityKey.getModelId());
|
||||||
// The Password Change form
|
|
||||||
final FormHandle<UserInfo> formHandle = this.pageService.formBuilder(pageContext.copyOf(content))
|
// The Password Change form
|
||||||
.readonly(false)
|
final FormHandle<UserInfo> formHandle = this.pageService.formBuilder(pageContext.copyOf(content))
|
||||||
.putStaticValueIf(() -> entityKey != null,
|
.readonly(false)
|
||||||
Domain.USER.ATTR_UUID,
|
.putStaticValueIf(() -> entityKey != null,
|
||||||
entityKey.getModelId())
|
Domain.USER.ATTR_UUID,
|
||||||
.addField(FormBuilder.text(
|
entityKey.getModelId())
|
||||||
PasswordChange.ATTR_NAME_PASSWORD,
|
.addField(FormBuilder.text(
|
||||||
FORM_PASSWORD_TEXT_KEY)
|
PasswordChange.ATTR_NAME_PASSWORD,
|
||||||
.asPasswordField())
|
FORM_PASSWORD_TEXT_KEY)
|
||||||
.addField(FormBuilder.text(
|
.asPasswordField()
|
||||||
PasswordChange.ATTR_NAME_NEW_PASSWORD,
|
.mandatory())
|
||||||
FORM_PASSWORD_NEW_TEXT_KEY)
|
.addField(FormBuilder.text(
|
||||||
.asPasswordField())
|
PasswordChange.ATTR_NAME_NEW_PASSWORD,
|
||||||
.addFieldIf(
|
FORM_PASSWORD_NEW_TEXT_KEY)
|
||||||
() -> entityKey != null,
|
.asPasswordField()
|
||||||
() -> FormBuilder.text(
|
.mandatory())
|
||||||
PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD,
|
.addFieldIf(
|
||||||
FORM_PASSWORD_NEW_CONFIRM_TEXT_KEY)
|
() -> entityKey != null,
|
||||||
.asPasswordField())
|
() -> FormBuilder.text(
|
||||||
.buildFor(this.restService.getRestCall(ChangePassword.class));
|
PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD,
|
||||||
|
FORM_PASSWORD_NEW_CONFIRM_TEXT_KEY)
|
||||||
this.pageService.pageActionBuilder(pageContext)
|
.asPasswordField()
|
||||||
|
.mandatory())
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD_SAVE)
|
.buildFor(this.restService.getRestCall(ChangePassword.class));
|
||||||
.withExec(action -> {
|
|
||||||
final PageAction saveAction = formHandle.processFormSave(action);
|
this.pageService.pageActionBuilder(pageContext)
|
||||||
if (ownAccount) {
|
|
||||||
// NOTE: in this case the user changed the password of the own account
|
.newAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSWORD_SAVE)
|
||||||
// this should cause an logout with specified message that password change
|
.withExec(action -> {
|
||||||
// was successful and the pointing the need of re login with the new password
|
final PageAction saveAction = formHandle.processFormSave(action);
|
||||||
this.pageService.logout(pageContext);
|
if (ownAccount) {
|
||||||
final MessageBox error = new Message(
|
// NOTE: in this case the user changed the password of the own account
|
||||||
pageContext.getShell(),
|
// this should cause an logout with specified message that password change
|
||||||
this.i18nSupport.getText("sebserver.login.password.change"),
|
// was successful and the pointing the need of re login with the new password
|
||||||
this.i18nSupport.getText("sebserver.login.password.change.success"),
|
this.pageService.logout(pageContext);
|
||||||
SWT.ICON_INFORMATION,
|
final MessageBox error = new Message(
|
||||||
this.i18nSupport);
|
pageContext.getShell(),
|
||||||
error.open(null);
|
this.i18nSupport.getText("sebserver.login.password.change"),
|
||||||
}
|
this.i18nSupport.getText("sebserver.login.password.change.success"),
|
||||||
return saveAction;
|
SWT.ICON_INFORMATION,
|
||||||
})
|
this.i18nSupport);
|
||||||
.ignoreMoveAwayFromEdit()
|
error.open(null);
|
||||||
.publish()
|
}
|
||||||
|
return saveAction;
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
|
})
|
||||||
.withExec(this.pageService.backToCurrentFunction())
|
.ignoreMoveAwayFromEdit()
|
||||||
.publish();
|
.publish()
|
||||||
}
|
|
||||||
|
.newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
|
||||||
}
|
.withExec(this.pageService.backToCurrentFunction())
|
||||||
|
.publish();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,279 +1,291 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.tomcat.util.buf.StringUtils;
|
import org.apache.tomcat.util.buf.StringUtils;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
|
import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserAccount;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserAccount;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
import ch.ethz.seb.sebserver.gui.form.FormHandle;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.ActivateUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.DeactivateUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.DeactivateUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.NewUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.NewUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.SaveUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.SaveUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class UserAccountForm implements TemplateComposer {
|
public class UserAccountForm implements TemplateComposer {
|
||||||
|
|
||||||
static final LocTextKey TITLE_TEXT_KEY =
|
static final LocTextKey TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.title");
|
new LocTextKey("sebserver.useraccount.form.title");
|
||||||
static final LocTextKey NEW_TITLE_TEXT_KEY =
|
static final LocTextKey NEW_TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.title.new");
|
new LocTextKey("sebserver.useraccount.form.title.new");
|
||||||
|
|
||||||
static final LocTextKey FORM_PASSWORD_CONFIRM_TEXT_KEY =
|
static final LocTextKey FORM_PASSWORD_CONFIRM_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.password.confirm");
|
new LocTextKey("sebserver.useraccount.form.password.confirm");
|
||||||
static final LocTextKey FORM_PASSWORD_TEXT_KEY =
|
static final LocTextKey FORM_PASSWORD_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.password");
|
new LocTextKey("sebserver.useraccount.form.password");
|
||||||
static final LocTextKey FORM_ROLES_TEXT_KEY =
|
static final LocTextKey FORM_ROLES_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.roles");
|
new LocTextKey("sebserver.useraccount.form.roles");
|
||||||
static final LocTextKey FORM_TIMEZONE_TEXT_KEY =
|
static final LocTextKey FORM_TIMEZONE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.timezone");
|
new LocTextKey("sebserver.useraccount.form.timezone");
|
||||||
static final LocTextKey FORM_MAIL_TEXT_KEY =
|
static final LocTextKey FORM_MAIL_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.mail");
|
new LocTextKey("sebserver.useraccount.form.mail");
|
||||||
static final LocTextKey FORM_USERNAME_TEXT_KEY =
|
static final LocTextKey FORM_USERNAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.username");
|
new LocTextKey("sebserver.useraccount.form.username");
|
||||||
static final LocTextKey FORM_NAME_TEXT_KEY =
|
static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.name");
|
new LocTextKey("sebserver.useraccount.form.name");
|
||||||
static final LocTextKey FORM_SURNAME_TEXT_KEY =
|
static final LocTextKey FORM_SURNAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.surname");
|
new LocTextKey("sebserver.useraccount.form.surname");
|
||||||
static final LocTextKey FORM_INSTITUTION_TEXT_KEY =
|
static final LocTextKey FORM_INSTITUTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.institution");
|
new LocTextKey("sebserver.useraccount.form.institution");
|
||||||
static final LocTextKey FORM_CREATION_DATE_TEXT_KEY =
|
static final LocTextKey FORM_CREATION_DATE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.creationdate");
|
new LocTextKey("sebserver.useraccount.form.creationdate");
|
||||||
static final LocTextKey FORM_LANG_TEXT_KEY =
|
static final LocTextKey FORM_LANG_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.useraccount.form.language");
|
new LocTextKey("sebserver.useraccount.form.language");
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final ResourceService resourceService;
|
private final ResourceService resourceService;
|
||||||
private final boolean multilingual;
|
private final boolean multilingual;
|
||||||
|
|
||||||
protected UserAccountForm(
|
protected UserAccountForm(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final ResourceService resourceService,
|
final ResourceService resourceService,
|
||||||
@Value("${sebserver.gui.multilingual:false}") final Boolean multilingual) {
|
@Value("${sebserver.gui.multilingual:false}") final Boolean multilingual) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.resourceService = resourceService;
|
this.resourceService = resourceService;
|
||||||
this.multilingual = BooleanUtils.toBoolean(multilingual);
|
this.multilingual = BooleanUtils.toBoolean(multilingual);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final CurrentUser currentUser = this.resourceService.getCurrentUser();
|
final CurrentUser currentUser = this.resourceService.getCurrentUser();
|
||||||
final RestService restService = this.resourceService.getRestService();
|
final RestService restService = this.resourceService.getRestService();
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
|
|
||||||
final UserInfo user = currentUser.get();
|
final UserInfo user = currentUser.get();
|
||||||
final EntityKey entityKey = pageContext.getEntityKey();
|
final EntityKey entityKey = pageContext.getEntityKey();
|
||||||
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
final EntityKey parentEntityKey = pageContext.getParentEntityKey();
|
||||||
final boolean readonly = pageContext.isReadonly();
|
final boolean readonly = pageContext.isReadonly();
|
||||||
|
|
||||||
final BooleanSupplier isNew = () -> entityKey == null;
|
final BooleanSupplier isNew = () -> entityKey == null;
|
||||||
final BooleanSupplier isNotNew = () -> !isNew.getAsBoolean();
|
final BooleanSupplier isNotNew = () -> !isNew.getAsBoolean();
|
||||||
final BooleanSupplier isSEBAdmin = () -> user.hasRole(UserRole.SEB_SERVER_ADMIN);
|
final BooleanSupplier isSEBAdmin = () -> user.hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||||
|
|
||||||
// get data or create new. handle error if happen
|
// get data or create new. handle error if happen
|
||||||
final UserAccount userAccount = isNew.getAsBoolean()
|
final UserAccount userAccount = isNew.getAsBoolean()
|
||||||
? UserMod.createNew((parentEntityKey != null)
|
? UserMod.createNew((parentEntityKey != null)
|
||||||
? Long.valueOf(parentEntityKey.modelId)
|
? Long.valueOf(parentEntityKey.modelId)
|
||||||
: user.institutionId)
|
: currentUser.get().institutionId)
|
||||||
: restService
|
: restService
|
||||||
.getBuilder(GetUserAccount.class)
|
.getBuilder(GetUserAccount.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
.call()
|
.call()
|
||||||
.onError(error -> pageContext.notifyLoadError(EntityType.USER, error))
|
.onError(error -> pageContext.notifyLoadError(EntityType.USER, error))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final boolean roleBasedEditGrant = Privilege.hasRoleBasedUserAccountEditGrant(userAccount, currentUser.get());
|
final boolean roleBasedEditGrant = Privilege.hasRoleBasedUserAccountEditGrant(userAccount, currentUser.get());
|
||||||
// new PageContext with actual EntityKey
|
// new PageContext with actual EntityKey
|
||||||
final PageContext formContext = pageContext.withEntityKey(userAccount.getEntityKey());
|
final PageContext formContext = pageContext.withEntityKey(userAccount.getEntityKey());
|
||||||
final boolean ownAccount = user.uuid.equals(userAccount.getModelId());
|
final boolean ownAccount = user.uuid.equals(userAccount.getModelId());
|
||||||
final EntityGrantCheck userGrantCheck = currentUser.entityGrantCheck(userAccount);
|
final EntityGrantCheck userGrantCheck = currentUser.entityGrantCheck(userAccount);
|
||||||
|
|
||||||
final boolean writeGrant = roleBasedEditGrant && userGrantCheck.w();
|
final boolean writeGrant = roleBasedEditGrant && userGrantCheck.w();
|
||||||
final boolean modifyGrant = roleBasedEditGrant && userGrantCheck.m();
|
final boolean modifyGrant = roleBasedEditGrant && userGrantCheck.m();
|
||||||
final boolean institutionalWriteGrant = currentUser.hasInstitutionalPrivilege(
|
final boolean institutionalWriteGrant = currentUser.hasInstitutionalPrivilege(
|
||||||
PrivilegeType.WRITE,
|
PrivilegeType.WRITE,
|
||||||
EntityType.USER);
|
EntityType.USER);
|
||||||
|
|
||||||
final boolean institutionActive = restService.getBuilder(GetInstitution.class)
|
final boolean institutionActive = userAccount.getInstitutionId() != null &&
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(userAccount.getInstitutionId()))
|
restService.getBuilder(GetInstitution.class)
|
||||||
.call()
|
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(userAccount.getInstitutionId()))
|
||||||
.map(inst -> inst.active)
|
.call()
|
||||||
.getOr(false);
|
.map(inst -> inst.active)
|
||||||
|
.getOr(false);
|
||||||
// the default page layout with title
|
|
||||||
final LocTextKey titleKey = isNotNew.getAsBoolean()
|
// the default page layout with title
|
||||||
? TITLE_TEXT_KEY
|
final LocTextKey titleKey = isNotNew.getAsBoolean()
|
||||||
: NEW_TITLE_TEXT_KEY;
|
? TITLE_TEXT_KEY
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
: NEW_TITLE_TEXT_KEY;
|
||||||
formContext.getParent(),
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
titleKey);
|
formContext.getParent(),
|
||||||
|
titleKey);
|
||||||
// The UserAccount form
|
|
||||||
final FormHandle<UserInfo> formHandle = this.pageService.formBuilder(
|
// The UserAccount form
|
||||||
formContext.copyOf(content))
|
final FormHandle<UserInfo> formHandle = this.pageService.formBuilder(
|
||||||
.readonly(readonly)
|
formContext.copyOf(content))
|
||||||
.putStaticValueIf(isNotNew,
|
.readonly(readonly)
|
||||||
Domain.USER.ATTR_UUID,
|
.putStaticValueIf(isNotNew,
|
||||||
userAccount.getModelId())
|
Domain.USER.ATTR_UUID,
|
||||||
.putStaticValueIf(isNotNew,
|
userAccount.getModelId())
|
||||||
Domain.USER.ATTR_INSTITUTION_ID,
|
.putStaticValueIf(isNotNew,
|
||||||
String.valueOf(userAccount.getInstitutionId()))
|
Domain.USER.ATTR_INSTITUTION_ID,
|
||||||
.putStaticValueIf(
|
String.valueOf(userAccount.getInstitutionId()))
|
||||||
() -> !this.multilingual,
|
.putStaticValueIf(
|
||||||
Domain.USER.ATTR_LANGUAGE,
|
() -> !this.multilingual,
|
||||||
"en")
|
Domain.USER.ATTR_LANGUAGE,
|
||||||
.addFieldIf(
|
"en")
|
||||||
isSEBAdmin,
|
.addFieldIf(
|
||||||
() -> FormBuilder.singleSelection(
|
isSEBAdmin,
|
||||||
Domain.USER.ATTR_INSTITUTION_ID,
|
() -> FormBuilder.singleSelection(
|
||||||
FORM_INSTITUTION_TEXT_KEY,
|
Domain.USER.ATTR_INSTITUTION_ID,
|
||||||
String.valueOf(userAccount.getInstitutionId()),
|
FORM_INSTITUTION_TEXT_KEY,
|
||||||
() -> this.resourceService.institutionResource())
|
String.valueOf(userAccount.getInstitutionId()),
|
||||||
.readonlyIf(isNotNew))
|
this.resourceService::institutionResource)
|
||||||
.addFieldIf(
|
.readonlyIf(isNotNew)
|
||||||
() -> readonly,
|
.mandatory(!readonly))
|
||||||
() -> FormBuilder.text(
|
.addFieldIf(
|
||||||
Domain.USER.ATTR_CREATION_DATE,
|
() -> readonly,
|
||||||
FORM_CREATION_DATE_TEXT_KEY,
|
() -> FormBuilder.text(
|
||||||
this.pageService.getI18nSupport().formatDisplayDate(userAccount.getCreationDate()))
|
Domain.USER.ATTR_CREATION_DATE,
|
||||||
.readonly(true))
|
FORM_CREATION_DATE_TEXT_KEY,
|
||||||
.addField(FormBuilder.text(
|
this.pageService.getI18nSupport().formatDisplayDate(userAccount.getCreationDate()))
|
||||||
Domain.USER.ATTR_NAME,
|
.readonly(true))
|
||||||
FORM_NAME_TEXT_KEY,
|
.addField(FormBuilder.text(
|
||||||
userAccount.getName()))
|
Domain.USER.ATTR_NAME,
|
||||||
.addField(FormBuilder.text(
|
FORM_NAME_TEXT_KEY,
|
||||||
Domain.USER.ATTR_SURNAME,
|
userAccount.getName())
|
||||||
FORM_SURNAME_TEXT_KEY,
|
.mandatory(!readonly))
|
||||||
userAccount.getSurname()))
|
.addField(FormBuilder.text(
|
||||||
.addField(FormBuilder.text(
|
Domain.USER.ATTR_SURNAME,
|
||||||
Domain.USER.ATTR_USERNAME,
|
FORM_SURNAME_TEXT_KEY,
|
||||||
FORM_USERNAME_TEXT_KEY,
|
userAccount.getSurname())
|
||||||
userAccount.getUsername()))
|
.mandatory(!readonly))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
Domain.USER.ATTR_EMAIL,
|
Domain.USER.ATTR_USERNAME,
|
||||||
FORM_MAIL_TEXT_KEY,
|
FORM_USERNAME_TEXT_KEY,
|
||||||
userAccount.getEmail()))
|
userAccount.getUsername())
|
||||||
.addFieldIf(
|
.mandatory(!readonly))
|
||||||
() -> this.multilingual,
|
.addField(FormBuilder.text(
|
||||||
() -> FormBuilder.singleSelection(
|
Domain.USER.ATTR_EMAIL,
|
||||||
Domain.USER.ATTR_LANGUAGE,
|
FORM_MAIL_TEXT_KEY,
|
||||||
FORM_LANG_TEXT_KEY,
|
userAccount.getEmail()))
|
||||||
userAccount.getLanguage().getLanguage(),
|
.addFieldIf(
|
||||||
this.resourceService::languageResources))
|
() -> this.multilingual,
|
||||||
.addField(FormBuilder.singleSelection(
|
() -> FormBuilder.singleSelection(
|
||||||
Domain.USER.ATTR_TIMEZONE,
|
Domain.USER.ATTR_LANGUAGE,
|
||||||
FORM_TIMEZONE_TEXT_KEY,
|
FORM_LANG_TEXT_KEY,
|
||||||
userAccount.getTimeZone().getID(),
|
userAccount.getLanguage().getLanguage(),
|
||||||
this.resourceService::timeZoneResources))
|
this.resourceService::languageResources))
|
||||||
.addFieldIf(
|
.addField(FormBuilder.singleSelection(
|
||||||
() -> modifyGrant,
|
Domain.USER.ATTR_TIMEZONE,
|
||||||
() -> FormBuilder.multiCheckboxSelection(
|
FORM_TIMEZONE_TEXT_KEY,
|
||||||
USER_ROLE.REFERENCE_NAME,
|
userAccount.getTimeZone().getID(),
|
||||||
FORM_ROLES_TEXT_KEY,
|
this.resourceService::timeZoneResources)
|
||||||
StringUtils.join(userAccount.getRoles(), Constants.LIST_SEPARATOR_CHAR),
|
.mandatory(!readonly))
|
||||||
this.resourceService::userRoleResources)
|
.addFieldIf(
|
||||||
.visibleIf(writeGrant))
|
() -> modifyGrant,
|
||||||
.addFieldIf(
|
() -> FormBuilder.multiCheckboxSelection(
|
||||||
isNew,
|
USER_ROLE.REFERENCE_NAME,
|
||||||
() -> FormBuilder.text(
|
FORM_ROLES_TEXT_KEY,
|
||||||
PasswordChange.ATTR_NAME_NEW_PASSWORD,
|
StringUtils.join(userAccount.getRoles(), Constants.LIST_SEPARATOR_CHAR),
|
||||||
FORM_PASSWORD_TEXT_KEY)
|
this.resourceService::userRoleResources)
|
||||||
.asPasswordField())
|
.visibleIf(writeGrant)
|
||||||
.addFieldIf(
|
.mandatory(!readonly))
|
||||||
isNew,
|
.addFieldIf(
|
||||||
() -> FormBuilder.text(
|
isNew,
|
||||||
PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD,
|
() -> FormBuilder.text(
|
||||||
FORM_PASSWORD_CONFIRM_TEXT_KEY)
|
PasswordChange.ATTR_NAME_NEW_PASSWORD,
|
||||||
.asPasswordField())
|
FORM_PASSWORD_TEXT_KEY)
|
||||||
.buildFor((entityKey == null)
|
.asPasswordField()
|
||||||
? restService.getRestCall(NewUserAccount.class)
|
.mandatory(!readonly))
|
||||||
: restService.getRestCall(SaveUserAccount.class));
|
.addFieldIf(
|
||||||
|
isNew,
|
||||||
// propagate content actions to action-pane
|
() -> FormBuilder.text(
|
||||||
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
PasswordChange.ATTR_NAME_CONFIRM_NEW_PASSWORD,
|
||||||
|
FORM_PASSWORD_CONFIRM_TEXT_KEY)
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_NEW)
|
.asPasswordField()
|
||||||
.publishIf(() -> institutionalWriteGrant && readonly && institutionActive)
|
.mandatory(!readonly))
|
||||||
|
.buildFor((entityKey == null)
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_MODIFY)
|
? restService.getRestCall(NewUserAccount.class)
|
||||||
.withEntityKey(entityKey)
|
: restService.getRestCall(SaveUserAccount.class));
|
||||||
.publishIf(() -> modifyGrant && readonly && institutionActive)
|
|
||||||
|
// propagate content actions to action-pane
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD)
|
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
||||||
.withEntityKey(entityKey)
|
|
||||||
.publishIf(() -> modifyGrant && readonly && institutionActive && userAccount.isActive())
|
.newAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||||
|
.publishIf(() -> institutionalWriteGrant && readonly && institutionActive)
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE)
|
|
||||||
.withEntityKey(entityKey)
|
.newAction(ActionDefinition.USER_ACCOUNT_MODIFY)
|
||||||
.withSimpleRestCall(restService, DeactivateUserAccount.class)
|
.withEntityKey(entityKey)
|
||||||
.withConfirm(this.pageService.confirmDeactivation(userAccount))
|
.publishIf(() -> modifyGrant && readonly && institutionActive)
|
||||||
.publishIf(() -> writeGrant && readonly && institutionActive && userAccount.isActive())
|
|
||||||
|
.newAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSWORD)
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_ACTIVATE)
|
.withEntityKey(entityKey)
|
||||||
.withEntityKey(entityKey)
|
.publishIf(() -> modifyGrant && readonly && institutionActive && userAccount.isActive())
|
||||||
.withSimpleRestCall(restService, ActivateUserAccount.class)
|
|
||||||
.publishIf(() -> writeGrant && readonly && institutionActive && !userAccount.isActive())
|
.newAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_SAVE)
|
.withSimpleRestCall(restService, DeactivateUserAccount.class)
|
||||||
.withEntityKey(entityKey)
|
.withConfirm(this.pageService.confirmDeactivation(userAccount))
|
||||||
.withExec(action -> {
|
.publishIf(() -> writeGrant && readonly && institutionActive && userAccount.isActive())
|
||||||
return formHandle.handleFormPost(formHandle.doAPIPost()
|
|
||||||
.map(userInfo -> {
|
.newAction(ActionDefinition.USER_ACCOUNT_ACTIVATE)
|
||||||
if (ownAccount) {
|
.withEntityKey(entityKey)
|
||||||
currentUser.refresh(userInfo);
|
.withSimpleRestCall(restService, ActivateUserAccount.class)
|
||||||
}
|
.publishIf(() -> writeGrant && readonly && institutionActive && !userAccount.isActive())
|
||||||
return userInfo;
|
|
||||||
}),
|
.newAction(ActionDefinition.USER_ACCOUNT_SAVE)
|
||||||
action);
|
.withEntityKey(entityKey)
|
||||||
})
|
.withExec(action -> formHandle.handleFormPost(formHandle.doAPIPost()
|
||||||
.ignoreMoveAwayFromEdit()
|
.map(userInfo -> {
|
||||||
.publishIf(() -> !readonly)
|
if (ownAccount) {
|
||||||
|
currentUser.refresh(userInfo);
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
|
}
|
||||||
.withExec(this.pageService.backToCurrentFunction())
|
return userInfo;
|
||||||
.publishIf(() -> !readonly);
|
}),
|
||||||
}
|
action))
|
||||||
|
.ignoreMoveAwayFromEdit()
|
||||||
}
|
.publishIf(() -> !readonly)
|
||||||
|
|
||||||
|
.newAction(ActionDefinition.USER_ACCOUNT_SAVE_AND_ACTIVATE)
|
||||||
|
.withEntityKey(entityKey)
|
||||||
|
.withExec(formHandle::saveAndActivate)
|
||||||
|
.ignoreMoveAwayFromEdit()
|
||||||
|
.publishIf(() -> !readonly && !ownAccount && !userAccount.isActive())
|
||||||
|
|
||||||
|
.newAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
|
||||||
|
.withExec(this.pageService.backToCurrentFunction())
|
||||||
|
.publishIf(() -> !readonly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,236 +1,250 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.function.BooleanSupplier;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import java.util.function.Function;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import org.springframework.stereotype.Component;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccountPage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccountPage;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.GrantCheck;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import org.springframework.stereotype.Component;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import java.util.function.BooleanSupplier;
|
||||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
import java.util.function.Function;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
|
||||||
|
@Lazy
|
||||||
@Lazy
|
@Component
|
||||||
@Component
|
@GuiProfile
|
||||||
@GuiProfile
|
public class UserAccountList implements TemplateComposer {
|
||||||
public class UserAccountList implements TemplateComposer {
|
|
||||||
|
// localized text keys
|
||||||
// localized text keys
|
private static final LocTextKey EMPTY_TEXT_KEY =
|
||||||
private static final LocTextKey EMPTY_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.empty");
|
||||||
new LocTextKey("sebserver.useraccount.list.empty");
|
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
||||||
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.column.institution");
|
||||||
new LocTextKey("sebserver.useraccount.list.column.institution");
|
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
||||||
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.info.pleaseSelect");
|
||||||
new LocTextKey("sebserver.useraccount.info.pleaseSelect");
|
private static final LocTextKey ACTIVE_TEXT_KEY =
|
||||||
private static final LocTextKey ACTIVE_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.column.active");
|
||||||
new LocTextKey("sebserver.useraccount.list.column.active");
|
private static final LocTextKey LANG_TEXT_KEY =
|
||||||
private static final LocTextKey LANG_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.column.language");
|
||||||
new LocTextKey("sebserver.useraccount.list.column.language");
|
private static final LocTextKey MAIL_TEXT_KEY =
|
||||||
private static final LocTextKey MAIL_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.column.email");
|
||||||
new LocTextKey("sebserver.useraccount.list.column.email");
|
private static final LocTextKey USER_NAME_TEXT_KEY =
|
||||||
private static final LocTextKey USER_NAME_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.column.username");
|
||||||
new LocTextKey("sebserver.useraccount.list.column.username");
|
private static final LocTextKey NAME_TEXT_KEY =
|
||||||
private static final LocTextKey NAME_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.column.name");
|
||||||
new LocTextKey("sebserver.useraccount.list.column.name");
|
private static final LocTextKey TITLE_TEXT_KEY =
|
||||||
private static final LocTextKey TITLE_TEXT_KEY =
|
new LocTextKey("sebserver.useraccount.list.title");
|
||||||
new LocTextKey("sebserver.useraccount.list.title");
|
private static final LocTextKey NO_EDIT_RIGHT_MESSAGE =
|
||||||
private static final LocTextKey NO_EDIT_RIGHT_MESSAGE =
|
new LocTextKey("sebserver.useraccount.info.notEditable");
|
||||||
new LocTextKey("sebserver.useraccount.info.notEditable");
|
|
||||||
|
// filter attribute models
|
||||||
// filter attribute models
|
private final TableFilterAttribute institutionFilter;
|
||||||
private final TableFilterAttribute institutionFilter;
|
private final TableFilterAttribute nameFilter =
|
||||||
private final TableFilterAttribute nameFilter =
|
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
|
private final TableFilterAttribute usernameFilter =
|
||||||
private final TableFilterAttribute usernameFilter =
|
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_USER_NAME);
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_USER_NAME);
|
private final TableFilterAttribute mailFilter =
|
||||||
private final TableFilterAttribute mailFilter =
|
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_EMAIL);
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_EMAIL);
|
private final TableFilterAttribute languageFilter;
|
||||||
private final TableFilterAttribute languageFilter;
|
private final TableFilterAttribute activityFilter;
|
||||||
private final TableFilterAttribute activityFilter;
|
|
||||||
|
// dependencies
|
||||||
// dependencies
|
private final PageService pageService;
|
||||||
private final PageService pageService;
|
private final ResourceService resourceService;
|
||||||
private final ResourceService resourceService;
|
private final int pageSize;
|
||||||
private final int pageSize;
|
private final boolean multilingual;
|
||||||
private final boolean multilingual;
|
|
||||||
|
protected UserAccountList(
|
||||||
protected UserAccountList(
|
final PageService pageService,
|
||||||
final PageService pageService,
|
final ResourceService resourceService,
|
||||||
final ResourceService resourceService,
|
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize,
|
||||||
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize,
|
@Value("${sebserver.gui.multilingual:false}") final Boolean ml) {
|
||||||
@Value("${sebserver.gui.multilingual:false}") final Boolean ml) {
|
|
||||||
|
this.pageService = pageService;
|
||||||
this.pageService = pageService;
|
this.resourceService = resourceService;
|
||||||
this.resourceService = resourceService;
|
this.pageSize = pageSize;
|
||||||
this.pageSize = pageSize;
|
this.multilingual = BooleanUtils.isTrue(ml);
|
||||||
this.multilingual = BooleanUtils.isTrue(ml);
|
|
||||||
|
this.institutionFilter = new TableFilterAttribute(
|
||||||
this.institutionFilter = new TableFilterAttribute(
|
CriteriaType.SINGLE_SELECTION,
|
||||||
CriteriaType.SINGLE_SELECTION,
|
Entity.FILTER_ATTR_INSTITUTION,
|
||||||
Entity.FILTER_ATTR_INSTITUTION,
|
this.resourceService::institutionResource);
|
||||||
this.resourceService::institutionResource);
|
|
||||||
|
this.languageFilter = new TableFilterAttribute(
|
||||||
this.languageFilter = new TableFilterAttribute(
|
CriteriaType.SINGLE_SELECTION,
|
||||||
CriteriaType.SINGLE_SELECTION,
|
UserInfo.FILTER_ATTR_LANGUAGE,
|
||||||
UserInfo.FILTER_ATTR_LANGUAGE,
|
this.resourceService::languageResources);
|
||||||
this.resourceService::languageResources);
|
|
||||||
|
this.activityFilter = new TableFilterAttribute(
|
||||||
this.activityFilter = new TableFilterAttribute(
|
CriteriaType.SINGLE_SELECTION,
|
||||||
CriteriaType.SINGLE_SELECTION,
|
UserInfo.FILTER_ATTR_ACTIVE,
|
||||||
UserInfo.FILTER_ATTR_ACTIVE,
|
this.resourceService::activityResources);
|
||||||
this.resourceService::activityResources);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public void compose(final PageContext pageContext) {
|
||||||
public void compose(final PageContext pageContext) {
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final CurrentUser currentUser = this.resourceService.getCurrentUser();
|
||||||
final CurrentUser currentUser = this.resourceService.getCurrentUser();
|
final RestService restService = this.resourceService.getRestService();
|
||||||
final RestService restService = this.resourceService.getRestService();
|
// content page layout with title
|
||||||
// content page layout with title
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
pageContext.getParent(),
|
||||||
pageContext.getParent(),
|
TITLE_TEXT_KEY);
|
||||||
TITLE_TEXT_KEY);
|
|
||||||
|
final BooleanSupplier isSEBAdmin = () -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||||
final BooleanSupplier isSEBAdmin = () -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
||||||
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(pageContext.clearEntityKeys());
|
|
||||||
|
// table
|
||||||
// table
|
final EntityTable<UserInfo> table = this.pageService.entityTableBuilder(
|
||||||
final EntityTable<UserInfo> table = this.pageService.entityTableBuilder(
|
restService.getRestCall(GetUserAccountPage.class))
|
||||||
restService.getRestCall(GetUserAccountPage.class))
|
.withEmptyMessage(EMPTY_TEXT_KEY)
|
||||||
.withEmptyMessage(EMPTY_TEXT_KEY)
|
.withPaging(this.pageSize)
|
||||||
.withPaging(this.pageSize)
|
|
||||||
|
.withColumnIf(
|
||||||
.withColumnIf(
|
isSEBAdmin,
|
||||||
isSEBAdmin,
|
() -> new ColumnDefinition<>(
|
||||||
() -> new ColumnDefinition<>(
|
Domain.USER.ATTR_INSTITUTION_ID,
|
||||||
Domain.USER.ATTR_INSTITUTION_ID,
|
INSTITUTION_TEXT_KEY,
|
||||||
INSTITUTION_TEXT_KEY,
|
userInstitutionNameFunction(this.resourceService))
|
||||||
userInstitutionNameFunction(this.resourceService))
|
.withFilter(this.institutionFilter)
|
||||||
.withFilter(this.institutionFilter)
|
.widthProportion(2))
|
||||||
.widthProportion(2))
|
|
||||||
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withColumn(new ColumnDefinition<>(
|
Domain.USER.ATTR_NAME,
|
||||||
Domain.USER.ATTR_NAME,
|
NAME_TEXT_KEY,
|
||||||
NAME_TEXT_KEY,
|
UserInfo::getName)
|
||||||
UserInfo::getName)
|
.withFilter(this.nameFilter)
|
||||||
.withFilter(this.nameFilter)
|
.sortable()
|
||||||
.sortable()
|
.widthProportion(2))
|
||||||
.widthProportion(2))
|
|
||||||
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withColumn(new ColumnDefinition<>(
|
Domain.USER.ATTR_USERNAME,
|
||||||
Domain.USER.ATTR_USERNAME,
|
USER_NAME_TEXT_KEY,
|
||||||
USER_NAME_TEXT_KEY,
|
UserInfo::getUsername)
|
||||||
UserInfo::getUsername)
|
.withFilter(this.usernameFilter)
|
||||||
.withFilter(this.usernameFilter)
|
.sortable()
|
||||||
.sortable()
|
.widthProportion(2))
|
||||||
.widthProportion(2))
|
|
||||||
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withColumn(new ColumnDefinition<>(
|
Domain.USER.ATTR_EMAIL,
|
||||||
Domain.USER.ATTR_EMAIL,
|
MAIL_TEXT_KEY,
|
||||||
MAIL_TEXT_KEY,
|
UserInfo::getEmail)
|
||||||
UserInfo::getEmail)
|
.withFilter(this.mailFilter)
|
||||||
.withFilter(this.mailFilter)
|
.sortable()
|
||||||
.sortable()
|
.widthProportion(3))
|
||||||
.widthProportion(3))
|
|
||||||
|
.withColumnIf(() -> this.multilingual,
|
||||||
.withColumnIf(() -> this.multilingual,
|
() -> new ColumnDefinition<>(
|
||||||
() -> new ColumnDefinition<>(
|
Domain.USER.ATTR_LANGUAGE,
|
||||||
Domain.USER.ATTR_LANGUAGE,
|
LANG_TEXT_KEY,
|
||||||
LANG_TEXT_KEY,
|
this::getLocaleDisplayText)
|
||||||
this::getLocaleDisplayText)
|
.withFilter(this.languageFilter)
|
||||||
.withFilter(this.languageFilter)
|
.localized()
|
||||||
.localized()
|
.sortable()
|
||||||
.sortable()
|
.widthProportion(1))
|
||||||
.widthProportion(1))
|
|
||||||
|
.withColumn(new ColumnDefinition<>(
|
||||||
.withColumn(new ColumnDefinition<>(
|
Domain.USER.ATTR_ACTIVE,
|
||||||
Domain.USER.ATTR_ACTIVE,
|
ACTIVE_TEXT_KEY,
|
||||||
ACTIVE_TEXT_KEY,
|
this.pageService.getResourceService().<UserInfo> localizedActivityFunction())
|
||||||
this.pageService.getResourceService().<UserInfo> localizedActivityFunction())
|
.sortable()
|
||||||
.sortable()
|
.withFilter(this.activityFilter)
|
||||||
.withFilter(this.activityFilter)
|
.widthProportion(1))
|
||||||
.widthProportion(1))
|
|
||||||
|
.withDefaultAction(actionBuilder
|
||||||
.withDefaultAction(actionBuilder
|
.newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
|
.create())
|
||||||
.create())
|
|
||||||
.compose(pageContext.copyOf(content));
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
|
ActionDefinition.USER_ACCOUNT_TOGGLE_ACTIVITY,
|
||||||
// propagate content actions to action-pane
|
ActionDefinition.USER_ACCOUNT_ACTIVATE,
|
||||||
final GrantCheck userGrant = currentUser.grantCheck(EntityType.USER);
|
ActionDefinition.USER_ACCOUNT_DEACTIVATE,
|
||||||
actionBuilder
|
pageContext,
|
||||||
|
ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST,
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_NEW)
|
ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST,
|
||||||
.publishIf(userGrant::iw)
|
ActionDefinition.USER_ACCOUNT_TOGGLE_ACTIVITY))
|
||||||
|
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
|
.compose(pageContext.copyOf(content));
|
||||||
.withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
|
||||||
.publishIf(() -> table.hasAnyContent())
|
// propagate content actions to action-pane
|
||||||
|
final GrantCheck userGrant = currentUser.grantCheck(EntityType.USER);
|
||||||
.newAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST)
|
actionBuilder
|
||||||
.withSelect(table::getSelection, this::editAction, EMPTY_SELECTION_TEXT_KEY)
|
|
||||||
.publishIf(() -> userGrant.im() && table.hasAnyContent());
|
.newAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||||
}
|
.publishIf(userGrant::iw)
|
||||||
|
|
||||||
private PageAction editAction(final PageAction pageAction) {
|
.newAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
|
||||||
if (!this.resourceService.getRestService()
|
.withSelect(table::getSelection, PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
||||||
.getBuilder(GetUserAccount.class)
|
.publishIf(table::hasAnyContent, false)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, pageAction.getSingleSelection().modelId)
|
|
||||||
.call()
|
.newAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST)
|
||||||
.map(user -> Privilege.hasRoleBasedUserAccountEditGrant(user,
|
.withSelect(table::getSelection, this::editAction, EMPTY_SELECTION_TEXT_KEY)
|
||||||
this.resourceService.getCurrentUser().get()))
|
.publishIf(() -> userGrant.im() && table.hasAnyContent(), false)
|
||||||
.getOr(false)) {
|
|
||||||
throw new PageMessageException(NO_EDIT_RIGHT_MESSAGE);
|
.newAction(ActionDefinition.USER_ACCOUNT_TOGGLE_ACTIVITY)
|
||||||
}
|
.withExec(this.pageService.activationToggleActionFunction(table, EMPTY_SELECTION_TEXT_KEY))
|
||||||
|
.withConfirm(this.pageService.confirmDeactivation(table))
|
||||||
return PageAction.applySingleSelectionAsEntityKey(pageAction);
|
.publishIf(() -> userGrant.m() && table.hasAnyContent(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getLocaleDisplayText(final UserInfo userInfo) {
|
private PageAction editAction(final PageAction pageAction) {
|
||||||
return (userInfo.language != null)
|
if (!this.resourceService.getRestService()
|
||||||
? userInfo.language.getDisplayLanguage(this.pageService.getI18nSupport().getUsersLanguageLocale())
|
.getBuilder(GetUserAccount.class)
|
||||||
: Constants.EMPTY_NOTE;
|
.withURIVariable(API.PARAM_MODEL_ID, pageAction.getSingleSelection().modelId)
|
||||||
}
|
.call()
|
||||||
|
.map(user -> Privilege.hasRoleBasedUserAccountEditGrant(user,
|
||||||
private static Function<UserInfo, String> userInstitutionNameFunction(final ResourceService resourceService) {
|
this.resourceService.getCurrentUser().get()))
|
||||||
final Function<String, String> institutionNameFunction = resourceService.getInstitutionNameFunction();
|
.getOr(false)) {
|
||||||
return userInfo -> institutionNameFunction.apply(String.valueOf(userInfo.institutionId));
|
throw new PageMessageException(NO_EDIT_RIGHT_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
return PageAction.applySingleSelectionAsEntityKey(pageAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getLocaleDisplayText(final UserInfo userInfo) {
|
||||||
|
return (userInfo.language != null)
|
||||||
|
? userInfo.language.getDisplayLanguage(this.pageService.getI18nSupport().getUsersLanguageLocale())
|
||||||
|
: Constants.EMPTY_NOTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Function<UserInfo, String> userInstitutionNameFunction(final ResourceService resourceService) {
|
||||||
|
final Function<String, String> institutionNameFunction = resourceService.getInstitutionNameFunction();
|
||||||
|
return userInfo -> institutionNameFunction.apply(String.valueOf(userInfo.institutionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,276 +1,279 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.logs.GetUserLogPage;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.logs.GetUserLogPage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccount;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class UserActivityLogs implements TemplateComposer {
|
public class UserActivityLogs implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey DETAILS_TITLE_TEXT_KEY =
|
private static final LocTextKey DETAILS_TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.details.title");
|
new LocTextKey("sebserver.userlogs.details.title");
|
||||||
private static final LocTextKey TITLE_TEXT_KEY =
|
private static final LocTextKey TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.title");
|
new LocTextKey("sebserver.userlogs.list.title");
|
||||||
private static final LocTextKey EMPTY_TEXT_KEY =
|
private static final LocTextKey EMPTY_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.empty");
|
new LocTextKey("sebserver.userlogs.list.empty");
|
||||||
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
private static final LocTextKey INSTITUTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.column.institution");
|
new LocTextKey("sebserver.userlogs.list.column.institution");
|
||||||
private static final LocTextKey USER_TEXT_KEY =
|
private static final LocTextKey USER_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.column.user");
|
new LocTextKey("sebserver.userlogs.list.column.user");
|
||||||
private static final LocTextKey DATE_TEXT_KEY =
|
private static final LocTextKey DATE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.column.dateTime");
|
new LocTextKey("sebserver.userlogs.list.column.dateTime");
|
||||||
private static final LocTextKey DETAILS_DATE_TEXT_KEY =
|
private static final LocTextKey DETAILS_DATE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.seblogs.details.dateTime");
|
new LocTextKey("sebserver.seblogs.details.dateTime");
|
||||||
private static final LocTextKey ACTIVITY_TEXT_KEY =
|
private static final LocTextKey ACTIVITY_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.column.activityType");
|
new LocTextKey("sebserver.userlogs.list.column.activityType");
|
||||||
private static final LocTextKey ENTITY_TYPE_TEXT_KEY =
|
private static final LocTextKey ENTITY_TYPE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.column.entityType");
|
new LocTextKey("sebserver.userlogs.list.column.entityType");
|
||||||
private static final LocTextKey ENTITY_ID_TEXT_KEY =
|
private static final LocTextKey ENTITY_ID_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.column.entityId");
|
new LocTextKey("sebserver.userlogs.list.column.entityId");
|
||||||
private static final LocTextKey MESSAGE_TEXT_KEY =
|
private static final LocTextKey MESSAGE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.userlogs.list.column.message");
|
new LocTextKey("sebserver.userlogs.list.column.message");
|
||||||
private final static LocTextKey EMPTY_SELECTION_TEXT =
|
private final static LocTextKey EMPTY_SELECTION_TEXT =
|
||||||
new LocTextKey("sebserver.userlogs.info.pleaseSelect");
|
new LocTextKey("sebserver.userlogs.info.pleaseSelect");
|
||||||
|
|
||||||
private final TableFilterAttribute institutionFilter;
|
private final TableFilterAttribute institutionFilter;
|
||||||
private final TableFilterAttribute userNameFilter =
|
private final TableFilterAttribute userNameFilter =
|
||||||
new TableFilterAttribute(CriteriaType.TEXT, UserActivityLog.FILTER_ATTR_USER_NAME);
|
new TableFilterAttribute(CriteriaType.TEXT, UserActivityLog.FILTER_ATTR_USER_NAME);
|
||||||
private final TableFilterAttribute activityFilter;
|
private final TableFilterAttribute activityFilter;
|
||||||
private final TableFilterAttribute entityFilter;
|
private final TableFilterAttribute entityFilter;
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final ResourceService resourceService;
|
private final ResourceService resourceService;
|
||||||
private final I18nSupport i18nSupport;
|
private final I18nSupport i18nSupport;
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
|
|
||||||
public UserActivityLogs(
|
public UserActivityLogs(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.resourceService = pageService.getResourceService();
|
this.resourceService = pageService.getResourceService();
|
||||||
this.i18nSupport = this.resourceService.getI18nSupport();
|
this.i18nSupport = this.resourceService.getI18nSupport();
|
||||||
this.widgetFactory = pageService.getWidgetFactory();
|
this.widgetFactory = pageService.getWidgetFactory();
|
||||||
this.pageSize = pageSize;
|
this.pageSize = pageSize;
|
||||||
|
|
||||||
this.institutionFilter = new TableFilterAttribute(
|
this.institutionFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
Entity.FILTER_ATTR_INSTITUTION,
|
Entity.FILTER_ATTR_INSTITUTION,
|
||||||
this.resourceService::institutionResource);
|
this.resourceService::institutionResource);
|
||||||
|
|
||||||
this.activityFilter = new TableFilterAttribute(
|
this.activityFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES,
|
UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES,
|
||||||
this.resourceService::userActivityTypeResources);
|
this.resourceService::userActivityTypeResources);
|
||||||
|
|
||||||
this.entityFilter = new TableFilterAttribute(
|
this.entityFilter = new TableFilterAttribute(
|
||||||
CriteriaType.SINGLE_SELECTION,
|
CriteriaType.SINGLE_SELECTION,
|
||||||
UserActivityLog.FILTER_ATTR_ENTITY_TYPES,
|
UserActivityLog.FILTER_ATTR_ENTITY_TYPES,
|
||||||
this.resourceService::entityTypeResources);
|
this.resourceService::entityTypeResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final CurrentUser currentUser = this.resourceService.getCurrentUser();
|
final CurrentUser currentUser = this.resourceService.getCurrentUser();
|
||||||
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
final WidgetFactory widgetFactory = this.pageService.getWidgetFactory();
|
||||||
final RestService restService = this.resourceService.getRestService();
|
final RestService restService = this.resourceService.getRestService();
|
||||||
// content page layout with title
|
// content page layout with title
|
||||||
final Composite content = widgetFactory.defaultPageLayout(
|
final Composite content = widgetFactory.defaultPageLayout(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
TITLE_TEXT_KEY);
|
TITLE_TEXT_KEY);
|
||||||
|
|
||||||
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(
|
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(
|
||||||
pageContext
|
pageContext
|
||||||
.clearEntityKeys()
|
.clearEntityKeys()
|
||||||
.clearAttributes());
|
.clearAttributes());
|
||||||
|
|
||||||
final BooleanSupplier isSebAdmin =
|
final BooleanSupplier isSebAdmin =
|
||||||
() -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
() -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
|
||||||
|
|
||||||
final Function<UserActivityLog, String> institutionNameFunction =
|
final Function<UserActivityLog, String> institutionNameFunction =
|
||||||
this.resourceService.getInstitutionNameFunction()
|
this.resourceService.getInstitutionNameFunction()
|
||||||
.compose(log -> {
|
.compose(log -> {
|
||||||
try {
|
try {
|
||||||
final UserInfo user = restService.getBuilder(GetUserAccount.class)
|
final UserInfo user = restService.getBuilder(GetUserAccount.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, log.getUserUuid())
|
.withURIVariable(API.PARAM_MODEL_ID, log.getUserUuid())
|
||||||
.call().getOrThrow();
|
.call().getOrThrow();
|
||||||
return String.valueOf(user.getInstitutionId());
|
return String.valueOf(user.getInstitutionId());
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
return Constants.EMPTY_NOTE;
|
return Constants.EMPTY_NOTE;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// table
|
// table
|
||||||
final EntityTable<UserActivityLog> table = this.pageService.entityTableBuilder(
|
final EntityTable<UserActivityLog> table = this.pageService.entityTableBuilder(
|
||||||
restService.getRestCall(GetUserLogPage.class))
|
restService.getRestCall(GetUserLogPage.class))
|
||||||
.withEmptyMessage(EMPTY_TEXT_KEY)
|
.withEmptyMessage(EMPTY_TEXT_KEY)
|
||||||
.withPaging(this.pageSize)
|
.withPaging(this.pageSize)
|
||||||
|
|
||||||
.withColumnIf(
|
.withColumnIf(
|
||||||
isSebAdmin,
|
isSebAdmin,
|
||||||
() -> new ColumnDefinition<>(
|
() -> new ColumnDefinition<>(
|
||||||
UserActivityLog.FILTER_ATTR_INSTITUTION,
|
UserActivityLog.FILTER_ATTR_INSTITUTION,
|
||||||
INSTITUTION_TEXT_KEY,
|
INSTITUTION_TEXT_KEY,
|
||||||
institutionNameFunction)
|
institutionNameFunction)
|
||||||
.withFilter(this.institutionFilter))
|
.withFilter(this.institutionFilter))
|
||||||
|
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
UserActivityLog.ATTR_USER_NAME,
|
UserActivityLog.ATTR_USER_NAME,
|
||||||
USER_TEXT_KEY,
|
USER_TEXT_KEY,
|
||||||
UserActivityLog::getUsername)
|
UserActivityLog::getUsername)
|
||||||
.withFilter(this.userNameFilter))
|
.withFilter(this.userNameFilter))
|
||||||
|
|
||||||
.withColumn(new ColumnDefinition<UserActivityLog>(
|
.withColumn(new ColumnDefinition<UserActivityLog>(
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_ACTIVITY_TYPE,
|
Domain.USER_ACTIVITY_LOG.ATTR_ACTIVITY_TYPE,
|
||||||
ACTIVITY_TEXT_KEY,
|
ACTIVITY_TEXT_KEY,
|
||||||
this.resourceService::getUserActivityTypeName)
|
this.resourceService::getUserActivityTypeName)
|
||||||
.withFilter(this.activityFilter)
|
.withFilter(this.activityFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
|
|
||||||
.withColumn(new ColumnDefinition<UserActivityLog>(
|
.withColumn(new ColumnDefinition<UserActivityLog>(
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_ENTITY_ID,
|
Domain.USER_ACTIVITY_LOG.ATTR_ENTITY_ID,
|
||||||
ENTITY_TYPE_TEXT_KEY,
|
ENTITY_TYPE_TEXT_KEY,
|
||||||
this.resourceService::getEntityTypeName)
|
this.resourceService::getEntityTypeName)
|
||||||
.withFilter(this.entityFilter)
|
.withFilter(this.entityFilter)
|
||||||
.sortable())
|
.sortable())
|
||||||
|
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_TIMESTAMP,
|
Domain.USER_ACTIVITY_LOG.ATTR_TIMESTAMP,
|
||||||
new LocTextKey(DATE_TEXT_KEY.name, this.i18nSupport.getUsersTimeZoneTitleSuffix()),
|
new LocTextKey(DATE_TEXT_KEY.name, this.i18nSupport.getUsersTimeZoneTitleSuffix()),
|
||||||
this::getLogTime)
|
this::getLogTime)
|
||||||
.withFilter(new TableFilterAttribute(
|
.withFilter(new TableFilterAttribute(
|
||||||
CriteriaType.DATE_RANGE,
|
CriteriaType.DATE_RANGE,
|
||||||
UserActivityLog.FILTER_ATTR_FROM_TO,
|
UserActivityLog.FILTER_ATTR_FROM_TO,
|
||||||
Utils.toDateTimeUTC(Utils.getMillisecondsNow())
|
Utils.toDateTimeUTC(Utils.getMillisecondsNow())
|
||||||
.minusYears(1)
|
.minusYears(1)
|
||||||
.toString()))
|
.toString()))
|
||||||
.sortable())
|
.sortable())
|
||||||
|
|
||||||
.withDefaultAction(t -> actionBuilder
|
.withDefaultAction(t -> actionBuilder
|
||||||
.newAction(ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS)
|
.newAction(ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS)
|
||||||
.withExec(action -> this.showDetails(action, t.getSingleSelectedROWData()))
|
.withExec(action -> this.showDetails(action, t.getSingleSelectedROWData()))
|
||||||
.noEventPropagation()
|
.noEventPropagation()
|
||||||
.create())
|
.create())
|
||||||
|
|
||||||
.compose(pageContext.copyOf(content));
|
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||||
|
pageContext,
|
||||||
actionBuilder
|
ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS))
|
||||||
.newAction(ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS)
|
.compose(pageContext.copyOf(content));
|
||||||
.withSelect(
|
|
||||||
table::getSelection,
|
actionBuilder
|
||||||
action -> this.showDetails(action, table.getSingleSelectedROWData()),
|
.newAction(ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS)
|
||||||
EMPTY_SELECTION_TEXT)
|
.withSelect(
|
||||||
.noEventPropagation()
|
table::getSelection,
|
||||||
.publishIf(table::hasAnyContent);
|
action -> this.showDetails(action, table.getSingleSelectedROWData()),
|
||||||
|
EMPTY_SELECTION_TEXT)
|
||||||
}
|
.noEventPropagation()
|
||||||
|
.publishIf(table::hasAnyContent, false);
|
||||||
private final String getLogTime(final UserActivityLog log) {
|
|
||||||
if (log == null || log.timestamp == null) {
|
}
|
||||||
return Constants.EMPTY_NOTE;
|
|
||||||
}
|
private String getLogTime(final UserActivityLog log) {
|
||||||
|
if (log == null || log.timestamp == null) {
|
||||||
return this.i18nSupport
|
return Constants.EMPTY_NOTE;
|
||||||
.formatDisplayDateTime(Utils.toDateTimeUTC(log.timestamp));
|
}
|
||||||
}
|
|
||||||
|
return this.i18nSupport
|
||||||
private PageAction showDetails(final PageAction action, final UserActivityLog userActivityLog) {
|
.formatDisplayDateTime(Utils.toDateTimeUTC(log.timestamp));
|
||||||
action.getSingleSelection();
|
}
|
||||||
|
|
||||||
final ModalInputDialog<Void> dialog = new ModalInputDialog<>(
|
private PageAction showDetails(final PageAction action, final UserActivityLog userActivityLog) {
|
||||||
action.pageContext().getParent().getShell(),
|
action.getSingleSelection();
|
||||||
this.widgetFactory);
|
|
||||||
dialog.setLargeDialogWidth();
|
final ModalInputDialog<Void> dialog = new ModalInputDialog<>(
|
||||||
dialog.open(
|
action.pageContext().getParent().getShell(),
|
||||||
DETAILS_TITLE_TEXT_KEY,
|
this.widgetFactory);
|
||||||
action.pageContext(),
|
dialog.setLargeDialogWidth();
|
||||||
pc -> createDetailsForm(userActivityLog, pc));
|
dialog.open(
|
||||||
|
DETAILS_TITLE_TEXT_KEY,
|
||||||
return action;
|
action.pageContext(),
|
||||||
}
|
pc -> createDetailsForm(userActivityLog, pc));
|
||||||
|
|
||||||
private void createDetailsForm(final UserActivityLog userActivityLog, final PageContext pc) {
|
return action;
|
||||||
|
}
|
||||||
final Composite parent = pc.getParent();
|
|
||||||
final Composite grid = this.widgetFactory.createPopupScrollComposite(parent);
|
private void createDetailsForm(final UserActivityLog userActivityLog, final PageContext pc) {
|
||||||
|
|
||||||
this.pageService.formBuilder(pc.copyOf(grid))
|
final Composite parent = pc.getParent();
|
||||||
.withDefaultSpanInput(6)
|
final Composite grid = this.widgetFactory.createPopupScrollComposite(parent);
|
||||||
.withEmptyCellSeparation(false)
|
|
||||||
.readonly(true)
|
this.pageService.formBuilder(pc.copyOf(grid))
|
||||||
.addField(FormBuilder.text(
|
.withDefaultSpanInput(6)
|
||||||
UserActivityLog.ATTR_USER_NAME,
|
.withEmptyCellSeparation(false)
|
||||||
USER_TEXT_KEY,
|
.readonly(true)
|
||||||
String.valueOf(userActivityLog.getUsername())))
|
.addField(FormBuilder.text(
|
||||||
.addField(FormBuilder.text(
|
UserActivityLog.ATTR_USER_NAME,
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_ACTIVITY_TYPE,
|
USER_TEXT_KEY,
|
||||||
ACTIVITY_TEXT_KEY,
|
String.valueOf(userActivityLog.getUsername())))
|
||||||
this.resourceService.getUserActivityTypeName(userActivityLog)))
|
.addField(FormBuilder.text(
|
||||||
.addField(FormBuilder.text(
|
Domain.USER_ACTIVITY_LOG.ATTR_ACTIVITY_TYPE,
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_ENTITY_TYPE,
|
ACTIVITY_TEXT_KEY,
|
||||||
ENTITY_TYPE_TEXT_KEY,
|
this.resourceService.getUserActivityTypeName(userActivityLog)))
|
||||||
this.resourceService.getEntityTypeName(userActivityLog)))
|
.addField(FormBuilder.text(
|
||||||
.addField(FormBuilder.text(
|
Domain.USER_ACTIVITY_LOG.ATTR_ENTITY_TYPE,
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_ENTITY_ID,
|
ENTITY_TYPE_TEXT_KEY,
|
||||||
ENTITY_ID_TEXT_KEY,
|
this.resourceService.getEntityTypeName(userActivityLog)))
|
||||||
userActivityLog.entityId))
|
.addField(FormBuilder.text(
|
||||||
.addField(FormBuilder.text(
|
Domain.USER_ACTIVITY_LOG.ATTR_ENTITY_ID,
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_TIMESTAMP,
|
ENTITY_ID_TEXT_KEY,
|
||||||
DETAILS_DATE_TEXT_KEY,
|
userActivityLog.entityId))
|
||||||
this.widgetFactory.getI18nSupport()
|
.addField(FormBuilder.text(
|
||||||
.formatDisplayDateTime(Utils.toDateTimeUTC(userActivityLog.timestamp)) + " " +
|
Domain.USER_ACTIVITY_LOG.ATTR_TIMESTAMP,
|
||||||
this.i18nSupport.getUsersTimeZoneTitleSuffix()))
|
DETAILS_DATE_TEXT_KEY,
|
||||||
.addField(FormBuilder.text(
|
this.widgetFactory.getI18nSupport()
|
||||||
Domain.USER_ACTIVITY_LOG.ATTR_MESSAGE,
|
.formatDisplayDateTime(Utils.toDateTimeUTC(userActivityLog.timestamp)) + " " +
|
||||||
MESSAGE_TEXT_KEY,
|
this.i18nSupport.getUsersTimeZoneTitleSuffix()))
|
||||||
String.valueOf(userActivityLog.message))
|
.addField(FormBuilder.text(
|
||||||
.asArea())
|
Domain.USER_ACTIVITY_LOG.ATTR_MESSAGE,
|
||||||
.build();
|
MESSAGE_TEXT_KEY,
|
||||||
}
|
String.valueOf(userActivityLog.message))
|
||||||
|
.asArea())
|
||||||
}
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,138 +1,137 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content.activity;
|
package ch.ethz.seb.sebserver.gui.content.activity;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateAttributeForm;
|
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateAttributeForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateForm;
|
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateList;
|
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.ExamForm;
|
import ch.ethz.seb.sebserver.gui.content.ExamForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.ExamList;
|
import ch.ethz.seb.sebserver.gui.content.ExamList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.IndicatorForm;
|
import ch.ethz.seb.sebserver.gui.content.IndicatorForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.InstitutionForm;
|
import ch.ethz.seb.sebserver.gui.content.InstitutionForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.InstitutionList;
|
import ch.ethz.seb.sebserver.gui.content.InstitutionList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.LmsSetupForm;
|
import ch.ethz.seb.sebserver.gui.content.LmsSetupForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.LmsSetupList;
|
import ch.ethz.seb.sebserver.gui.content.LmsSetupList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.MonitoringClientConnection;
|
import ch.ethz.seb.sebserver.gui.content.MonitoringClientConnection;
|
||||||
import ch.ethz.seb.sebserver.gui.content.MonitoringRunningExam;
|
import ch.ethz.seb.sebserver.gui.content.MonitoringRunningExam;
|
||||||
import ch.ethz.seb.sebserver.gui.content.MonitoringRunningExamList;
|
import ch.ethz.seb.sebserver.gui.content.MonitoringRunningExamList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.QuizDiscoveryList;
|
import ch.ethz.seb.sebserver.gui.content.QuizDiscoveryList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebClientConfigForm;
|
import ch.ethz.seb.sebserver.gui.content.SebClientConfigForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebClientConfigList;
|
import ch.ethz.seb.sebserver.gui.content.SebClientConfigList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebClientLogs;
|
import ch.ethz.seb.sebserver.gui.content.SebClientLogs;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebExamConfigList;
|
import ch.ethz.seb.sebserver.gui.content.SebExamConfigList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebExamConfigPropForm;
|
import ch.ethz.seb.sebserver.gui.content.SebExamConfigPropForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.SebExamConfigSettingsForm;
|
import ch.ethz.seb.sebserver.gui.content.SebExamConfigSettingsForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm;
|
import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.UserAccountForm;
|
import ch.ethz.seb.sebserver.gui.content.UserAccountForm;
|
||||||
import ch.ethz.seb.sebserver.gui.content.UserAccountList;
|
import ch.ethz.seb.sebserver.gui.content.UserAccountList;
|
||||||
import ch.ethz.seb.sebserver.gui.content.UserActivityLogs;
|
import ch.ethz.seb.sebserver.gui.content.UserActivityLogs;
|
||||||
import ch.ethz.seb.sebserver.gui.content.action.ActionPane;
|
import ch.ethz.seb.sebserver.gui.content.action.ActionPane;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.Activity;
|
import ch.ethz.seb.sebserver.gui.service.page.Activity;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageStateDefinition;
|
import ch.ethz.seb.sebserver.gui.service.page.PageStateDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
|
|
||||||
public enum PageStateDefinitionImpl implements PageStateDefinition {
|
public enum PageStateDefinitionImpl implements PageStateDefinition {
|
||||||
|
|
||||||
INSTITUTION_LIST(Type.LIST_VIEW, InstitutionList.class, ActivityDefinition.INSTITUTION),
|
INSTITUTION_LIST(Type.LIST_VIEW, InstitutionList.class, ActivityDefinition.INSTITUTION),
|
||||||
INSTITUTION_VIEW(Type.FORM_VIEW, InstitutionForm.class, ActivityDefinition.INSTITUTION),
|
INSTITUTION_VIEW(Type.FORM_VIEW, InstitutionForm.class, ActivityDefinition.INSTITUTION),
|
||||||
INSTITUTION_EDIT(Type.FORM_EDIT, InstitutionForm.class, ActivityDefinition.INSTITUTION),
|
INSTITUTION_EDIT(Type.FORM_EDIT, InstitutionForm.class, ActivityDefinition.INSTITUTION),
|
||||||
|
|
||||||
USER_ACCOUNT_LIST(Type.LIST_VIEW, UserAccountList.class, ActivityDefinition.USER_ACCOUNT),
|
USER_ACCOUNT_LIST(Type.LIST_VIEW, UserAccountList.class, ActivityDefinition.USER_ACCOUNT),
|
||||||
USER_ACCOUNT_VIEW(Type.FORM_VIEW, UserAccountForm.class, ActivityDefinition.USER_ACCOUNT),
|
USER_ACCOUNT_VIEW(Type.FORM_VIEW, UserAccountForm.class, ActivityDefinition.USER_ACCOUNT),
|
||||||
USER_ACCOUNT_EDIT(Type.FORM_EDIT, UserAccountForm.class, ActivityDefinition.USER_ACCOUNT),
|
USER_ACCOUNT_EDIT(Type.FORM_EDIT, UserAccountForm.class, ActivityDefinition.USER_ACCOUNT),
|
||||||
USER_ACCOUNT_PASSWORD_CHANGE(Type.FORM_EDIT, UserAccountChangePasswordForm.class, ActivityDefinition.USER_ACCOUNT),
|
USER_ACCOUNT_PASSWORD_CHANGE(Type.FORM_EDIT, UserAccountChangePasswordForm.class, ActivityDefinition.USER_ACCOUNT),
|
||||||
|
|
||||||
LMS_SETUP_LIST(Type.LIST_VIEW, LmsSetupList.class, ActivityDefinition.LMS_SETUP),
|
LMS_SETUP_LIST(Type.LIST_VIEW, LmsSetupList.class, ActivityDefinition.LMS_SETUP),
|
||||||
LMS_SETUP_VIEW(Type.FORM_VIEW, LmsSetupForm.class, ActivityDefinition.LMS_SETUP),
|
LMS_SETUP_VIEW(Type.FORM_VIEW, LmsSetupForm.class, ActivityDefinition.LMS_SETUP),
|
||||||
LMS_SETUP_EDIT(Type.FORM_EDIT, LmsSetupForm.class, ActivityDefinition.LMS_SETUP),
|
LMS_SETUP_EDIT(Type.FORM_EDIT, LmsSetupForm.class, ActivityDefinition.LMS_SETUP),
|
||||||
|
|
||||||
QUIZ_LIST(Type.LIST_VIEW, QuizDiscoveryList.class, ActivityDefinition.QUIZ_DISCOVERY),
|
QUIZ_LIST(Type.LIST_VIEW, QuizDiscoveryList.class, ActivityDefinition.QUIZ_DISCOVERY),
|
||||||
|
|
||||||
EXAM_LIST(Type.LIST_VIEW, ExamList.class, ActivityDefinition.EXAM),
|
EXAM_LIST(Type.LIST_VIEW, ExamList.class, ActivityDefinition.EXAM),
|
||||||
EXAM_VIEW(Type.FORM_VIEW, ExamForm.class, ActivityDefinition.EXAM),
|
EXAM_VIEW(Type.FORM_VIEW, ExamForm.class, ActivityDefinition.EXAM),
|
||||||
EXAM_EDIT(Type.FORM_EDIT, ExamForm.class, ActivityDefinition.EXAM),
|
EXAM_EDIT(Type.FORM_EDIT, ExamForm.class, ActivityDefinition.EXAM),
|
||||||
INDICATOR_EDIT(Type.FORM_EDIT, IndicatorForm.class, ActivityDefinition.EXAM),
|
INDICATOR_EDIT(Type.FORM_EDIT, IndicatorForm.class, ActivityDefinition.EXAM),
|
||||||
|
|
||||||
SEB_CLIENT_CONFIG_LIST(Type.LIST_VIEW, SebClientConfigList.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
SEB_CLIENT_CONFIG_LIST(Type.LIST_VIEW, SebClientConfigList.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
||||||
SEB_CLIENT_CONFIG_VIEW(Type.FORM_VIEW, SebClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
SEB_CLIENT_CONFIG_VIEW(Type.FORM_VIEW, SebClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
||||||
SEB_CLIENT_CONFIG_EDIT(Type.FORM_EDIT, SebClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
SEB_CLIENT_CONFIG_EDIT(Type.FORM_EDIT, SebClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG),
|
||||||
|
|
||||||
SEB_EXAM_CONFIG_LIST(Type.LIST_VIEW, SebExamConfigList.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_LIST(Type.LIST_VIEW, SebExamConfigList.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
SEB_EXAM_CONFIG_PROP_VIEW(Type.FORM_VIEW, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_PROP_VIEW(Type.FORM_VIEW, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
SEB_EXAM_CONFIG_PROP_EDIT(Type.FORM_EDIT, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_PROP_EDIT(Type.FORM_EDIT, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
SEB_EXAM_CONFIG_EDIT(Type.FORM_IN_TIME_EDIT, SebExamConfigSettingsForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_EDIT(Type.FORM_IN_TIME_EDIT, SebExamConfigSettingsForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
SEB_EXAM_CONFIG_VIEW(Type.FORM_VIEW, SebExamConfigSettingsForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
SEB_EXAM_CONFIG_VIEW(Type.FORM_VIEW, SebExamConfigSettingsForm.class, ActivityDefinition.SEB_EXAM_CONFIG),
|
||||||
|
|
||||||
SEB_EXAM_CONFIG_TEMPLATE_LIST(Type.LIST_VIEW, ConfigTemplateList.class,
|
SEB_EXAM_CONFIG_TEMPLATE_LIST(Type.LIST_VIEW, ConfigTemplateList.class,
|
||||||
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
||||||
SEB_EXAM_CONFIG_TEMPLATE_VIEW(Type.FORM_VIEW, ConfigTemplateForm.class,
|
SEB_EXAM_CONFIG_TEMPLATE_VIEW(Type.FORM_VIEW, ConfigTemplateForm.class,
|
||||||
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
||||||
SEB_EXAM_CONFIG_TEMPLATE_EDIT(Type.FORM_EDIT, ConfigTemplateForm.class,
|
SEB_EXAM_CONFIG_TEMPLATE_EDIT(Type.FORM_EDIT, ConfigTemplateForm.class,
|
||||||
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
||||||
|
SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_EDIT(
|
||||||
SEB_EXAM_CONFIG_TEMPLATE_ATTRIBUTE_EDIT(
|
Type.FORM_EDIT,
|
||||||
Type.FORM_EDIT,
|
ConfigTemplateAttributeForm.class,
|
||||||
ConfigTemplateAttributeForm.class,
|
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
||||||
ActivityDefinition.SEB_EXAM_CONFIG),
|
|
||||||
|
MONITORING_RUNNING_EXAM_LIST(Type.LIST_VIEW, MonitoringRunningExamList.class, ActivityDefinition.MONITORING_EXAMS),
|
||||||
MONITORING_RUNNING_EXAM_LIST(Type.LIST_VIEW, MonitoringRunningExamList.class, ActivityDefinition.MONITORING_EXAMS),
|
MONITORING_RUNNING_EXAM(Type.FORM_VIEW, MonitoringRunningExam.class, ActivityDefinition.MONITORING_EXAMS),
|
||||||
MONITORING_RUNNING_EXAM(Type.FORM_VIEW, MonitoringRunningExam.class, ActivityDefinition.MONITORING_EXAMS),
|
MONITORING_CLIENT_CONNECTION(Type.FORM_VIEW, MonitoringClientConnection.class, ActivityDefinition.MONITORING_EXAMS),
|
||||||
MONITORING_CLIENT_CONNECTION(Type.FORM_VIEW, MonitoringClientConnection.class, ActivityDefinition.MONITORING_EXAMS),
|
|
||||||
|
USER_ACTIVITY_LOGS(Type.LIST_VIEW, UserActivityLogs.class, ActivityDefinition.USER_ACTIVITY_LOGS),
|
||||||
USER_ACTIVITY_LOGS(Type.LIST_VIEW, UserActivityLogs.class, ActivityDefinition.USER_ACTIVITY_LOGS),
|
SEB_CLIENT_LOGS(Type.LIST_VIEW, SebClientLogs.class, ActivityDefinition.SEB_CLIENT_LOGS)
|
||||||
SEB_CLIENT_LOGS(Type.LIST_VIEW, SebClientLogs.class, ActivityDefinition.SEB_CLIENT_LOGS)
|
|
||||||
|
;
|
||||||
;
|
|
||||||
|
public final Type type;
|
||||||
public final Type type;
|
public final Class<? extends TemplateComposer> contentPaneComposer;
|
||||||
public final Class<? extends TemplateComposer> contentPaneComposer;
|
public final Class<? extends TemplateComposer> actionPaneComposer;
|
||||||
public final Class<? extends TemplateComposer> actionPaneComposer;
|
public final Activity activityAnchor;
|
||||||
public final Activity activityAnchor;
|
|
||||||
|
private PageStateDefinitionImpl(
|
||||||
private PageStateDefinitionImpl(
|
final Type type,
|
||||||
final Type type,
|
final Class<? extends TemplateComposer> contentPaneComposer,
|
||||||
final Class<? extends TemplateComposer> contentPaneComposer,
|
final Activity activityAnchor) {
|
||||||
final Activity activityAnchor) {
|
|
||||||
|
this(type, contentPaneComposer, ActionPane.class, activityAnchor);
|
||||||
this(type, contentPaneComposer, ActionPane.class, activityAnchor);
|
}
|
||||||
}
|
|
||||||
|
private PageStateDefinitionImpl(
|
||||||
private PageStateDefinitionImpl(
|
final Type type,
|
||||||
final Type type,
|
final Class<? extends TemplateComposer> contentPaneComposer,
|
||||||
final Class<? extends TemplateComposer> contentPaneComposer,
|
final Class<? extends TemplateComposer> actionPaneComposer,
|
||||||
final Class<? extends TemplateComposer> actionPaneComposer,
|
final Activity activityAnchor) {
|
||||||
final Activity activityAnchor) {
|
|
||||||
|
this.type = type;
|
||||||
this.type = type;
|
this.contentPaneComposer = contentPaneComposer;
|
||||||
this.contentPaneComposer = contentPaneComposer;
|
this.actionPaneComposer = actionPaneComposer;
|
||||||
this.actionPaneComposer = actionPaneComposer;
|
this.activityAnchor = activityAnchor;
|
||||||
this.activityAnchor = activityAnchor;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Type type() {
|
||||||
public Type type() {
|
return this.type;
|
||||||
return this.type;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Class<? extends TemplateComposer> contentPaneComposer() {
|
||||||
public Class<? extends TemplateComposer> contentPaneComposer() {
|
return this.contentPaneComposer;
|
||||||
return this.contentPaneComposer;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Class<? extends TemplateComposer> actionPaneComposer() {
|
||||||
public Class<? extends TemplateComposer> actionPaneComposer() {
|
return this.actionPaneComposer;
|
||||||
return this.actionPaneComposer;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Activity activityAnchor() {
|
||||||
public Activity activityAnchor() {
|
return this.activityAnchor;
|
||||||
return this.activityAnchor;
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,181 +1,186 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.i18n;
|
package ch.ethz.seb.sebserver.gui.service.i18n;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
|
||||||
public interface I18nSupport {
|
public interface I18nSupport {
|
||||||
|
|
||||||
public static final String SUPPORTED_LANGUAGES_KEY = "sebserver.gui.supported.languages";
|
public static final String SUPPORTED_LANGUAGES_KEY = "sebserver.gui.supported.languages";
|
||||||
public static final String MULTILINGUAL_KEY = "sebserver.gui.multilingual";
|
public static final String MULTILINGUAL_KEY = "sebserver.gui.multilingual";
|
||||||
public static final String FORMAL_LOCALE_KEY = "sebserver.gui.date.displayformat";
|
public static final String FORMAL_LOCALE_KEY = "sebserver.gui.date.displayformat";
|
||||||
public static final String ATTR_CURRENT_SESSION_LOCALE = "CURRENT_SESSION_LOCALE";
|
public static final String ATTR_CURRENT_SESSION_LOCALE = "CURRENT_SESSION_LOCALE";
|
||||||
|
|
||||||
/** Get all supported languages as a collection of Locale
|
/** Get all supported languages as a collection of Locale
|
||||||
*
|
*
|
||||||
* @return all supported languages as a collection of Locale */
|
* @return all supported languages as a collection of Locale */
|
||||||
Collection<Locale> supportedLanguages();
|
Collection<Locale> supportedLanguages();
|
||||||
|
|
||||||
/** Get the current users language based Locale (from user info language selection)
|
/** Get the current users language based Locale (from user info language selection)
|
||||||
* Or the default language Locale if the user has not defined any language
|
* Or the default language Locale if the user has not defined any language
|
||||||
*
|
*
|
||||||
* @return the current user language Locale to use in context */
|
* @return the current user language Locale to use in context */
|
||||||
Locale getUsersLanguageLocale();
|
Locale getUsersLanguageLocale();
|
||||||
|
|
||||||
/** Get the current users format based Locale (from user info format selection)
|
/** Get the current users format based Locale (from user info format selection)
|
||||||
* Or the default format Locale if the user has not defined any language
|
* Or the default format Locale if the user has not defined any language
|
||||||
*
|
*
|
||||||
* @return the current user format Locale to use in context */
|
* @return the current user format Locale to use in context */
|
||||||
Locale getUsersFormatLocale();
|
Locale getUsersFormatLocale();
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display.
|
/** Format a DateTime to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param date the DateTime instance
|
||||||
* @return date formatted date String to display */
|
* @return date formatted date String to display */
|
||||||
String formatDisplayDate(DateTime date);
|
String formatDisplayDate(DateTime date);
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display with additional time zone name at the end.
|
/** Format a DateTime to a text format to display with additional time zone name at the end.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param date the DateTime instance
|
||||||
* @return date formatted date String to display */
|
* @return date formatted date String to display */
|
||||||
default String formatDisplayDateWithTimeZone(final DateTime date) {
|
default String formatDisplayDateWithTimeZone(final DateTime date) {
|
||||||
return formatDisplayDateTime(date) + " " + this.getUsersTimeZoneTitleSuffix();
|
return formatDisplayDateTime(date) + " " + this.getUsersTimeZoneTitleSuffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a time-stamp (milliseconds) to a text format to display.
|
/** Format a time-stamp (milliseconds) to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param date the DateTime instance
|
||||||
* @return date formatted date String to display */
|
* @return date formatted date String to display */
|
||||||
default String formatDisplayDate(final Long timestamp) {
|
default String formatDisplayDate(final Long timestamp) {
|
||||||
return formatDisplayDate(Utils.toDateTimeUTC(timestamp));
|
return formatDisplayDate(Utils.toDateTimeUTC(timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display.
|
/** Format a DateTime to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.displayformat'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param date the DateTime instance
|
||||||
* @return date formatted date time String to display */
|
* @return date formatted date time String to display */
|
||||||
String formatDisplayDateTime(DateTime date);
|
String formatDisplayDateTime(DateTime date);
|
||||||
|
|
||||||
/** Format a time-stamp (milliseconds) to a text format to display.
|
/** Format a time-stamp (milliseconds) to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.displayformat'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param date the DateTime instance
|
||||||
* @return date formatted date time String to display */
|
* @return date formatted date time String to display */
|
||||||
default String formatDisplayDateTime(final Long timestamp) {
|
default String formatDisplayDateTime(final Long timestamp) {
|
||||||
return formatDisplayDateTime(Utils.toDateTimeUTC(timestamp));
|
return formatDisplayDateTime(Utils.toDateTimeUTC(timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display.
|
/** Format a DateTime to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.time.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.time.displayformat'
|
||||||
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param date the DateTime instance
|
||||||
* @return date formatted time String to display */
|
* @return date formatted time String to display */
|
||||||
String formatDisplayTime(DateTime date);
|
String formatDisplayTime(DateTime date);
|
||||||
|
|
||||||
/** Format a time-stamp (milliseconds) to a text format to display.
|
/** Format a time-stamp (milliseconds) to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.time.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.time.displayformat'
|
||||||
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param date the DateTime instance
|
||||||
* @return date formatted time String to display */
|
* @return date formatted time String to display */
|
||||||
default String formatDisplayTime(final Long timestamp) {
|
default String formatDisplayTime(final Long timestamp) {
|
||||||
return formatDisplayTime(Utils.toDateTimeUTC(timestamp));
|
return formatDisplayTime(Utils.toDateTimeUTC(timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If the current user has another time zone then UTC this will return a tile suffix that describes
|
/** If the current user has another time zone then UTC this will return a tile suffix that describes
|
||||||
* a date/time column title with adding (UTC|{usersTimeZone}) that can be added to the title.
|
* a date/time column title with adding (UTC|{usersTimeZone}) that can be added to the title.
|
||||||
*
|
*
|
||||||
* @return date/time column title suffix for current user */
|
* @return date/time column title suffix for current user */
|
||||||
String getUsersTimeZoneTitleSuffix();
|
String getUsersTimeZoneTitleSuffix();
|
||||||
|
|
||||||
/** Get localized text of specified key for currently set Locale.
|
/** Get localized text of specified key for currently set Locale.
|
||||||
*
|
*
|
||||||
* @param key LocTextKey instance
|
* @param key LocTextKey instance
|
||||||
* @param def default text
|
* @param def default text
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
default String getText(final LocTextKey key, final String def) {
|
default String getText(final LocTextKey key, final String def) {
|
||||||
return getText(key.name, def, key.args);
|
return getText(key.name, def, key.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get localized text of specified key for currently set Locale.
|
/** Get localized text of specified key for currently set Locale.
|
||||||
*
|
*
|
||||||
* @param key LocTextKey instance
|
* @param key LocTextKey instance
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
default String getText(final LocTextKey key) {
|
default String getText(final LocTextKey key) {
|
||||||
return getText(key.name, key.name, key.args);
|
return getText(key.name, key.name, key.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get localized text of specified key for currently set Locale.
|
/** Get localized text of specified key for currently set Locale.
|
||||||
*
|
*
|
||||||
* @param key the key name of localized text
|
* @param key the key name of localized text
|
||||||
* @param args additional arguments to parse the localized text
|
* @param args additional arguments to parse the localized text
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
default String getText(final String key, final Object... args) {
|
default String getText(final String key, final Object... args) {
|
||||||
return getText(key, key, args);
|
return getText(key, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get localized text of specified key for currently set Locale.
|
/** Get localized text of specified key for currently set Locale.
|
||||||
*
|
*
|
||||||
* @param key the key name of localized text
|
* @param key the key name of localized text
|
||||||
* @param def default text that is returned if no localized test with specified key was found
|
* @param def default text that is returned if no localized test with specified key was found
|
||||||
* @param args additional arguments to parse the localized text
|
* @param args additional arguments to parse the localized text
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
String getText(final String key, String def, Object... args);
|
String getText(final String key, String def, Object... args);
|
||||||
|
|
||||||
/** Get localized text of specified key and Locale.
|
/** Get localized text of specified key and Locale.
|
||||||
*
|
*
|
||||||
* @param key the key name of localized text
|
* @param key the key name of localized text
|
||||||
* @param locale the Locale
|
* @param locale the Locale
|
||||||
* @param args additional arguments to parse the localized text
|
* @param args additional arguments to parse the localized text
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
default String getText(final String key, final Locale locale, final Object... args) {
|
default String getText(final String key, final Locale locale, final Object... args) {
|
||||||
return getText(key, locale, key, args);
|
return getText(key, locale, key, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get localized text of specified key and Locale.
|
/** Get localized text of specified key and Locale.
|
||||||
*
|
*
|
||||||
* @param key the key name of localized text
|
* @param key the key name of localized text
|
||||||
* @param locale the Locale
|
* @param locale the Locale
|
||||||
* @param def default text that is returned if no localized test with specified key was found
|
* @param def default text that is returned if no localized test with specified key was found
|
||||||
* @param args additional arguments to parse the localized text
|
* @param args additional arguments to parse the localized text
|
||||||
* @return the text in current language parsed from localized text */
|
* @return the text in current language parsed from localized text */
|
||||||
String getText(String key, Locale locale, String def, Object... args);
|
String getText(String key, Locale locale, String def, Object... args);
|
||||||
|
|
||||||
boolean hasText(LocTextKey locTextKey);
|
/** Indicates if there is a localized text defined for a specified LocTextKey
|
||||||
|
*
|
||||||
}
|
* @param locTextKey the LocTextKey instance
|
||||||
|
* @return true if there is a localized text defined for a specified LocTextKey, false otherwise
|
||||||
|
*/
|
||||||
|
boolean hasText(LocTextKey locTextKey);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,296 +1,294 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.i18n.impl;
|
package ch.ethz.seb.sebserver.gui.service.i18n.impl;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Control;
|
import org.eclipse.swt.widgets.Control;
|
||||||
import org.eclipse.swt.widgets.Group;
|
import org.eclipse.swt.widgets.Group;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.eclipse.swt.widgets.TabFolder;
|
import org.eclipse.swt.widgets.TabFolder;
|
||||||
import org.eclipse.swt.widgets.TabItem;
|
import org.eclipse.swt.widgets.TabItem;
|
||||||
import org.eclipse.swt.widgets.Table;
|
import org.eclipse.swt.widgets.Table;
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
import org.eclipse.swt.widgets.Tree;
|
import org.eclipse.swt.widgets.Tree;
|
||||||
import org.eclipse.swt.widgets.TreeItem;
|
import org.eclipse.swt.widgets.TreeItem;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
|
import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.ImageUploadSelection;
|
import ch.ethz.seb.sebserver.gui.widget.ImageUploadSelection;
|
||||||
|
|
||||||
/** Service that supports page language change on the fly */
|
/** Service that supports page language change on the fly */
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public final class PolyglotPageServiceImpl implements PolyglotPageService {
|
public final class PolyglotPageServiceImpl implements PolyglotPageService {
|
||||||
|
|
||||||
private final I18nSupport i18nSupport;
|
private final I18nSupport i18nSupport;
|
||||||
|
|
||||||
public PolyglotPageServiceImpl(final I18nSupport i18nSupport) {
|
public PolyglotPageServiceImpl(final I18nSupport i18nSupport) {
|
||||||
this.i18nSupport = i18nSupport;
|
this.i18nSupport = i18nSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public I18nSupport getI18nSupport() {
|
public I18nSupport getI18nSupport() {
|
||||||
return this.i18nSupport;
|
return this.i18nSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDefaultPageLocale(final Composite root) {
|
public void setDefaultPageLocale(final Composite root) {
|
||||||
setPageLocale(root, this.i18nSupport.getUsersLanguageLocale());
|
setPageLocale(root, this.i18nSupport.getUsersLanguageLocale());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void setPageLocale(final Composite root, final Locale locale) {
|
public void setPageLocale(final Composite root, final Locale locale) {
|
||||||
RWT.getUISession()
|
RWT.getUISession()
|
||||||
.getHttpSession()
|
.getHttpSession()
|
||||||
.setAttribute(I18nSupport.ATTR_CURRENT_SESSION_LOCALE, locale);
|
.setAttribute(I18nSupport.ATTR_CURRENT_SESSION_LOCALE, locale);
|
||||||
|
|
||||||
ComposerService.traversePageTree(
|
ComposerService.traversePageTree(
|
||||||
root,
|
root,
|
||||||
comp -> comp.getData(POLYGLOT_WIDGET_FUNCTION_KEY) != null,
|
comp -> comp.getData(POLYGLOT_WIDGET_FUNCTION_KEY) != null,
|
||||||
comp -> ((Consumer<Control>) comp.getData(POLYGLOT_WIDGET_FUNCTION_KEY)).accept(comp));
|
comp -> ((Consumer<Control>) comp.getData(POLYGLOT_WIDGET_FUNCTION_KEY)).accept(comp));
|
||||||
|
|
||||||
root.layout(true, true);
|
root.layout(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final ImageUploadSelection imageUpload, final LocTextKey locTextKey) {
|
public void injectI18n(final ImageUploadSelection imageUpload, final LocTextKey locTextKey) {
|
||||||
final Consumer<ImageUploadSelection> imageUploadFunction = iu -> {
|
final Consumer<ImageUploadSelection> imageUploadFunction = iu -> {
|
||||||
if (locTextKey != null) {
|
if (locTextKey != null) {
|
||||||
iu.setSelectionText(this.i18nSupport.getText(locTextKey));
|
iu.setSelectionText(this.i18nSupport.getText(locTextKey));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
imageUpload.setData(POLYGLOT_WIDGET_FUNCTION_KEY, imageUploadFunction);
|
imageUpload.setData(POLYGLOT_WIDGET_FUNCTION_KEY, imageUploadFunction);
|
||||||
imageUploadFunction.accept(imageUpload);
|
imageUploadFunction.accept(imageUpload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final Label label, final LocTextKey locTextKey) {
|
public void injectI18n(final Label label, final LocTextKey locTextKey) {
|
||||||
injectI18n(label, locTextKey, null);
|
injectI18n(label, locTextKey, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final Label label, final LocTextKey locTextKey, final LocTextKey locToolTipKey) {
|
public void injectI18n(final Label label, final LocTextKey locTextKey, final LocTextKey locToolTipKey) {
|
||||||
final Consumer<Label> labelFunction = labelFunction(locTextKey, locToolTipKey, this.i18nSupport);
|
final Consumer<Label> labelFunction = labelFunction(locTextKey, locToolTipKey, this.i18nSupport);
|
||||||
label.setData(POLYGLOT_WIDGET_FUNCTION_KEY, labelFunction);
|
label.setData(POLYGLOT_WIDGET_FUNCTION_KEY, labelFunction);
|
||||||
labelFunction.accept(label);
|
labelFunction.accept(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final Group group, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
public void injectI18n(final Group group, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
||||||
final Consumer<Group> groupFunction = groupFunction(locTextKey, locTooltipKey, this.i18nSupport);
|
final Consumer<Group> groupFunction = groupFunction(locTextKey, locTooltipKey, this.i18nSupport);
|
||||||
group.setData(POLYGLOT_WIDGET_FUNCTION_KEY, groupFunction);
|
group.setData(POLYGLOT_WIDGET_FUNCTION_KEY, groupFunction);
|
||||||
groupFunction.accept(group);
|
groupFunction.accept(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final Button button, final LocTextKey locTextKey) {
|
public void injectI18n(final Button button, final LocTextKey locTextKey) {
|
||||||
injectI18n(button, locTextKey, null);
|
injectI18n(button, locTextKey, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final Button button, final LocTextKey locTextKey, final LocTextKey locToolTipKey) {
|
public void injectI18n(final Button button, final LocTextKey locTextKey, final LocTextKey locToolTipKey) {
|
||||||
final Consumer<Button> buttonFunction = b -> {
|
final Consumer<Button> buttonFunction = b -> {
|
||||||
if (locTextKey != null) {
|
if (locTextKey != null) {
|
||||||
b.setText(this.i18nSupport.getText(locTextKey));
|
b.setText(this.i18nSupport.getText(locTextKey));
|
||||||
}
|
}
|
||||||
if (locToolTipKey != null) {
|
if (i18nSupport.hasText(locToolTipKey)) {
|
||||||
b.setToolTipText(Utils.formatLineBreaks(this.i18nSupport.getText(locToolTipKey)));
|
b.setToolTipText(Utils.formatLineBreaks(this.i18nSupport.getText(locToolTipKey)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
button.setData(POLYGLOT_WIDGET_FUNCTION_KEY, buttonFunction);
|
button.setData(POLYGLOT_WIDGET_FUNCTION_KEY, buttonFunction);
|
||||||
buttonFunction.accept(button);
|
buttonFunction.accept(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final Tree tree) {
|
public void injectI18n(final Tree tree) {
|
||||||
tree.setData(
|
tree.setData(
|
||||||
POLYGLOT_WIDGET_FUNCTION_KEY,
|
POLYGLOT_WIDGET_FUNCTION_KEY,
|
||||||
(Consumer<Tree>) t -> updateLocale(t.getItems(), this.i18nSupport));
|
(Consumer<Tree>) t -> updateLocale(t.getItems(), this.i18nSupport));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final TreeItem treeItem, final LocTextKey locTextKey) {
|
public void injectI18n(final TreeItem treeItem, final LocTextKey locTextKey) {
|
||||||
treeItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
treeItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
||||||
treeItem.setText(this.i18nSupport.getText(locTextKey));
|
treeItem.setText(this.i18nSupport.getText(locTextKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final Table table) {
|
public void injectI18n(final Table table) {
|
||||||
table.setData(
|
table.setData(
|
||||||
POLYGLOT_WIDGET_FUNCTION_KEY,
|
POLYGLOT_WIDGET_FUNCTION_KEY,
|
||||||
(Consumer<Table>) t -> {
|
(Consumer<Table>) t -> {
|
||||||
updateLocale(t.getColumns(), this.i18nSupport);
|
updateLocale(t.getColumns(), this.i18nSupport);
|
||||||
updateLocale(t.getItems(), this.i18nSupport);
|
updateLocale(t.getItems(), this.i18nSupport);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final TabFolder tabFolder) {
|
public void injectI18n(final TabFolder tabFolder) {
|
||||||
tabFolder.setData(
|
tabFolder.setData(
|
||||||
POLYGLOT_WIDGET_FUNCTION_KEY,
|
POLYGLOT_WIDGET_FUNCTION_KEY,
|
||||||
(Consumer<TabFolder>) t -> updateLocale(t.getItems(), this.i18nSupport));
|
(Consumer<TabFolder>) t -> updateLocale(t.getItems(), this.i18nSupport));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final TableColumn tableColumn, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
public void injectI18n(final TableColumn tableColumn, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
||||||
tableColumn.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
tableColumn.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
||||||
tableColumn.setText(this.i18nSupport.getText(locTextKey));
|
tableColumn.setText(this.i18nSupport.getText(locTextKey));
|
||||||
|
|
||||||
if (this.i18nSupport.hasText(locTooltipKey)) {
|
if (this.i18nSupport.hasText(locTooltipKey)) {
|
||||||
tableColumn.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
tableColumn.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
||||||
tableColumn.setToolTipText(Utils.formatLineBreaks(this.i18nSupport.getText(locTooltipKey)));
|
tableColumn.setToolTipText(Utils.formatLineBreaks(this.i18nSupport.getText(locTooltipKey)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final TableItem tableItem, final LocTextKey... locTextKey) {
|
public void injectI18n(final TableItem tableItem, final LocTextKey... locTextKey) {
|
||||||
if (locTextKey == null) {
|
if (locTextKey == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tableItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
tableItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
||||||
for (int i = 0; i < locTextKey.length; i++) {
|
for (int i = 0; i < locTextKey.length; i++) {
|
||||||
tableItem.setText(i, this.i18nSupport.getText(locTextKey[i]));
|
tableItem.setText(i, this.i18nSupport.getText(locTextKey[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final TabItem tabItem, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
public void injectI18n(final TabItem tabItem, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
||||||
tabItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
tabItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
||||||
tabItem.setText(this.i18nSupport.getText(locTextKey));
|
tabItem.setText(this.i18nSupport.getText(locTextKey));
|
||||||
|
|
||||||
if (this.i18nSupport.hasText(locTooltipKey)) {
|
if (this.i18nSupport.hasText(locTooltipKey)) {
|
||||||
tabItem.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
tabItem.setData(POLYGLOT_ITEM_TOOLTIP_DATA_KEY, locTooltipKey);
|
||||||
tabItem.setToolTipText(Utils.formatLineBreaks(this.i18nSupport.getText(locTooltipKey)));
|
tabItem.setToolTipText(Utils.formatLineBreaks(this.i18nSupport.getText(locTooltipKey)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLanguageSelector(final PageContext composerCtx) {
|
public void createLanguageSelector(final PageContext composerCtx) {
|
||||||
for (final Locale locale : this.i18nSupport.supportedLanguages()) {
|
for (final Locale locale : this.i18nSupport.supportedLanguages()) {
|
||||||
final Label languageSelection = new Label(composerCtx.getParent(), SWT.NONE);
|
final Label languageSelection = new Label(composerCtx.getParent(), SWT.NONE);
|
||||||
languageSelection.setData(
|
languageSelection.setData(
|
||||||
POLYGLOT_WIDGET_FUNCTION_KEY,
|
POLYGLOT_WIDGET_FUNCTION_KEY,
|
||||||
(Consumer<Label>) label -> label.setVisible(
|
(Consumer<Label>) label -> label.setVisible(
|
||||||
!this.i18nSupport.getUsersLanguageLocale()
|
!this.i18nSupport.getUsersLanguageLocale()
|
||||||
.getLanguage()
|
.getLanguage()
|
||||||
.equals(locale.getLanguage())));
|
.equals(locale.getLanguage())));
|
||||||
languageSelection.setData(RWT.CUSTOM_VARIANT, "header");
|
languageSelection.setData(RWT.CUSTOM_VARIANT, "header");
|
||||||
languageSelection.setText("| " + locale.getLanguage().toUpperCase(locale));
|
languageSelection.setText("| " + locale.getLanguage().toUpperCase(locale));
|
||||||
languageSelection.addListener(SWT.MouseDown, event -> {
|
languageSelection.addListener(SWT.MouseDown, event -> this.setPageLocale(composerCtx.getRoot(), locale));
|
||||||
this.setPageLocale(composerCtx.getRoot(), locale);
|
}
|
||||||
});
|
}
|
||||||
}
|
|
||||||
}
|
private static Consumer<Label> labelFunction(
|
||||||
|
final LocTextKey locTextKey,
|
||||||
private static final Consumer<Label> labelFunction(
|
final LocTextKey locToolTipKey,
|
||||||
final LocTextKey locTextKey,
|
final I18nSupport i18nSupport) {
|
||||||
final LocTextKey locToolTipKey,
|
|
||||||
final I18nSupport i18nSupport) {
|
return label -> {
|
||||||
|
if (locTextKey != null) {
|
||||||
return label -> {
|
label.setText(i18nSupport.getText(locTextKey));
|
||||||
if (locTextKey != null) {
|
}
|
||||||
label.setText(i18nSupport.getText(locTextKey));
|
if (i18nSupport.hasText(locToolTipKey)) {
|
||||||
}
|
label.setToolTipText(Utils.formatLineBreaks(i18nSupport.getText(locToolTipKey)));
|
||||||
if (locToolTipKey != null) {
|
}
|
||||||
label.setToolTipText(Utils.formatLineBreaks(i18nSupport.getText(locToolTipKey)));
|
};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
private static Consumer<Group> groupFunction(
|
||||||
|
final LocTextKey locTextKey,
|
||||||
private static final Consumer<Group> groupFunction(
|
final LocTextKey locToolTipKey,
|
||||||
final LocTextKey locTextKey,
|
final I18nSupport i18nSupport) {
|
||||||
final LocTextKey locToolTipKey,
|
|
||||||
final I18nSupport i18nSupport) {
|
return group -> {
|
||||||
|
if (locTextKey != null) {
|
||||||
return group -> {
|
group.setText(i18nSupport.getText(locTextKey));
|
||||||
if (locTextKey != null) {
|
}
|
||||||
group.setText(i18nSupport.getText(locTextKey));
|
if (i18nSupport.hasText(locToolTipKey)) {
|
||||||
}
|
group.setToolTipText(Utils.formatLineBreaks(i18nSupport.getText(locToolTipKey, StringUtils.EMPTY)));
|
||||||
if (locToolTipKey != null) {
|
}
|
||||||
group.setToolTipText(Utils.formatLineBreaks(i18nSupport.getText(locToolTipKey, StringUtils.EMPTY)));
|
};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
private static void updateLocale(final TabItem[] items, final I18nSupport i18nSupport) {
|
||||||
|
if (items == null) {
|
||||||
private static final void updateLocale(final TabItem[] items, final I18nSupport i18nSupport) {
|
return;
|
||||||
if (items == null) {
|
}
|
||||||
return;
|
|
||||||
}
|
for (final TabItem childItem : items) {
|
||||||
|
final LocTextKey locTextKey = (LocTextKey) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
||||||
for (final TabItem childItem : items) {
|
if (locTextKey != null) {
|
||||||
final LocTextKey locTextKey = (LocTextKey) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
childItem.setText(i18nSupport.getText(locTextKey));
|
||||||
if (locTextKey != null) {
|
}
|
||||||
childItem.setText(i18nSupport.getText(locTextKey));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
private static void updateLocale(final TreeItem[] items, final I18nSupport i18nSupport) {
|
||||||
|
if (items == null) {
|
||||||
private static final void updateLocale(final TreeItem[] items, final I18nSupport i18nSupport) {
|
return;
|
||||||
if (items == null) {
|
}
|
||||||
return;
|
|
||||||
}
|
for (final TreeItem childItem : items) {
|
||||||
|
final LocTextKey locTextKey = (LocTextKey) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
||||||
for (final TreeItem childItem : items) {
|
if (locTextKey != null) {
|
||||||
final LocTextKey locTextKey = (LocTextKey) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
childItem.setText(i18nSupport.getText(locTextKey));
|
||||||
if (locTextKey != null) {
|
}
|
||||||
childItem.setText(i18nSupport.getText(locTextKey));
|
updateLocale(childItem.getItems(), i18nSupport);
|
||||||
}
|
}
|
||||||
updateLocale(childItem.getItems(), i18nSupport);
|
}
|
||||||
}
|
|
||||||
}
|
private static void updateLocale(final TableItem[] items, final I18nSupport i18nSupport) {
|
||||||
|
if (items == null) {
|
||||||
private static void updateLocale(final TableItem[] items, final I18nSupport i18nSupport) {
|
return;
|
||||||
if (items == null) {
|
}
|
||||||
return;
|
|
||||||
}
|
for (final TableItem childItem : items) {
|
||||||
|
final LocTextKey[] locTextKey = (LocTextKey[]) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
||||||
for (final TableItem childItem : items) {
|
if (locTextKey != null) {
|
||||||
final LocTextKey[] locTextKey = (LocTextKey[]) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
for (int i = 0; i < locTextKey.length; i++) {
|
||||||
if (locTextKey != null) {
|
if (locTextKey[i] != null) {
|
||||||
for (int i = 0; i < locTextKey.length; i++) {
|
childItem.setText(i, i18nSupport.getText(locTextKey[i]));
|
||||||
if (locTextKey[i] != null) {
|
}
|
||||||
childItem.setText(i, i18nSupport.getText(locTextKey[i]));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
private static void updateLocale(final TableColumn[] columns, final I18nSupport i18nSupport) {
|
||||||
|
if (columns == null) {
|
||||||
private static void updateLocale(final TableColumn[] columns, final I18nSupport i18nSupport) {
|
return;
|
||||||
if (columns == null) {
|
}
|
||||||
return;
|
|
||||||
}
|
for (final TableColumn childItem : columns) {
|
||||||
|
final LocTextKey locTextKey = (LocTextKey) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
||||||
for (final TableColumn childItem : columns) {
|
if (locTextKey != null) {
|
||||||
final LocTextKey locTextKey = (LocTextKey) childItem.getData(POLYGLOT_ITEM_TEXT_DATA_KEY);
|
childItem.setText(i18nSupport.getText(locTextKey));
|
||||||
if (locTextKey != null) {
|
}
|
||||||
childItem.setText(i18nSupport.getText(locTextKey));
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,134 +1,141 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.widget;
|
package ch.ethz.seb.sebserver.gui.widget;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple3;
|
||||||
import org.eclipse.swt.SWT;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Listener;
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import org.eclipse.swt.widgets.Listener;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
public final class MultiSelectionCheckbox extends Composite implements Selection {
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
|
|
||||||
private static final long serialVersionUID = -8507565817745610126L;
|
public final class MultiSelectionCheckbox extends Composite implements Selection {
|
||||||
|
|
||||||
private Listener listener = null;
|
private static final long serialVersionUID = -8507565817745610126L;
|
||||||
private final Map<String, Button> checkboxes;
|
|
||||||
|
private Listener listener = null;
|
||||||
MultiSelectionCheckbox(final Composite parent) {
|
private final Map<String, Button> checkboxes;
|
||||||
super(parent, SWT.NONE);
|
|
||||||
final GridLayout gridLayout = new GridLayout(1, true);
|
MultiSelectionCheckbox(final Composite parent) {
|
||||||
gridLayout.verticalSpacing = 1;
|
super(parent, SWT.NONE);
|
||||||
gridLayout.marginLeft = 0;
|
final GridLayout gridLayout = new GridLayout(1, true);
|
||||||
gridLayout.marginHeight = 0;
|
gridLayout.verticalSpacing = 1;
|
||||||
gridLayout.marginWidth = 0;
|
gridLayout.marginLeft = 0;
|
||||||
setLayout(gridLayout);
|
gridLayout.marginHeight = 0;
|
||||||
|
gridLayout.marginWidth = 0;
|
||||||
this.checkboxes = new LinkedHashMap<>();
|
setLayout(gridLayout);
|
||||||
}
|
|
||||||
|
this.checkboxes = new LinkedHashMap<>();
|
||||||
@Override
|
}
|
||||||
public Type type() {
|
|
||||||
return Type.MULTI_CHECKBOX;
|
@Override
|
||||||
}
|
public Type type() {
|
||||||
|
return Type.MULTI_CHECKBOX;
|
||||||
@Override
|
}
|
||||||
public void applyNewMapping(final List<Tuple<String>> mapping) {
|
|
||||||
final String selectionValue = getSelectionValue();
|
@Override
|
||||||
this.checkboxes.clear();
|
public void applyNewMapping(final List<Tuple<String>> mapping) {
|
||||||
PageService.clearComposite(this);
|
final String selectionValue = getSelectionValue();
|
||||||
|
this.checkboxes.clear();
|
||||||
for (final Tuple<String> tuple : mapping) {
|
PageService.clearComposite(this);
|
||||||
final Button button = new Button(this, SWT.CHECK);
|
|
||||||
button.setText(tuple._2);
|
for (final Tuple<String> tuple : mapping) {
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true);
|
final Button button = new Button(this, SWT.CHECK);
|
||||||
button.setLayoutData(gridData);
|
button.setText(tuple._2);
|
||||||
button.setData(OPTION_VALUE, tuple._1);
|
final GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true);
|
||||||
button.addListener(SWT.Selection, event -> {
|
button.setLayoutData(gridData);
|
||||||
if (this.listener != null) {
|
button.setData(OPTION_VALUE, tuple._1);
|
||||||
this.listener.handleEvent(event);
|
button.addListener(SWT.Selection, event -> {
|
||||||
}
|
if (this.listener != null) {
|
||||||
});
|
this.listener.handleEvent(event);
|
||||||
this.checkboxes.put(tuple._1, button);
|
}
|
||||||
}
|
});
|
||||||
|
this.checkboxes.put(tuple._1, button);
|
||||||
if (StringUtils.isNotBlank(selectionValue)) {
|
|
||||||
select(selectionValue);
|
Tuple3<String> tuple3 = tuple.adaptTo(Tuple3.class);
|
||||||
}
|
if (tuple3 != null && StringUtils.isNotBlank(tuple3._3)) {
|
||||||
}
|
button.setToolTipText(tuple3._3);
|
||||||
|
}
|
||||||
@Override
|
}
|
||||||
public void applyToolTipsForItems(final List<Tuple<String>> mapping) {
|
|
||||||
mapping
|
if (StringUtils.isNotBlank(selectionValue)) {
|
||||||
.stream()
|
select(selectionValue);
|
||||||
.filter(tuple -> StringUtils.isNotBlank(tuple._2))
|
}
|
||||||
.forEach(tuple -> {
|
}
|
||||||
final Button button = this.checkboxes.get(tuple._1);
|
|
||||||
if (button != null) {
|
@Override
|
||||||
button.setToolTipText(Utils.formatLineBreaks(tuple._2));
|
public void applyToolTipsForItems(final List<Tuple<String>> mapping) {
|
||||||
}
|
mapping
|
||||||
});
|
.stream()
|
||||||
}
|
.filter(tuple -> StringUtils.isNotBlank(tuple._2))
|
||||||
|
.forEach(tuple -> {
|
||||||
@Override
|
final Button button = this.checkboxes.get(tuple._1);
|
||||||
public void select(final String keys) {
|
if (button != null) {
|
||||||
clear();
|
button.setToolTipText(Utils.formatLineBreaks(tuple._2));
|
||||||
if (StringUtils.isBlank(keys)) {
|
}
|
||||||
return;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Arrays.asList(StringUtils.split(keys, Constants.LIST_SEPARATOR))
|
@Override
|
||||||
.stream()
|
public void select(final String keys) {
|
||||||
.forEach(key -> {
|
clear();
|
||||||
final Button button = this.checkboxes.get(key);
|
if (StringUtils.isBlank(keys)) {
|
||||||
if (button != null) {
|
return;
|
||||||
button.setSelection(true);
|
}
|
||||||
}
|
|
||||||
});
|
Arrays.asList(StringUtils.split(keys, Constants.LIST_SEPARATOR))
|
||||||
}
|
.stream()
|
||||||
|
.forEach(key -> {
|
||||||
@Override
|
final Button button = this.checkboxes.get(key);
|
||||||
public String getSelectionValue() {
|
if (button != null) {
|
||||||
return StringUtils.joinWith(
|
button.setSelection(true);
|
||||||
Constants.LIST_SEPARATOR,
|
}
|
||||||
this.checkboxes
|
});
|
||||||
.values()
|
}
|
||||||
.stream()
|
|
||||||
.filter(button -> button.getSelection())
|
@Override
|
||||||
.map(button -> (String) button.getData(OPTION_VALUE))
|
public String getSelectionValue() {
|
||||||
.collect(Collectors.toList()).toArray());
|
return StringUtils.joinWith(
|
||||||
}
|
Constants.LIST_SEPARATOR,
|
||||||
|
this.checkboxes
|
||||||
@Override
|
.values()
|
||||||
public void clear() {
|
.stream()
|
||||||
this.checkboxes
|
.filter(button -> button.getSelection())
|
||||||
.values()
|
.map(button -> (String) button.getData(OPTION_VALUE))
|
||||||
.stream()
|
.collect(Collectors.toList()).toArray());
|
||||||
.forEach(button -> button.setSelection(false));
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public void clear() {
|
||||||
public void setSelectionListener(final Listener listener) {
|
this.checkboxes
|
||||||
this.listener = listener;
|
.values()
|
||||||
}
|
.stream()
|
||||||
|
.forEach(button -> button.setSelection(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelectionListener(final Listener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -59,6 +59,8 @@ sebserver.overall.types.entityType.INSTITUTION=Institution
|
||||||
sebserver.overall.types.entityType.SEB_CLIENT_CONFIGURATION=Client Configuration
|
sebserver.overall.types.entityType.SEB_CLIENT_CONFIGURATION=Client Configuration
|
||||||
sebserver.overall.types.entityType.LMS_SETUP=LMS Setup
|
sebserver.overall.types.entityType.LMS_SETUP=LMS Setup
|
||||||
sebserver.overall.types.entityType.USER=User Account
|
sebserver.overall.types.entityType.USER=User Account
|
||||||
|
sebserver.overall.types.entityType.CLIENT_INSTRUCTION=SEB Client Instruction
|
||||||
|
sebserver.overall.types.entityType.EXAM_SEB_RESTRICTION=SEB Exam Restriction
|
||||||
|
|
||||||
sebserver.overall.activity.title.serveradmin=SEB Server Administration
|
sebserver.overall.activity.title.serveradmin=SEB Server Administration
|
||||||
sebserver.overall.activity.title.sebconfig=SEB Configuration
|
sebserver.overall.activity.title.sebconfig=SEB Configuration
|
||||||
|
@ -174,18 +176,27 @@ sebserver.institution.form.logoImage.unsupportedFileType=The selected file is no
|
||||||
|
|
||||||
sebserver.useraccount.list.actions=
|
sebserver.useraccount.list.actions=
|
||||||
sebserver.useraccount.role.SEB_SERVER_ADMIN=SEB Server Administrator
|
sebserver.useraccount.role.SEB_SERVER_ADMIN=SEB Server Administrator
|
||||||
|
sebserver.useraccount.role.SEB_SERVER_ADMIN.tooltip=A SEB server administrator has overall read privileges</br>and is able to create new institutions and user accounts
|
||||||
sebserver.useraccount.role.INSTITUTIONAL_ADMIN=Institutional Administrator
|
sebserver.useraccount.role.INSTITUTIONAL_ADMIN=Institutional Administrator
|
||||||
|
sebserver.useraccount.role.INSTITUTIONAL_ADMIN.tooltip=An institutional administrator has overall read privileges on the assigned institution</br>and is able to edit the institution and create new user accounts for the institution.</br>Furthermore an institutional administrator is able to create new LMS bindings and SEB client configurations for the institution.
|
||||||
sebserver.useraccount.role.EXAM_ADMIN=Exam Administrator
|
sebserver.useraccount.role.EXAM_ADMIN=Exam Administrator
|
||||||
|
sebserver.useraccount.role.EXAM_ADMIN.tooltip=An exam administrator has overall read privileges for the institution but cannot see or manage other user accounts.</br>An exam administrator is able to create new SEB configurations and import and setup exams.
|
||||||
sebserver.useraccount.role.EXAM_SUPPORTER=Exam Supporter
|
sebserver.useraccount.role.EXAM_SUPPORTER=Exam Supporter
|
||||||
|
sebserver.useraccount.role.EXAM_SUPPORTER.tooltip=An exam supporter can only see and edit the own user account</br> and monitor exams for that he/she was attached by an exam administrator.
|
||||||
|
|
||||||
sebserver.useraccount.list.empty=No user account has been found. Please adapt the filter or create a new user account
|
sebserver.useraccount.list.empty=No user account has been found. Please adapt the filter or create a new user account
|
||||||
sebserver.useraccount.list.title=User Accounts
|
sebserver.useraccount.list.title=User Accounts
|
||||||
sebserver.useraccount.list.column.institution=Institution
|
sebserver.useraccount.list.column.institution=Institution
|
||||||
|
sebserver.useraccount.list.column.institution.tooltip=The institution of the user account.</br></br>Use the filter above to specify the institution.</br>{0}
|
||||||
sebserver.useraccount.list.column.name=First Name
|
sebserver.useraccount.list.column.name=First Name
|
||||||
|
sebserver.useraccount.list.column.name.tooltip=The first name of the user.</br></br>Use the filter above to narrow down a specific first name.</br>{0}
|
||||||
sebserver.useraccount.list.column.username=User Name
|
sebserver.useraccount.list.column.username=User Name
|
||||||
|
sebserver.useraccount.list.column.username.tooltip=The internal user name of the user.</br></br>Use the filter above to narrow down a specific user name.</br>{0}
|
||||||
sebserver.useraccount.list.column.email=Mail
|
sebserver.useraccount.list.column.email=Mail
|
||||||
|
sebserver.useraccount.list.column.email.tooltip=The e-mail address of the user.</br></br>Use the filter above to narrow down a specific e-mail address.</br>{0}
|
||||||
sebserver.useraccount.list.column.language=Language
|
sebserver.useraccount.list.column.language=Language
|
||||||
sebserver.useraccount.list.column.active=Active
|
sebserver.useraccount.list.column.active=Active
|
||||||
|
sebserver.useraccount.list.column.active.tooltip=The activity of the user.</br></br>Use the filter above to specify the activity.</br>{0}
|
||||||
|
|
||||||
sebserver.useraccount.action.list=User Account
|
sebserver.useraccount.action.list=User Account
|
||||||
sebserver.useraccount.action.form=User Account of {0}
|
sebserver.useraccount.action.form=User Account of {0}
|
||||||
|
@ -206,19 +217,32 @@ sebserver.useraccount.info.notEditable=You have no edit rights for this User Acc
|
||||||
sebserver.useraccount.form.title=User Account
|
sebserver.useraccount.form.title=User Account
|
||||||
sebserver.useraccount.form.title.new=Add User Account
|
sebserver.useraccount.form.title.new=Add User Account
|
||||||
sebserver.useraccount.form.institution=Institution
|
sebserver.useraccount.form.institution=Institution
|
||||||
|
sebserver.useraccount.form.institution.tooltip=The institution the user belongs to.
|
||||||
sebserver.useraccount.form.creationdate=Creation Date
|
sebserver.useraccount.form.creationdate=Creation Date
|
||||||
|
sebserver.useraccount.form.creationdate.tooltip=The date when the user-account was first created.
|
||||||
sebserver.useraccount.form.name=First Name
|
sebserver.useraccount.form.name=First Name
|
||||||
|
sebserver.useraccount.form.name.tooltip=The first name of the user.
|
||||||
sebserver.useraccount.form.surname=Surname
|
sebserver.useraccount.form.surname=Surname
|
||||||
|
sebserver.useraccount.form.surname.tooltip=The last- or surname of the user.
|
||||||
sebserver.useraccount.form.username=Username
|
sebserver.useraccount.form.username=Username
|
||||||
|
sebserver.useraccount.form.username.tooltip=The internal user name of the account.
|
||||||
sebserver.useraccount.form.mail=E-Mail
|
sebserver.useraccount.form.mail=E-Mail
|
||||||
|
sebserver.useraccount.form.mail.tooltip=The e-mail address of the user.
|
||||||
sebserver.useraccount.form.language=Language
|
sebserver.useraccount.form.language=Language
|
||||||
|
sebserver.useraccount.form.language.tooltip=The users language.
|
||||||
sebserver.useraccount.form.timezone=Time Zone
|
sebserver.useraccount.form.timezone=Time Zone
|
||||||
|
sebserver.useraccount.form.timezone.tooltip=The time-zone of the user.</br></br>Note that this also defines the exact time and date that is displayed to the user.
|
||||||
sebserver.useraccount.form.roles=User Roles
|
sebserver.useraccount.form.roles=User Roles
|
||||||
|
sebserver.useraccount.form.roles.tooltip=Select the roles for the user.</br>A user can have more then one role but must have at least one.</br></br>Please use the tooltip on the role name for more information about a specific role.
|
||||||
sebserver.useraccount.form.password=Password
|
sebserver.useraccount.form.password=Password
|
||||||
|
sebserver.useraccount.form.password.tooltip=The password of the user account
|
||||||
sebserver.useraccount.form.password.confirm=Confirm Password
|
sebserver.useraccount.form.password.confirm=Confirm Password
|
||||||
|
sebserver.useraccount.form.password.confirm.tooltip=Please confirm the password
|
||||||
sebserver.useraccount.form.pwchange.title=Change Password : {0}
|
sebserver.useraccount.form.pwchange.title=Change Password : {0}
|
||||||
sebserver.useraccount.form.password.new=New Password
|
sebserver.useraccount.form.password.new=New Password
|
||||||
|
sebserver.useraccount.form.password.new.tooltip=The new password for the user account
|
||||||
sebserver.useraccount.form.password.new.confirm=Confirm New Password
|
sebserver.useraccount.form.password.new.confirm=Confirm New Password
|
||||||
|
sebserver.useraccount.form.password.new.confirm.tooltip=Please confirm the password
|
||||||
|
|
||||||
################################
|
################################
|
||||||
# LMS Setup
|
# LMS Setup
|
||||||
|
@ -465,19 +489,28 @@ sebserver.clientconfig.list.empty=There is currently no SEB-Client configuration
|
||||||
sebserver.clientconfig.list.title=SEB Client Configurations
|
sebserver.clientconfig.list.title=SEB Client Configurations
|
||||||
sebserver.clientconfig.list.actions=
|
sebserver.clientconfig.list.actions=
|
||||||
sebserver.clientconfig.list.column.institution=Institution
|
sebserver.clientconfig.list.column.institution=Institution
|
||||||
|
sebserver.clientconfig.list.column.institution.tooltip=The institution of the SEB client configuration.</br></br>Use the filter above to specify the institution.</br>{0}
|
||||||
sebserver.clientconfig.list.column.name=Name
|
sebserver.clientconfig.list.column.name=Name
|
||||||
|
sebserver.clientconfig.list.column.name.tooltip=The name of the SEB client configuration.</br></br>Use the filter above to narrow down a specific name.</br>{0}
|
||||||
sebserver.clientconfig.list.column.date=Creation Date {0}
|
sebserver.clientconfig.list.column.date=Creation Date {0}
|
||||||
|
sebserver.clientconfig.list.column.date.tooltip=The date when the SEB client configuration was first created.</br></br>Use the filter above to specify a from-date.</br>{0}
|
||||||
sebserver.clientconfig.list.column.active=Active
|
sebserver.clientconfig.list.column.active=Active
|
||||||
|
sebserver.clientconfig.list.column.active.tooltip=The activity of SEB client configuration.</br></br>Use the filter above to specify the activity.</br>{0}
|
||||||
sebserver.clientconfig.info.pleaseSelect=Please select first a Client Configuration from the list
|
sebserver.clientconfig.info.pleaseSelect=Please select first a Client Configuration from the list
|
||||||
sebserver.clientconfig.list.action.no.modify.privilege=No Access: A SEB Client Configuration from other institution cannot be modified.
|
sebserver.clientconfig.list.action.no.modify.privilege=No Access: A SEB Client Configuration from other institution cannot be modified.
|
||||||
|
|
||||||
sebserver.clientconfig.form.title.new=Add Client Configuration
|
sebserver.clientconfig.form.title.new=Add Client Configuration
|
||||||
sebserver.clientconfig.form.title=SEB Client Configuration
|
sebserver.clientconfig.form.title=SEB Client Configuration
|
||||||
sebserver.clientconfig.form.name=Name
|
sebserver.clientconfig.form.name=Name
|
||||||
|
sebserver.clientconfig.form.name.tooltip=The name of the SEB Client Configuration.</br>Can be any name that not already exists for another SEB Client Configuration
|
||||||
sebserver.clientconfig.form.fallback-url=Fallback Start URL
|
sebserver.clientconfig.form.fallback-url=Fallback Start URL
|
||||||
|
sebserver.clientconfig.form.fallback-url.tooltip=A fallback URL that tells the SEB where to go when the SEB Server service is unavailable.
|
||||||
sebserver.clientconfig.form.date=Creation Date
|
sebserver.clientconfig.form.date=Creation Date
|
||||||
|
sebserver.clientconfig.form.date.tooltip=The date when the SEB client configuration was first created.
|
||||||
sebserver.clientconfig.form.encryptSecret=Configuration Password
|
sebserver.clientconfig.form.encryptSecret=Configuration Password
|
||||||
|
sebserver.clientconfig.form.encryptSecret.tooltip=Define a password if the SEB client configuration shall be password-encrypted
|
||||||
sebserver.clientconfig.form.encryptSecret.confirm=Confirm Password
|
sebserver.clientconfig.form.encryptSecret.confirm=Confirm Password
|
||||||
|
sebserver.clientconfig.form.encryptSecret.confirm.tooltip=Please retype the given password for configrmation
|
||||||
|
|
||||||
sebserver.clientconfig.action.list.new=Add Configuration
|
sebserver.clientconfig.action.list.new=Add Configuration
|
||||||
sebserver.clientconfig.action.list.view=View Configuration
|
sebserver.clientconfig.action.list.view=View Configuration
|
||||||
|
@ -494,9 +527,13 @@ sebserver.clientconfig.action.deactivate=Deactivate Configuration
|
||||||
sebserver.examconfig.action.list=Exam Configuration
|
sebserver.examconfig.action.list=Exam Configuration
|
||||||
sebserver.examconfig.list.title=Exam Configurations
|
sebserver.examconfig.list.title=Exam Configurations
|
||||||
sebserver.examconfig.list.column.institution=Institution
|
sebserver.examconfig.list.column.institution=Institution
|
||||||
|
sebserver.examconfig.list.column.institution.tooltip=The institution of the SEB exam configuration.</br></br>Use the filter above to specify the institution.</br>{0}
|
||||||
sebserver.examconfig.list.column.name=Name
|
sebserver.examconfig.list.column.name=Name
|
||||||
|
sebserver.examconfig.list.column.name.tooltip=The name of the SEB exam configuration.</br></br>Use the filter above to narrow down a specific name.</br>{0}
|
||||||
sebserver.examconfig.list.column.description=Description
|
sebserver.examconfig.list.column.description=Description
|
||||||
|
sebserver.examconfig.list.column.description.tooltip=The description of the SEB exam configuration.</br></br>Use the filter above to find configurations that contains specific words or phrases within the description.</br>{0}
|
||||||
sebserver.examconfig.list.column.status=Status
|
sebserver.examconfig.list.column.status=Status
|
||||||
|
sebserver.examconfig.list.column.status.tooltip=The status of the SEB exam configuration.</br></br>Use the filter above to specify a status.</br>{0}
|
||||||
|
|
||||||
sebserver.examconfig.list.actions=
|
sebserver.examconfig.list.actions=
|
||||||
|
|
||||||
|
@ -506,10 +543,9 @@ sebserver.examconfig.list.action.no.modify.privilege=No Access: An Exam Configur
|
||||||
|
|
||||||
sebserver.examconfig.action.list.new=Add Exam Configuration
|
sebserver.examconfig.action.list.new=Add Exam Configuration
|
||||||
sebserver.examconfig.action.list.view=View Configuration
|
sebserver.examconfig.action.list.view=View Configuration
|
||||||
sebserver.examconfig.action.list.modify=Edit Settings
|
sebserver.examconfig.action.list.modify=Configuration Settings
|
||||||
sebserver.examconfig.action.list.modify.properties=Edit Configuration
|
sebserver.examconfig.action.list.modify.properties=Edit Configuration
|
||||||
sebserver.examconfig.action.view=View Settings
|
sebserver.examconfig.action.modify=Configuration Settings
|
||||||
sebserver.examconfig.action.modify=Edit Settings
|
|
||||||
sebserver.examconfig.action.modify.properties=Edit Configuration
|
sebserver.examconfig.action.modify.properties=Edit Configuration
|
||||||
sebserver.examconfig.action.view.properties=View Configuration
|
sebserver.examconfig.action.view.properties=View Configuration
|
||||||
sebserver.examconfig.action.save=Save
|
sebserver.examconfig.action.save=Save
|
||||||
|
@ -534,12 +570,17 @@ sebserver.examconfig.action.state-change.confirm=This configuration is already a
|
||||||
sebserver.examconfig.form.title.new=Add Exam Configuration
|
sebserver.examconfig.form.title.new=Add Exam Configuration
|
||||||
sebserver.examconfig.form.title=Exam Configuration
|
sebserver.examconfig.form.title=Exam Configuration
|
||||||
sebserver.examconfig.form.name=Name
|
sebserver.examconfig.form.name=Name
|
||||||
|
sebserver.examconfig.form.name.tooltip=The name of the SEB exam configuration.
|
||||||
sebserver.examconfig.form.description=Description
|
sebserver.examconfig.form.description=Description
|
||||||
|
sebserver.examconfig.form.description.tooltip=The description text of the SEB exam configuration.
|
||||||
sebserver.examconfig.form.with-history=With History
|
sebserver.examconfig.form.with-history=With History
|
||||||
sebserver.examconfig.form.template=Template
|
sebserver.examconfig.form.template=Template
|
||||||
|
sebserver.examconfig.form.template.tooltip=The template this SEB exam configuration depends on.
|
||||||
sebserver.examconfig.form.status=Status
|
sebserver.examconfig.form.status=Status
|
||||||
|
sebserver.examconfig.form.status.tooltip=The status of this SEB exam configuration.</br></br>Under Construction marks a SEB exam configuration to not be able to attach to an exam so far.</br></br>Ready to use marks an SEB exam configuration to be able to attach to an exam.</br></br>In Use marks a SEB exam configuration is already been used from one or more exam(s)
|
||||||
sebserver.examconfig.form.config-key.title=Config Key
|
sebserver.examconfig.form.config-key.title=Config Key
|
||||||
sebserver.examconfig.form.attched-to=Attached To Exam
|
sebserver.examconfig.form.attached-to=Attached To Exam
|
||||||
|
sebserver.examconfig.form.attached-to.tooltip=This SEB exam configuration is currently attached to the following exams.</br></br>Select an exam from the list and use the "View Exam" or Double-Click on the list to go to a specific exam.
|
||||||
|
|
||||||
sebserver.examconfig.status.CONSTRUCTION=Under Construction
|
sebserver.examconfig.status.CONSTRUCTION=Under Construction
|
||||||
sebserver.examconfig.status.READY_TO_USE=Ready To Use
|
sebserver.examconfig.status.READY_TO_USE=Ready To Use
|
||||||
|
@ -1037,7 +1078,9 @@ sebserver.configtemplate.action.create-config.dialog=Exam Configuration
|
||||||
sebserver.configtemplate.form.title.new=Add Template
|
sebserver.configtemplate.form.title.new=Add Template
|
||||||
sebserver.configtemplate.form.title=Configuration Template
|
sebserver.configtemplate.form.title=Configuration Template
|
||||||
sebserver.configtemplate.form.name=Name
|
sebserver.configtemplate.form.name=Name
|
||||||
|
sebserver.configtemplate.form.name.tooltip=The name of the SEB exam configuration template
|
||||||
sebserver.configtemplate.form.description=Description
|
sebserver.configtemplate.form.description=Description
|
||||||
|
sebserver.configtemplate.form.description.tooltip=The description of the SEB exam configuration template
|
||||||
sebserver.configtemplate.action.save=Save Template
|
sebserver.configtemplate.action.save=Save Template
|
||||||
|
|
||||||
sebserver.configtemplate.attr.type.TEXT_FIELD=Text Field
|
sebserver.configtemplate.attr.type.TEXT_FIELD=Text Field
|
||||||
|
@ -1058,10 +1101,15 @@ sebserver.configtemplate.attr.type.INLINE_TABLE=Table
|
||||||
sebserver.configtemplate.attr.type.COMPOSITE_TABLE=Table
|
sebserver.configtemplate.attr.type.COMPOSITE_TABLE=Table
|
||||||
|
|
||||||
sebserver.configtemplate.attrs.list.title=Configuration Attributes
|
sebserver.configtemplate.attrs.list.title=Configuration Attributes
|
||||||
|
sebserver.configtemplate.attrs.list.title.tooltip=Table of all SEB exam configuration attributes of this template
|
||||||
sebserver.configtemplate.attrs.list.name=Name
|
sebserver.configtemplate.attrs.list.name=Name
|
||||||
|
sebserver.configtemplate.attrs.list.name.tooltip=The technical name of the SEB exam configuration attribute with the display name in brackets if available.</br></br>{0}
|
||||||
sebserver.configtemplate.attrs.list.view=View
|
sebserver.configtemplate.attrs.list.view=View
|
||||||
|
sebserver.configtemplate.attrs.list.view.tooltip=The view/tab where the SEB exam configuration attribute belongs to.</br></br>{0}
|
||||||
sebserver.configtemplate.attrs.list.group=Group
|
sebserver.configtemplate.attrs.list.group=Group
|
||||||
|
sebserver.configtemplate.attrs.list.group.tooltip=The group on the view/tab where the SEB exam configuration attribute belongs to.</br></br>{0}
|
||||||
sebserver.configtemplate.attrs.list.type=Type
|
sebserver.configtemplate.attrs.list.type=Type
|
||||||
|
sebserver.configtemplate.attrs.list.type.tooltip=The type of the SEB exam configuration attribute.</br></br>{0}
|
||||||
|
|
||||||
sebserver.configtemplate.attr.list.actions=
|
sebserver.configtemplate.attr.list.actions=
|
||||||
sebserver.configtemplate.attr.list.actions.modify=Edit Attribute
|
sebserver.configtemplate.attr.list.actions.modify=Edit Attribute
|
||||||
|
@ -1072,10 +1120,15 @@ sebserver.configtemplate.attr.info.pleaseSelect=Please select first an Attribute
|
||||||
|
|
||||||
sebserver.configtemplate.attr.form.title=Template Attribute
|
sebserver.configtemplate.attr.form.title=Template Attribute
|
||||||
sebserver.configtemplate.attr.form.name=Name
|
sebserver.configtemplate.attr.form.name=Name
|
||||||
|
sebserver.configtemplate.attr.form.name.tooltip=The technical name of the SEB exam configuration attribute with the display name in brackets if available.
|
||||||
sebserver.configtemplate.attr.form.type=Type
|
sebserver.configtemplate.attr.form.type=Type
|
||||||
|
sebserver.configtemplate.attr.form.type.tooltip=The type of the SEB exam configuration attribute.
|
||||||
sebserver.configtemplate.attr.form.view=View
|
sebserver.configtemplate.attr.form.view=View
|
||||||
|
sebserver.configtemplate.attr.form.view.tooltip=The view/tab where the SEB exam configuration attribute belongs to.
|
||||||
sebserver.configtemplate.attr.form.group=Group
|
sebserver.configtemplate.attr.form.group=Group
|
||||||
|
sebserver.configtemplate.attr.form.group.tooltip=The group on the view/tab where the SEB exam configuration attribute belongs to.
|
||||||
sebserver.configtemplate.attr.form.value=Template Attribute Value
|
sebserver.configtemplate.attr.form.value=Template Attribute Value
|
||||||
|
sebserver.configtemplate.attr.form.value.tooltip=The SEB exam configuration attribute value that can be set as default for this template
|
||||||
|
|
||||||
sebserver.configtemplate.attr.action.setdefault=Set Default Values
|
sebserver.configtemplate.attr.action.setdefault=Set Default Values
|
||||||
sebserver.configtemplate.attr.action.template=View Template
|
sebserver.configtemplate.attr.action.template=View Template
|
||||||
|
@ -1165,10 +1218,15 @@ sebserver.logs.activity.seblogs.details=Show Details
|
||||||
|
|
||||||
sebserver.userlogs.list.title=User Activity Logs
|
sebserver.userlogs.list.title=User Activity Logs
|
||||||
sebserver.userlogs.list.column.institution=Institution
|
sebserver.userlogs.list.column.institution=Institution
|
||||||
|
sebserver.userlogs.list.column.institution.tooltip=The institution of the user activity log.</br></br>Use the filter above to specify the institution.</br>{0}
|
||||||
sebserver.userlogs.list.column.user=User
|
sebserver.userlogs.list.column.user=User
|
||||||
|
sebserver.userlogs.list.column.user.tooltip=The user account of the user activity log.</br></br>Use the filter above to specify a user account.</br>{0}
|
||||||
sebserver.userlogs.list.column.dateTime=Date {0}
|
sebserver.userlogs.list.column.dateTime=Date {0}
|
||||||
|
sebserver.userlogs.list.column.dateTime.tooltip=The date when the user activity log happened.</br></br>Use the filter above to specify a from- and to-date range.</br>{0}
|
||||||
sebserver.userlogs.list.column.activityType=User Activity
|
sebserver.userlogs.list.column.activityType=User Activity
|
||||||
sebserver.userlogs.list.column.entityType=Entity Type
|
sebserver.userlogs.list.column.activityType.tooltip=The type of the user activity.</br></br>Use the filter above to specify a activity type.</br>{0}
|
||||||
|
sebserver.userlogs.list.column.entityType=Domain Type
|
||||||
|
sebserver.userlogs.list.column.entityType.tooltip=The domain type of the user activity.</br></br>Use the filter above to specify a domain type.</br>{0}
|
||||||
sebserver.userlogs.list.column.entityId=Entity-ID
|
sebserver.userlogs.list.column.entityId=Entity-ID
|
||||||
sebserver.userlogs.list.column.message=Message
|
sebserver.userlogs.list.column.message=Message
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 1.7 KiB |
Loading…
Add table
Reference in a new issue