SEBSERV-30 default action for list double click and code cleanup

This commit is contained in:
anhefti 2019-03-29 14:34:51 +01:00
parent 7ccacfcb73
commit 98deb870eb
32 changed files with 529 additions and 255 deletions

View file

@ -35,11 +35,11 @@ import ch.ethz.seb.sebserver.gui.form.PageFormService;
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.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicator;
@ -176,6 +176,7 @@ public class ExamForm implements TemplateComposer {
QuizData.QUIZ_ATTR_DESCRIPTION,
"sebserver.exam.form.description",
exam.description)
.asArea()
.readonly(true))
.addField(FormBuilder.text(
QuizData.QUIZ_ATTR_START_TIME,
@ -273,7 +274,7 @@ public class ExamForm implements TemplateComposer {
.createAction(ActionDefinition.EXAM_INDICATOR_MODIFY_FROM_LIST)
.withParentEntityKey(entityKey)
.withSelect(indicatorTable::getSelection, Action::applySingleSelection, emptySelectionTextKey)
.withSelect(indicatorTable::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent())
.createAction(ActionDefinition.EXAM_INDICATOR_DELETE_FROM_LIST)
@ -287,7 +288,7 @@ public class ExamForm implements TemplateComposer {
}
private Action deleteSelectedIndicator(final Action action) {
private PageAction deleteSelectedIndicator(final PageAction action) {
final EntityKey indicatorKey = action.getSingleSelection();
this.resourceService.getRestService()
.getBuilder(DeleteIndicator.class)
@ -337,17 +338,17 @@ public class ExamForm implements TemplateComposer {
.toString();
}
public static Action cancelModify(final Action action) {
public static PageAction cancelModify(final PageAction action) {
final boolean importFromQuizData = BooleanUtils.toBoolean(
action.pageContext().getAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA));
if (importFromQuizData) {
final PageContext pageContext = action.pageContext();
final Action activityHomeAction = pageContext.createAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST);
final PageAction activityHomeAction = pageContext.createAction(ActionDefinition.QUIZ_DISCOVERY_VIEW_LIST);
action.pageContext().firePageEvent(new ActionEvent(activityHomeAction, false));
return activityHomeAction;
}
return Action.onEmptyEntityKeyGoToActivityHome(action);
return PageAction.onEmptyEntityKeyGoToActivityHome(action);
}
}

View file

@ -28,9 +28,9 @@ import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
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.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
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.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExams;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -59,6 +59,13 @@ public class ExamList implements TemplateComposer {
private final static LocTextKey columnTitleTypeKey =
new LocTextKey("sebserver.exam.list.column.type");
private final TableFilterAttribute institutionFilter;
private final TableFilterAttribute lmsFilter;
private final TableFilterAttribute nameFilter =
new TableFilterAttribute(CriteriaType.TEXT, QuizData.FILTER_ATTR_NAME);
private final TableFilterAttribute startTimeFilter =
new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME);
protected ExamList(
final WidgetFactory widgetFactory,
final ResourceService resourceService,
@ -67,6 +74,16 @@ public class ExamList implements TemplateComposer {
this.widgetFactory = widgetFactory;
this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20;
this.institutionFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Entity.FILTER_ATTR_INSTITUTION,
this.resourceService::institutionResource);
this.lmsFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
LmsSetup.FILTER_ATTR_LMS_SETUP,
this.resourceService::lmsSetupResource);
}
@Override
@ -92,25 +109,19 @@ public class ExamList implements TemplateComposer {
Domain.EXAM.ATTR_INSTITUTION_ID,
new LocTextKey("sebserver.exam.list.column.institution"),
examInstitutionNameFunction(this.resourceService),
new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Entity.FILTER_ATTR_INSTITUTION,
this.resourceService::institutionResource),
this.institutionFilter,
false))
.withColumn(new ColumnDefinition<>(
Domain.EXAM.ATTR_LMS_SETUP_ID,
columnTitleLmsSetupKey,
examLmsSetupNameFunction(this.resourceService),
new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
LmsSetup.FILTER_ATTR_LMS_SETUP,
this.resourceService::lmsSetupResource),
this.lmsFilter,
false))
.withColumn(new ColumnDefinition<>(
QuizData.QUIZ_ATTR_NAME,
columnTitleNameKey,
Exam::getName,
new TableFilterAttribute(CriteriaType.TEXT, QuizData.FILTER_ATTR_NAME),
this.nameFilter,
true))
.withColumn(new ColumnDefinition<>(
QuizData.QUIZ_ATTR_START_TIME,
@ -118,32 +129,31 @@ public class ExamList implements TemplateComposer {
"sebserver.exam.list.column.starttime",
i18nSupport.getUsersTimeZoneTitleSuffix()),
Exam::getStartTime,
new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME),
this.startTimeFilter,
true))
.withColumn(new ColumnDefinition<>(
Domain.EXAM.ATTR_TYPE,
columnTitleTypeKey,
this::examTypeName,
true))
.withDefaultAction(pageContext
.clearEntityKeys()
.createAction(ActionDefinition.EXAM_VIEW_FROM_LIST))
.compose(content);
// propagate content actions to action-pane
final GrantCheck userGrant = currentUser.grantCheck(EntityType.EXAM);
pageContext.clearEntityKeys()
// .createAction(ActionDefinition.TEST_ACTION)
// .withExec(this::testModalInput)
// .publish()
.createAction(ActionDefinition.EXAM_IMPORT)
.publishIf(userGrant::im)
.createAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionTextKey)
.withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
.publishIf(table::hasAnyContent)
.createAction(ActionDefinition.EXAM_MODIFY_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionTextKey)
.withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
.publishIf(() -> userGrant.im() && table.hasAnyContent());
}
@ -167,29 +177,4 @@ public class ExamList implements TemplateComposer {
.getText("sebserver.exam.type." + exam.type.name());
}
// private Action testModalInput(final Action action) {
// final ModalInputDialog<String> dialog = new ModalInputDialog<>(
// action.pageContext().getParent().getShell(),
// this.widgetFactory);
//
// dialog.open(
// "Test Input Dialog",
// action.pageContext(),
// value -> {
// System.out.println("********************** value: " + value);
// },
// pc -> {
// final Composite parent = pc.getParent();
// final Label label = new Label(parent, SWT.NONE);
// label.setText("Please Enter:");
// label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
//
// final Text text = new Text(parent, SWT.LEFT | SWT.BORDER);
// text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// return () -> text.getText();
// });
//
// return action;
// }
}

View file

@ -26,9 +26,9 @@ import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
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.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicator;
@ -144,7 +144,7 @@ public class IndicatorForm implements TemplateComposer {
.createAction(ActionDefinition.EXAM_INDICATOR_CANCEL_MODIFY)
.withEntityKey(parentEntityKey)
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome)
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
.publishIf(() -> !isReadonly);

