info monitoring disable
This commit is contained in:
parent
0e528a3c86
commit
663662d50e
21 changed files with 309 additions and 192 deletions
|
@ -8,6 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gbl.model.session;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
|
@ -234,4 +235,14 @@ public final class ClientConnection implements GrantEntity {
|
|||
return connection -> connection.status == status;
|
||||
}
|
||||
|
||||
public static Predicate<ClientConnection> getStatusPredicate(final ConnectionStatus... status) {
|
||||
final EnumSet<ConnectionStatus> stati = EnumSet.allOf(ConnectionStatus.class);
|
||||
if (status != null) {
|
||||
for (int i = 0; i < status.length; i++) {
|
||||
stati.add(status[i]);
|
||||
}
|
||||
}
|
||||
return connection -> stati.contains(connection.status);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -110,11 +110,13 @@ public class InstitutionForm implements TemplateComposer {
|
|||
.addField(FormBuilder.text(
|
||||
Domain.INSTITUTION.ATTR_NAME,
|
||||
FORM_NAME_TEXT_KEY,
|
||||
institution.name))
|
||||
institution.name)
|
||||
.withInfoLeft(new LocTextKey("some info text here!\nwith line brake")))
|
||||
.addField(FormBuilder.text(
|
||||
Domain.INSTITUTION.ATTR_URL_SUFFIX,
|
||||
FORM_URL_SUFFIX_TEXT_KEY,
|
||||
institution.urlSuffix))
|
||||
institution.urlSuffix)
|
||||
.withInfoRight(new LocTextKey("some info text here!\nwith line brake")))
|
||||
.addField(FormBuilder.imageUpload(
|
||||
Domain.INSTITUTION.ATTR_LOGO_IMAGE,
|
||||
FORM_LOGO_IMAGE_TEXT_KEY,
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
package ch.ethz.seb.sebserver.gui.content;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
|
@ -31,7 +29,6 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
|
|||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||
|
@ -71,6 +68,8 @@ public class MonitoringRunningExam implements TemplateComposer {
|
|||
new LocTextKey("sebserver.monitoring.exam.connection.action.instruction.quit.selected.confirm");
|
||||
private static final LocTextKey CONFIRM_QUIT_ALL =
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.action.instruction.quit.all.confirm");
|
||||
private static final LocTextKey CONFIRM_DISABLE_SELECTED =
|
||||
new LocTextKey("sebserver.monitoring.exam.connection.action.instruction.disable.selected.confirm");
|
||||
|
||||
private final ServerPushService serverPushService;
|
||||
private final PageService pageService;
|
||||
|
@ -183,7 +182,19 @@ public class MonitoringRunningExam implements TemplateComposer {
|
|||
action -> this.quitSebClients(action, clientTable, false),
|
||||
EMPTY_SELECTION_TEXT_KEY)
|
||||
.noEventPropagation()
|
||||
.publishIf(privilege);
|
||||
.publishIf(privilege)
|
||||
|
||||
.newAction(ActionDefinition.MONITOR_EXAM_DISABLE_SELECTED_CONNECTION)
|
||||
.withEntityKey(entityKey)
|
||||
.withConfirm(() -> CONFIRM_DISABLE_SELECTED)
|
||||
.withSelect(
|
||||
clientTable::getSelection,
|
||||
action -> this.disableSebClients(action, clientTable, false),
|
||||
EMPTY_SELECTION_TEXT_KEY)
|
||||
.noEventPropagation()
|
||||
.publishIf(privilege)
|
||||
|
||||
;
|
||||
|
||||
clientTable.hideStatus(ConnectionStatus.DISABLED);
|
||||
|
||||
|
@ -228,6 +239,7 @@ public class MonitoringRunningExam implements TemplateComposer {
|
|||
|
||||
return action -> {
|
||||
clientTable.showStatus(status);
|
||||
clientTable.removeSelection();
|
||||
return action;
|
||||
};
|
||||
}
|
||||
|
@ -238,6 +250,7 @@ public class MonitoringRunningExam implements TemplateComposer {
|
|||
|
||||
return action -> {
|
||||
clientTable.hideStatus(status);
|
||||
clientTable.removeSelection();
|
||||
return action;
|
||||
};
|
||||
}
|
||||
|
@ -247,20 +260,27 @@ public class MonitoringRunningExam implements TemplateComposer {
|
|||
final ClientConnectionTable clientTable,
|
||||
final boolean all) {
|
||||
|
||||
final Predicate<ClientConnection> activePredicate = ClientConnection
|
||||
.getStatusPredicate(ConnectionStatus.ACTIVE);
|
||||
|
||||
final Set<String> connectionTokens = clientTable.getConnectionTokens(
|
||||
activePredicate,
|
||||
!all);
|
||||
|
||||
if (connectionTokens.isEmpty()) {
|
||||
return action;
|
||||
}
|
||||
|
||||
this.instructionProcessor.propagateSebQuitInstruction(
|
||||
clientTable.getExam().id,
|
||||
connectionTokens,
|
||||
statesPredicate -> clientTable.getConnectionTokens(
|
||||
statesPredicate,
|
||||
!all),
|
||||
action.pageContext());
|
||||
|
||||
clientTable.removeSelection();
|
||||
return action;
|
||||
}
|
||||
|
||||
private PageAction disableSebClients(
|
||||
final PageAction action,
|
||||
final ClientConnectionTable clientTable,
|
||||
final boolean all) {
|
||||
|
||||
this.instructionProcessor.disableConnection(
|
||||
clientTable.getExam().id,
|
||||
statesPredicate -> clientTable.getConnectionTokens(
|
||||
statesPredicate,
|
||||
!all),
|
||||
action.pageContext());
|
||||
|
||||
clientTable.removeSelection();
|
||||
|
|
|
@ -26,15 +26,8 @@ public class CheckboxFieldBuilder extends FieldBuilder<String> {
|
|||
@Override
|
||||
void build(final FormBuilder builder) {
|
||||
final boolean readonly = builder.readonly || this.readonly;
|
||||
final Label lab = (this.label != null)
|
||||
? builder.labelLocalized(
|
||||
builder.formParent,
|
||||
this.label,
|
||||
this.defaultLabel,
|
||||
this.spanLabel)
|
||||
: null;
|
||||
|
||||
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Label titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Button checkbox = builder.widgetFactory.buttonLocalized(
|
||||
fieldGrid,
|
||||
SWT.CHECK,
|
||||
|
@ -48,7 +41,7 @@ public class CheckboxFieldBuilder extends FieldBuilder<String> {
|
|||
checkbox.setEnabled(false);
|
||||
}
|
||||
|
||||
builder.form.putField(this.name, lab, checkbox);
|
||||
builder.form.putField(this.name, titleLabel, checkbox);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,17 +10,31 @@ package ch.ethz.seb.sebserver.gui.form;
|
|||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||
|
||||
public abstract class FieldBuilder<T> {
|
||||
int spanLabel = -1;
|
||||
int spanInput = -1;
|
||||
int spanEmptyCell = -1;
|
||||
int titleValign = SWT.TOP;
|
||||
Boolean autoEmptyCellSeparation = null;
|
||||
String group = null;
|
||||
boolean readonly = false;
|
||||
boolean visible = true;
|
||||
String defaultLabel = null;
|
||||
LocTextKey infoText;
|
||||
boolean infoLeft = false;
|
||||
boolean infoRight = false;
|
||||
|
||||
final String name;
|
||||
final LocTextKey label;
|
||||
|
@ -42,6 +56,18 @@ public abstract class FieldBuilder<T> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public FieldBuilder<T> withInfoLeft(final LocTextKey infoText) {
|
||||
this.infoText = infoText;
|
||||
this.infoLeft = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldBuilder<T> withInfoRight(final LocTextKey infoText) {
|
||||
this.infoText = infoText;
|
||||
this.infoRight = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldBuilder<T> withInputSpan(final int span) {
|
||||
this.spanInput = span;
|
||||
return this;
|
||||
|
@ -79,4 +105,102 @@ public abstract class FieldBuilder<T> {
|
|||
|
||||
abstract void build(FormBuilder builder);
|
||||
|
||||
protected static Label createTitleLabel(
|
||||
final Composite parent,
|
||||
final FormBuilder builder,
|
||||
final FieldBuilder<?> fieldBuilder) {
|
||||
|
||||
final Composite infoGrid = new Composite(parent, SWT.NONE);
|
||||
final GridLayout gridLayout = new GridLayout(2, false);
|
||||
gridLayout.verticalSpacing = 0;
|
||||
gridLayout.marginHeight = 0;
|
||||
gridLayout.marginWidth = 0;
|
||||
gridLayout.marginRight = 0;
|
||||
infoGrid.setLayout(gridLayout);
|
||||
|
||||
final GridData gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
|
||||
infoGrid.setLayoutData(gridData);
|
||||
|
||||
if (fieldBuilder.infoText != null && fieldBuilder.infoLeft) {
|
||||
final Label info = builder.widgetFactory.imageButton(
|
||||
WidgetFactory.ImageIcon.HELP,
|
||||
infoGrid,
|
||||
fieldBuilder.infoText);
|
||||
info.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
|
||||
}
|
||||
final Label lab = (fieldBuilder.label != null)
|
||||
? labelLocalized(
|
||||
builder.widgetFactory,
|
||||
infoGrid,
|
||||
fieldBuilder.label,
|
||||
fieldBuilder.defaultLabel,
|
||||
(fieldBuilder.spanLabel > 0) ? fieldBuilder.spanLabel : 1,
|
||||
fieldBuilder.titleValign)
|
||||
: null;
|
||||
|
||||
if (fieldBuilder.infoText != null && fieldBuilder.infoRight) {
|
||||
final Label info = builder.widgetFactory.imageButton(
|
||||
WidgetFactory.ImageIcon.HELP,
|
||||
infoGrid,
|
||||
fieldBuilder.infoText);
|
||||
info.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
|
||||
}
|
||||
|
||||
return lab;
|
||||
}
|
||||
|
||||
public static Label labelLocalized(
|
||||
final WidgetFactory widgetFactory,
|
||||
final Composite parent,
|
||||
final LocTextKey locTextKey,
|
||||
final String defaultText,
|
||||
final int hspan) {
|
||||
|
||||
return labelLocalized(widgetFactory, parent, locTextKey, defaultText, hspan, SWT.CENTER);
|
||||
}
|
||||
|
||||
public static final Label labelLocalized(
|
||||
final WidgetFactory widgetFactory,
|
||||
final Composite parent,
|
||||
final LocTextKey locTextKey,
|
||||
final String defaultText,
|
||||
final int hspan,
|
||||
final int verticalAlignment) {
|
||||
|
||||
final Label label = widgetFactory.labelLocalized(
|
||||
parent,
|
||||
locTextKey,
|
||||
(StringUtils.isNotBlank(defaultText) ? defaultText : locTextKey.name));
|
||||
final GridData gridData = new GridData(SWT.LEFT, verticalAlignment, true, true, hspan, 1);
|
||||
gridData.heightHint = FormBuilder.FORM_ROW_HEIGHT;
|
||||
label.setLayoutData(gridData);
|
||||
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.TITLE_LABEL.key);
|
||||
return label;
|
||||
}
|
||||
|
||||
public static Composite createFieldGrid(final Composite parent, final int hspan) {
|
||||
final Composite fieldGrid = new Composite(parent, SWT.NONE);
|
||||
final GridLayout gridLayout = new GridLayout();
|
||||
gridLayout.verticalSpacing = 0;
|
||||
gridLayout.marginHeight = 0;
|
||||
gridLayout.marginWidth = 0;
|
||||
gridLayout.marginRight = 0;
|
||||
fieldGrid.setLayout(gridLayout);
|
||||
|
||||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gridData.horizontalSpan = hspan;
|
||||
fieldGrid.setLayoutData(gridData);
|
||||
|
||||
return fieldGrid;
|
||||
}
|
||||
|
||||
public static Label createErrorLabel(final Composite innerGrid) {
|
||||
final Label errorLabel = new Label(innerGrid, SWT.NONE);
|
||||
final GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true);
|
||||
errorLabel.setLayoutData(gridData);
|
||||
errorLabel.setVisible(false);
|
||||
errorLabel.setData(RWT.CUSTOM_VARIANT, CustomVariant.ERROR.key);
|
||||
return errorLabel;
|
||||
}
|
||||
|
||||
}
|
|
@ -34,14 +34,8 @@ public class FileUploadFieldBuilder extends FieldBuilder<String> {
|
|||
|
||||
@Override
|
||||
void build(final FormBuilder builder) {
|
||||
|
||||
final Label lab = builder.labelLocalized(
|
||||
builder.formParent,
|
||||
this.label,
|
||||
this.defaultLabel,
|
||||
1);
|
||||
|
||||
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Label titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||
final FileUploadSelection fileUpload = builder.widgetFactory.fileUploadSelection(
|
||||
fieldGrid,
|
||||
builder.readonly || this.readonly,
|
||||
|
@ -50,8 +44,8 @@ public class FileUploadFieldBuilder extends FieldBuilder<String> {
|
|||
fileUpload.setLayoutData(gridData);
|
||||
fileUpload.setFileName(this.value);
|
||||
|
||||
final Label errorLabel = Form.createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, lab, fileUpload, errorLabel);
|
||||
final Label errorLabel = createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, titleLabel, fileUpload, errorLabel);
|
||||
builder.setFieldVisible(this.visible, this.name);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,8 @@ import java.util.function.Predicate;
|
|||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
@ -512,29 +508,4 @@ public final class Form implements FormBinding {
|
|||
}
|
||||
}
|
||||
|
||||
public static Composite createFieldGrid(final Composite parent, final int hspan) {
|
||||
final Composite fieldGrid = new Composite(parent, SWT.NONE);
|
||||
final GridLayout gridLayout = new GridLayout();
|
||||
gridLayout.verticalSpacing = 0;
|
||||
gridLayout.marginHeight = 0;
|
||||
gridLayout.marginWidth = 0;
|
||||
gridLayout.marginRight = 0;
|
||||
fieldGrid.setLayout(gridLayout);
|
||||
|
||||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gridData.horizontalSpan = hspan;
|
||||
fieldGrid.setLayoutData(gridData);
|
||||
|
||||
return fieldGrid;
|
||||
}
|
||||
|
||||
public static Label createErrorLabel(final Composite innerGrid) {
|
||||
final Label errorLabel = new Label(innerGrid, SWT.NONE);
|
||||
final GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, true);
|
||||
errorLabel.setLayoutData(gridData);
|
||||
errorLabel.setVisible(false);
|
||||
errorLabel.setData(RWT.CUSTOM_VARIANT, CustomVariant.ERROR.key);
|
||||
return errorLabel;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import java.util.function.BooleanSupplier;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
@ -24,7 +23,6 @@ import org.eclipse.swt.widgets.TabItem;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
|
@ -35,11 +33,10 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
|||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
import ch.ethz.seb.sebserver.gui.widget.Selection;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||
|
||||
public class FormBuilder {
|
||||
|
||||
private static final int FORM_ROW_HEIGHT = 25;
|
||||
public static final int FORM_ROW_HEIGHT = 25;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FormBuilder.class);
|
||||
|
||||
|
@ -283,54 +280,4 @@ public class FormBuilder {
|
|||
(supportedFiles != null) ? Arrays.asList(supportedFiles) : Collections.emptyList());
|
||||
}
|
||||
|
||||
Label labelLocalized(
|
||||
final Composite parent,
|
||||
final LocTextKey locTextKey,
|
||||
final String defaultText,
|
||||
final int hspan) {
|
||||
|
||||
return labelLocalized(parent, locTextKey, defaultText, hspan, SWT.CENTER);
|
||||
}
|
||||
|
||||
Label labelLocalized(
|
||||
final Composite parent,
|
||||
final LocTextKey locTextKey,
|
||||
final String defaultText,
|
||||
final int hspan,
|
||||
final int verticalAlignment) {
|
||||
|
||||
final Label label = this.widgetFactory.labelLocalized(
|
||||
parent,
|
||||
locTextKey,
|
||||
(StringUtils.isNotBlank(defaultText) ? defaultText : locTextKey.name));
|
||||
final GridData gridData = new GridData(SWT.LEFT, verticalAlignment, true, true, hspan, 1);
|
||||
gridData.heightHint = FORM_ROW_HEIGHT;
|
||||
label.setLayoutData(gridData);
|
||||
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.TITLE_LABEL.key);
|
||||
return label;
|
||||
}
|
||||
|
||||
Label valueLabel(
|
||||
final Composite parent,
|
||||
final String value,
|
||||
final int hspan,
|
||||
final boolean centered) {
|
||||
|
||||
final Label label = new Label(parent, SWT.NONE);
|
||||
label.setText((StringUtils.isNotBlank(value)) ? value : Constants.EMPTY_NOTE);
|
||||
final GridData gridData = new GridData(
|
||||
SWT.FILL,
|
||||
(centered) ? SWT.CENTER : SWT.TOP,
|
||||
true, false,
|
||||
hspan, 1);
|
||||
|
||||
if (centered) {
|
||||
label.setAlignment(SWT.CENTER);
|
||||
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.FORM_CENTER.key);
|
||||
}
|
||||
|
||||
label.setLayoutData(gridData);
|
||||
return label;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,14 +37,8 @@ public final class ImageUploadFieldBuilder extends FieldBuilder<String> {
|
|||
|
||||
@Override
|
||||
void build(final FormBuilder builder) {
|
||||
|
||||
final Label lab = builder.labelLocalized(
|
||||
builder.formParent,
|
||||
this.label,
|
||||
this.defaultLabel,
|
||||
1);
|
||||
|
||||
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Label titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||
final ImageUploadSelection imageUpload = builder.widgetFactory.imageUploadLocalized(
|
||||
fieldGrid,
|
||||
new LocTextKey("sebserver.overall.upload"),
|
||||
|
@ -55,8 +49,8 @@ public final class ImageUploadFieldBuilder extends FieldBuilder<String> {
|
|||
imageUpload.setLayoutData(gridData);
|
||||
imageUpload.setImageBase64(this.value);
|
||||
|
||||
final Label errorLabel = Form.createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, lab, imageUpload, errorLabel);
|
||||
final Label errorLabel = createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, titleLabel, imageUpload, errorLabel);
|
||||
builder.setFieldVisible(this.visible, this.name);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,25 +55,18 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
|||
|
||||
@Override
|
||||
void build(final FormBuilder builder) {
|
||||
final Label lab = (this.label != null)
|
||||
? builder.labelLocalized(
|
||||
builder.formParent,
|
||||
this.label,
|
||||
this.defaultLabel,
|
||||
this.spanLabel,
|
||||
SWT.TOP)
|
||||
: null;
|
||||
final Label titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||
|
||||
if (builder.readonly || this.readonly) {
|
||||
buildReadOnly(builder, lab);
|
||||
buildReadOnly(builder, titleLabel);
|
||||
} else {
|
||||
buildInput(builder, lab);
|
||||
buildInput(builder, titleLabel);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildInput(final FormBuilder builder, final Label lab) {
|
||||
private void buildInput(final FormBuilder builder, final Label titleLabel) {
|
||||
|
||||
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||
final String actionKey = (this.label != null) ? this.label.name + ".action" : null;
|
||||
final Selection selection = builder.widgetFactory.selectionLocalized(
|
||||
this.type,
|
||||
|
@ -87,8 +80,8 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
|||
((Control) selection).setLayoutData(gridData);
|
||||
selection.select(this.value);
|
||||
|
||||
final Label errorLabel = Form.createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, lab, selection, errorLabel);
|
||||
final Label errorLabel = createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, titleLabel, selection, errorLabel);
|
||||
|
||||
if (this.selectionListener != null) {
|
||||
((Control) selection).addListener(SWT.Selection, e -> {
|
||||
|
@ -100,7 +93,7 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
|||
}
|
||||
|
||||
/* Build the read-only representation of the selection field */
|
||||
private void buildReadOnly(final FormBuilder builder, final Label lab) {
|
||||
private void buildReadOnly(final FormBuilder builder, final Label titleLabel) {
|
||||
if (this.type == Type.MULTI || this.type == Type.MULTI_COMBO) {
|
||||
final Composite composite = new Composite(builder.formParent, SWT.NONE);
|
||||
final GridLayout gridLayout = new GridLayout(1, true);
|
||||
|
@ -127,7 +120,7 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
|
|||
} else {
|
||||
builder.form.putReadonlyField(
|
||||
this.name,
|
||||
lab,
|
||||
titleLabel,
|
||||
buildReadonlyLabel(builder.formParent, this.value, this.spanInput));
|
||||
builder.setFieldVisible(this.visible, this.name);
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
|
|||
|
||||
public TextFieldBuilder asArea() {
|
||||
this.isArea = true;
|
||||
this.titleValign = SWT.CENTER;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -63,16 +64,8 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
|
|||
@Override
|
||||
void build(final FormBuilder builder) {
|
||||
final boolean readonly = builder.readonly || this.readonly;
|
||||
final Label lab = (this.label != null)
|
||||
? builder.labelLocalized(
|
||||
builder.formParent,
|
||||
this.label,
|
||||
this.defaultLabel,
|
||||
this.spanLabel,
|
||||
(this.isArea) ? SWT.TOP : SWT.CENTER)
|
||||
: null;
|
||||
|
||||
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Label titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Text textInput = (this.isNumber)
|
||||
? builder.widgetFactory.numberInput(fieldGrid, this.numberCheck, readonly)
|
||||
: (this.isArea)
|
||||
|
@ -95,12 +88,13 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
|
|||
|
||||
if (readonly) {
|
||||
textInput.setEditable(false);
|
||||
builder.form.putReadonlyField(this.name, lab, textInput);
|
||||
builder.form.putReadonlyField(this.name, titleLabel, textInput);
|
||||
} else {
|
||||
final Label errorLabel = Form.createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, lab, textInput, errorLabel);
|
||||
final Label errorLabel = createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, titleLabel, textInput, errorLabel);
|
||||
builder.setFieldVisible(this.visible, this.name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -39,18 +39,13 @@ public class ThresholdListBuilder extends FieldBuilder<Collection<Threshold>> {
|
|||
|
||||
@Override
|
||||
void build(final FormBuilder builder) {
|
||||
final Label lab = builder.labelLocalized(
|
||||
builder.formParent,
|
||||
this.label,
|
||||
this.defaultLabel,
|
||||
this.spanLabel);
|
||||
|
||||
final Label titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||
if (builder.readonly || this.readonly) {
|
||||
// No read-only view needed for this so far?
|
||||
return;
|
||||
} else {
|
||||
|
||||
final Composite fieldGrid = Form.createFieldGrid(builder.formParent, this.spanInput);
|
||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||
|
||||
final ThresholdList thresholdList = builder.widgetFactory.thresholdList(
|
||||
fieldGrid,
|
||||
|
@ -68,8 +63,8 @@ public class ThresholdListBuilder extends FieldBuilder<Collection<Threshold>> {
|
|||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
||||
thresholdList.setLayoutData(gridData);
|
||||
|
||||
final Label errorLabel = Form.createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, lab, thresholdList, errorLabel);
|
||||
final Label errorLabel = createErrorLabel(fieldGrid);
|
||||
builder.form.putField(this.name, titleLabel, thresholdList, errorLabel);
|
||||
builder.setFieldVisible(this.visible, this.name);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.form.Form;
|
||||
import ch.ethz.seb.sebserver.gui.form.FieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
|
@ -82,7 +82,7 @@ public class PassworFieldBuilder implements InputFieldBuilder {
|
|||
orientation,
|
||||
passwordInput,
|
||||
confirmInput,
|
||||
Form.createErrorLabel(innerGrid));
|
||||
FieldBuilder.createErrorLabel(innerGrid));
|
||||
|
||||
if (viewContext.readonly) {
|
||||
passwordInput.setEditable(false);
|
||||
|
|
|
@ -19,7 +19,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.form.Form;
|
||||
import ch.ethz.seb.sebserver.gui.form.FieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||
|
@ -74,7 +74,7 @@ public class SingleSelectionFieldBuilder extends SelectionFieldBuilder implement
|
|||
attribute,
|
||||
orientation,
|
||||
selection,
|
||||
Form.createErrorLabel(innerGrid));
|
||||
FieldBuilder.createErrorLabel(innerGrid));
|
||||
|
||||
if (viewContext.readonly) {
|
||||
selection.setEnabled(false);
|
||||
|
|
|
@ -25,7 +25,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.form.Form;
|
||||
import ch.ethz.seb.sebserver.gui.form.FieldBuilder;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||
|
@ -102,7 +102,7 @@ public class TextFieldBuilder implements InputFieldBuilder {
|
|||
attribute,
|
||||
orientation,
|
||||
text,
|
||||
Form.createErrorLabel(innerGrid));
|
||||
FieldBuilder.createErrorLabel(innerGrid));
|
||||
|
||||
if (viewContext.readonly) {
|
||||
text.setEditable(false);
|
||||
|
|
|
@ -10,6 +10,11 @@ package ch.ethz.seb.sebserver.gui.service.session;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -23,14 +28,17 @@ import ch.ethz.seb.sebserver.gbl.Constants;
|
|||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
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.remote.webservice.api.RestCallError;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.DisableClientConnection;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.PropagateInstruction;
|
||||
|
||||
@Lazy
|
||||
|
@ -53,15 +61,23 @@ public class InstructionProcessor {
|
|||
final String connectionToken,
|
||||
final PageContext pageContext) {
|
||||
|
||||
propagateSebQuitInstruction(examId, Utils.immutableSetOf(connectionToken), pageContext);
|
||||
propagateSebQuitInstruction(
|
||||
examId,
|
||||
p -> Stream.of(connectionToken).collect(Collectors.toSet()),
|
||||
pageContext);
|
||||
|
||||
}
|
||||
|
||||
public void propagateSebQuitInstruction(
|
||||
final Long examId,
|
||||
final Set<String> connectionTokens,
|
||||
final Function<Predicate<ClientConnection>, Set<String>> selectionFunction,
|
||||
final PageContext pageContext) {
|
||||
|
||||
if (examId == null || connectionTokens == null || connectionTokens.isEmpty()) {
|
||||
final Set<String> connectionTokens = selectionFunction
|
||||
.apply(ClientConnection.getStatusPredicate(ConnectionStatus.ACTIVE));
|
||||
|
||||
if (connectionTokens.isEmpty()) {
|
||||
// TODO message
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -75,15 +91,59 @@ public class InstructionProcessor {
|
|||
null,
|
||||
examId,
|
||||
InstructionType.SEB_QUIT,
|
||||
StringUtils.join(connectionTokens, Constants.COMMA),
|
||||
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR),
|
||||
null);
|
||||
|
||||
try {
|
||||
final String response = this.restService.getBuilder(PropagateInstruction.class)
|
||||
processInstruction(() -> {
|
||||
return this.restService.getBuilder(PropagateInstruction.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(examId))
|
||||
.withBody(clientInstruction)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
},
|
||||
pageContext);
|
||||
|
||||
}
|
||||
|
||||
public void disableConnection(
|
||||
final Long examId,
|
||||
final Function<Predicate<ClientConnection>, Set<String>> selectionFunction,
|
||||
final PageContext pageContext) {
|
||||
|
||||
final Set<String> connectionTokens = selectionFunction
|
||||
.apply(ClientConnection.getStatusPredicate(
|
||||
ConnectionStatus.CONNECTION_REQUESTED,
|
||||
ConnectionStatus.UNDEFINED,
|
||||
ConnectionStatus.CLOSED,
|
||||
ConnectionStatus.AUTHENTICATED));
|
||||
|
||||
if (connectionTokens.isEmpty()) {
|
||||
// TOOD message
|
||||
return;
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Disable SEB client connections for exam: {} and connections: {}",
|
||||
examId,
|
||||
connectionTokens);
|
||||
}
|
||||
|
||||
processInstruction(() -> {
|
||||
return this.restService.getBuilder(DisableClientConnection.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(examId))
|
||||
.withFormParam(
|
||||
Domain.CLIENT_CONNECTION.ATTR_CONNECTION_TOKEN,
|
||||
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR))
|
||||
.call()
|
||||
.getOrThrow();
|
||||
},
|
||||
pageContext);
|
||||
|
||||
}
|
||||
|
||||
private void processInstruction(final Supplier<String> apiCall, final PageContext pageContext) {
|
||||
try {
|
||||
final String response = apiCall.get();
|
||||
|
||||
if (StringUtils.isNotBlank(response)) {
|
||||
try {
|
||||
|
@ -93,7 +153,7 @@ public class InstructionProcessor {
|
|||
});
|
||||
|
||||
pageContext.notifyUnexpectedError(new RestCallError(
|
||||
"Failed to propagate SEB quit instruction: ",
|
||||
"Failed to propagate SEB client instruction: ",
|
||||
errorMessage));
|
||||
|
||||
} catch (final Exception e) {
|
||||
|
@ -101,7 +161,7 @@ public class InstructionProcessor {
|
|||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to propagate SEB quit instruction: ", e);
|
||||
log.error("Failed to propagate SEB client instruction: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,8 @@ public class WidgetFactory {
|
|||
INDICATOR("indicator.png"),
|
||||
TEMPLATE("template.png"),
|
||||
DISABLE("disable.png"),
|
||||
SEND_QUIT("send-quit.png");
|
||||
SEND_QUIT("send-quit.png"),
|
||||
HELP("help.png");
|
||||
|
||||
private String fileName;
|
||||
private ImageData image = null;
|
||||
|
@ -502,6 +503,14 @@ public class WidgetFactory {
|
|||
return label;
|
||||
}
|
||||
|
||||
public Label imageButton(
|
||||
final ImageIcon type,
|
||||
final Composite parent,
|
||||
final LocTextKey toolTip) {
|
||||
|
||||
return this.imageButton(type, parent, toolTip, null);
|
||||
}
|
||||
|
||||
public Label imageButton(
|
||||
final ImageIcon type,
|
||||
final Composite parent,
|
||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
|||
import java.security.Principal;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -374,6 +375,13 @@ public class SebClientConnectionServiceImpl implements SebClientConnectionServic
|
|||
});
|
||||
}
|
||||
|
||||
private static final Predicate<ClientConnection> DISABLE_STATE_PREDICATE = ClientConnection
|
||||
.getStatusPredicate(
|
||||
ConnectionStatus.UNDEFINED,
|
||||
ConnectionStatus.CONNECTION_REQUESTED,
|
||||
ConnectionStatus.AUTHENTICATED,
|
||||
ConnectionStatus.CLOSED);
|
||||
|
||||
@Override
|
||||
public Result<ClientConnection> disableConnection(final String connectionToken, final Long institutionId) {
|
||||
return Result.tryCatch(() -> {
|
||||
|
@ -390,9 +398,7 @@ public class SebClientConnectionServiceImpl implements SebClientConnectionServic
|
|||
.getOrThrow();
|
||||
|
||||
ClientConnection updatedClientConnection;
|
||||
if (clientConnection.status == ConnectionStatus.CONNECTION_REQUESTED ||
|
||||
clientConnection.status == ConnectionStatus.UNDEFINED ||
|
||||
clientConnection.status == ConnectionStatus.AUTHENTICATED) {
|
||||
if (DISABLE_STATE_PREDICATE.test(clientConnection)) {
|
||||
|
||||
updatedClientConnection = saveInState(
|
||||
clientConnection,
|
||||
|
|
|
@ -231,7 +231,8 @@ public class ExamMonitoringController {
|
|||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@PathVariable(name = API.PARAM_MODEL_ID, required = true) final Long examId,
|
||||
@PathVariable(name = Domain.CLIENT_CONNECTION.ATTR_CONNECTION_TOKEN,
|
||||
@RequestParam(
|
||||
name = Domain.CLIENT_CONNECTION.ATTR_CONNECTION_TOKEN,
|
||||
required = true) final String connectionToken) {
|
||||
|
||||
if (connectionToken.contains(Constants.LIST_SEPARATOR)) {
|
||||
|
@ -242,7 +243,8 @@ public class ExamMonitoringController {
|
|||
.onError(error -> log.error("Failed to disable SEB client connection: {}", token));
|
||||
}
|
||||
} else {
|
||||
this.sebClientConnectionService.disableConnection(connectionToken, institutionId)
|
||||
this.sebClientConnectionService
|
||||
.disableConnection(connectionToken, institutionId)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
|
|
@ -1065,12 +1065,14 @@ sebserver.monitoring.connection.list.column.vdiAddress=IP Address (VDI)
|
|||
sebserver.monitoring.exam.connection.emptySelection=Please select a connection from the list
|
||||
sebserver.monitoring.exam.connection.title=SEB Client Connection
|
||||
sebserver.monitoring.exam.connection.list.actions=Selected Connection
|
||||
sebserver.monitoring.exam.connection.action.view=View Details
|
||||
sebserver.monitoring.exam.connection.action.view=Back To Monitoring
|
||||
sebserver.monitoring.exam.connection.action.instruction.quit=Send SEB Quit
|
||||
sebserver.monitoring.exam.connection.action.instruction.quit.all=Send SEB Quit
|
||||
sebserver.monitoring.exam.connection.action.instruction.quit.all.confirm=Are you sure to quit this SEB client connection?
|
||||
sebserver.monitoring.exam.connection.action.instruction.quit.confirm=Are you sure to quit this SEB client connection?
|
||||
sebserver.monitoring.exam.connection.action.instruction.quit.selected.confirm=Are you sure to quit all selected, active SEB client connections?
|
||||
sebserver.monitoring.exam.connection.action.instruction.quit.all.confirm=Are you sure to quit all active SEB client connections?
|
||||
sebserver.monitoring.exam.connection.action.instruction.disable.selected.confirm=Are you sure to disable all selected SEB client connections?
|
||||
sebserver.monitoring.exam.connection.action.instruction.disable.all.confirm=Are you sure to disable all active SEB client connections?
|
||||
sebserver.monitoring.exam.connection.action.disable=Mark As Disabled
|
||||
sebserver.monitoring.exam.connection.action.hide.requested=Hide Requested
|
||||
sebserver.monitoring.exam.connection.action.show.requested=Show Requested
|
||||
|
|
BIN
src/main/resources/static/images/help.png
Normal file
BIN
src/main/resources/static/images/help.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 643 B |
Loading…
Reference in a new issue