SEBSERV-75 implementation and fixes

This commit is contained in:
anhefti 2020-01-22 13:26:33 +01:00
parent c009ccc7e8
commit 77aae3ad54
8 changed files with 119 additions and 36 deletions

View file

@ -8,6 +8,8 @@
package ch.ethz.seb.sebserver.gui.content;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
@ -86,6 +88,9 @@ public class QuizDiscoveryList implements TemplateComposer {
private final static LocTextKey NO_IMPORT_OF_OUT_DATED_QUIZ =
new LocTextKey("sebserver.quizdiscovery.quiz.import.out.dated");
private final static String TEXT_KEY_ADDITIONAL_ATTR_PREFIX =
"sebserver.quizdiscovery.quiz.details.additional.";
// filter attribute models
private final TableFilterAttribute institutionFilter;
private final TableFilterAttribute lmsFilter;
@ -270,6 +275,9 @@ public class QuizDiscoveryList implements TemplateComposer {
return action;
}
private static final Collection<String> ADDITIONAL_HTML_ATTRIBUTES = Arrays.asList(
"course_summary");
private void createDetailsForm(
final QuizData quizData,
final PageContext pc,
@ -318,14 +326,43 @@ public class QuizDiscoveryList implements TemplateComposer {
quizData.additionalAttributes
.entrySet()
.stream()
.forEach(entry -> formbuilder
.addField(FormBuilder.text(
entry.getKey(),
new LocTextKey(entry.getKey()),
entry.getValue())));
.forEach(entry -> {
LocTextKey titleKey = new LocTextKey(TEXT_KEY_ADDITIONAL_ATTR_PREFIX + entry.getKey());
if (!this.pageService.getI18nSupport().hasText(titleKey)) {
titleKey = new LocTextKey(entry.getKey());
}
formbuilder
.addField(FormBuilder.text(
entry.getKey(),
titleKey,
toAdditionalValue(entry.getKey(), entry.getValue()))
.asHTML(ADDITIONAL_HTML_ATTRIBUTES.contains(entry.getKey())));
});
}
formbuilder.build();
}
private String toAdditionalValue(final String name, final String value) {
if ("timecreated".equals(name)) {
try {
return this.pageService
.getI18nSupport()
.formatDisplayDate(Utils.toDateTimeUTCUnix(Long.parseLong(value)));
} catch (final Exception e) {
return value;
}
} else if ("timelimit".equals(name)) {
try {
return this.pageService
.getI18nSupport()
.formatDisplayTime(Utils.toDateTimeUTCUnix(Long.parseLong(value)));
} catch (final Exception e) {
return value;
}
} else {
return value;
}
}
}

View file

@ -14,6 +14,8 @@ import org.apache.commons.lang3.StringUtils;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
@ -73,6 +75,11 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
return this;
}
public FieldBuilder<?> asHTML(final boolean html) {
this.isHTML = html;
return this;
}
public TextFieldBuilder asColorbox() {
this.isColorbox = true;
return this;
@ -88,9 +95,10 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
final Browser browser = new Browser(fieldGrid, SWT.NONE);
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true);
gridData.minimumHeight = this.areaMinHeight;
browser.setBackground(new Color(builder.formParent.getDisplay(), new RGB(240, 240, 240)));
browser.setLayoutData(gridData);
if (StringUtils.isNoneBlank(this.value)) {
browser.setText(HTML_TEXT_BLOCK_START + this.value + HTML_TEXT_BLOCK_END);
browser.setText(createHTMLText(this.value));
} else if (readonly) {
browser.setText(Constants.EMPTY_NOTE);
}
@ -129,4 +137,14 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
}
private String createHTMLText(final String text) {
return HTML_TEXT_BLOCK_START
+ text
.replace("<a", "<span")
.replace("</a", "</span")
.replace("<A", "<span")
.replace("</A", "</span")
+ HTML_TEXT_BLOCK_END;
}
}

View file