View file

@ -28,10 +28,10 @@ import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.SebClientConfigDownload;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
@ -180,7 +180,7 @@ public class InstitutionForm implements TemplateComposer {
.createAction(ActionDefinition.INSTITUTION_CANCEL_MODIFY)
.withEntityKey(entityKey)
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome)
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
.publishIf(() -> !isReadonly);
}

View file

@ -18,9 +18,9 @@ import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
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.page.PageAction;
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.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutions;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -34,6 +34,19 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@GuiProfile
public class InstitutionList implements TemplateComposer {
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
new LocTextKey("sebserver.institution.list.empty");
private static final LocTextKey TITLE_TEXT_KEY =
new LocTextKey("sebserver.institution.list.title");
private static final LocTextKey NAME_TEXT_KEY =
new LocTextKey("sebserver.institution.list.column.name");
private static final LocTextKey URL_TEXT_KEY =
new LocTextKey("sebserver.institution.list.column.urlSuffix");
private static final LocTextKey ACTIVE_TEXT_KEY =
new LocTextKey("sebserver.institution.list.column.active");
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
new LocTextKey("sebserver.institution.info.pleaseSelect");
private final WidgetFactory widgetFactory;
private final RestService restService;
private final CurrentUser currentUser;
@ -52,34 +65,36 @@ public class InstitutionList implements TemplateComposer {
public void compose(final PageContext pageContext) {
final Composite content = this.widgetFactory.defaultPageLayout(
pageContext.getParent(),
new LocTextKey("sebserver.institution.list.title"));
TITLE_TEXT_KEY);
// table
final EntityTable<Institution> table =
this.widgetFactory.entityTableBuilder(this.restService.getRestCall(GetInstitutions.class))
.withEmptyMessage(new LocTextKey("sebserver.institution.list.empty"))
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(3)
.withColumn(new ColumnDefinition<>(
Domain.INSTITUTION.ATTR_NAME,
new LocTextKey("sebserver.institution.list.column.name"),
NAME_TEXT_KEY,
entity -> entity.name,
true))
.withColumn(new ColumnDefinition<>(
Domain.INSTITUTION.ATTR_URL_SUFFIX,
new LocTextKey("sebserver.institution.list.column.urlSuffix"),
URL_TEXT_KEY,
entity -> entity.urlSuffix,
true))
.withColumn(new ColumnDefinition<>(
Domain.INSTITUTION.ATTR_ACTIVE,
new LocTextKey("sebserver.institution.list.column.active"),
ACTIVE_TEXT_KEY,
entity -> entity.active,
true))
.withDefaultAction(pageContext
.clearEntityKeys()
.createAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST))
.compose(content);
// propagate content actions to action-pane
final GrantCheck instGrant = this.currentUser.grantCheck(EntityType.INSTITUTION);
final GrantCheck userGrant = this.currentUser.grantCheck(EntityType.USER);
final LocTextKey emptySelectionText = new LocTextKey("sebserver.institution.info.pleaseSelect");
pageContext.clearEntityKeys()
.createAction(ActionDefinition.INSTITUTION_NEW)
@ -89,11 +104,11 @@ public class InstitutionList implements TemplateComposer {
.publishIf(userGrant::w)
.createAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionText)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent())
.createAction(ActionDefinition.INSTITUTION_MODIFY_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionText)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> instGrant.m() && table.hasAnyContent());
;

View file

@ -33,11 +33,11 @@ import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
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.PageUtils;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
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.lmssetup.GetLmsSetup;
@ -206,21 +206,21 @@ public class LmsSetupForm implements TemplateComposer {
.createAction(ActionDefinition.LMS_SETUP_CANCEL_MODIFY)
.withEntityKey(entityKey)
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome)
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
.publishIf(() -> !readonly);
}
/** Save and test connection before activation */
private Action activate(final Action action, final FormHandle<LmsSetup> formHandle) {
private PageAction activate(final PageAction action, final FormHandle<LmsSetup> formHandle) {
final RestService restService = this.resourceService.getRestService();
final Action testLmsSetup = this.testLmsSetup(action, formHandle);
final Action activation = restService.activation(testLmsSetup);
final PageAction testLmsSetup = this.testLmsSetup(action, formHandle);
final PageAction activation = restService.activation(testLmsSetup);
return activation;
}
/** LmsSetup test action implementation */
private Action testLmsSetup(final Action action, final FormHandle<LmsSetup> formHandle) {
private PageAction testLmsSetup(final PageAction action, final FormHandle<LmsSetup> formHandle) {
// If we are in edit-mode we have to save the form before testing
if (!action.pageContext().isReadonly()) {
final Result<LmsSetup> postResult = formHandle.doAPIPost();

View file

@ -25,9 +25,9 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
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.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetups;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -43,6 +43,26 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@GuiProfile
public class LmsSetupList implements TemplateComposer {
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.info.pleaseSelect");
private static final LocTextKey ACTIVITY_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.list.column.active");
private static final LocTextKey TYPE_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.list.column.type");
private static final LocTextKey NAME_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.list.column.name");
private static final LocTextKey INSTITUTION_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.list.column.institution");
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.list.empty");
private static final LocTextKey TITLE_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.list.title");
private final TableFilterAttribute institutionFilter;
private final TableFilterAttribute nameFilter =
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
private final TableFilterAttribute typeFilter;
private final WidgetFactory widgetFactory;
private final ResourceService resourceService;
private final int pageSize;
@ -55,6 +75,16 @@ public class LmsSetupList implements TemplateComposer {
this.widgetFactory = widgetFactory;
this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20;
this.institutionFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Entity.FILTER_ATTR_INSTITUTION,
this.resourceService::institutionResource);
this.typeFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Domain.LMS_SETUP.ATTR_LMS_TYPE,
this.resourceService::lmsTypeResources);
}
@Override
@ -65,65 +95,58 @@ public class LmsSetupList implements TemplateComposer {
// content page layout with title
final Composite content = this.widgetFactory.defaultPageLayout(
pageContext.getParent(),
new LocTextKey("sebserver.lmssetup.list.title"));
TITLE_TEXT_KEY);
final boolean isSEBAdmin = currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
// table
final EntityTable<LmsSetup> table =
this.widgetFactory.entityTableBuilder(restService.getRestCall(GetLmsSetups.class))
.withEmptyMessage(new LocTextKey("sebserver.lmssetup.list.empty"))
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(this.pageSize)
.withColumnIf(() -> isSEBAdmin,
new ColumnDefinition<>(
Domain.LMS_SETUP.ATTR_INSTITUTION_ID,
new LocTextKey("sebserver.lmssetup.list.column.institution"),
INSTITUTION_TEXT_KEY,
lmsSetupInstitutionNameFunction(this.resourceService),
new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Entity.FILTER_ATTR_INSTITUTION,
this.resourceService::institutionResource),
this.institutionFilter,
false))
.withColumn(new ColumnDefinition<>(
Domain.LMS_SETUP.ATTR_NAME,
new LocTextKey("sebserver.lmssetup.list.column.name"),
NAME_TEXT_KEY,
entity -> entity.name,
(isSEBAdmin)
? new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME)
: null,
(isSEBAdmin) ? this.nameFilter : null,
true))
.withColumn(new ColumnDefinition<>(
Domain.LMS_SETUP.ATTR_LMS_TYPE,
new LocTextKey("sebserver.lmssetup.list.column.type"),
TYPE_TEXT_KEY,
this::lmsSetupTypeName,
(isSEBAdmin)
? new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Domain.LMS_SETUP.ATTR_LMS_TYPE,
this.resourceService::lmsTypeResources)
: null,
(isSEBAdmin) ? this.typeFilter : null,
false, true))
.withColumn(new ColumnDefinition<>(
Domain.LMS_SETUP.ATTR_ACTIVE,
new LocTextKey("sebserver.lmssetup.list.column.active"),
ACTIVITY_TEXT_KEY,
entity -> entity.active,
true))
.withDefaultAction(pageContext
.clearEntityKeys()
.createAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST))
.compose(content);
// propagate content actions to action-pane
final GrantCheck userGrant = currentUser.grantCheck(EntityType.LMS_SETUP);
final LocTextKey emptySelectionText = new LocTextKey("sebserver.lmssetup.info.pleaseSelect");
pageContext.clearEntityKeys()
.createAction(ActionDefinition.LMS_SETUP_NEW)
.publishIf(userGrant::iw)
.createAction(ActionDefinition.LMS_SETUP_VIEW_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionText)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent())
.createAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionText)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> userGrant.im() && table.hasAnyContent());
}

