diff --git a/.gitignore b/.gitignore index 571cf011ab01e0ba9c2f0c1dcc704f7f53e307d7..4e879538ecaaf3590de0b1aea7da36ef8ec6bff2 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ src/test/java/org/olat/selenium/SeleniumTest.java **/*/.sass-cache +/.sts4-cache diff --git a/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java b/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java index 6fc7e7a408e56a13ecedb924978e72d7167d3324..ddee744d569728282dbf0db4eb8e718048e81b4f 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java @@ -62,14 +62,34 @@ public class SingleKeyTranslatorController extends FormBasicController { private static final String LBL_NAME_PREFIX = "lbl."; private Map<String, TextElement> textElements; private Object uobject; + private boolean textArea; @Autowired private I18nManager i18nMng; @Autowired private I18nModule i18nModule; + /** + * + * @param ureq The user request + * @param wControl The window control + * @param keyToTranslate The key to translate + * @param translatorBaseClass The package to translate + */ public SingleKeyTranslatorController(UserRequest ureq, WindowControl wControl, String keyToTranslate, Class<?> translatorBaseClass) { - this(ureq,wControl,new String[]{keyToTranslate},translatorBaseClass); + this(ureq, wControl, new String[]{keyToTranslate}, translatorBaseClass, false); + } + + /** + * + * @param ureq The user request + * @param wControl The window control + * @param keyToTranslate The key to translate + * @param translatorBaseClass The package to translate + * @param textArea true if the edit field is a text area, false for a simple text field + */ + public SingleKeyTranslatorController(UserRequest ureq, WindowControl wControl, String keyToTranslate, Class<?> translatorBaseClass, boolean textArea) { + this(ureq, wControl, new String[]{keyToTranslate}, translatorBaseClass, textArea); } /** @@ -84,14 +104,17 @@ public class SingleKeyTranslatorController extends FormBasicController { /** * - * @param ureq - * @param wControl + * @param ureq The user request + * @param wControl The window control * @param keysToTranslate array of keys to translate (each key will have the * same value, translation is only done once (for each language) !) - * @param translatorBaseClass + * @param translatorBaseClass The package to translate + * @param textArea true if the edit field is a text area, false for a simple text field */ - public SingleKeyTranslatorController(UserRequest ureq, WindowControl wControl, String[] keysToTranslate, Class<?> translatorBaseClass) { + public SingleKeyTranslatorController(UserRequest ureq, WindowControl wControl, String[] keysToTranslate, + Class<?> translatorBaseClass, boolean textArea) { super(ureq, wControl, FormBasicController.LAYOUT_VERTICAL); + this.textArea = textArea; i18nItemKeys = keysToTranslate; this.translatorBaseClass = translatorBaseClass; initForm(ureq); @@ -119,18 +142,24 @@ public class SingleKeyTranslatorController extends FormBasicController { // build the form textElements = new HashMap<>(); for (I18nRowBundle i18nRowBundle : bundles) { - uifactory.addStaticTextElement(LBL_NAME_PREFIX + i18nRowBundle.getLanguageKey(), null, i18nRowBundle.getKeyTranslator().getLocale() - .getDisplayLanguage(getLocale()), formLayout); + String labelId = LBL_NAME_PREFIX + i18nRowBundle.getLanguageKey(); + String label = i18nRowBundle.getKeyTranslator().getLocale().getDisplayLanguage(getLocale()); + uifactory.addStaticTextElement(labelId, null, label, formLayout); String value = ""; if (i18nRowBundle.hasTranslationForValue(i18nItemKeys[0])) { value = i18nRowBundle.getKeyTranslator().translate(i18nItemKeys[0]); } - TextElement te = uifactory.addTextElement(TXT_NAME_PREFIX + i18nRowBundle.getLanguageKey(), null, 255, value, formLayout); + String textId = TXT_NAME_PREFIX + i18nRowBundle.getLanguageKey(); + TextElement te; + if(textArea) { + te = uifactory.addTextAreaElement(textId, null, -1, 8, 60, false, false, value, formLayout); + } else { + te = uifactory.addTextElement(textId, null, null, 255, value, formLayout); + te.setDisplaySize(60); + } te.setMandatory(true); - te.setDisplaySize(60); textElements.put(i18nRowBundle.getLanguageKey(), te); - } FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("ok_cancel", getTranslator()); @@ -190,11 +219,11 @@ public class SingleKeyTranslatorController extends FormBasicController { * * @author strentini */ - class I18nRowBundle { - private Locale overlayLocale; - private Locale locale; - private String languageKey; - private Translator keyTranslator; + private class I18nRowBundle { + private final Locale overlayLocale; + private final Locale locale; + private final String languageKey; + private final Translator keyTranslator; /** * @@ -217,10 +246,6 @@ public class SingleKeyTranslatorController extends FormBasicController { return overlayLocale; } - public Locale getLocale() { - return locale; - } - public String getLanguageKey() { return languageKey; } @@ -228,7 +253,5 @@ public class SingleKeyTranslatorController extends FormBasicController { public Translator getKeyTranslator() { return keyTranslator; } - } - } diff --git a/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java index a9b1534b440d6068a573dcce080d8c10afbad1ad..c4c6fdeb72b13942e4485ae97f989b631594062d 100644 --- a/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java +++ b/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java @@ -380,12 +380,8 @@ public class AssessmentModeManagerImpl implements AssessmentModeManager { assessedKeys.addAll(courseMemberKeys); } - if(targetAudience == Target.curriculumEls || targetAudience == Target.courseAndGroups) { - List<Long> courseMemberKeys = assessmentMode.isApplySettingsForCoach() - ? repositoryEntryRelationDao.getMemberKeys(re, RepositoryEntryRelationType.entryAndCurriculums, GroupRoles.coach.name(), GroupRoles.participant.name()) - : repositoryEntryRelationDao.getMemberKeys(re, RepositoryEntryRelationType.entryAndCurriculums, GroupRoles.participant.name()); - assessedKeys.addAll(courseMemberKeys); - + // For courseAndGroups, the curriculums are retrieved by the relation type. + if(targetAudience == Target.curriculumEls) { List<CurriculumElementRef> curriculumElements = new ArrayList<>(); Set<AssessmentModeToCurriculumElement> modeTocurriculumElements = assessmentMode.getCurriculumElements(); for(AssessmentModeToCurriculumElement modeTocurriculumElement:modeTocurriculumElements) { diff --git a/src/main/java/org/olat/course/reminder/rule/AttemptsRuleSPI.java b/src/main/java/org/olat/course/reminder/rule/AttemptsRuleSPI.java index 5e1d63059c2bb69ec991fa2dadeb11882469911c..cc25c520f0ea5d4a848ee60c119e9ad2b5ad3901 100644 --- a/src/main/java/org/olat/course/reminder/rule/AttemptsRuleSPI.java +++ b/src/main/java/org/olat/course/reminder/rule/AttemptsRuleSPI.java @@ -87,7 +87,7 @@ public class AttemptsRuleSPI implements FilterRuleSPI { CourseNode courseNode = course.getRunStructure().getNode(nodeIdent); if (courseNode == null) { identities.clear(); - log.error("Attempts rule in course " + entry.getKey() + " (" + entry.getDisplayname() + ") is missing a course element"); + log.warn("Attempts rule in course {} ({}) is missing a course element", entry.getKey(), entry.getDisplayname()); return; } diff --git a/src/main/java/org/olat/ims/qti21/AssessmentTestHelper.java b/src/main/java/org/olat/ims/qti21/AssessmentTestHelper.java index 876423142d66ad3bdbd6ef25116031559bbd9158..4addfebcbbc08aa724d2a33f39eae3ad49a72a8f 100644 --- a/src/main/java/org/olat/ims/qti21/AssessmentTestHelper.java +++ b/src/main/java/org/olat/ims/qti21/AssessmentTestHelper.java @@ -66,7 +66,9 @@ public class AssessmentTestHelper { .getItemRefsBySystemIdMap().get(currentItem.getItemSystemId()); AssessmentItemRef itemRef = null; - if(itemRefs.size() == 1) { + if(itemRefs == null) { + // itemRef stay null + } else if(itemRefs.size() == 1) { itemRef = itemRefs.get(0); } else { Identifier itemId = itemKey.getIdentifier(); diff --git a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java index 53ca58e8b30cfe438a9766f9dae01c02be8e5310..d8c73c8413beb067bb4b4f035b3aa29392a0d30f 100644 --- a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java +++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java @@ -369,7 +369,7 @@ public class AssessmentTestDisplayController extends BasicController implements initNewAssessmentTestSession(ureq, assessmentEntry, authorMode); } } catch(Exception e) { - logError("Cannot resume session as author", e); + logWarn("Cannot resume session as author", e); initNewAssessmentTestSession(ureq, assessmentEntry, authorMode); } } else { @@ -414,12 +414,15 @@ public class AssessmentTestDisplayController extends BasicController implements if(subIdent == null && !authorMode) { resourcesList.deregisterResourceable(entry, subIdent, getWindow()); } - - suspendAssessmentTest(new Date()); - if(candidateSession != null) { - OLATResourceable sessionOres = OresHelper - .createOLATResourceableInstance(AssessmentTestSession.class, candidateSession.getKey()); - CoordinatorManager.getInstance().getCoordinator().getEventBus().deregisterFor(this, sessionOres); + try { + suspendAssessmentTest(new Date()); + if(candidateSession != null) { + OLATResourceable sessionOres = OresHelper + .createOLATResourceableInstance(AssessmentTestSession.class, candidateSession.getKey()); + CoordinatorManager.getInstance().getCoordinator().getEventBus().deregisterFor(this, sessionOres); + } + } catch (Exception e) { + logError("", e); } } diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java index f4b2dd4fe57f3fc405c7873d3a3bd20eca3bdb5a..7d1ccbc8117f6d03a6f7456f9238e14fbc3fbcb9 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java @@ -92,7 +92,7 @@ import uk.ac.ed.ph.jqtiplus.state.TestSessionState; /** * A table with the list of assessment items of the test - * with statistics about the users wo answered (or not answered) + * with statistics about the users who answered (or not answered) * every assessment item. * * @@ -472,7 +472,7 @@ public class CorrectionAssessmentItemListController extends FormBasicController boolean readOnly = model.isReadOnly(assessedIdentity); identityItemCtrl = new CorrectionIdentityAssessmentItemNavigationController(ureq, getWindowControl(), model.getTestEntry(), model.getResolvedAssessmentTest(), itemCorrection, listEntry, - selectedItemSessions, model, null, readOnly); + selectedItemSessions, model, null, readOnly, true); listenTo(identityItemCtrl); updatePreviousNext(); diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemController.java index 86ea3fb3ab264935ce97d2efcd748e0800df1274..b94cc51effcbf48a9991ebe0807ad45dc96f298e 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemController.java @@ -88,6 +88,7 @@ public class CorrectionIdentityAssessmentItemController extends FormBasicControl private final ResourcesMapper resourcesMapper; private final boolean readOnly; + private final boolean pageIdentity; private CorrectionOverviewModel model; private final RepositoryEntry testEntry; private AssessmentItemCorrection itemCorrection; @@ -114,7 +115,7 @@ public class CorrectionIdentityAssessmentItemController extends FormBasicControl RepositoryEntry testEntry, ResolvedAssessmentTest resolvedAssessmentTest, AssessmentItemCorrection itemCorrection, AssessmentItemListEntry assessmentEntry, List<? extends AssessmentItemListEntry> assessmentEntryList, CorrectionOverviewModel model, - GradingTimeRecordRef gradingTimeRecord, boolean readOnly) { + GradingTimeRecordRef gradingTimeRecord, boolean readOnly, boolean pageIdentity) { super(ureq, wControl, "correction_identity_assessment_item"); this.readOnly = readOnly; this.gradingTimeRecord = gradingTimeRecord; @@ -126,6 +127,7 @@ public class CorrectionIdentityAssessmentItemController extends FormBasicControl this.model = model; this.testEntry = testEntry; + this.pageIdentity = pageIdentity; this.itemCorrection = itemCorrection; this.assessmentEntry = assessmentEntry; this.assessmentEntryList = assessmentEntryList; @@ -166,12 +168,15 @@ public class CorrectionIdentityAssessmentItemController extends FormBasicControl formLayout.add("interactions", identityInteractionsCtrl.getInitialFormItem()); uifactory.addFormCancelButton("cancel", formLayout, ureq, getWindowControl()); + if(readOnly) { - nextQuestionButton = uifactory.addFormLink("next.item", formLayout, Link.BUTTON); + String nextI18n = pageIdentity ? "next.user" : "next.item"; + nextQuestionButton = uifactory.addFormLink("next.item", nextI18n, null, formLayout, Link.BUTTON); backOverviewButton = uifactory.addFormLink("back.overview", formLayout, Link.BUTTON); } else { uifactory.addFormSubmitButton("save", formLayout); - saveNextQuestionButton = uifactory.addFormLink("save.next", formLayout, Link.BUTTON); + String saveNextI18n = pageIdentity ? "save.next.identity" : "save.next"; + saveNextQuestionButton = uifactory.addFormLink("save.next", saveNextI18n, null, formLayout, Link.BUTTON); saveBackOverviewButton = uifactory.addFormLink("save.back", formLayout, Link.BUTTON); } } diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemListController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemListController.java index 7554969282ff4a1fb81276adebbbdd3ae69ee4ab..3d60ff2d2898e35398fc52d65db80d33f2581e91 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemListController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemListController.java @@ -408,7 +408,7 @@ public class CorrectionIdentityAssessmentItemListController extends FormBasicCon AssessmentItem assessmentItem = resolvedAssessmentItem.getRootNodeLookup().extractIfSuccessful(); identityItemCtrl = new CorrectionIdentityAssessmentItemNavigationController(ureq, getWindowControl(), model.getTestEntry(), model.getResolvedAssessmentTest(), itemCorrection, row, - tableModel.getObjects(), model, gradingTimeRecord, readOnly); + tableModel.getObjects(), model, gradingTimeRecord, readOnly, false); listenTo(identityItemCtrl); stackPanel.pushController(assessmentItem.getTitle(), identityItemCtrl); updatePreviousNext(); diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemNavigationController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemNavigationController.java index ddbd698bcf3485f5220d41f95d5e6f9d7f6a9868..5b197d8e77cc63d7e1e77e28642c1dac759cdc18 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemNavigationController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionIdentityAssessmentItemNavigationController.java @@ -64,12 +64,12 @@ public class CorrectionIdentityAssessmentItemNavigationController extends BasicC RepositoryEntry testEntry, ResolvedAssessmentTest resolvedAssessmentTest, AssessmentItemCorrection itemCorrection, AssessmentItemListEntry assessmentEntry, List<? extends AssessmentItemListEntry> assessmentEntryList, CorrectionOverviewModel model, - GradingTimeRecordRef gradingTimeRecord, boolean readOnly) { + GradingTimeRecordRef gradingTimeRecord, boolean readOnly, boolean pageIdentity) { super(ureq, wControl); mainVC = createVelocityContainer("corrections_navigation"); itemCtrl = new CorrectionIdentityAssessmentItemController(ureq, wControl, testEntry, resolvedAssessmentTest, - itemCorrection, assessmentEntry, assessmentEntryList, model, gradingTimeRecord, readOnly); + itemCorrection, assessmentEntry, assessmentEntryList, model, gradingTimeRecord, readOnly, pageIdentity); listenTo(itemCtrl); mainVC.put("items", itemCtrl.getInitialComponent()); diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties index 017fb110e7c01e52999e923473df2a84c84bbf50..72fc0bb3dcb865a0dc495109ea44f0d23613f317 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_de.properties @@ -28,10 +28,11 @@ previous.item=Vorherige Frage previous.user=Vorheriger Benutzer save.back=Speichern und zur \u00DCbersicht save.next=Speichern und n\u00E4chste Frage +save.next.identity=Speichern und n\u00E4chster Teilnehmer save.tests=Als endg\u00FCltiges Resultat speichern score=Punkte show.rubric=Beschreibung anzeigen -show.rubric.with.title=Beschreibung f\u00FCr "<b>{0}</b>" anzeigen +show.rubric.with.title=Beschreibung f\u00FCr "<strong>{0}</strong>" anzeigen status=Status table.header.action=<i class='o_icon o_icon_actions o_icon-lg'> </i> table.header.answered=Beantwortet diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties index a27b4b521427c2e13b20914ffdc9a8efb56f700d..524ddb4f1e4df2d52ab33ed3b2a44941eee606a3 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_en.properties @@ -28,10 +28,11 @@ previous.item=Previous question previous.user=Previous user save.back=Save and back to overview save.next=Save and next question +save.next.identity=Save and next participant save.tests=Save results as completed score=Score show.rubric=Show description -show.rubric.with.title=Show description for "<b>{0}</b>" +show.rubric.with.title=Show description for "<strong>{0}</strong>" status=Status table.header.action=<i class\='o_icon o_icon_actions o_icon-lg'> </i> table.header.answered=Answered diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties index 09386334c17266c5013ba2a800b3c6d425332950..d41a0314c2f66f966f9e8519456fa56e23b3a9c1 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/_i18n/LocalStrings_fr.properties @@ -28,6 +28,7 @@ previous.item=Question pr\u00E9c\u00E9dente previous.user=Utilisateur pr\u00E9c\u00E9dent save.back=Sauver et retourner \u00E0 l'aper\u00E7u save.next=Sauver et question suivante +save.next.identity=Sauver et participant suivant save.tests=Sauver les r\u00E9sultats d\u00E9finitifs score=R\u00E9sultats show.rubric=Montrer la description diff --git a/src/main/java/org/olat/modules/fo/Message.java b/src/main/java/org/olat/modules/fo/Message.java index e452453420194721eb5cd9b81051802d2e766f6b..c2db05cd9807c0b4933f0b75271f7fd21355b9e1 100644 --- a/src/main/java/org/olat/modules/fo/Message.java +++ b/src/main/java/org/olat/modules/fo/Message.java @@ -25,6 +25,8 @@ package org.olat.modules.fo; +import java.util.Date; + import org.olat.core.id.CreateInfo; import org.olat.core.id.Identity; import org.olat.core.id.ModifiedInfo; @@ -57,6 +59,13 @@ public interface Message extends MessageLight, CreateInfo, ModifiedInfo, Persis public void setModifier(Identity identity); + /** + * @return The date the modifier makes a change + */ + public Date getModificationDate(); + + public void setModificationDate(Date date); + public Message getParent(); public void setParent(Message message); diff --git a/src/main/java/org/olat/modules/fo/MessageLight.java b/src/main/java/org/olat/modules/fo/MessageLight.java index b81bad0ad9b4f51f0752bd37aea793f914d9cd9b..0170e47618982937cb13f952939853d435f6cd34 100644 --- a/src/main/java/org/olat/modules/fo/MessageLight.java +++ b/src/main/java/org/olat/modules/fo/MessageLight.java @@ -43,6 +43,11 @@ public interface MessageLight extends MessageRef { public Identity getModifier(); + /** + * @return The date the modifier makes a change + */ + public Date getModificationDate(); + public Date getCreationDate(); public Date getLastModified(); diff --git a/src/main/java/org/olat/modules/fo/archiver/MessageNode.java b/src/main/java/org/olat/modules/fo/archiver/MessageNode.java index e3865c00f3bc2e8b9fc7b2f71cacedaf590d61c7..80fca14b639b0e287ff388ad50cddbabad4f732d 100644 --- a/src/main/java/org/olat/modules/fo/archiver/MessageNode.java +++ b/src/main/java/org/olat/modules/fo/archiver/MessageNode.java @@ -66,7 +66,11 @@ public class MessageNode extends GenericNode implements Serializable { creator = message.getCreator(); creationDate = message.getCreationDate(); modifier = message.getModifier(); - modifiedDate = message.getLastModified(); + if(message.getModificationDate() != null) { + modifiedDate = message.getModificationDate(); + } else { + modifiedDate = message.getLastModified(); + } guest = message.isGuest(); pseudonym = message.getPseudonym(); if(message.getParent()==null) { diff --git a/src/main/java/org/olat/modules/fo/manager/ForumManager.java b/src/main/java/org/olat/modules/fo/manager/ForumManager.java index 1b2e4d042f0470fbad0280b82dae1292837622d6..9feeb02040cecb09e23b06e8de94234af3bc23bf 100644 --- a/src/main/java/org/olat/modules/fo/manager/ForumManager.java +++ b/src/main/java/org/olat/modules/fo/manager/ForumManager.java @@ -1231,6 +1231,7 @@ public class ForumManager { ((MessageImpl)message).setCreationDate(oldMessage.getCreationDate()); message.setLastModified(oldMessage.getLastModified()); message.setModifier(oldMessage.getModifier()); + message.setModificationDate(oldMessage.getModificationDate()); message.setTitle(oldMessage.getTitle()); message.setBody(oldMessage.getBody()); message.setPseudonym(oldMessage.getPseudonym()); diff --git a/src/main/java/org/olat/modules/fo/model/MessageImpl.java b/src/main/java/org/olat/modules/fo/model/MessageImpl.java index 9bb1255adbed67fba7d1e0662554a56ad6e01d98..355b591057b24ca91f34b900461aab2d9db1c594 100644 --- a/src/main/java/org/olat/modules/fo/model/MessageImpl.java +++ b/src/main/java/org/olat/modules/fo/model/MessageImpl.java @@ -90,6 +90,9 @@ public class MessageImpl implements CreateInfo, Persistable, Message { @Column(name="numofwords", nullable=true, insertable=true, updatable=true) private Integer numOfWords; + @Column(name="modification_date", nullable=true, insertable=true, updatable=true) + private Date modificationDate; + @ManyToOne(targetEntity=MessageImpl.class,fetch=FetchType.LAZY,optional=true) @JoinColumn(name="parent_id", nullable=true, insertable=true, updatable=true) private Message parent; @@ -130,18 +133,12 @@ public class MessageImpl implements CreateInfo, Persistable, Message { this.creationDate = creationDate; } - - /** - * @return - */ + @Override public String getBody() { return body; } - - /** - * @return - */ + @Override public Identity getCreator() { return creator; } @@ -153,14 +150,17 @@ public class MessageImpl implements CreateInfo, Persistable, Message { creator = identity; } + @Override public String getPseudonym() { return pseudonym; } + @Override public void setPseudonym(String pseudonym) { this.pseudonym = pseudonym; } + @Override public boolean isGuest() { return guest; } @@ -169,9 +169,7 @@ public class MessageImpl implements CreateInfo, Persistable, Message { this.guest = guest; } - /** - * @return - */ + @Override public Forum getForum() { return forum; } @@ -180,16 +178,12 @@ public class MessageImpl implements CreateInfo, Persistable, Message { this.forum = forum; } - /** - * @return - */ + @Override public Identity getModifier() { return modifier; } - /** - * @return - */ + @Override public Message getParent() { return parent; } @@ -199,90 +193,86 @@ public class MessageImpl implements CreateInfo, Persistable, Message { return parent == null ? null : parent.getKey(); } - /** - * @return - */ + @Override public Message getThreadtop() { return threadtop; } - /** - * @return - */ + @Override public String getTitle() { return title; } - /** - * @param string - */ + @Override public void setBody(String string) { body = string; } - /** - * @param identity - */ + @Override public void setModifier(Identity identity) { modifier = identity; } - /** - * @param message - */ + @Override public void setParent(Message message) { parent = message; } - /** - * @param message - */ + @Override public void setThreadtop(Message message) { threadtop = message; } - /** - * @param string - */ + @Override public void setTitle(String string) { title = string; } - + + @Override public int getStatusCode() { return statusCode; } + + @Override public void setStatusCode(int statusCode) { this.statusCode = statusCode; } - /** - * - * @see org.olat.core.id.ModifiedInfo#getLastModified() - */ + @Override public Date getLastModified() { return lastModified; } - /** - * - * @see org.olat.core.id.ModifiedInfo#setLastModified(java.util.Date) - */ + @Override public void setLastModified(Date date) { this.lastModified = date; } + @Override + public Date getModificationDate() { + return modificationDate; + } + + public void setModificationDate(Date modificationDate) { + this.modificationDate = modificationDate; + } + + @Override public Integer getNumOfCharacters() { return numOfCharacters; } + @Override public void setNumOfCharacters(Integer numOfCharacters) { this.numOfCharacters = numOfCharacters; } + @Override public Integer getNumOfWords() { return numOfWords; } + @Override public void setNumOfWords(Integer numOfWords) { this.numOfWords = numOfWords; } diff --git a/src/main/java/org/olat/modules/fo/model/MessageLightImpl.java b/src/main/java/org/olat/modules/fo/model/MessageLightImpl.java index 54fd2e06ed4d3bdf2220103a5cf0078412db65da..50eff107ceeb497669ea8adf932b327063b0bbc0 100644 --- a/src/main/java/org/olat/modules/fo/model/MessageLightImpl.java +++ b/src/main/java/org/olat/modules/fo/model/MessageLightImpl.java @@ -82,6 +82,9 @@ public class MessageLightImpl implements MessageLight, CreateInfo, Persistable, private String title; @Column(name="body", nullable=false, insertable=false, updatable=false) private String body; + + @Column(name="modification_date", nullable=true, insertable=true, updatable=true) + private Date modificationDate; @Column(name="parent_id", nullable=true, insertable=false, updatable=false) private Long parentKey; @@ -112,27 +115,33 @@ public class MessageLightImpl implements MessageLight, CreateInfo, Persistable, public Date getCreationDate() { return creationDate; } - + + @Override public int getStatusCode() { return statusCode; } - + + @Override public String getTitle() { return title; } + @Override public String getBody() { return body; } + @Override public Identity getCreator() { return creator; } + @Override public String getPseudonym() { return pseudonym; } + @Override public boolean isGuest() { return guest; } @@ -141,21 +150,30 @@ public class MessageLightImpl implements MessageLight, CreateInfo, Persistable, return forumKey; } + @Override public Identity getModifier() { return modifier; } + @Override public Long getParentKey() { return parentKey; } + @Override public MessageRef getThreadtop() { return threadtop; } + @Override public Date getLastModified() { return lastModified; } + + @Override + public Date getModificationDate() { + return modificationDate; + } @Override public int hashCode() { diff --git a/src/main/java/org/olat/modules/fo/restapi/MessageVO.java b/src/main/java/org/olat/modules/fo/restapi/MessageVO.java index 81b0399f74209f9f7b5790d7af079692f3b309b7..0652ff9df4983e81336be7461e21729cc033b93f 100644 --- a/src/main/java/org/olat/modules/fo/restapi/MessageVO.java +++ b/src/main/java/org/olat/modules/fo/restapi/MessageVO.java @@ -89,7 +89,7 @@ public class MessageVO { body = message.getBody(); Status messageStatus = Status.getStatus(message.getStatusCode()); - sticky = new Boolean(messageStatus.isSticky()); + sticky = Boolean.valueOf(messageStatus.isSticky()); } public Long getKey() { diff --git a/src/main/java/org/olat/modules/fo/ui/MessageEditController.java b/src/main/java/org/olat/modules/fo/ui/MessageEditController.java index c2714266c793a80d0994f34f76cbb86c95e0aaae..c6e8abfe19ef777b8eb3997af1b2b706f753fb09 100644 --- a/src/main/java/org/olat/modules/fo/ui/MessageEditController.java +++ b/src/main/java/org/olat/modules/fo/ui/MessageEditController.java @@ -24,6 +24,7 @@ import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.List; import javax.persistence.PersistenceException; @@ -559,7 +560,8 @@ public class MessageEditController extends FormBasicController { private void commitEditMode() { boolean children = fm.countMessageChildren(message.getKey()) > 0; if (foCallback.mayEditMessageAsModerator() || (userIsMsgCreator && !children)) { - message.setModifier(getIdentity()); + message.setModifier(getIdentity()); + message.setModificationDate(new Date()); message = fm.updateMessage(message, true); persistTempUploadedFiles(message); notifiySubscription(); diff --git a/src/main/java/org/olat/modules/fo/ui/MessageListController.java b/src/main/java/org/olat/modules/fo/ui/MessageListController.java index 7d05902624a9ac97dca26fcbcae16d5dcb376f5c..d459573b058ebde3c0c2d9ab1d5e0e3bea12d0ad 100644 --- a/src/main/java/org/olat/modules/fo/ui/MessageListController.java +++ b/src/main/java/org/olat/modules/fo/ui/MessageListController.java @@ -600,6 +600,12 @@ public class MessageListController extends BasicController implements GenericEve messageView.setModifierFirstName(modifier.getUser().getProperty(UserConstants.FIRSTNAME, getLocale())); messageView.setModifierLastName(modifier.getUser().getProperty(UserConstants.LASTNAME, getLocale())); } + + if(m.getModificationDate() != null) { + messageView.setFormattedModificationDate(formatter.formatDateAndTime(m.getModificationDate())); + } else { + messageView.setFormattedModificationDate(messageView.getFormattedLastModified()); + } } else { messageView.setModified(false); } diff --git a/src/main/java/org/olat/modules/fo/ui/MessageView.java b/src/main/java/org/olat/modules/fo/ui/MessageView.java index c92e46ad79b18c295f05c5bb4fab3405e679ddd9..2a419eef6456ed93c8ea47ac9ff6e7c87f81bd91 100644 --- a/src/main/java/org/olat/modules/fo/ui/MessageView.java +++ b/src/main/java/org/olat/modules/fo/ui/MessageView.java @@ -45,6 +45,7 @@ public class MessageView extends MessageLightView { private String modifierFirstName; private String modifierLastName; private String modifierPseudonym; + private String formattedModificationDate; private String creatorFirstname; private String creatorLastname; @@ -140,6 +141,14 @@ public class MessageView extends MessageLightView { this.modifierPseudonym = modifierPseudonym; } + public String getFormattedModificationDate() { + return formattedModificationDate; + } + + public void setFormattedModificationDate(String formattedModificationDate) { + this.formattedModificationDate = formattedModificationDate; + } + public boolean isAuthor() { return author; } diff --git a/src/main/java/org/olat/modules/fo/ui/_content/threadview.html b/src/main/java/org/olat/modules/fo/ui/_content/threadview.html index c56798979da302640d2e6064e352ed798c06c017..0516c20957da370a157d08bcd3e2e4ec34b6b67c 100644 --- a/src/main/java/org/olat/modules/fo/ui/_content/threadview.html +++ b/src/main/java/org/olat/modules/fo/ui/_content/threadview.html @@ -112,7 +112,7 @@ #else $r.escapeHtml($message.modifierFirstName) $r.escapeHtml($message.modifierLastName) #end - $message.formattedLastModified + $message.formattedModificationDate #end #if($message.moved) $r.translate("msg.moved") diff --git a/src/main/java/org/olat/modules/grading/ui/GradingAdminTemplatesController.java b/src/main/java/org/olat/modules/grading/ui/GradingAdminTemplatesController.java index 2e099272351750dab0eabba318e93d6b6f1b6c74..d4f95b8f9529c36eadd9bcb90fbdf256b7312312 100644 --- a/src/main/java/org/olat/modules/grading/ui/GradingAdminTemplatesController.java +++ b/src/main/java/org/olat/modules/grading/ui/GradingAdminTemplatesController.java @@ -31,6 +31,7 @@ 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.generic.closablewrapper.CloseableModalController; +import org.olat.core.util.Formatter; import org.olat.core.util.i18n.ui.SingleKeyTranslatorController; /** @@ -55,30 +56,34 @@ public class GradingAdminTemplatesController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { // new grader - initForm("mail.to.grader.subject", "mail.grader.to.entry.subject", formLayout); - initForm("mail.to.grader.body", "mail.grader.to.entry.body", formLayout); + initForm("mail.to.grader.subject", "mail.grader.to.entry.subject", false, formLayout); + initForm("mail.to.grader.body", "mail.grader.to.entry.body", true, formLayout); uifactory.addSpacerElement("spacer-new-grader", formLayout, false); // notifications - initForm("notification.subject", "mail.notification.subject", formLayout); - initForm("notification.body", "mail.notification.body", formLayout); + initForm("notification.subject", "mail.notification.subject", false, formLayout); + initForm("notification.body", "mail.notification.body", true, formLayout); uifactory.addSpacerElement("spacer-notification", formLayout, false); // reminder 1 - initForm("reminder.1.subject", "mail.reminder1.subject", formLayout); - initForm("reminder.1.body", "mail.reminder1.body", formLayout); + initForm("reminder.1.subject", "mail.reminder1.subject", false, formLayout); + initForm("reminder.1.body", "mail.reminder1.body", true, formLayout); uifactory.addSpacerElement("spacer-1-reminder", formLayout, false); // reminder 2 - initForm("reminder.2.subject", "mail.reminder2.subject", formLayout); - initForm("reminder.2.body", "mail.reminder2.body", formLayout); + initForm("reminder.2.subject", "mail.reminder2.subject", false, formLayout); + initForm("reminder.2.body", "mail.reminder2.body", true, formLayout); } - private void initForm(String labelI18nKey, String textI18nKey, FormItemContainer formLayout) { + private void initForm(String labelI18nKey, String textI18nKey, boolean multiLines, FormItemContainer formLayout) { String text = translate(textI18nKey); + if(multiLines) { + text = Formatter.escWithBR(text).toString(); + } + StaticTextElement viewEl = uifactory.addStaticTextElement("view." + counter++, labelI18nKey, text, formLayout); FormLink translationLink = uifactory.addFormLink("translate." + counter++, "translate", null, formLayout, Link.LINK); - translationLink.setUserObject(new TranslationBundle(textI18nKey, labelI18nKey, viewEl)); + translationLink.setUserObject(new TranslationBundle(textI18nKey, labelI18nKey, multiLines, viewEl)); } @Override @@ -124,7 +129,7 @@ public class GradingAdminTemplatesController extends FormBasicController { if(guardModalController(translatorCtrl)) return; translatorCtrl = new SingleKeyTranslatorController(ureq, getWindowControl(), bundle.getI18nKey(), - GradingAdminTemplatesController.class); + GradingAdminTemplatesController.class, bundle.isMultiLines()); translatorCtrl.setUserObject(bundle); listenTo(translatorCtrl); @@ -135,18 +140,24 @@ public class GradingAdminTemplatesController extends FormBasicController { } private void doUpdate(TranslationBundle bundle) { - bundle.getViewEl().setValue(translate(bundle.getI18nKey())); + String text = translate(bundle.getI18nKey()); + if(bundle.isMultiLines()) { + text = Formatter.escWithBR(text).toString(); + } + bundle.getViewEl().setValue(text); } private static class TranslationBundle { private final String i18nKey; + private final boolean multiLines; private final String labelI18nKey; private final StaticTextElement viewEl; - public TranslationBundle(String i18nKey, String labelI18nKey, StaticTextElement viewEl) { + public TranslationBundle(String i18nKey, String labelI18nKey, boolean multiLines, StaticTextElement viewEl) { this.i18nKey = i18nKey; this.viewEl = viewEl; + this.multiLines = multiLines; this.labelI18nKey = labelI18nKey; } @@ -161,5 +172,9 @@ public class GradingAdminTemplatesController extends FormBasicController { public String getLabelI18nKey() { return labelI18nKey; } + + public boolean isMultiLines() { + return multiLines; + } } } diff --git a/src/main/java/org/olat/restapi/system/BigBlueButtonWebService.java b/src/main/java/org/olat/restapi/system/BigBlueButtonWebService.java new file mode 100644 index 0000000000000000000000000000000000000000..68d185ab3e897a29a663607fdf91fba28af769f5 --- /dev/null +++ b/src/main/java/org/olat/restapi/system/BigBlueButtonWebService.java @@ -0,0 +1,80 @@ +package org.olat.restapi.system; + +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.olat.core.CoreSpringFactory; +import org.olat.modules.bigbluebutton.BigBlueButtonManager; +import org.olat.modules.bigbluebutton.BigBlueButtonModule; +import org.olat.modules.bigbluebutton.model.BigBlueButtonMeetingInfos; +import org.olat.modules.bigbluebutton.model.BigBlueButtonServerInfos; +import org.olat.restapi.system.vo.BigBlueButtonStatisticsVO; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; + +/** + * Initial Date: 2 jul. 2020 <br> + * @author mjenny, moritz.jenny@frentix.com, http://www.frentix.com + */ + +public class BigBlueButtonWebService { + + /** + * Return the statistics about Big Blue Button + * + * @return The statistics about Big Blue Button + */ + @GET + @Operation(summary = "Return the statistics about Big Blue Button", description = "Return the statistics about Big Blue Button") + @ApiResponse(responseCode = "200", description = "Statistics about the Big Blue Button", content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = BigBlueButtonStatisticsVO.class)), + @Content(mediaType = "application/xml", schema = @Schema(implementation = BigBlueButtonStatisticsVO.class)) }) + @ApiResponse(responseCode = "401", description = "The roles of the authenticated user are not sufficient") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + + public Response getStatistics() { + BigBlueButtonStatisticsVO stats = getBigBlueButtonStatistics(); + return Response.ok(stats).build(); + } + + private BigBlueButtonStatisticsVO getBigBlueButtonStatistics() { + BigBlueButtonStatisticsVO stats = new BigBlueButtonStatisticsVO(); + BigBlueButtonModule bbbModule = CoreSpringFactory.getImpl(BigBlueButtonModule.class); + if(bbbModule.isEnabled()) { + BigBlueButtonManager bbbManager = CoreSpringFactory.getImpl(BigBlueButtonManager.class); + long sumAttendees = 0; + long sumMeetings = 0; + long recordingCount = 0; + long videoCount = 0; + long capacity = 0; + List<BigBlueButtonServerInfos> bbbServerInfos = bbbManager.filterServersInfos(bbbManager.getServersInfos()); + for (int i = 0; i < bbbServerInfos.size(); i++) { + List<BigBlueButtonMeetingInfos> bbbMeetingInfos = bbbServerInfos.get(i).getMeetingsInfos(); + for(int j = 0; j < bbbMeetingInfos.size(); j++) { + if(bbbMeetingInfos.get(j).isRunning()) { + sumMeetings += 1; + videoCount += bbbMeetingInfos.get(j).getVideoCount(); + capacity += bbbMeetingInfos.get(j).getMaxUsers(); + sumAttendees += bbbMeetingInfos.get(j).getParticipantCount(); + if(bbbMeetingInfos.get(j).isRecording()){ + recordingCount += 1; + } + } + } + } + stats.setMeetingsCount(sumMeetings); + stats.setAttendeesCount(sumAttendees); + stats.setRecordingCount(recordingCount); + stats.setVideoCount(videoCount); + stats.setCapacity(capacity); + } + return stats; + } +} diff --git a/src/main/java/org/olat/restapi/system/MonitoringWebService.java b/src/main/java/org/olat/restapi/system/MonitoringWebService.java index 6cff96611e49849d0fd42e2d9f7e9038bfb0b67a..72ee48bca1cc5d715cd9e218363af7c79db0f552 100644 --- a/src/main/java/org/olat/restapi/system/MonitoringWebService.java +++ b/src/main/java/org/olat/restapi/system/MonitoringWebService.java @@ -51,6 +51,7 @@ public class MonitoringWebService { private static final ThreadsWebService threadsWebService = new ThreadsWebService(); private static final OpenOLATStatisticsWebService ooStatsWebService = new OpenOLATStatisticsWebService(); private static final VFSStatsWebService vfsStatsWebService = new VFSStatsWebService(); + private static final BigBlueButtonWebService bigBlueButtonWebService = new BigBlueButtonWebService(); public MonitoringWebService() { //make Spring happy @@ -91,6 +92,11 @@ public class MonitoringWebService { return vfsStatsWebService; } + @Path("bigbluebutton") + public BigBlueButtonWebService getBigBlueButtonStatistics() { + return bigBlueButtonWebService; + } + /** diff --git a/src/main/java/org/olat/restapi/system/vo/BigBlueButtonStatisticsVO.java b/src/main/java/org/olat/restapi/system/vo/BigBlueButtonStatisticsVO.java new file mode 100644 index 0000000000000000000000000000000000000000..2af61a6c7748767bb1726277c28c91e039ac129a --- /dev/null +++ b/src/main/java/org/olat/restapi/system/vo/BigBlueButtonStatisticsVO.java @@ -0,0 +1,57 @@ +package org.olat.restapi.system.vo; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "bigBlueButtonStatisticsVO") +public class BigBlueButtonStatisticsVO { + + private long attendeeCount; + private long meetingCount; + private long recordingCount; + private long videoCount; + private long maximalUserCount; + + + public long getAttendeesCount() { + return attendeeCount; + } + + public void setAttendeesCount(long attendees) { + this.attendeeCount = attendees; + } + + public long getMeetingsCount() { + return meetingCount; + } + + public void setMeetingsCount(long meetings) { + this.meetingCount = meetings; + } + + public long getRecordingCount() { + return recordingCount; + } + + public void setRecordingCount(long recordingCount) { + this.recordingCount = recordingCount; + } + + public long getVideoCount() { + return videoCount; + } + + public void setVideoCount(long videoCount) { + this.videoCount = videoCount; + } + + public long getCapacity() { + return maximalUserCount; + } + + public void setCapacity(long capacity) { + this.maximalUserCount = capacity; + } +} diff --git a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml index a6905f231cd6743dcfdcabb7958f3ce8f90ee0f2..2ade21fdc7e4888020f748cddfae0d101d8e509e 100644 --- a/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml +++ b/src/main/java/org/olat/upgrade/_spring/databaseUpgradeContext.xml @@ -228,6 +228,10 @@ <constructor-arg index="0" value="OLAT_14.2.13" /> <property name="alterDbStatements" value="alter_14_2_x_to_14_2_13.sql" /> </bean> + <bean id="database_upgrade_14_2_16" class="org.olat.upgrade.DatabaseUpgrade"> + <constructor-arg index="0" value="OLAT_14.2.16" /> + <property name="alterDbStatements" value="alter_14_2_x_to_14_2_16.sql" /> + </bean> <bean id="database_upgrade_15_pre_0" class="org.olat.upgrade.DatabaseUpgrade"> <constructor-arg index="0" value="OLAT_15.pre.0" /> <property name="alterDbStatements" value="alter_14_2_x_to_15_pre_0.sql" /> diff --git a/src/main/java/org/olat/user/propertyhandlers/ui/UsrPropCfgTableController.java b/src/main/java/org/olat/user/propertyhandlers/ui/UsrPropCfgTableController.java index a64e4f74bd3877c82a8962678b60811473130dd6..6471ddda91b8dd7e62c12a5d167576176097c46a 100644 --- a/src/main/java/org/olat/user/propertyhandlers/ui/UsrPropCfgTableController.java +++ b/src/main/java/org/olat/user/propertyhandlers/ui/UsrPropCfgTableController.java @@ -216,7 +216,7 @@ public class UsrPropCfgTableController extends FormBasicController { String key2Translate2 = handler.i18nColumnDescriptorLabelKey(); String[] keys2Translate = { key2Translate1, key2Translate2 }; - singleKeyTrnsCtrl = new SingleKeyTranslatorController(ureq, getWindowControl(), keys2Translate, UserPropertyHandler.class); + singleKeyTrnsCtrl = new SingleKeyTranslatorController(ureq, getWindowControl(), keys2Translate, UserPropertyHandler.class, false); listenTo(singleKeyTrnsCtrl); removeAsListenerAndDispose(translatorCallout); translatorCallout = new CloseableCalloutWindowController(ureq, getWindowControl(), singleKeyTrnsCtrl.getInitialComponent(), diff --git a/src/main/resources/database/mysql/alter_14_2_x_to_14_2_16.sql b/src/main/resources/database/mysql/alter_14_2_x_to_14_2_16.sql new file mode 100644 index 0000000000000000000000000000000000000000..653a4f486bedee86c8bc15089722c9553a662969 --- /dev/null +++ b/src/main/resources/database/mysql/alter_14_2_x_to_14_2_16.sql @@ -0,0 +1,3 @@ +-- Forum +alter table o_message add column modification_date datetime; + diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index 9bfb12beabfff6678776124b8e0fb511529ecc56..29174514bbb946619838e65bb5425ffdf5ea5e21 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -418,6 +418,7 @@ create table if not exists o_message ( topthread_id bigint, creator_id bigint, modifier_id bigint, + modification_date datetime, forum_fk bigint, statuscode integer, numofwords integer, diff --git a/src/main/resources/database/oracle/alter_14_2_x_to_14_2_16.sql b/src/main/resources/database/oracle/alter_14_2_x_to_14_2_16.sql new file mode 100644 index 0000000000000000000000000000000000000000..97b1f33e661210eee5299a077450552c549342a0 --- /dev/null +++ b/src/main/resources/database/oracle/alter_14_2_x_to_14_2_16.sql @@ -0,0 +1,3 @@ +-- Forum +alter table o_message add modification_date date; + diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index 5f911680e7fca659a629c14b48a404807e76656f..ac8aaed042648df1c43faddd23c79ade34bdced0 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -456,6 +456,7 @@ CREATE TABLE o_message ( topthread_id number(20), creator_id number(20), modifier_id number(20), + modification_date date, forum_fk number(20), statuscode number(11), numofwords number(11), diff --git a/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_16.sql b/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_16.sql new file mode 100644 index 0000000000000000000000000000000000000000..9b1f658350230fa7de3b8ab00c02ea608db1ef88 --- /dev/null +++ b/src/main/resources/database/postgresql/alter_14_2_x_to_14_2_16.sql @@ -0,0 +1,3 @@ +-- Forum +alter table o_message add column modification_date timestamp; + diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index e386e52daadd02cac208a6ef8b96c5caa26ac29d..1064d3b87f426294062fc2f0bc8596dda9241948 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -416,6 +416,7 @@ create table o_message ( topthread_id int8, creator_id int8, modifier_id int8, + modification_date timestamp, forum_fk int8, statuscode int4, numofwords int4, diff --git a/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java b/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java index e102c9d950776d481803c369f13e11ad0e04a7b8..f2fa98477781eaf41a01de760cce6347ae20bdf7 100644 --- a/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java +++ b/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java @@ -994,8 +994,54 @@ public class AssessmentModeManagerTest extends OlatTestCase { Assert.assertTrue(assessedIdentityKeys.contains(participant1.getKey())); Assert.assertTrue(assessedIdentityKeys.contains(coach2.getKey())); Assert.assertTrue(assessedIdentityKeys.contains(participant2.getKey())); - } + } + @Test + public void getAssessedIdentities_course_curriculumElements() { + Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("as-mode-39"); + RepositoryEntry entry = JunitTestHelper.deployBasicCourse(author); + Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-mode-40"); + Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-mode-41"); + Identity coach1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-mode-42"); + + Curriculum curriculum = curriculumService.createCurriculum("cur-as-mode-4", "Curriculum for assessment", "Curriculum", null); + CurriculumElement element1 = curriculumService.createCurriculumElement("Element-for-rel-1", "Element for assessment", CurriculumElementStatus.active, + null, null, null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, CurriculumLearningProgress.disabled, curriculum); + CurriculumElement element2 = curriculumService.createCurriculumElement("Element-for-rel-2", "Element for assessment", CurriculumElementStatus.active, + null, null, null, null, CurriculumCalendars.disabled, CurriculumLectures.disabled, CurriculumLearningProgress.disabled, curriculum); + + dbInstance.commit(); + curriculumService.addRepositoryEntry(element1, entry, false); + curriculumService.addRepositoryEntry(element2, entry, false); + curriculumService.addMember(element1, participant1, CurriculumRoles.participant); + curriculumService.addMember(element2, participant2, CurriculumRoles.participant); + curriculumService.addMember(element1, coach1, CurriculumRoles.coach); + curriculumService.addMember(element2, coach1, CurriculumRoles.coach); + dbInstance.commitAndCloseSession(); + + Identity participant3 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-mode-23"); + Identity coach2 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-mode-24"); + repositoryEntryRelationDao.addRole(participant3, entry, GroupRoles.participant.name()); + repositoryEntryRelationDao.addRole(coach2, entry, GroupRoles.coach.name()); + repositoryEntryRelationDao.addRole(author, entry, GroupRoles.owner.name()); + + AssessmentMode mode = createMinimalAssessmentmode(entry); + mode.setTargetAudience(AssessmentMode.Target.curriculumEls); + mode.setApplySettingsForCoach(true); + mode = assessmentModeMgr.persist(mode); + + AssessmentModeToCurriculumElement modeToElement = assessmentModeMgr.createAssessmentModeToCurriculumElement(mode, element1); + mode.getCurriculumElements().add(modeToElement); + mode = assessmentModeMgr.merge(mode, true); + dbInstance.commitAndCloseSession(); + Assert.assertNotNull(mode); + + Set<Long> assessedIdentityKeys = assessmentModeMgr.getAssessedIdentityKeys(mode); + Assert.assertNotNull(assessedIdentityKeys); + Assert.assertEquals(2, assessedIdentityKeys.size()); + Assert.assertTrue(assessedIdentityKeys.contains(coach1.getKey())); + Assert.assertTrue(assessedIdentityKeys.contains(participant1.getKey())); + } @Test public void isIpAllowed_exactMatch() {