SEBSERV-147 GUI implementation
This commit is contained in:
parent
9267d34d3a
commit
a7a4b60917
10 changed files with 352 additions and 20 deletions
|
@ -13,6 +13,7 @@ import java.util.Base64.Encoder;
|
|||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.rap.rwt.client.service.JavaScriptExecutor;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
@ -57,7 +58,9 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam;
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicators;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetProctoringSettings;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.logs.GetExtendedClientEventPage;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.ConfirmPendingClientNotification;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetClientConnectionData;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetPendingClientNotifications;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProcotringRooms;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProctorRoomConnectionData;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
|
@ -66,6 +69,7 @@ import ch.ethz.seb.sebserver.gui.service.session.InstructionProcessor;
|
|||
import ch.ethz.seb.sebserver.gui.service.session.ProctoringGUIService;
|
||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
|
@ -76,19 +80,16 @@ public class MonitoringClientConnection implements TemplateComposer {
|
|||
|
||||
private static final Logger log = LoggerFactory.getLogger(MonitoringClientConnection.class);
|
||||
|
||||
// // @formatter:off
|
||||
// private static final String OPEN_SINGEL_ROOM_SCRIPT =
|
||||
// "var existingWin = window.open('', '%s', 'height=420,width=640,location=no,scrollbars=yes,status=no,menubar=yes,toolbar=yes,titlebar=yes,dialog=yes');\n" +
|
||||
// "if(existingWin.location.href === 'about:blank'){\n" +
|
||||
// " existingWin.location.href = '%s%s';\n" +
|
||||
// " existingWin.focus();\n" +
|
||||
// "} else {\n" +
|
||||
// " existingWin.focus();\n" +
|
||||
// "}";
|
||||
// // @formatter:on
|
||||
|
||||
private static final LocTextKey PAGE_TITLE_KEY =
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.title");
|
||||
|
||||
private static final LocTextKey NOTIFICATION_LIST_TITLE_KEY =
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.notificationlist.title");
|
||||
private static final LocTextKey NOTIFICATION_LIST_TITLE_TOOLTIP_KEY =
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.notificationlist.title.tooltip");
|
||||
private static final LocTextKey NOTIFICATION_LIST_CONFIRM_TEXT_KEY =
|
||||
new LocTextKey("monitoring.exam.connection.action.confirm.notification.text");
|
||||
|
||||
private static final LocTextKey EVENT_LIST_TITLE_KEY =
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.eventlist.title");
|
||||
private static final LocTextKey EVENT_LIST_TITLE_TOOLTIP_KEY =
|
||||
|
@ -205,17 +206,77 @@ public class MonitoringClientConnection implements TemplateComposer {
|
|||
context1 -> clientConnectionDetails.updateData(),
|
||||
context -> clientConnectionDetails.updateGUI());
|
||||
|
||||
widgetFactory.addFormSubContextHeader(
|
||||
content,
|
||||
EVENT_LIST_TITLE_KEY,
|
||||
EVENT_LIST_TITLE_TOOLTIP_KEY);
|
||||
|
||||
final PageService.PageActionBuilder actionBuilder = this.pageService
|
||||
.pageActionBuilder(
|
||||
pageContext
|
||||
.clearAttributes()
|
||||
.clearEntityKeys());
|
||||
|
||||
final boolean hasNotification = BooleanUtils.isTrue(connectionData.pendingNotification());
|
||||
if (hasNotification) {
|
||||
// add notification table
|
||||
|
||||
widgetFactory.addFormSubContextHeader(
|
||||
content,
|
||||
NOTIFICATION_LIST_TITLE_KEY,
|
||||
NOTIFICATION_LIST_TITLE_TOOLTIP_KEY);
|
||||
|
||||
final EntityTable<ClientEvent> notificationTable = this.pageService.remoteListTableBuilder(
|
||||
restService.getRestCall(GetPendingClientNotifications.class),
|
||||
EntityType.CLIENT_EVENT)
|
||||
.withRestCallAdapter(builder -> builder.withURIVariable(
|
||||
API.PARAM_PARENT_MODEL_ID,
|
||||
parentEntityKey.modelId)
|
||||
.withURIVariable(
|
||||
API.EXAM_API_SEB_CONNECTION_TOKEN,
|
||||
connectionToken))
|
||||
.withPaging(5)
|
||||
.withColumn(new ColumnDefinition<ClientEvent>(
|
||||
Domain.CLIENT_EVENT.ATTR_TYPE,
|
||||
LIST_COLUMN_TYPE_KEY,
|
||||
this.resourceService::getEventTypeName)
|
||||
.sortable()
|
||||
.widthProportion(2))
|
||||
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
Domain.CLIENT_EVENT.ATTR_TEXT,
|
||||
LIST_COLUMN_TEXT_KEY,
|
||||
ClientEvent::getText)
|
||||
.sortable()
|
||||
.withCellTooltip()
|
||||
.widthProportion(4))
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
Domain.CLIENT_EVENT.ATTR_SERVER_TIME,
|
||||
new LocTextKey(LIST_COLUMN_SERVER_TIME_KEY.name,
|
||||
this.i18nSupport.getUsersTimeZoneTitleSuffix()),
|
||||
this::getServerTime)
|
||||
.sortable()
|
||||
.widthProportion(1))
|
||||
.withDefaultAction(t -> actionBuilder
|
||||
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION_CONFIRM_NOTIFICATION)
|
||||
.withParentEntityKey(parentEntityKey)
|
||||
.withConfirm(() -> NOTIFICATION_LIST_CONFIRM_TEXT_KEY)
|
||||
.withExec(action -> this.confirmNotification(action, connectionData))
|
||||
.noEventPropagation()
|
||||
.create())
|
||||
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||
pageContext,
|
||||
ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION_CONFIRM_NOTIFICATION))
|
||||
.compose(pageContext.copyOf(content));
|
||||
|
||||
actionBuilder
|
||||
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION_CONFIRM_NOTIFICATION)
|
||||
.withParentEntityKey(parentEntityKey)
|
||||
.withConfirm(() -> NOTIFICATION_LIST_CONFIRM_TEXT_KEY)
|
||||
.withExec(action -> this.confirmNotification(action, connectionData))
|
||||
.publishIf(() -> currentUser.get().hasRole(UserRole.EXAM_SUPPORTER));
|
||||
}
|
||||
|
||||
widgetFactory.addFormSubContextHeader(
|
||||
content,
|
||||
EVENT_LIST_TITLE_KEY,
|
||||
EVENT_LIST_TITLE_TOOLTIP_KEY);
|
||||
|
||||
// client event table for this connection
|
||||
this.pageService.entityTableBuilder(restService.getRestCall(GetExtendedClientEventPage.class))
|
||||
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
|
||||
|
@ -325,6 +386,24 @@ public class MonitoringClientConnection implements TemplateComposer {
|
|||
}
|
||||
}
|
||||
|
||||
private PageAction confirmNotification(
|
||||
final PageAction pageAction,
|
||||
final ClientConnectionData connectionData) {
|
||||
|
||||
final EntityKey entityKey = pageAction.getSingleSelection();
|
||||
final EntityKey parentEntityKey = pageAction.getParentEntityKey();
|
||||
|
||||
this.pageService.getRestService()
|
||||
.getBuilder(ConfirmPendingClientNotification.class)
|
||||
.withURIVariable(API.PARAM_PARENT_MODEL_ID, parentEntityKey.modelId)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||
.withURIVariable(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionData.clientConnection.connectionToken)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
|
||||
return pageAction;
|
||||
}
|
||||
|
||||
private PageAction openExamCollectionProctorScreen(
|
||||
final PageAction action,
|
||||
final ClientConnectionData connectionData) {
|
||||
|
|
|
@ -640,6 +640,11 @@ public enum ActionDefinition {
|
|||
ImageIcon.PROCTOR_ROOM,
|
||||
PageStateDefinitionImpl.MONITORING_CLIENT_CONNECTION,
|
||||
ActionCategory.FORM),
|
||||
MONITOR_EXAM_CLIENT_CONNECTION_CONFIRM_NOTIFICATION(
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.action.confirm.notification"),
|
||||
ImageIcon.YES,
|
||||
PageStateDefinitionImpl.MONITORING_CLIENT_CONNECTION,
|
||||
ActionCategory.FORM),
|
||||
|
||||
MONITOR_EXAM_QUIT_SELECTED(
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.action.instruction.quit.selected"),
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.gui.service.page;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -336,6 +337,8 @@ public interface PageService {
|
|||
|
||||
<T> TableBuilder<T> staticListTableBuilder(final List<T> staticList, EntityType entityType);
|
||||
|
||||
<T> TableBuilder<T> remoteListTableBuilder(RestCall<Collection<T>> apiCall, EntityType entityType);
|
||||
|
||||
/** Get a new PageActionBuilder for a given PageContext.
|
||||
*
|
||||
* @param pageContext the PageContext that is used by the new PageActionBuilder
|
||||
|
|
|
@ -110,6 +110,10 @@ public final class PageAction {
|
|||
return this.pageContext.getEntityKey();
|
||||
}
|
||||
|
||||
public EntityKey getParentEntityKey() {
|
||||
return this.pageContext.getParentEntityKey();
|
||||
}
|
||||
|
||||
public PageContext pageContext() {
|
||||
return this.pageContext;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||
import ch.ethz.seb.sebserver.gui.table.RemoteListPageSupplier;
|
||||
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
|
@ -383,6 +384,20 @@ public class PageServiceImpl implements PageService {
|
|||
this, staticList, entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TableBuilder<T> remoteListTableBuilder(
|
||||
final RestCall<Collection<T>> apiCall,
|
||||
final EntityType entityType) {
|
||||
|
||||
return new TableBuilder<>(
|
||||
(entityType != null)
|
||||
? entityType.name()
|
||||
: "",
|
||||
this,
|
||||
new RemoteListPageSupplier<>(apiCall, entityType),
|
||||
entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean logout(final PageContext pageContext) {
|
||||
this.clearState();
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.gui.service.remote.webservice.api.session;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class ConfirmPendingClientNotification extends RestCall<Void> {
|
||||
|
||||
public ConfirmPendingClientNotification() {
|
||||
super(new TypeKey<>(
|
||||
CallType.UNDEFINED,
|
||||
EntityType.CLIENT_EVENT,
|
||||
new TypeReference<Void>() {
|
||||
}),
|
||||
HttpMethod.POST,
|
||||
MediaType.APPLICATION_JSON_UTF8,
|
||||
API.EXAM_MONITORING_ENDPOINT
|
||||
+ API.PARENT_MODEL_ID_VAR_PATH_SEGMENT
|
||||
+ API.EXAM_MONITORING_NOTIFICATION_ENDPOINT
|
||||
+ API.MODEL_ID_VAR_PATH_SEGMENT
|
||||
+ API.EXAM_MONITORING_SEB_CONNECTION_TOKEN_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.gui.service.remote.webservice.api.session;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetPendingClientNotifications extends RestCall<Collection<ClientEvent>> {
|
||||
|
||||
public GetPendingClientNotifications() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_LIST,
|
||||
EntityType.CLIENT_EVENT,
|
||||
new TypeReference<Collection<ClientEvent>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_MONITORING_ENDPOINT
|
||||
+ API.PARENT_MODEL_ID_VAR_PATH_SEGMENT
|
||||
+ API.EXAM_MONITORING_NOTIFICATION_ENDPOINT
|
||||
+ API.EXAM_MONITORING_SEB_CONNECTION_TOKEN_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.gui.table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
public class RemoteListPageSupplier<T> implements PageSupplier<T> {
|
||||
|
||||
private final EntityType entityType;
|
||||
private final RestCall<Collection<T>> restCall;
|
||||
|
||||
public RemoteListPageSupplier(final RestCall<Collection<T>> restCall, final EntityType entityType) {
|
||||
this.restCall = restCall;
|
||||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getEntityType() {
|
||||
return this.entityType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T> newBuilder() {
|
||||
return new StaticListTableBuilderAdapter<>(this.restCall);
|
||||
}
|
||||
|
||||
public static final class StaticListTableBuilderAdapter<T> implements Builder<T> {
|
||||
|
||||
private final RestCall<Collection<T>>.RestCallBuilder restCallBuilder;
|
||||
private int pageNumber;
|
||||
private int pageSize;
|
||||
private String column;
|
||||
|
||||
private StaticListTableBuilderAdapter(final RestCall<Collection<T>> restCall) {
|
||||
this.restCallBuilder = restCall.newBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T> withPaging(final int pageNumber, final int pageSize) {
|
||||
this.pageNumber = pageNumber;
|
||||
this.pageSize = pageSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T> withSorting(final String column, final PageSortOrder order) {
|
||||
this.restCallBuilder.withSorting(column, order);
|
||||
this.column = column;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T> withQueryParams(final MultiValueMap<String, String> params) {
|
||||
this.restCallBuilder.withQueryParams(params);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T> withQueryParam(final String name, final String value) {
|
||||
this.restCallBuilder.withQueryParam(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T> withURIVariable(final String name, final String id) {
|
||||
this.restCallBuilder.withURIVariable(name, id);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder<T> apply(final Function<Builder<T>, Builder<T>> f) {
|
||||
return f.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Page<T>> getPage() {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final Collection<T> collection = this.restCallBuilder.call().getOrThrow();
|
||||
final List<T> list = (collection == null || collection.isEmpty())
|
||||
? Collections.emptyList()
|
||||
: new ArrayList<>(collection);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return new Page<>(0, this.pageNumber, this.column, list);
|
||||
}
|
||||
|
||||
if (this.pageSize <= 0) {
|
||||
return new Page<>(1, 1, this.column, list);
|
||||
}
|
||||
|
||||
final int numOfPages = list.size() / this.pageSize;
|
||||
final List<T> subList = list.subList(this.pageNumber * this.pageSize,
|
||||
this.pageNumber * this.pageSize + this.pageSize);
|
||||
return new Page<>(numOfPages, this.pageNumber, this.column, subList);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,7 @@ public class TableBuilder<ROW> {
|
|||
private final String name;
|
||||
private final PageService pageService;
|
||||
final RestCall<Page<ROW>> restCall;
|
||||
final List<ROW> staticList;
|
||||
final PageSupplier<ROW> pageSupplier;
|
||||
final EntityType entityType;
|
||||
private final MultiValueMap<String, String> staticQueryParams;
|
||||
final List<ColumnDefinition<ROW>> columns = new ArrayList<>();
|
||||
|
@ -58,7 +58,7 @@ public class TableBuilder<ROW> {
|
|||
this.name = name;
|
||||
this.pageService = pageService;
|
||||
this.restCall = restCall;
|
||||
this.staticList = null;
|
||||
this.pageSupplier = null;
|
||||
this.entityType = null;
|
||||
this.staticQueryParams = new LinkedMultiValueMap<>();
|
||||
}
|
||||
|
@ -72,8 +72,22 @@ public class TableBuilder<ROW> {
|
|||
this.name = name;
|
||||
this.pageService = pageService;
|
||||
this.restCall = null;
|
||||
this.staticList = staticList;
|
||||
this.entityType = entityType;
|
||||
this.pageSupplier = new StaticListPageSupplier<>(staticList, entityType);
|
||||
this.staticQueryParams = new LinkedMultiValueMap<>();
|
||||
}
|
||||
|
||||
public TableBuilder(
|
||||
final String name,
|
||||
final PageService pageService,
|
||||
final PageSupplier<ROW> pageSupplier,
|
||||
final EntityType entityType) {
|
||||
|
||||
this.name = name;
|
||||
this.pageService = pageService;
|
||||
this.restCall = null;
|
||||
this.entityType = entityType;
|
||||
this.pageSupplier = pageSupplier;
|
||||
this.staticQueryParams = new LinkedMultiValueMap<>();
|
||||
}
|
||||
|
||||
|
@ -184,7 +198,7 @@ public class TableBuilder<ROW> {
|
|||
pageContext,
|
||||
(this.restCall != null)
|
||||
? new RestCallPageSupplier<>(this.restCall)
|
||||
: new StaticListPageSupplier<>(this.staticList, this.entityType),
|
||||
: this.pageSupplier,
|
||||
this.restCallAdapter,
|
||||
this.pageService,
|
||||
this.columns,
|
||||
|
|
|
@ -1522,6 +1522,12 @@ sebserver.monitoring.exam.connection.action.hide.undefined=Hide Undefined
|
|||
sebserver.monitoring.exam.connection.action.show.undefined=Show Undefined
|
||||
sebserver.monitoring.exam.connection.action.proctoring=Single Room Proctoring
|
||||
sebserver.monitoring.exam.connection.action.proctoring.examroom=Exam Room Proctoring
|
||||
sebserver.monitoring.exam.connection.action.confirm.notification=Confirm Notification
|
||||
sebserver.monitoring.exam.connection.action.confirm.notification.text=Are you sure you want to confirm this pending notification?<br/><br/>Note that this will send a notification confirmation instruction to the SEB client and remove this notification from the pending list.
|
||||
|
||||
sebserver.monitoring.exam.connection.notificationlist.title=Pending Notification
|
||||
sebserver.monitoring.exam.connection.notificationlist.title.tooltip=All pending notifications sent by the SEB Client
|
||||
|
||||
|
||||
sebserver.monitoring.exam.connection.eventlist.title=Events
|
||||
sebserver.monitoring.exam.connection.eventlist.title.tooltip=All events and logs sent by the SEB Client
|
||||
|
|
Loading…
Reference in a new issue