View file

@ -21,13 +21,16 @@ import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
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.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialog;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.quiz.GetQuizzes;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -43,25 +46,48 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@GuiProfile
public class QuizDiscoveryList implements TemplateComposer {
// localized text keys
private static final LocTextKey TITLE_TEXT_KEY =
new LocTextKey("sebserver.quizdiscovery.list.title");
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
new LocTextKey("sebserver.quizdiscovery.list.empty");
private final static LocTextKey EMPTY_SELECTION_TEXT =
new LocTextKey("sebserver.quizdiscovery.info.pleaseSelect");
private final static LocTextKey LMS_TEXT_KEY =
new LocTextKey("sebserver.quizdiscovery.list.column.lmssetup");
private final static LocTextKey NAME_TEXT_KEY =
new LocTextKey("sebserver.quizdiscovery.list.column.name");
private final static LocTextKey DETAILS_TITLE_TEXT_KEY =
new LocTextKey("sebserver.quizdiscovery.quiz.details.title");
// filter attribute models
private final TableFilterAttribute lmsFilter;
private final TableFilterAttribute nameFilter =
new TableFilterAttribute(CriteriaType.TEXT, QuizData.FILTER_ATTR_NAME);
private final TableFilterAttribute startTimeFilter =
new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME);
// dependencies
private final WidgetFactory widgetFactory;
private final ResourceService resourceService;
private final PageFormService pageFormService;
private final int pageSize;
private final static LocTextKey emptySelectionText =
new LocTextKey("sebserver.quizdiscovery.info.pleaseSelect");
private final static LocTextKey columnTitleLmsSetup =
new LocTextKey("sebserver.quizdiscovery.list.column.lmssetup");
private final static LocTextKey columnTitleName =
new LocTextKey("sebserver.quizdiscovery.list.column.name");
protected QuizDiscoveryList(
final PageFormService pageFormService,
final WidgetFactory widgetFactory,
final ResourceService resourceService,
@Value("${sebserver.gui.list.page.size}") final Integer pageSize) {
this.pageFormService = pageFormService;
this.widgetFactory = widgetFactory;
this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20;
this.lmsFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
LmsSetup.FILTER_ATTR_LMS_SETUP,
this.resourceService::lmsSetupResource);
}
@Override
@ -73,27 +99,24 @@ public class QuizDiscoveryList implements TemplateComposer {
// content page layout with title
final Composite content = this.widgetFactory.defaultPageLayout(
pageContext.getParent(),
new LocTextKey("sebserver.quizdiscovery.list.title"));
TITLE_TEXT_KEY);
// table
final EntityTable<QuizData> table =
this.widgetFactory.entityTableBuilder(restService.getRestCall(GetQuizzes.class))
.withEmptyMessage(new LocTextKey("sebserver.quizdiscovery.list.empty"))
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(this.pageSize)
.withColumn(new ColumnDefinition<>(
QuizData.QUIZ_ATTR_LMS_SETUP_ID,
columnTitleLmsSetup,
LMS_TEXT_KEY,
quizDataLmsSetupNameFunction(this.resourceService),
new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
LmsSetup.FILTER_ATTR_LMS_SETUP,
this.resourceService::lmsSetupResource),
this.lmsFilter,
false))
.withColumn(new ColumnDefinition<>(
QuizData.QUIZ_ATTR_NAME,
columnTitleName,
NAME_TEXT_KEY,
quizData -> quizData.name,
new TableFilterAttribute(CriteriaType.TEXT, QuizData.FILTER_ATTR_NAME),
this.nameFilter,
true))
.withColumn(new ColumnDefinition<>(
QuizData.QUIZ_ATTR_START_TIME,
@ -101,7 +124,7 @@ public class QuizDiscoveryList implements TemplateComposer {
"sebserver.quizdiscovery.list.column.starttime",
i18nSupport.getUsersTimeZoneTitleSuffix()),
quizData -> quizData.startTime,
new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME),
this.startTimeFilter,
true))
.withColumn(new ColumnDefinition<>(
QuizData.QUIZ_ATTR_END_TIME,
@ -110,6 +133,11 @@ public class QuizDiscoveryList implements TemplateComposer {
i18nSupport.getUsersTimeZoneTitleSuffix()),
quizData -> quizData.endTime,
true))
.withDefaultAction(t -> pageContext
.clearEntityKeys()
.createAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS)
.withExec(action -> this.showDetails(action, t.getSelectedROWData()))
.noEventPropagation())
.compose(content);
// propagate content actions to action-pane
@ -120,11 +148,19 @@ public class QuizDiscoveryList implements TemplateComposer {
.createAction(ActionDefinition.LMS_SETUP_NEW)
.publishIf(lmsSetupGrant::iw)
.createAction(ActionDefinition.QUIZ_DISCOVERY_SHOW_DETAILS)
.withSelect(
table::getSelection,
action -> this.showDetails(action, table.getSelectedROWData()),
EMPTY_SELECTION_TEXT)
.noEventPropagation()
.publishIf(table::hasAnyContent)
.createAction(ActionDefinition.QUIZ_DISCOVERY_EXAM_IMPORT)
.withSelect(
table::getSelection,
action -> this.importQuizData(action, table),
emptySelectionText)
EMPTY_SELECTION_TEXT)
.publishIf(() -> examGrant.im() && table.hasAnyContent());
}
@ -133,7 +169,7 @@ public class QuizDiscoveryList implements TemplateComposer {
.apply(String.valueOf(quizzData.lmsSetupId));
}
private Action importQuizData(final Action action, final EntityTable<QuizData> table) {
private PageAction importQuizData(final PageAction action, final EntityTable<QuizData> table) {
final QuizData selectedROWData = table.getSelectedROWData();
return action
@ -142,4 +178,53 @@ public class QuizDiscoveryList implements TemplateComposer {
.withAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA, "true");
}
private PageAction showDetails(final PageAction action, final QuizData quizData) {
action.getSingleSelection();
final ModalInputDialog<Void> dialog = new ModalInputDialog<>(
action.pageContext().getParent().getShell(),
this.widgetFactory);
dialog.open(
DETAILS_TITLE_TEXT_KEY,
action.pageContext(),
pc -> createDetailsForm(quizData, pc));
return action;
}
private void createDetailsForm(final QuizData quizData, final PageContext pc) {
this.widgetFactory.labelSeparator(pc.getParent());
this.pageFormService.getBuilder(pc, 4)
.readonly(true)
.addField(FormBuilder.singleSelection(
QuizData.QUIZ_ATTR_LMS_SETUP_ID,
"sebserver.quizdiscovery.quiz.details.lms",
String.valueOf(quizData.lmsSetupId),
() -> this.resourceService.lmsSetupResource()))
.addField(FormBuilder.text(
QuizData.QUIZ_ATTR_NAME,
"sebserver.quizdiscovery.quiz.details.name",
quizData.name))
.addField(FormBuilder.text(
QuizData.QUIZ_ATTR_DESCRIPTION,
"sebserver.quizdiscovery.quiz.details.description",
quizData.description)
.asArea())
.addField(FormBuilder.text(
QuizData.QUIZ_ATTR_START_TIME,
"sebserver.quizdiscovery.quiz.details.starttime",
this.widgetFactory.getI18nSupport().formatDisplayDate(quizData.startTime)))
.addField(FormBuilder.text(
QuizData.QUIZ_ATTR_END_TIME,
"sebserver.quizdiscovery.quiz.details.endtime",
this.widgetFactory.getI18nSupport().formatDisplayDate(quizData.startTime)))
.addField(FormBuilder.text(
QuizData.QUIZ_ATTR_START_URL,
"sebserver.quizdiscovery.quiz.details.url",
quizData.startURL))
.build();
this.widgetFactory.labelSeparator(pc.getParent());
}
}

