From 5ff5f2f026839f2d128f25d1ce48d1639c31351f Mon Sep 17 00:00:00 2001 From: uhensler <urs.hensler@frentix.com> Date: Tue, 6 Aug 2019 15:43:29 +0200 Subject: [PATCH] OO-4168: Course tool "E-mail" --- .../LearningResourceLoggingAction.java | 4 + .../org/olat/course/config/CourseConfig.java | 169 ++++-------------- .../olat/course/config/CourseConfigEvent.java | 5 +- .../config/ui/CourseToolbarController.java | 28 ++- .../ui/_i18n/LocalStrings_de.properties | 1 + .../ui/_i18n/LocalStrings_en.properties | 1 + .../course/nodes/co/COEditController.java | 21 +-- .../olat/course/nodes/co/CORunController.java | 11 +- .../course/nodes/co/COToolController.java | 147 +++++++++++++++ .../nodes/co/COToolRecipientsController.java | 124 +++++++++++++ .../olat/course/nodes/co/_content/tool.html | 2 + .../nodes/co/_i18n/LocalStrings_de.properties | 19 +- .../nodes/co/_i18n/LocalStrings_en.properties | 21 +-- .../ui/group/_i18n/LocalStrings_en.properties | 2 +- .../course/run/CourseRuntimeController.java | 45 ++++- .../run/_i18n/LocalStrings_de.properties | 1 + .../run/_i18n/LocalStrings_en.properties | 1 + .../java/org/olat/modules/co/ContactForm.java | 23 ++- .../modules/co/ContactFormController.java | 6 + .../RepositoryEntryManagedFlag.java | 1 + 20 files changed, 433 insertions(+), 199 deletions(-) create mode 100644 src/main/java/org/olat/course/nodes/co/COToolController.java create mode 100644 src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java create mode 100644 src/main/java/org/olat/course/nodes/co/_content/tool.html diff --git a/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java b/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java index 361b06045bf..ba5d8cbb3f3 100644 --- a/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java +++ b/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java @@ -103,6 +103,10 @@ public class LearningResourceLoggingAction extends BaseLoggingAction { new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.add, ActionObject.infomessage).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_PARTICIPANTINFO_DISABLED = new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.remove, ActionObject.infomessage).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); + public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_EMAIL_ENABLED = + new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.add, ActionObject.mail).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); + public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_EMAIL_DISABLED = + new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.remove, ActionObject.mail).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_GLOSSARY_ENABLED = new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.add, ActionObject.glossar).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_GLOSSARY_DISABLED = diff --git a/src/main/java/org/olat/course/config/CourseConfig.java b/src/main/java/org/olat/course/config/CourseConfig.java index b77f29092ce..9e059823e5a 100644 --- a/src/main/java/org/olat/course/config/CourseConfig.java +++ b/src/main/java/org/olat/course/config/CourseConfig.java @@ -73,25 +73,11 @@ public class CourseConfig implements Serializable, Cloneable { * current config file version */ private static final transient int CURRENTVERSION = 15; - /** - * Log levels - */ + public static final transient String KEY_LOGLEVEL_ADMIN = "LOGLEVELADMIN"; - /** - * Log levels - */ public static final transient String KEY_LOGLEVEL_USER = "LOGLEVELUSER"; - /** - * Log levels - */ public static final transient String KEY_LOGLEVEL_STATISTIC = "LOGLEVELSTAT"; - /** - * Chat enabled boolean - */ - public static final transient String KEY_CHAT_ENABLED = "COURSE_CHAT_ENABLED"; - /** - * efficency statement - */ + public static final transient String KEY_EFFICENCY_ENABLED = "KEY_EFFICENCY_ENABLED"; public static final transient String CERTIFICATE_AUTO_ENABLED = "CERTIFICATE_AUTO"; public static final transient String CERTIFICATE_MANUAL_ENABLED = "CERTIFICATE_MANUAL"; @@ -103,49 +89,24 @@ public class CourseConfig implements Serializable, Cloneable { public static final transient String RECERTIFICATION_TIMELAPSE = "RECERTIFICATION_TIMELAPSE"; public static final transient String RECERTIFICATION_TIMELAPSE_UNIT = "RECERTIFICATION_TIMELAPSE_UNIT"; - /** - * The menu is enabled by default - */ public static final transient String MENU_ENABLED = "MENU_ENABLED"; - /** - * The toolbar is enabled by default - */ public static final transient String TOOLBAR_ENABLED = "TOOLBAR_ENABLED"; - /** - * The bread crumb is enabled by default - */ public static final transient String BREADCRUMB_ENABLED = "BREADCRUMB_ENABLED"; - /** - * The course search is enabled by default - */ + public static final transient String COURSESEARCH_ENABLED = "COURSESEARCH_ENABLED"; + public static final transient String KEY_CHAT_ENABLED = "COURSE_CHAT_ENABLED"; public static final transient String PARTICIPANT_LIST_ENABLED = "PARTICIPANT_LIST_ENABLED"; public static final transient String PARTICIPANT_INFO_ENABLED = "PARTICIPANT_INFO_ENABLED"; - /** - * course calendar - */ + public static final transient String EMAIL_ENABLED = "EMAIL_ENABLED"; public static final transient String KEY_CALENDAR_ENABLED = "KEY_CALENDAR_ENABLED"; - /** - * course glossary in toolbar enabled - */ public static final transient String KEY_GLOSSARY_ENABLED = "KEY_GLOSSARY_ENABLED"; - /** - * course glossary - */ public static final transient String KEY_GLOSSARY_SOFTKEY = "KEY_GLOSSARY_SOFTKEY"; - /** - * - */ public static final transient String KEY_CSS_FILEREF = "CSS_FILEREF"; - /** - * - */ + public static final transient String KEY_SHAREDFOLDER_SOFTKEY = "SHAREDFOLDER_SOFTKEY"; - /** - * - */ public static final transient String KEY_SHAREDFOLDER_READONLY = "SHAREDFOLDER_RO"; + /** * current key set */ @@ -158,18 +119,22 @@ public class CourseConfig implements Serializable, Cloneable { * holds the configuration */ private Map<String,Object> configuration = new Hashtable<>(); - + public CourseConfig() { - // empty, for XSTream + // empty, for XSTream } - + /** * @return version of this loaded/created instance */ public int getVersion() { return version; } - + + public void setVersion(int version) { + this.version = version; + } + /** * initialize with default values */ @@ -192,13 +157,13 @@ public class CourseConfig implements Serializable, Cloneable { configuration.remove(KEY_LOGLEVEL_USER); configuration.remove(KEY_LOGLEVEL_STATISTIC); - configuration.put(MENU_ENABLED, Boolean.TRUE); configuration.put(TOOLBAR_ENABLED, Boolean.TRUE); configuration.put(COURSESEARCH_ENABLED, Boolean.TRUE); configuration.put(PARTICIPANT_LIST_ENABLED, Boolean.FALSE); configuration.put(PARTICIPANT_INFO_ENABLED, Boolean.FALSE); + configuration.put(EMAIL_ENABLED, Boolean.FALSE); this.version = CURRENTVERSION; } @@ -217,47 +182,41 @@ public class CourseConfig implements Serializable, Cloneable { public boolean resolveVersionIssues() { boolean versionChanged = false; if (version < CURRENTVERSION) { - // from version 1 -> 2 if (version == 1) { this.version = 2; } - // from version 2 -> 3 + if (version == 2) { - // add the new key if (!configuration.containsKey(KEY_CHAT_ENABLED)) configuration.put(KEY_CHAT_ENABLED, Boolean.TRUE); this.version = 3; } - // from version 3 -> 4 + if (version == 3) { - // add the new key if (!configuration.containsKey(KEY_CSS_FILEREF)) configuration.put(KEY_CSS_FILEREF, VALUE_EMPTY_CSS_FILEREF); this.version = 4; } - // from version 4 -> 5 + if (version == 4) { - // add the new key if (!configuration.containsKey(KEY_SHAREDFOLDER_SOFTKEY)) configuration.put(KEY_SHAREDFOLDER_SOFTKEY, VALUE_EMPTY_SHAREDFOLDER_SOFTKEY); this.version = 5; } - // from version 5 -> 6 + if (version == 5) { - // add the new key if (!configuration.containsKey(KEY_EFFICENCY_ENABLED)) configuration.put(KEY_EFFICENCY_ENABLED, Boolean.FALSE); this.version = 6; } - // from version 6 -> 7 + if (version == 6) { - // add the new key if (!configuration.containsKey(KEY_CALENDAR_ENABLED)) configuration.put(KEY_CALENDAR_ENABLED, Boolean.TRUE); this.version = 7; } - // from version 7 -> 8 + if (version == 7) { // glossary configuration has been added. no default values needed this.version = 8; } - // from version 8 -> 9 + if (version == 8) { if (configuration.containsKey(KEY_LOGLEVEL_ADMIN)) configuration.remove(KEY_LOGLEVEL_ADMIN); if (configuration.containsKey(KEY_LOGLEVEL_USER)) configuration.remove(KEY_LOGLEVEL_USER); @@ -284,7 +243,7 @@ public class CourseConfig implements Serializable, Cloneable { if (!configuration.containsKey(COURSESEARCH_ENABLED)) configuration.put(COURSESEARCH_ENABLED, Boolean.FALSE); this.version = 12; } - + if (version == 12) { if (!configuration.containsKey(BREADCRUMB_ENABLED)) configuration.put(BREADCRUMB_ENABLED, Boolean.TRUE); this.version = 13; @@ -301,6 +260,7 @@ public class CourseConfig implements Serializable, Cloneable { if (version == 14) { if (!configuration.containsKey(PARTICIPANT_LIST_ENABLED)) configuration.put(PARTICIPANT_LIST_ENABLED, Boolean.FALSE); if (!configuration.containsKey(PARTICIPANT_INFO_ENABLED)) configuration.put(PARTICIPANT_INFO_ENABLED, Boolean.FALSE); + if (!configuration.containsKey(EMAIL_ENABLED)) configuration.put(EMAIL_ENABLED, Boolean.FALSE); this.version = 15; } @@ -335,37 +295,24 @@ public class CourseConfig implements Serializable, Cloneable { return versionChanged; } - /** - * @return if chat is enabled - */ public boolean isChatEnabled() { Boolean bool = (Boolean) configuration.get(KEY_CHAT_ENABLED); return bool != null && bool.booleanValue(); } - /** - * @param b - */ public void setChatIsEnabled(boolean b) { configuration.put(KEY_CHAT_ENABLED, Boolean.valueOf(b)); } - /** - * @return if chat is enabled - */ public boolean isGlossaryEnabled() { Boolean bool = (Boolean) configuration.get(KEY_GLOSSARY_ENABLED); return bool != null && bool.booleanValue(); } - /** - * @param b - */ public void setGlossaryIsEnabled(boolean b) { configuration.put(KEY_GLOSSARY_ENABLED, Boolean.valueOf(b)); } - /** * set the course layout by adding a reference to a css file, or disabling * custom layout by adding the empty css fileref @@ -407,23 +354,14 @@ public class CourseConfig implements Serializable, Cloneable { return (String) configuration.get(KEY_GLOSSARY_SOFTKEY); } - /** - * @return boolean - */ public boolean hasGlossary() { return (getGlossarySoftKey() != null); } - /** - * @return boolean - */ public boolean hasCustomCourseCSS() { return !(VALUE_EMPTY_CSS_FILEREF.equals(getCssLayoutRef())); } - /** - * @param softkey - */ public void setSharedFolderSoftkey(String softkey) { if(softkey == null) { configuration.put(KEY_SHAREDFOLDER_SOFTKEY, VALUE_EMPTY_SHAREDFOLDER_SOFTKEY); @@ -432,16 +370,10 @@ public class CourseConfig implements Serializable, Cloneable { } } - /** - * @return softkey - */ public String getSharedFolderSoftkey() { return (String) configuration.get(KEY_SHAREDFOLDER_SOFTKEY); } - /** - * @return boolean - */ public boolean hasCustomSharedFolder() { return !(VALUE_EMPTY_SHAREDFOLDER_SOFTKEY.equals(getSharedFolderSoftkey())); } @@ -455,25 +387,15 @@ public class CourseConfig implements Serializable, Cloneable { configuration.put(KEY_SHAREDFOLDER_READONLY, Boolean.valueOf(mount)); } - /** - * @param b - */ public void setEfficencyStatementIsEnabled(boolean b) { configuration.put(KEY_EFFICENCY_ENABLED, Boolean.valueOf(b)); } - /** - * @return true if the efficency statement is enabled - */ public boolean isEfficencyStatementEnabled() { Boolean bool = (Boolean) configuration.get(KEY_EFFICENCY_ENABLED); return bool.booleanValue(); } - - /** - * @return true if the efficency statement is enabled - */ public Long getCertificateTemplate() { Object templateIdObj = configuration.get(CERTIFICATE_TEMPLATE); Long templateId = null; @@ -519,9 +441,6 @@ public class CourseConfig implements Serializable, Cloneable { } } - /** - * @param b - */ public void setCertificateTemplate(Long templateId ) { if(templateId != null) { configuration.put(CERTIFICATE_TEMPLATE, templateId); @@ -552,17 +471,11 @@ public class CourseConfig implements Serializable, Cloneable { configuration.put(CERTIFICATE_MANUAL_ENABLED, Boolean.valueOf(enabled)); } - /** - * @return true if the efficency statement is enabled - */ public boolean isRecertificationEnabled() { Boolean bool = (Boolean) configuration.get(RECERTIFICATION_ENABLED); return bool != null && bool.booleanValue(); } - /** - * @param b - */ public void setRecertificationEnabled(boolean b) { configuration.put(RECERTIFICATION_ENABLED, Boolean.valueOf(b)); } @@ -596,17 +509,11 @@ public class CourseConfig implements Serializable, Cloneable { } } - /** - * @return true if calendar is enabled - */ public boolean isCalendarEnabled() { Boolean bool = (Boolean) configuration.get(KEY_CALENDAR_ENABLED); return bool != null && bool.booleanValue(); } - /** - * @param b - */ public void setCalendarEnabled(boolean b) { configuration.put(KEY_CALENDAR_ENABLED, Boolean.valueOf(b)); } @@ -647,6 +554,15 @@ public class CourseConfig implements Serializable, Cloneable { configuration.put(PARTICIPANT_INFO_ENABLED, Boolean.valueOf(b)); } + public boolean isEmailEnabled() { + Boolean bool = (Boolean) configuration.get(EMAIL_ENABLED); + return bool.booleanValue(); + } + + public void setEmailEnabled(boolean b) { + configuration.put(EMAIL_ENABLED, Boolean.valueOf(b)); + } + public boolean isToolbarEnabled() { Boolean bool = (Boolean) configuration.get(TOOLBAR_ENABLED); return bool.booleanValue(); @@ -665,11 +581,6 @@ public class CourseConfig implements Serializable, Cloneable { configuration.put(BREADCRUMB_ENABLED, Boolean.valueOf(b)); } - /** - * Creates a deep clone for the current object. - * - * @see java.lang.Object#clone() - */ @Override public CourseConfig clone() { CourseConfig clone = new CourseConfig(); @@ -696,13 +607,10 @@ public class CourseConfig implements Serializable, Cloneable { clone.setCourseSearchEnabled(isCourseSearchEnabled()); clone.setParticipantListEnabled(isParticipantListEnabled()); clone.setParticipantInfoEnabled(isParticipantInfoEnabled()); + clone.setEmailEnabled(isEmailEnabled()); return clone; } - /** - * - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(Object obj) { if(obj == this) { @@ -735,11 +643,4 @@ public class CourseConfig implements Serializable, Cloneable { return false; } - /** - * @param version The version to set. - */ - public void setVersion(int version) { - this.version = version; - } - } diff --git a/src/main/java/org/olat/course/config/CourseConfigEvent.java b/src/main/java/org/olat/course/config/CourseConfigEvent.java index ee23318ddf4..9265caad496 100644 --- a/src/main/java/org/olat/course/config/CourseConfigEvent.java +++ b/src/main/java/org/olat/course/config/CourseConfigEvent.java @@ -58,10 +58,11 @@ public class CourseConfigEvent extends MultiUserEvent { public enum CourseConfigType { efficiencyStatement, + search, + calendar, participantList, participantInfo, - calendar, - search, + email, chat, glossary, layout diff --git a/src/main/java/org/olat/course/config/ui/CourseToolbarController.java b/src/main/java/org/olat/course/config/ui/CourseToolbarController.java index c431586758f..2e7b52cc514 100644 --- a/src/main/java/org/olat/course/config/ui/CourseToolbarController.java +++ b/src/main/java/org/olat/course/config/ui/CourseToolbarController.java @@ -72,6 +72,7 @@ public class CourseToolbarController extends FormBasicController { private SelectionElement calendarEl; private SelectionElement participantListEl; private SelectionElement participantInfoEl; + private SelectionElement emailEl; private SelectionElement chatEl; private SelectionElement glossaryEl; @@ -170,6 +171,15 @@ public class CourseToolbarController extends FormBasicController { canHideToolbar &= false; } + boolean emailEnabled = courseConfig.isEmailEnabled(); + boolean managedEmail = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.email); + emailEl = uifactory.addCheckboxesHorizontal("emailIsOn", "chkbx.email.onoff", formLayout, onKeys, onValues); + emailEl.select(onKeys[0], emailEnabled); + emailEl.setEnabled(editable && !managedEmail); + if(managedEmail && emailEnabled) { + canHideToolbar &= false; + } + boolean chatEnabled = courseConfig.isChatEnabled(); boolean managedChat = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.chat); chatEl = uifactory.addCheckboxesHorizontal("chatIsOn", "chkbx.chat.onoff", formLayout, onKeys, onValues); @@ -216,6 +226,7 @@ public class CourseToolbarController extends FormBasicController { || (calendarEl != null && calendarEl.isSelected(0)) || participantListEl.isSelected(0) || participantInfoEl.isSelected(0) + || emailEl.isSelected(0) || chatEl.isSelected(0) || glossaryEl.isSelected(0); } @@ -229,6 +240,7 @@ public class CourseToolbarController extends FormBasicController { } participantListEl.setVisible(enabled); participantInfoEl.setVisible(enabled); + emailEl.setVisible(enabled); chatEl.setVisible(enabled); glossaryEl.setVisible(enabled); } @@ -258,6 +270,10 @@ public class CourseToolbarController extends FormBasicController { boolean updateParticipantInfo = courseConfig.isParticipantInfoEnabled() != enableParticipantInfo; courseConfig.setParticipantInfoEnabled(enableParticipantInfo && toolbarEnabled); + boolean enableEmail = emailEl.isSelected(0); + boolean updateEmail = courseConfig.isEmailEnabled() != enableEmail; + courseConfig.setEmailEnabled(enableEmail && toolbarEnabled); + boolean enableChat = chatEl.isSelected(0); boolean updateChat = courseConfig.isChatEnabled() != enableChat; courseConfig.setChatIsEnabled(enableChat && toolbarEnabled); @@ -300,7 +316,7 @@ public class CourseToolbarController extends FormBasicController { CoordinatorManager.getInstance().getCoordinator().getEventBus() .fireEventToListenersOf(new CourseConfigEvent(CourseConfigType.participantList, course.getResourceableId()), course); } - + if(updateParticipantInfo) { ILoggingAction loggingAction = enableParticipantInfo ? LearningResourceLoggingAction.REPOSITORY_ENTRY_PROPERTIES_PARTICIPANTINFO_ENABLED: @@ -311,6 +327,16 @@ public class CourseToolbarController extends FormBasicController { .fireEventToListenersOf(new CourseConfigEvent(CourseConfigType.participantInfo, course.getResourceableId()), course); } + if(updateEmail) { + ILoggingAction loggingAction = enableEmail ? + LearningResourceLoggingAction.REPOSITORY_ENTRY_PROPERTIES_EMAIL_ENABLED: + LearningResourceLoggingAction.REPOSITORY_ENTRY_PROPERTIES_EMAIL_DISABLED; + ThreadLocalUserActivityLogger.log(loggingAction, getClass()); + + CoordinatorManager.getInstance().getCoordinator().getEventBus() + .fireEventToListenersOf(new CourseConfigEvent(CourseConfigType.email, course.getResourceableId()), course); + } + if(updateChat) { ILoggingAction loggingAction =enableChat ? LearningResourceLoggingAction.REPOSITORY_ENTRY_PROPERTIES_IM_ENABLED: diff --git a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties index b5b1594ea8f..c69e1b4036d 100644 --- a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties @@ -2,6 +2,7 @@ chkbx.calendar.onoff=Kurskalender chkbx.chat.onoff=Kurs-Chat chkbx.efficency.onoff=Leistungsnachweis verwenden +chkbx.email.onoff=E-Mail chkbx.glossary.explain=Das Glossar muss unter "Optionen" konfiguriert werden. chkbx.glossary.inverse.explain=Glossar Menu in Toolbar muss unter "Toolbar" konfiguriert werden. chkbx.glossary.onoff=Glossar diff --git a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties index 64e7109a265..6007cec9805 100644 --- a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties @@ -2,6 +2,7 @@ chkbx.calendar.onoff=Course calendar chkbx.chat.onoff=Course chat chkbx.search.onoff=Course search +chkbx.email.onoff=E-mail chkbx.efficency.onoff=Use evidence of achievement chkbx.glossary.explain=The glossary need to be configured under "Options". chkbx.glossary.inverse.explain=Glossary menu in toolbar is configured under "Toolbar". diff --git a/src/main/java/org/olat/course/nodes/co/COEditController.java b/src/main/java/org/olat/course/nodes/co/COEditController.java index 4dd90c7845b..21fbd8146a2 100755 --- a/src/main/java/org/olat/course/nodes/co/COEditController.java +++ b/src/main/java/org/olat/course/nodes/co/COEditController.java @@ -128,18 +128,11 @@ public class COEditController extends ActivateableTabbableDefaultController impl listenTo(accessibilityCondContr); } - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) - */ + @Override public void event(UserRequest ureq, Component source, Event event) { // } - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event) - */ @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == accessibilityCondContr) { @@ -156,9 +149,7 @@ public class COEditController extends ActivateableTabbableDefaultController impl } } - /** - * @see org.olat.core.gui.control.generic.tabbable.TabbableDefaultController#addTabs(org.olat.core.gui.components.TabbedPane) - */ + @Override public void addTabs(TabbedPane tabbedPane) { myTabbedPane = tabbedPane; @@ -166,17 +157,17 @@ public class COEditController extends ActivateableTabbableDefaultController impl tabbedPane.addTab(translate(PANE_TAB_COCONFIG), myContent); } - /** - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ + @Override protected void doDispose() { - //nothing to do + // } + @Override public String[] getPaneKeys() { return paneKeys; } + @Override public TabbedPane getTabbedPane() { return myTabbedPane; } diff --git a/src/main/java/org/olat/course/nodes/co/CORunController.java b/src/main/java/org/olat/course/nodes/co/CORunController.java index 08555c64a13..ea211ba4b69 100755 --- a/src/main/java/org/olat/course/nodes/co/CORunController.java +++ b/src/main/java/org/olat/course/nodes/co/CORunController.java @@ -300,17 +300,12 @@ public class CORunController extends BasicController { return cl; } - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * @see org.olat.core.gui.components.Component, @see org.olat.core.gui.control.Event) - */ + @Override public void event(UserRequest ureq, Component source, Event event) { - // no components to listen to + // } - /** - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ + @Override protected void doDispose() { // } diff --git a/src/main/java/org/olat/course/nodes/co/COToolController.java b/src/main/java/org/olat/course/nodes/co/COToolController.java new file mode 100644 index 00000000000..60784427c9e --- /dev/null +++ b/src/main/java/org/olat/course/nodes/co/COToolController.java @@ -0,0 +1,147 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.nodes.co; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.id.Identity; +import org.olat.core.util.mail.ContactList; +import org.olat.core.util.mail.ContactMessage; +import org.olat.course.groupsandrights.CourseGroupManager; +import org.olat.course.nodes.co.COToolRecipientsController.Recipients; +import org.olat.course.nodes.members.MembersHelpers; +import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.modules.co.ContactFormController; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 6 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class COToolController extends BasicController { + + private final ContactFormController emailCtrl; + private final COToolRecipientsController recipientCtrl; + + private final RepositoryEntry courseRepositoryEntry; + private final CourseGroupManager courseGroupManager; + + @Autowired + private RepositoryService repositoryService; + + public COToolController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv) { + super(ureq, wControl); + courseGroupManager = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); + this.courseRepositoryEntry = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); + + VelocityContainer mainVC = createVelocityContainer("tool"); + + recipientCtrl = new COToolRecipientsController(ureq, wControl); + listenTo(recipientCtrl); + mainVC.put("recipients", recipientCtrl.getInitialComponent()); + + ContactMessage cmsg = new ContactMessage(getIdentity()); + Set<Recipients> recipients = recipientCtrl.getSelectedRecipients(); + for (ContactList recipientList : getRecipientsLists(recipients)) { + cmsg.addEmailTo(recipientList); + } + emailCtrl = new ContactFormController(ureq, getWindowControl(), false, false, false, cmsg, null); + emailCtrl.setContactFormTitle(null); + listenTo(emailCtrl); + mainVC.put("email", emailCtrl.getInitialComponent()); + + putInitialPanel(mainVC); + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if (source == recipientCtrl && event == FormEvent.CHANGED_EVENT) { + Set<Recipients> recipients = recipientCtrl.getSelectedRecipients(); + doSetReciepients(recipients); + } + super.event(ureq, source, event); + } + + private void doSetReciepients(Set<Recipients> recipients) { + List<ContactList> contactLists = getRecipientsLists(recipients); + emailCtrl.setRecipientsLists(contactLists); + } + + private List<ContactList> getRecipientsLists(Set<Recipients> recipients) { + List<ContactList> contactLists = new ArrayList<>(); + if (recipients.contains(Recipients.participants)) { + contactLists.add(getParticipantsContactList()); + } + if (recipients.contains(Recipients.coaches)) { + contactLists.add(getCoachesContactList()); + } + if (recipients.contains(Recipients.owners)) { + contactLists.add(getOwnersContactList()); + } + return contactLists; + } + + private ContactList getOwnersContactList() { + ContactList cl = new ContactList(translate("form.message.chckbx.owners")); + List<Identity> identities = MembersHelpers.getOwners(repositoryService, courseRepositoryEntry); + cl.addAllIdentites(identities); + return cl; + } + + private ContactList getCoachesContactList() { + ContactList cl = new ContactList(translate("form.message.chckbx.coaches")); + Collection<Identity> identities = courseGroupManager.getCoaches(); + cl.addAllIdentites(identities); + return cl; + } + + private ContactList getParticipantsContactList() { + ContactList cl = new ContactList(translate("form.message.chckbx.partips")); + Collection<Identity> identities = courseGroupManager.getParticipants(); + cl.addAllIdentites(identities); + return cl; + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // + } + + @Override + protected void doDispose() { + // + } + +} diff --git a/src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java b/src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java new file mode 100644 index 00000000000..469f1be5299 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/co/COToolRecipientsController.java @@ -0,0 +1,124 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.nodes.co; + +import static org.olat.core.gui.components.util.KeyValues.entry; + +import java.util.HashSet; +import java.util.Set; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.util.KeyValues; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; + +/** + * + * Initial date: 6 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class COToolRecipientsController extends FormBasicController { + + public enum Recipients { + owners("tool.recipients.owners"), + coaches("tool.recipients.coaches"), + participants("tool.recipients.participants"); + + private final String i18nKey; + + private Recipients(String i18nKey) { + this.i18nKey = i18nKey; + + } + + public String getI18nKey() { + return i18nKey; + } + } + + private MultipleSelectionElement recipientsEl; + + public COToolRecipientsController(UserRequest ureq, WindowControl wControl) { + super(ureq, wControl); + initForm(ureq); + } + + public Set<Recipients> getSelectedRecipients() { + Set<Recipients> recipients = new HashSet<>(); + for (String key : recipientsEl.getSelectedKeys()) { + recipients.add(Recipients.valueOf(key)); + } + return recipients; + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + setFormTitle("tool.title"); + + KeyValues recipientKV = new KeyValues(); + for (Recipients recipient : Recipients.values()) { + recipientKV.add(entry(recipient.name(), translate(recipient.getI18nKey()))); + } + recipientsEl = uifactory.addCheckboxesHorizontal("tool.recipients", formLayout, recipientKV.keys(), recipientKV.values()); + recipientsEl.select(Recipients.owners.name(), true); + recipientsEl.addActionListener(FormEvent.ONCHANGE); + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if (source == recipientsEl) { + boolean valid = validateFormLogic(ureq); + if (valid) { + fireEvent(ureq, FormEvent.CHANGED_EVENT); + } + } + super.formInnerEvent(ureq, source, event); + } + + @Override + protected boolean validateFormLogic(UserRequest ureq) { + boolean allOk = true; + + recipientsEl.clearError(); + if (!recipientsEl.isAtLeastSelected(1)) { + recipientsEl.setErrorKey("tool.recipients.mandatory", null); + allOk = false; + } + + return allOk & super.validateFormLogic(ureq); + } + + @Override + protected void formOK(UserRequest ureq) { + // + } + + @Override + protected void doDispose() { + // + } + +} diff --git a/src/main/java/org/olat/course/nodes/co/_content/tool.html b/src/main/java/org/olat/course/nodes/co/_content/tool.html new file mode 100644 index 00000000000..1d2b31ec095 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/co/_content/tool.html @@ -0,0 +1,2 @@ +$r.render("recipients") +$r.render("email") \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties index 0146dbdfad2..c19bc69bff1 100755 --- a/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_de.properties @@ -1,14 +1,4 @@ #Mon Mar 02 09:54:04 CET 2009 - - - - - - - - - - groupCoachesChoose=Gruppe ausw\u00E4hlen groupParticipantsChoose=Gruppe ausw\u00E4hlen groupCreate=Gruppe erstellen @@ -22,7 +12,7 @@ error.norecipients.long=Es sind keine Empf\u00E4nger f\u00FCr {0} definiert. Die error.norecipients.short=Empf\u00E4nger f\u00FCr {0} fehlen. error.notfound.name=Der angegebene Name ({1}) wurde im Gruppenmanagement dieses Kurses nicht gefunden. error.notfound.names=Die angegebenen Namen ({1}) wurden im Gruppenmanagement dieses Kurses nicht gefunden. -error.no.choice.specified=W\u00e4hlen Sie mindestens +error.no.choice.specified=W\u00E4hlen Sie mindestens error.no.group.specified=W\u00E4hlen Sie eine Gruppe/Lernbereich form.areanames.wrong=Geben Sie Namen von Lernbereichen getrennt mit Kommas ein oder lassen Sie dieses Feld leer. form.choose.coachesandpartips=Sie m\u00FCssen Teilnehmer oder Betreuer ausw\u00E4hlen @@ -42,7 +32,6 @@ form.message.participants.group=Nur Teilnehmer aus den Gruppen form.message.participants.course=Nur Teilnehmer aus dem Kurs form.noGroupsOrAreas=Es muss mindestens eine Lerngruppe oder ein Lernbereich angegeben werden header=Empf\u00E4nger - message.body=Nachricht (Vorlage) message.emailtoadresses=E-Mailadressen message.subject=Betreff (Vorlage) @@ -57,3 +46,9 @@ pane.tab.coconfig=Empf\u00E4nger popupchooseareas=Lernbereiche aus Gruppenmanagement w\u00E4hlen popupchoosegroups=Gruppen aus Gruppenmanagement w\u00E4hlen recipients=Externe Empf\u00E4nger +tool.recipients=Empf\u00E4nger +tool.recipients.coaches=Betreuer +tool.recipients.participants=Kursbesitzer +tool.recipients.mandatory=Sie m\u00FCssen mindestens eine Option ausw\u00E4hlen. +tool.recipients.owners=Teilnehmer +tool.title=E-Mail diff --git a/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_en.properties index 5d1937ef10f..e1f012deee4 100755 --- a/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/co/_i18n/LocalStrings_en.properties @@ -1,14 +1,4 @@ #Sun Aug 15 18:44:08 CEST 2010 - - - - - - - - - - groupCoachesChoose=Select group groupParticipantsChoose=Select group groupCreate=Create group @@ -28,7 +18,7 @@ form.areanames.wrong=Please indicate titles of learning areas separated by comma form.choose.coachesandpartips=You have to select some participants or tutors form.groupnames.wrong=Please indicate titles of learning groups separated by commas or leave this box blank. form.message.area=Selected areas -form.message.chckbx.coaches=Tutors of selected learning groups +form.message.chckbx.coaches=Coaches of selected learning groups form.message.chckbx.partips=Participants of selected learning groups form.message.chckbx.owners=Course owners form.message.example.area=(Example\: Gr_1, Gr_2) @@ -42,7 +32,6 @@ form.message.participants.group=Only group participants form.message.participants.course=Only course participants form.noGroupsOrAreas=At least one learning group or learning area has to be indicated header=Recipient - message.body=Message (template) message.emailtoadresses=E-mail addresses message.subject=Subject (template) @@ -56,4 +45,10 @@ pane.tab.accessibility=Access pane.tab.coconfig=Recipient popupchooseareas=Select learning areas from group management popupchoosegroups=Select groups from group management -recipients=External recipients \ No newline at end of file +recipients=External recipients +tool.recipients=Recipients +tool.recipients.coaches=Coaches +tool.recipients.participants=Participants +tool.recipients.mandatory=You have to select at least one option. +tool.recipients.owners=Owners +tool.title=E-mail \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/members/ui/group/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/members/ui/group/_i18n/LocalStrings_en.properties index bd8c02edb9b..7b09e5babe7 100755 --- a/src/main/java/org/olat/course/nodes/members/ui/group/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/members/ui/group/_i18n/LocalStrings_en.properties @@ -31,7 +31,7 @@ form.areanames.wrong=Please indicate titles of learning areas separated by comma form.choose.coachesandpartips=You have to select some participants or tutors form.groupnames.wrong=Please indicate titles of learning groups separated by commas or leave this box blank. form.message.area=Selected areas -form.message.chckbx.coaches=Tutors of selected learning groups +form.message.chckbx.coaches=Coaches of selected learning groups form.message.chckbx.partips=Participants of selected learning groups form.message.chckbx.owners=Course owners form.message.curriculum.element=Curriculum diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java index 78cf9ca6e08..f54966a1a0a 100644 --- a/src/main/java/org/olat/course/run/CourseRuntimeController.java +++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java @@ -103,6 +103,7 @@ import org.olat.course.groupsandrights.CourseRights; import org.olat.course.member.MembersManagementMainController; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.ENCourseNode; +import org.olat.course.nodes.co.COToolController; import org.olat.course.nodes.info.InfoRunController; import org.olat.course.nodes.members.MembersToolRunController; import org.olat.course.reminder.ui.CourseRemindersController; @@ -174,25 +175,26 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im assessmentModeLink, lifeCycleChangeLink, //my course efficiencyStatementsLink, calendarLink, noteLink, chatLink, leaveLink, searchLink, - participantListLink, participantInfoLink, + participantListLink, participantInfoLink, emailLink, //glossary openGlossaryLink, enableGlossaryLink, lecturesLink; private Link currentUserCountLink; private Dropdown myCourse, glossary; private CloseableModalController cmc; + private COToolController emailCtrl; private CourseAreasController areasCtrl; private ConfirmLeaveController leaveDialogBox; private ArchiverMainController archiverCtrl; private CustomDBMainController databasesCtrl; private FolderRunController courseFolderCtrl; - private MembersToolRunController participatListCtrl; private InfoRunController participatInfoCtrl; private SearchInputController searchController; private StatisticMainController statisticsCtrl; private CourseRemindersController remindersCtrl; private TeacherOverviewController lecturesCtrl; private AssessmentToolController assessmentToolCtr; + private MembersToolRunController participatListCtrl; private MembersManagementMainController membersCtrl; private StatisticCourseNodesController statsToolCtr; private AssessmentModeListController assessmentModeCtrl; @@ -807,13 +809,19 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im participantListLink.setVisible(cc.isParticipantListEnabled()); toolbarPanel.addTool(participantListLink); } - + if(!assessmentLock) { participantInfoLink = LinkFactory.createToolLink("participantinfo", translate("command.participant.info"), this, "o_infomsg_icon"); participantInfoLink.setVisible(cc.isParticipantInfoEnabled()); toolbarPanel.addTool(participantInfoLink); } + if(!assessmentLock) { + emailLink = LinkFactory.createToolLink("email", translate("command.email"), this, "o_co_icon"); + emailLink.setVisible(cc.isEmailEnabled()); + toolbarPanel.addTool(emailLink); + } + if(!assessmentLock) { glossary = new Dropdown("glossary", "command.glossary", false, getTranslator()); glossary.setIconCSS("o_icon o_FileResource-GLOSSARY_icon"); @@ -944,6 +952,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im doParticipantList(ureq); } else if(participantInfoLink == source) { doParticipantInfo(ureq); + } else if(emailLink == source) { + doEmail(ureq); } else if(calendarLink == source) { launchCalendar(ureq); } else if(chatLink == source) { @@ -1047,6 +1057,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im case pop: popToRoot(ureq); cleanUp(); break; case participantList: doParticipantList(ureq); break; case participantInfo: doParticipantInfo(ureq); break; + case email: doEmail(ureq); break; } delayedClose = null; } else { @@ -1692,6 +1703,22 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im }; } + private void doEmail(UserRequest ureq) { + if(delayedClose == Delayed.email || requestForClose(ureq)) { + removeCustomCSS(); + + OLATResourceable ores = OresHelper.createOLATResourceableType("email"); + WindowControl swControl = addToHistory(ureq, ores, null); + emailCtrl = new COToolController(ureq, swControl, getUserCourseEnvironment()); + + pushController(ureq, translate("command.email"), emailCtrl); + setActiveTool(emailLink); + currentToolCtr = emailCtrl; + } else { + delayedClose = Delayed.email; + }; + } + private void launchCalendar(UserRequest ureq) { ControllerCreator ctrlCreator = (lureq, lwControl) -> { ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); @@ -1835,6 +1862,15 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im } break; } + case email: { + if(emailLink != null) { + ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); + CourseConfig cc = course.getCourseEnvironment().getCourseConfig(); + emailLink.setVisible(cc.isEmailEnabled()); + toolbarPanel.setDirty(true); + } + break; + } case chat: { if(chatLink != null) { ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); @@ -1973,6 +2009,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im close, pop, participantList, - participantInfo + participantInfo, + email } } \ No newline at end of file diff --git a/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties index 22e96227320..fa932ad6d66 100644 --- a/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties @@ -13,6 +13,7 @@ command.courseconfig=Kursinfo command.coursefolder=Ablageordner command.coursesearch=Kurssuche command.efficiencystatement=Leistungsnachweis +command.email=E-Mail command.glossary=Glossar command.glossary.open=Glossar in separatem Fenster \u00F6ffnen command.glossary.off=aus diff --git a/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties index d062cae4275..bbb9249bc7e 100644 --- a/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties @@ -13,6 +13,7 @@ command.courseconfig=Course info command.coursefolder=Storage folder command.coursesearch=Course search command.efficiencystatement=Evidence of achievement +command.email=E-Mail command.glossary=Glossary command.glossary.off=off command.glossary.off.alt=Hide glossary terms of learning content diff --git a/src/main/java/org/olat/modules/co/ContactForm.java b/src/main/java/org/olat/modules/co/ContactForm.java index 0a3305e72e9..1bbd87a17d9 100644 --- a/src/main/java/org/olat/modules/co/ContactForm.java +++ b/src/main/java/org/olat/modules/co/ContactForm.java @@ -100,7 +100,7 @@ public class ContactForm extends FormBasicController { private FileElement attachmentEl; private List<FormLink> attachmentLinks = new ArrayList<>(); private FormLayoutContainer uploadCont; - private boolean recipientsAreEditable = false; + private final boolean recipientsAreEditable; private static final int emailCols = 60; private boolean readOnly=false; private boolean hasMsgCancel=false; @@ -146,6 +146,15 @@ public class ContactForm extends FormBasicController { tsubject.setMandatory(tsubject.isEnabled()); } + public void setRecipientsLists(List<ContactList> recipientsLists) { + contactLists.clear(); + tto.setValue(""); + ttoBig.setValue(""); + for (ContactList contactList : recipientsLists) { + addEmailTo(contactList); + } + } + /** * add a ContactList as EmailTo: * @@ -171,9 +180,6 @@ public class ContactForm extends FormBasicController { defaultEmailTo += tto.getValue(); tto.setValue(defaultEmailTo); ttoBig.setValue(defaultEmailTo); - - tto.setVisible(!recipientsAreEditable); - ttoBig.setVisible(recipientsAreEditable); } public void setBody(String defaultBody) { @@ -371,18 +377,17 @@ public class ContactForm extends FormBasicController { fullName = "[" + fullName + "]"; } tfrom = uifactory.addTextElement("ttfrom", NLS_CONTACT_FROM, 255, fullName, formLayout); - tfrom.setElementCssClass("o_sel_contact_to"); + tfrom.setElementCssClass("o_sel_contact_from"); // When no identity is set, let user enter a valid email address tfrom.setEnabled((this.emailFrom == null)); tto = uifactory.addTextElement("tto", NLS_CONTACT_TO, 255, "", formLayout); tto.setElementCssClass("o_sel_contact_to"); tto.setEnabled(false); - tto.setVisible(false); + tto.setVisible(!recipientsAreEditable); ttoBig = uifactory.addTextAreaElement("ttoBig", NLS_CONTACT_TO, -1, 2, emailCols, true, false, "", formLayout); - ttoBig.setEnabled(false); - ttoBig.setVisible(false); + ttoBig.setVisible(recipientsAreEditable); tsubject = uifactory.addTextElement("tsubject", NLS_CONTACT_SUBJECT, 255, "", formLayout); tsubject.setElementCssClass("o_sel_contact_subject"); @@ -422,5 +427,5 @@ public class ContactForm extends FormBasicController { protected void doDispose() { cleanUpAttachments(); } - + } \ No newline at end of file diff --git a/src/main/java/org/olat/modules/co/ContactFormController.java b/src/main/java/org/olat/modules/co/ContactFormController.java index 142c326ed73..afc90808683 100644 --- a/src/main/java/org/olat/modules/co/ContactFormController.java +++ b/src/main/java/org/olat/modules/co/ContactFormController.java @@ -188,6 +188,12 @@ public class ContactFormController extends BasicController { } return null; } + + public void setRecipientsLists(List<ContactList> recipientsLists) { + if (cntctForm != null) { + cntctForm.setRecipientsLists(recipientsLists); + } + } private void init(UserRequest ureq, boolean hasAtLeastOneAddress, List<Identity> disabledIdentities) { if (hasAtLeastOneAddress) { diff --git a/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java b/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java index 74f407ed780..591545ab9fe 100644 --- a/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java +++ b/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java @@ -49,6 +49,7 @@ public enum RepositoryEntryManagedFlag { search(settings, all), participantList(settings, all), participantInfo(settings, all), + email(settings, all), chat(settings,all), layout(settings,all), resourcefolder(settings,all), -- GitLab