@ -37,6 +37,7 @@ import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
import ch.ethz.seb.sebserver.gui.widget.Selection;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
public class TableFilter<ROW extends Entity> {
@ -418,10 +419,7 @@ public class TableFilter<ROW extends Entity> {
@Override
FilterComponent build(final Composite parent) {
final Composite innerComposite = createInnerComposite(parent);
final GridData gridData = new GridData(SWT.FILL, SWT.END, true, true);
this.selector = new DateTime(innerComposite, SWT.DATE | SWT.BORDER);
this.selector.setLayoutData(gridData);
this.selector = TableFilter.this.entityTable.widgetFactory.dateSelector(innerComposite);
return this;
}
@ -478,7 +476,7 @@ public class TableFilter<ROW extends Entity> {
private class DateRange extends FilterComponent {
private Composite innerComposite;
private final GridData rw1 = new GridData(SWT.FILL, SWT.FILL, true, true);
//private final GridData rw1 = new GridData(SWT.FILL, SWT.FILL, true, true);
private DateTime fromDateSelector;
private DateTime toDateSelector;
private DateTime fromTimeSelector;
@ -505,26 +503,17 @@ public class TableFilter<ROW extends Entity> {
this.innerComposite.setLayout(gridLayout);
this.innerComposite.setLayoutData(this.rowData);
TableFilter.this.entityTable.widgetFactory
.labelLocalized(this.innerComposite, DATE_FROM_TEXT);
this.fromDateSelector =
new DateTime(this.innerComposite, SWT.DATE | SWT.BORDER);
this.fromDateSelector.setLayoutData(this.rw1);
final WidgetFactory wf = TableFilter.this.entityTable.widgetFactory;
wf.labelLocalized(this.innerComposite, DATE_FROM_TEXT);
this.fromDateSelector = wf.dateSelector(this.innerComposite);
if (this.withTime) {
this.fromTimeSelector =
new DateTime(this.innerComposite, SWT.TIME | SWT.BORDER);
this.fromTimeSelector.setLayoutData(this.rw1);
this.fromTimeSelector = wf.timeSelector(this.innerComposite);
}
TableFilter.this.entityTable.widgetFactory
.labelLocalized(this.innerComposite, DATE_TO_TEXT);
this.toDateSelector =
new DateTime(this.innerComposite, SWT.DATE | SWT.BORDER);
this.toDateSelector.setLayoutData(this.rw1);
wf.labelLocalized(this.innerComposite, DATE_TO_TEXT);
this.toDateSelector = wf.dateSelector(this.innerComposite);
if (this.withTime) {
this.toTimeSelector =
new DateTime(this.innerComposite, SWT.TIME | SWT.BORDER);
this.toTimeSelector.setLayoutData(this.rw1);
this.toTimeSelector = wf.timeSelector(this.innerComposite);
}
return this;

View file

@ -25,6 +25,7 @@ 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.DateTime;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
@ -617,6 +618,27 @@ public class WidgetFactory {
return selection;
}
public DateTime dateSelector(final Composite parent) {
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
final DateTime dateTime = new DateTime(parent, SWT.DATE | SWT.BORDER | SWT.DROP_DOWN);
dateTime.setLayoutData(gridData);
return dateTime;
}
public DateTime timeSelector(final Composite parent) {
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
final DateTime dateTime = new DateTime(parent, SWT.TIME | SWT.BORDER | SWT.SHORT);
dateTime.setLayoutData(gridData);
return dateTime;
}
public DateTime timeSelectorWithSeconds(final Composite parent) {
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
final DateTime dateTime = new DateTime(parent, SWT.TIME | SWT.BORDER | SWT.MEDIUM);
dateTime.setLayoutData(gridData);
return dateTime;
}
public ThresholdList thresholdList(
final Composite parent,
final Composite updateAnchor,

View file

@ -183,7 +183,6 @@ public class MoodleCourseAccess extends CourseAccess {
.stream()
.map(courseQuizData -> {
final String startURI = uriPrefix + courseData.id;
additionalAttrs.put("coursemodule", courseQuizData.coursemodule);
additionalAttrs.put("timelimit", String.valueOf(courseQuizData.timelimit));
return new QuizData(
courseQuizData.id,

View file

@ -275,14 +275,6 @@ final class MoodleRestTemplateFactory {
functionReqEntity = new HttpEntity<>(null);
}
// // NOTE: The interpretation of a multi-value GET parameter on a URL quesry part
// // seems to be very PHP specific. It must have the form of:
// // ... &param[]=x&param[]=y& ...
// // And the square bracket must not be escaped on the URL like: %5B%5D
// String urlString = queryParam.toUriString()
// .replaceAll("%5B", "[")
// .replaceAll("%5D", "]");
final ResponseEntity<String> response = super.exchange(
queryParam.toUriString(),
usePOST ? HttpMethod.POST : HttpMethod.GET,

View file

@ -285,6 +285,12 @@ sebserver.quizdiscovery.quiz.details.description=Description
sebserver.quizdiscovery.quiz.details.starttime=Start Time
sebserver.quizdiscovery.quiz.details.endtime=End Time
sebserver.quizdiscovery.quiz.details.url=Start URL
sebserver.quizdiscovery.quiz.details.additional.timecreated=Creation Time
sebserver.quizdiscovery.quiz.details.additional.course_shortname=Short Name
sebserver.quizdiscovery.quiz.details.additional.course_fullname=Full Name
sebserver.quizdiscovery.quiz.details.additional.course_displayname=Display Name
sebserver.quizdiscovery.quiz.details.additional.course_summary=Summary
sebserver.quizdiscovery.quiz.details.additional.timelimit=Time Limit
################################
# Exam

View file

@ -398,6 +398,26 @@ DateTime-DropDownButton {
width: 30px;
}
DateTime-Calendar-Navbar {
border: none;
border-radius: 0;
background-color: #1F407A;
background-image: gradient(linear, left top, left bottom, from(#1F407A), to(#1F407A));
color: white;
font: 12px Arial, Helvetica, sans-serif;
text-shadow: none;
}
DateTime-Field:selected, DateTime-Calendar-Day:selected {
background-color: #1F407A;
color: #ffffff;
}
DateTime-Calendar-Day:selected:hover {
background-color: #1F407A;
color: #ffffff;
}
/* Message titlebar */
Shell.message {
font: 12px Arial, Helvetica, sans-serif;