View file

@ -26,9 +26,9 @@ import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
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.page.PageAction;
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.action.Action;
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.GetUserAccount;
@ -122,7 +122,7 @@ public class UserAccountChangePasswordForm implements TemplateComposer {
})
.publish()
.createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome)
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
.publish();
}

View file

@ -34,10 +34,10 @@ import ch.ethz.seb.sebserver.gui.form.FormHandle;
import ch.ethz.seb.sebserver.gui.form.PageFormService;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageUtils;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
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.useraccount.GetUserAccount;
@ -214,7 +214,7 @@ public class UserAccountForm implements TemplateComposer {
.createAction(ActionDefinition.USER_ACCOUNT_SAVE)
.withEntityKey(entityKey)
.withExec(action -> {
final Action postChanges = formHandle.processFormSave(action);
final PageAction postChanges = formHandle.processFormSave(action);
if (ownAccount) {
currentUser.refresh();
pageContext.forwardToMainPage();
@ -225,7 +225,7 @@ public class UserAccountForm implements TemplateComposer {
.createAction(ActionDefinition.USER_ACCOUNT_CANCEL_MODIFY)
.withEntityKey(entityKey)
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
.withExec(PageAction::onEmptyEntityKeyGoToActivityHome)
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
.publishIf(() -> !readonly);
}

View file

@ -26,9 +26,9 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
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.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.useraccount.GetUserAccounts;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@ -44,6 +44,35 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@GuiProfile
public class UserAccountList implements TemplateComposer {
// localized text keys
private static final LocTextKey INSTITUTION_TEXT_KEY =
new LocTextKey("sebserver.useraccount.list.column.institution");
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
new LocTextKey("sebserver.useraccount.info.pleaseSelect");
private static final LocTextKey ACTIVE_TEXT_KEY =
new LocTextKey("sebserver.useraccount.list.column.active");
private static final LocTextKey LANG_TEXT_KEY =
new LocTextKey("sebserver.useraccount.list.column.language");
private static final LocTextKey MAIL_TEXT_KEY =
new LocTextKey("sebserver.useraccount.list.column.email");
private static final LocTextKey USER_NAME_TEXT_KEY =
new LocTextKey("sebserver.useraccount.list.column.username");
private static final LocTextKey NAME_TEXT_KEY =
new LocTextKey("sebserver.useraccount.list.column.name");
private static final LocTextKey TITLE_TEXT_KEY =
new LocTextKey("sebserver.useraccount.list.title");
// filter attribute models
private final TableFilterAttribute institutionFilter;
private final TableFilterAttribute nameFilter =
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME);
private final TableFilterAttribute usernameFilter =
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_USER_NAME);
private final TableFilterAttribute mailFilter =
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_EMAIL);
private final TableFilterAttribute languageFilter;
// dependencies
private final WidgetFactory widgetFactory;
private final ResourceService resourceService;
private final int pageSize;
@ -56,6 +85,16 @@ public class UserAccountList implements TemplateComposer {
this.widgetFactory = widgetFactory;
this.resourceService = resourceService;
this.pageSize = (pageSize != null) ? pageSize : 20;
this.institutionFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Entity.FILTER_ATTR_INSTITUTION,
this.resourceService::institutionResource);
this.languageFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
UserInfo.FILTER_ATTR_LANGUAGE,
this.resourceService::languageResources);
}
@Override
@ -65,73 +104,70 @@ public class UserAccountList implements TemplateComposer {
// content page layout with title
final Composite content = this.widgetFactory.defaultPageLayout(
pageContext.getParent(),
new LocTextKey("sebserver.useraccount.list.title"));
TITLE_TEXT_KEY);
final BooleanSupplier isSEBAdmin = () -> currentUser.get().hasRole(UserRole.SEB_SERVER_ADMIN);
// table
final EntityTable<UserInfo> table =
this.widgetFactory.entityTableBuilder(restService.getRestCall(GetUserAccounts.class))
.withEmptyMessage(new LocTextKey("sebserver.useraccount.list.empty"))
.withPaging(this.pageSize)
.withColumnIf(isSEBAdmin,
new ColumnDefinition<>(
Domain.USER.ATTR_INSTITUTION_ID,
new LocTextKey("sebserver.useraccount.list.column.institution"),
userInstitutionNameFunction(this.resourceService),
new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
Entity.FILTER_ATTR_INSTITUTION,
this.resourceService::institutionResource),
false))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_NAME,
new LocTextKey("sebserver.useraccount.list.column.name"),
entity -> entity.name,
new TableFilterAttribute(CriteriaType.TEXT, Entity.FILTER_ATTR_NAME),
true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_USERNAME,
new LocTextKey("sebserver.useraccount.list.column.username"),
entity -> entity.username,
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_USER_NAME),
true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_EMAIL,
new LocTextKey("sebserver.useraccount.list.column.email"),
entity -> entity.email,
new TableFilterAttribute(CriteriaType.TEXT, UserInfo.FILTER_ATTR_EMAIL),
true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_LANGUAGE,
new LocTextKey("sebserver.useraccount.list.column.language"),
this::getLocaleDisplayText,
new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION,
UserInfo.FILTER_ATTR_LANGUAGE,
this.resourceService::languageResources),
true, true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_ACTIVE,
new LocTextKey("sebserver.useraccount.list.column.active"),
entity -> entity.active,
true))
.compose(content);
final EntityTable<UserInfo> table = this.widgetFactory.entityTableBuilder(
restService.getRestCall(GetUserAccounts.class))
.withEmptyMessage(new LocTextKey("sebserver.useraccount.list.empty"))
.withPaging(this.pageSize)
.withColumnIf(isSEBAdmin,
new ColumnDefinition<>(
Domain.USER.ATTR_INSTITUTION_ID,
INSTITUTION_TEXT_KEY,
userInstitutionNameFunction(this.resourceService),
this.institutionFilter,
false))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_NAME,
NAME_TEXT_KEY,
entity -> entity.name,
this.nameFilter,
true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_USERNAME,
USER_NAME_TEXT_KEY,
entity -> entity.username,
this.usernameFilter,
true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_EMAIL,
MAIL_TEXT_KEY,
entity -> entity.email,
this.mailFilter,
true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_LANGUAGE,
LANG_TEXT_KEY,
this::getLocaleDisplayText,
this.languageFilter,
true, true))
.withColumn(new ColumnDefinition<>(
Domain.USER.ATTR_ACTIVE,
ACTIVE_TEXT_KEY,
entity -> entity.active,
true))
.withDefaultAction(pageContext
.clearEntityKeys()
.createAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST))
.compose(content);
// propagate content actions to action-pane
final GrantCheck userGrant = currentUser.grantCheck(EntityType.USER);
final LocTextKey emptySelectionText = new LocTextKey("sebserver.useraccount.info.pleaseSelect");
pageContext.clearEntityKeys()
.createAction(ActionDefinition.USER_ACCOUNT_NEW)
.publishIf(userGrant::iw)
.createAction(ActionDefinition.USER_ACCOUNT_VIEW_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionText)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> table.hasAnyContent())
.createAction(ActionDefinition.USER_ACCOUNT_MODIFY_FROM_LIST)
.withSelect(table::getSelection, Action::applySingleSelection, emptySelectionText)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> userGrant.im() && table.hasAnyContent());
}

View file

@ -251,6 +251,10 @@ public enum ActionDefinition {
QUIZ_DISCOVERY_VIEW_LIST(
new LocTextKey("sebserver.quizdiscovery.action.list"),
QuizDiscoveryList.class),
QUIZ_DISCOVERY_SHOW_DETAILS(
new LocTextKey("sebserver.quizdiscovery.action.details"),
ImageIcon.SHOW,
ActionCategory.QUIZ_LIST),
QUIZ_DISCOVERY_EXAM_IMPORT(
new LocTextKey("sebserver.quizdiscovery.action.import"),
ImageIcon.IMPORT,
@ -382,6 +386,14 @@ public enum ActionDefinition {
this(title, null, contentPaneComposer, ActionPane.class, null, activityAlias, null, null);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,
final ActionCategory category) {
this(title, icon, null, ActionPane.class, null, null, category, null);
}
private ActionDefinition(
final LocTextKey title,
final ImageIcon icon,

View file

@ -28,9 +28,9 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
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.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
@ -160,7 +160,7 @@ public class ActionPane implements TemplateComposer {
actions.addListener(SWT.Selection, event -> {
final TreeItem treeItem = (TreeItem) event.item;
final Action action = (Action) treeItem.getData(ACTION_EVENT_CALL_KEY);
final PageAction action = (PageAction) treeItem.getData(ACTION_EVENT_CALL_KEY);
action.run();
if (!treeItem.isDisposed()) {

View file

@ -24,10 +24,10 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
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.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
@ -174,7 +174,7 @@ public class ActivitiesPane implements TemplateComposer {
System.out.println("selected: " + treeItem);
final MainPageState mainPageState = MainPageState.get();
final Action action = getActivitySelection(treeItem);
final PageAction action = getActivitySelection(treeItem);
if (mainPageState.action.definition != action.definition) {
mainPageState.action = action;
composerCtx.firePageEvent(
@ -192,7 +192,7 @@ public class ActivitiesPane implements TemplateComposer {
}
for (final TreeItem item : items) {
final Action action = getActivitySelection(item);
final PageAction action = getActivitySelection(item);
if (action == null) {
continue;
}
@ -225,11 +225,11 @@ public class ActivitiesPane implements TemplateComposer {
expand(item.getParentItem());
}
public static Action getActivitySelection(final TreeItem item) {
return (Action) item.getData(ATTR_ACTIVITY_SELECTION);
public static PageAction getActivitySelection(final TreeItem item) {
return (PageAction) item.getData(ATTR_ACTIVITY_SELECTION);
}
public static void injectActivitySelection(final TreeItem item, final Action action) {
public static void injectActivitySelection(final TreeItem item, final PageAction action) {
item.setData(ATTR_ACTIVITY_SELECTION, action);
}

View file

@ -71,7 +71,7 @@ public class FormBuilder {
layout.horizontalSpacing = 10;
layout.verticalSpacing = 10;
layout.marginLeft = 10;
layout.marginTop = 10;
layout.marginTop = 0;
this.formParent.setLayout(layout);
this.formParent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}
@ -169,6 +169,10 @@ public class FormBuilder {
return this;
}
public <T extends Entity> FormHandle<T> build() {
return buildFor(null);
}
public <T extends Entity> FormHandle<T> buildFor(
final RestCall<T> post) {

View file

@ -19,10 +19,10 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.form.Form.FormFieldAccessor;
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.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError;
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
@ -57,7 +57,7 @@ public class FormHandle<T extends Entity> {
*
* @param action the save action context
* @return the new Action context for read-only-view */
public final Action processFormSave(final Action action) {
public final PageAction processFormSave(final PageAction action) {
return handleFormPost(doAPIPost(), action);
}
@ -86,10 +86,10 @@ public class FormHandle<T extends Entity> {
* @param postResult The form post result
* @param action the action that was applied with the form post
* @return the new Action that was used to stay on page or go the read-only-view of the form */
public Action handleFormPost(final Result<T> postResult, final Action action) {
public PageAction handleFormPost(final Result<T> postResult, final PageAction action) {
return postResult
.map(result -> {
Action resultAction = action.createNew()
PageAction resultAction = action.createNew()
.withAttribute(AttributeKeys.READ_ONLY, "true");
if (resultAction.getEntityKey() == null) {
resultAction = resultAction.withEntityKey(result.getEntityKey());

View file

@ -17,6 +17,7 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
boolean isPassword = false;
boolean isNumber = false;
boolean isArea = false;
TextFieldBuilder(final String name, final String label, final String value) {
super(name, label, value);
@ -32,6 +33,11 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
return this;
}
public TextFieldBuilder asArea() {
this.isArea = true;
return this;
}
@Override
void build(final FormBuilder builder) {
if (this.isPassword && builder.readonly) {
@ -46,7 +52,9 @@ public final class TextFieldBuilder extends FieldBuilder<String> {
} else {
final Text textInput = (this.isNumber)
? builder.widgetFactory.numberInput(builder.formParent, null)
: builder.widgetFactory.textInput(builder.formParent, this.isPassword);
: (this.isArea)
? builder.widgetFactory.textAreaInput(builder.formParent)
: builder.widgetFactory.textInput(builder.formParent, this.isPassword);
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false, this.spanInput, 1);
textInput.setLayoutData(gridData);

View file

@ -23,14 +23,20 @@ import org.eclipse.swt.widgets.Shell;
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 class ModalInputDialog<T> extends Dialog {
private static final long serialVersionUID = -3448614119078234374L;
private final WidgetFactory widgetFactory;
private static final LocTextKey CANCEL_TEXT_KEY =
new LocTextKey("sebserver.overall.action.cancel");
private static final LocTextKey OK_TEXT_KEY =
new LocTextKey("sebserver.overall.action.ok");
private static final LocTextKey CLOSE_TEXT_KEY =
new LocTextKey("sebserver.overall.action.close");
private T returnValue = null;
private final WidgetFactory widgetFactory;
public ModalInputDialog(
final Shell parent,
@ -41,16 +47,16 @@ public class ModalInputDialog<T> extends Dialog {
}
public void open(
final String title,
final LocTextKey title,
final PageContext pageContext,
final Consumer<T> callback,
final ModalInputDialogComposer<T> contentComposer) {
// Create the dialog window
// Create the selection dialog window
final Shell shell = new Shell(getParent(), getStyle());
shell.setText(getText());
shell.setData(RWT.CUSTOM_VARIANT, "message");
shell.setText(title);
shell.setData(RWT.CUSTOM_VARIANT, CustomVariant.MESSAGE.key);
shell.setText(this.widgetFactory.getI18nSupport().getText(title));
shell.setLayout(new GridLayout(2, true));
shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
@ -63,30 +69,62 @@ public class ModalInputDialog<T> extends Dialog {
final PageContext internalPageContext = pageContext.copyOf(main);
final Supplier<T> valueSuppier = contentComposer.compose(internalPageContext);
final Button ok = this.widgetFactory.buttonLocalized(
shell,
new LocTextKey("sebserver.overall.action.ok"));
final Button ok = this.widgetFactory.buttonLocalized(shell, OK_TEXT_KEY);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END);
data.widthHint = 100;
ok.setLayoutData(data);
ok.addListener(SWT.Selection, event -> {
callback.accept(valueSuppier.get());
this.returnValue = valueSuppier.get();
if (valueSuppier != null) {
callback.accept(valueSuppier.get());
}
shell.close();
});
shell.setDefaultButton(ok);
final Button cancel = this.widgetFactory.buttonLocalized(
shell,
new LocTextKey("sebserver.overall.action.cancel"));
data = new GridData(GridData.CENTER);
final Button cancel = this.widgetFactory.buttonLocalized(shell, CANCEL_TEXT_KEY);
data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
data.widthHint = 100;
cancel.setLayoutData(data);
cancel.addListener(SWT.Selection, event -> {
shell.close();
});
finishUp(shell);
}
public void open(
final LocTextKey title,
final PageContext pageContext,
final Consumer<PageContext> contentComposer) {
// Create the info dialog window
final Shell shell = new Shell(getParent(), getStyle());
shell.setText(getText());
shell.setData(RWT.CUSTOM_VARIANT, CustomVariant.MESSAGE.key);
shell.setText(this.widgetFactory.getI18nSupport().getText(title));
shell.setLayout(new GridLayout());
shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Composite main = new Composite(shell, SWT.NONE);
main.setLayout(new GridLayout());
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true);
main.setLayoutData(gridData);
final PageContext internalPageContext = pageContext.copyOf(main);
contentComposer.accept(internalPageContext);
final Button close = this.widgetFactory.buttonLocalized(shell, CLOSE_TEXT_KEY);
final GridData data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
data.widthHint = 100;
close.setLayoutData(data);
close.addListener(SWT.Selection, event -> {
shell.close();
});
finishUp(shell);
}
private void finishUp(final Shell shell) {
shell.pack();
final Rectangle bounds = shell.getBounds();
final Rectangle bounds2 = super.getParent().getDisplay().getBounds();

View file

@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package ch.ethz.seb.sebserver.gui.service.page.action;
package ch.ethz.seb.sebserver.gui.service.page;
import java.util.Set;
import java.util.function.BooleanSupplier;
@ -20,16 +20,14 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
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.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
public final class Action implements Runnable {
public final class PageAction implements Runnable {
private static final Logger log = LoggerFactory.getLogger(Action.class);
private static final Logger log = LoggerFactory.getLogger(PageAction.class);
public final ActionDefinition definition;
Supplier<LocTextKey> confirm;
@ -40,9 +38,11 @@ public final class Action implements Runnable {
private final PageContext originalPageContext;
private PageContext pageContext;
private Function<Action, Action> exec = Function.identity();
private Function<PageAction, PageAction> exec = Function.identity();
public Action(
private boolean fireActionEvent = true;
public PageAction(
final ActionDefinition definition,
final PageContext pageContext) {
@ -71,44 +71,46 @@ public final class Action implements Runnable {
private void exec() {
try {
final Action executedAction = this.exec.apply(this);
this.pageContext.firePageEvent(new ActionEvent(executedAction, false));
final PageAction executedAction = this.exec.apply(this);
if (this.fireActionEvent) {
this.pageContext.firePageEvent(new ActionEvent(executedAction, false));
}
} catch (final PageMessageException pme) {
Action.this.pageContext.publishPageMessage(pme);
PageAction.this.pageContext.publishPageMessage(pme);
} catch (final RestCallError restCallError) {
if (restCallError.isFieldValidationError()) {
Action.this.pageContext.publishPageMessage(
PageAction.this.pageContext.publishPageMessage(
new LocTextKey("sebserver.form.validation.error.title"),
new LocTextKey("sebserver.form.validation.error.message"));
} else {
log.error("Failed to execute action: {}", Action.this, restCallError);
Action.this.pageContext.notifyError("action.error.unexpected.message", restCallError);
log.error("Failed to execute action: {}", PageAction.this, restCallError);
PageAction.this.pageContext.notifyError("action.error.unexpected.message", restCallError);
}
} catch (final Throwable t) {
log.error("Failed to execute action: {}", Action.this, t);
Action.this.pageContext.notifyError("action.error.unexpected.message", t);
log.error("Failed to execute action: {}", PageAction.this, t);
PageAction.this.pageContext.notifyError("action.error.unexpected.message", t);
}
}
public Action createNew() {
public PageAction createNew() {
return this.pageContext.createAction(this.definition);
}
public Action withExec(final Function<Action, Action> exec) {
public PageAction withExec(final Function<PageAction, PageAction> exec) {
this.exec = exec;
return this;
}
public Action withSelectionSupplier(final Supplier<Set<EntityKey>> selectionSupplier) {
public PageAction withSelectionSupplier(final Supplier<Set<EntityKey>> selectionSupplier) {
this.selectionSupplier = selectionSupplier;
return this;
}
public Action withSelect(
public PageAction withSelect(
final Supplier<Set<EntityKey>> selectionSupplier,
final Function<Action, Action> exec,
final Function<PageAction, PageAction> exec,
final LocTextKey noSelectionMessage) {
this.selectionSupplier = selectionSupplier;
@ -117,27 +119,32 @@ public final class Action implements Runnable {
return this;
}
public Action withConfirm(final String confirmationMessageKey) {
public PageAction withConfirm(final String confirmationMessageKey) {
this.confirm = () -> new LocTextKey(confirmationMessageKey);
return this;
}
public Action withConfirm(final Supplier<LocTextKey> confirm) {
public PageAction withConfirm(final Supplier<LocTextKey> confirm) {
this.confirm = confirm;
return this;
}
public Action withSuccess(final String successMessageKey) {
public PageAction withSuccess(final String successMessageKey) {
this.successMessage = new LocTextKey(successMessageKey);
return this;
}
public Action resetEntityKey() {
public PageAction resetEntityKey() {
this.pageContext = this.pageContext.withEntityKey(null);
return this;
}
public Action resetParentEntityKey() {
public PageAction noEventPropagation() {
this.fireActionEvent = false;
return this;
}
public PageAction resetParentEntityKey() {
this.pageContext = this.pageContext.withParentEntityKey(null);
return this;
}
@ -150,12 +157,12 @@ public final class Action implements Runnable {
return this.pageContext;
}
public Action withEntityKey(final EntityKey entityKey) {
public PageAction withEntityKey(final EntityKey entityKey) {
this.pageContext = this.pageContext.withEntityKey(entityKey);
return this;
}
public Action withEntityKey(final Long modelId, final EntityType entityType) {
public PageAction withEntityKey(final Long modelId, final EntityType entityType) {
if (modelId != null) {
return withEntityKey(String.valueOf(modelId), entityType);
}
@ -163,7 +170,7 @@ public final class Action implements Runnable {
return this;
}
public Action withEntityKey(final String modelId, final EntityType entityType) {
public PageAction withEntityKey(final String modelId, final EntityType entityType) {
if (modelId == null || entityType == null) {
return this;
}
@ -172,12 +179,12 @@ public final class Action implements Runnable {
return this;
}
public Action withParentEntityKey(final EntityKey entityKey) {
public PageAction withParentEntityKey(final EntityKey entityKey) {
this.pageContext = this.pageContext.withParentEntityKey(entityKey);
return this;
}
public Action withAttribute(final String name, final String value) {
public PageAction withAttribute(final String name, final String value) {
this.pageContext = this.pageContext.withAttribute(name, value);
return this;
}
@ -225,14 +232,14 @@ public final class Action implements Runnable {
return null;
}
public static Action applySingleSelection(final Action action) {
public static PageAction applySingleSelection(final PageAction action) {
return action.withEntityKey(action.getSingleSelection());
}
public static Action onEmptyEntityKeyGoToActivityHome(final Action action) {
public static PageAction onEmptyEntityKeyGoToActivityHome(final PageAction action) {
if (action.getEntityKey() == null) {
final PageContext pageContext = action.pageContext();
final Action activityHomeAction = pageContext.createAction(action.definition.activityAlias);
final PageAction activityHomeAction = pageContext.createAction(action.definition.activityAlias);
action.pageContext.firePageEvent(new ActionEvent(activityHomeAction, false));
return activityHomeAction;
}

View file

@ -16,7 +16,6 @@ import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
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.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
/** Holds a page-context and defines some convenient functionality for page handling */
@ -157,7 +156,7 @@ public interface PageContext {
* @param event the concrete PageEvent instance */
<T extends PageEvent> void firePageEvent(T event);
Action createAction(ActionDefinition actionDefinition);
PageAction createAction(ActionDefinition actionDefinition);
/** Apply a confirm dialog with a specified confirm message and a callback code
* block that will be executed on users OK selection.

View file

@ -8,16 +8,16 @@
package ch.ethz.seb.sebserver.gui.service.page.event;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
/** This Event is used to propagate a user-action to the GUI system.
* Potentially every component can listen to an Event and react on the user-action */
public final class ActionEvent implements PageEvent {
public final Action action;
public final PageAction action;
public final boolean activity;
public ActionEvent(final Action action, final boolean activity) {
public ActionEvent(final PageAction action, final boolean activity) {
super();
this.action = action;
this.activity = activity;

View file

@ -8,15 +8,15 @@
package ch.ethz.seb.sebserver.gui.service.page.event;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
/** This action is used to publish an Action to the Action-Pane for a specified context.
* The ActionPane is listening to this events and render specified actions on notify */
public class ActionPublishEvent implements PageEvent {
public final Action action;
public final PageAction action;
public ActionPublishEvent(final Action action) {
public ActionPublishEvent(final PageAction action) {
this.action = action;
}

View file

@ -91,7 +91,9 @@ public class ComposerServiceImpl implements ComposerService {
final Class<? extends TemplateComposer> composerType,
final PageContext pageContext) {
compose(composerType.getName(), pageContext);
if (composerType != null && pageContext != null) {
compose(composerType.getName(), pageContext);
}
}
@Override

View file

@ -15,13 +15,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gui.content.MainPage;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
public final class MainPageState {
private static final Logger log = LoggerFactory.getLogger(MainPageState.class);
public Action action = null;
public PageAction action = null;
private MainPageState() {
}

View file

@ -32,11 +32,11 @@ import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
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.page.PageAction;
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.PageDefinition;
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
import ch.ethz.seb.sebserver.gui.widget.Message;
@ -237,12 +237,18 @@ public class PageContextImpl implements PageContext {
listeners.stream()
.sorted(LIST_COMPARATOR)
.forEach(listener -> listener.notify(event));
.forEach(listener -> {
try {
listener.notify(event);
} catch (final Exception e) {
log.error("Unexpected error while notify PageEventListener: ", e);
}
});
}
@Override
public Action createAction(final ActionDefinition actionDefinition) {
return new Action(actionDefinition, this);
public PageAction createAction(final ActionDefinition actionDefinition) {
return new PageAction(actionDefinition, this);
}
@Override

View file

@ -12,7 +12,7 @@ import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType;
/** Interface to SEB Server webservice API thought RestCall's
@ -77,6 +77,6 @@ public interface RestService {
*
* @param action the Action that defines an entity activation
* @return the successfully executed Action */
<T> Action activation(Action action);
<T> PageAction activation(PageAction action);
}

View file

@ -21,8 +21,8 @@ import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
@ -114,7 +114,7 @@ public class RestServiceImpl implements RestService {
}
@Override
public <T> Action activation(final Action action) {
public <T> PageAction activation(final PageAction action) {
if (action.definition.restCallType == null) {
throw new IllegalArgumentException("ActionDefinition needs to define a restCallType to use this action");
}

View file

@ -16,6 +16,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.eclipse.swt.SWT;
@ -38,6 +39,7 @@ import ch.ethz.seb.sebserver.gbl.model.Page;
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.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
@ -77,7 +79,8 @@ public class EntityTable<ROW extends Entity> {
final List<ColumnDefinition<ROW>> columns,
final List<TableRowAction> actions,
final int pageSize,
final LocTextKey emptyMessage) {
final LocTextKey emptyMessage,
final Function<EntityTable<ROW>, PageAction> defaultActionFunction) {
this.composite = new Composite(parent, type);
this.widgetFactory = widgetFactory;
@ -124,6 +127,20 @@ public class EntityTable<ROW extends Entity> {
this.table.setHeaderVisible(true);
this.table.setLinesVisible(true);
if (defaultActionFunction != null) {
final PageAction defaultAction = defaultActionFunction.apply(this);
if (defaultAction != null) {
this.table.addListener(SWT.MouseDoubleClick, event -> {
final EntityKey selection = getSingleSelection();
if (selection != null) {
defaultAction
.withEntityKey(selection)
.run();
}
});
}
}
this.navigator = new TableNavigator(this);
createTableColumns();

View file

@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.table;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
@ -18,6 +19,7 @@ import org.eclipse.swt.widgets.Composite;
import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@ -43,7 +45,7 @@ public class TableBuilder<ROW extends Entity> {
final List<ColumnDefinition<ROW>> columns = new ArrayList<>();
final List<TableRowAction> actions = new ArrayList<>();
LocTextKey emptyMessage;
private Function<EntityTable<ROW>, PageAction> defaultActionFunction;
private int pageSize = -1;
private int type = SWT.NONE;
@ -90,6 +92,16 @@ public class TableBuilder<ROW extends Entity> {
return this;
}
public TableBuilder<ROW> withDefaultAction(final PageAction action) {
this.defaultActionFunction = table -> action;
return this;
}
public TableBuilder<ROW> withDefaultAction(final Function<EntityTable<ROW>, PageAction> defaultActionFunction) {
this.defaultActionFunction = defaultActionFunction;
return this;
}
public EntityTable<ROW> compose(final Composite parent) {
return new EntityTable<>(
this.type,
@ -99,7 +111,8 @@ public class TableBuilder<ROW extends Entity> {
this.columns,
this.actions,
this.pageSize,
this.emptyMessage);
this.emptyMessage,
this.defaultActionFunction);
}
}

View file

@ -127,9 +127,9 @@ public class ColorSelection extends Composite implements Selection {
return null;
}
return Integer.toHexString(color.red)
+ Integer.toHexString(color.green)
+ Integer.toHexString(color.blue);
return toColorFractionString(color.red)
+ toColorFractionString(color.green)
+ toColorFractionString(color.blue);
}
static RGB parseRGB(final String colorString) {
@ -144,4 +144,9 @@ public class ColorSelection extends Composite implements Selection {
return new RGB(r, g, b);
}
static String toColorFractionString(final int fraction) {
final String hexString = Integer.toHexString(fraction);
return (hexString.length() < 2) ? "0" + hexString : hexString;
}
}

View file

@ -116,7 +116,9 @@ public class WidgetFactory {
SELECTION_READONLY("selectionReadonly"),
FOOTER("footer"),
TITLE_LABEL("head")
TITLE_LABEL("head"),
MESSAGE("message")
;
@ -253,6 +255,10 @@ public class WidgetFactory {
return textInput(content, true);
}
public Text textAreaInput(final Composite content) {
return new Text(content, SWT.LEFT | SWT.BORDER | SWT.MULTI);
}
public Text textInput(final Composite content, final boolean password) {
return new Text(content, (password)
? SWT.LEFT | SWT.BORDER | SWT.PASSWORD
@ -326,6 +332,8 @@ public class WidgetFactory {
public Label labelSeparator(final Composite parent) {
final Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
final GridData data = new GridData(SWT.FILL, SWT.TOP, true, true);
label.setLayoutData(data);
return label;
}

View file

@ -14,6 +14,7 @@ sebserver.overall.action.filter=Apply Filter
sebserver.overall.action.filter.clear=Clear Filter Criteria
sebserver.overall.action.ok=OK
sebserver.overall.action.cancel=Cancel
sebserver.overall.action.close=Close
sebserver.overall.action.category.varia=Varia
@ -209,6 +210,15 @@ sebserver.quizdiscovery.info.pleaseSelect=Please Select a Quiz first
sebserver.quizdiscovery.action.list=Quiz Discovery
sebserver.quizdiscovery.action.import=Import as Exam
sebserver.quizdiscovery.action.details=Show Details
sebserver.quizdiscovery.quiz.details.title=Quiz Details
sebserver.quizdiscovery.quiz.details.lms=LMS
sebserver.quizdiscovery.quiz.details.name=Name
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
################################
# Exam