Skip to content
Snippets Groups Projects
Commit f8411d92 authored by srosse's avatar srosse
Browse files

Merge OpenOLAT default branch to OpenOLAT qti with 7568eceabcdbbf498acf3a8aec97a252a2c48521

parents cb546b93 b1ce4165
No related branches found
No related tags found
No related merge requests found
Showing
with 292 additions and 126 deletions
......@@ -134,3 +134,4 @@ bc8ce641a5620f5717e9a73e31028d41ab7cdc5d OpenOLAT 10.4.4
d355c6357d0e5aeb25fc978b747824447a214b88 OpenOLAT 10.4.5
fef7f6b2e2628d242e93f86d208f4cfb9c807d7c OpenOLAT 10.4.6
b38ed621ea53507fbf41eb616648ebad2340e613 OpenOLAT 10.4.7
273a6270a08460c07fdfbb53e31547b9c7e1c8c9 OpenOLAT 10.4.8
......@@ -141,7 +141,14 @@ public class ICalServlet extends HttpServlet {
private void getIcalDocument(String requestUrl, HttpServletResponse response)
throws ValidationException, IOException {
// get the individual path tokens
String pathInfo = requestUrl.replaceAll(".ics", "");
String pathInfo;
int icsIndex = requestUrl.indexOf(".ics");
if(icsIndex > 0) {
pathInfo = requestUrl.substring(0, icsIndex);
} else {
pathInfo = requestUrl;
}
String[] pathInfoTokens = pathInfo.split("/");
if(pathInfoTokens.length < 4) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, requestUrl);
......
......@@ -10,4 +10,4 @@ webdav.on=ein
webdav.termsfolders=Kurse nach Semesterdaten gruppieren
webdav.for.learners.participants=Zugriff für Studenten / Betreuer Kursen
webdav.for.learners.bookmarks=Zugriff für Studenten / Betreuer Favoriten
webdav.prepend.reference=Kursreferenz zu Titel voranstellen
\ No newline at end of file
webdav.prepend.reference=Kennzeichen zu Titel voranstellen
\ No newline at end of file
......@@ -10,4 +10,4 @@ webdav.on=enabled
webdav.termsfolders=Group courses by semester terms
webdav.for.learners.participants=Enable access for courses where user is participant or coach
webdav.for.learners.bookmarks=Enable for courses that users marked as favorite
webdav.prepend.reference=Prepend course reference to title
\ No newline at end of file
webdav.prepend.reference=Prepend external course reference to title
\ No newline at end of file
......@@ -9,5 +9,5 @@ webdav.for.learners.participants=Acc\u00E8s aux cours pour les \u00E9tudiants et
webdav.link=Montre les liens WebDAV
webdav.module=Acc\u00E8s WebDAV
webdav.on=on
webdav.prepend.reference=Ajouter la r\u00E9f\u00E9rence au nom du cours
webdav.prepend.reference=Ajouter la r\u00E9f\u00E9rence externe au nom du cours
webdav.termsfolders=Grouper les cours par semestre
......@@ -112,8 +112,8 @@ class CoursefolderWebDAVMergeSource extends WebDAVMergeSource {
duplicates.add(re);
String displayName = re.getDisplayname();
if(prependReference && StringHelper.containsNonWhitespace(re.getExternalId())) {
displayName = re.getExternalId() + " " + displayName;
if(prependReference && StringHelper.containsNonWhitespace(re.getExternalRef())) {
displayName = re.getExternalRef() + " " + displayName;
}
String courseTitle = RequestUtil.normalizeFilename(displayName);
NamedContainerImpl cfContainer = new CoursefolderWebDAVNamedContainer(courseTitle, re, editor ? null : identityEnv);
......
......@@ -27,8 +27,11 @@ package org.olat.course.nodes;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.stack.BreadcrumbPanel;
import org.olat.core.gui.control.Controller;
......@@ -53,6 +56,10 @@ import org.olat.course.properties.PersistingCoursePropertyManager;
import org.olat.course.run.navigation.NodeRunConstructionResult;
import org.olat.course.run.userview.NodeEvaluation;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.group.BusinessGroupService;
import org.olat.group.BusinessGroupShort;
import org.olat.group.area.BGArea;
import org.olat.group.area.BGAreaManager;
import org.olat.modules.ModuleConfiguration;
import org.olat.repository.RepositoryEntry;
......@@ -66,6 +73,7 @@ import org.olat.repository.RepositoryEntry;
*/
public class ENCourseNode extends AbstractAccessableCourseNode {
private static final String PACKAGE = Util.getPackageName(ENCourseNode.class);
private static final String PACKAGE_COND = Util.getPackageName(ConditionEditController.class);
/**
* property name for the initial enrollment date will be set only the first
......@@ -186,44 +194,28 @@ public class ENCourseNode extends AbstractAccessableCourseNode {
oneClickStatusCache = null;
// only here we know which translator to take for translating condition
// error messages
String translatorStr = Util.getPackageName(ConditionEditController.class);
List<StatusDescription> condErrs = isConfigValidWithTranslator(cev, translatorStr, getConditionExpressions());
List<StatusDescription> condErrs = isConfigValidWithTranslator(cev, PACKAGE_COND, getConditionExpressions());
List<StatusDescription> missingNames = new ArrayList<StatusDescription>();
/*
* check group and area names for existence
*/
String nodeId = getIdent();
ModuleConfiguration mc = getModuleConfiguration();
String areaStr = (String) mc.get(CONFIG_AREANAME);
if (areaStr != null) {
String[] areas = areaStr.split(",");
for (int i = 0; i < areas.length; i++) {
String trimmed = areas[i] != null ?
FilterFactory.getHtmlTagsFilter().filter(areas[i]).trim() : areas[i];
if (!trimmed.equals("") && !cev.existsArea(trimmed)) {
StatusDescription sd = new StatusDescription(StatusDescription.WARNING, "error.notfound.name", "solution.checkgroupmanagement",
new String[] { "NONE", trimmed }, translatorStr);
sd.setDescriptionForUnit(nodeId);
missingNames.add(sd);
}
}
String areaNames = (String) mc.get(CONFIG_AREANAME);
List<Long> areaKeys = mc.getList(ENCourseNode.CONFIG_AREA_IDS, Long.class);
List<String> missingAreas = getMissingAreas(areaKeys, areaNames, cev);
if(missingAreas.size() > 0) {
missingNames.add(addStatusErrorMissing(missingAreas));
}
String groupStr = (String) mc.get(CONFIG_GROUPNAME);
if (groupStr != null) {
String[] groups = groupStr.split(",");
for (int i = 0; i < groups.length; i++) {
String trimmed = groups[i] != null ?
FilterFactory.getHtmlTagsFilter().filter(groups[i]).trim() : groups[i];
if (!trimmed.equals("") && !cev.existsGroup(trimmed)) {
StatusDescription sd = new StatusDescription(StatusDescription.WARNING, "error.notfound.name", "solution.checkgroupmanagement",
new String[] { "NONE", trimmed }, translatorStr);
sd.setDescriptionForUnit(nodeId);
missingNames.add(sd);
}
}
String groupNames = (String) mc.get(CONFIG_GROUPNAME);
List<Long> groupKeys = mc.getList(ENCourseNode.CONFIG_GROUP_IDS, Long.class);
List<String> missingGroups = getMissingBusinessGroups(groupKeys, groupNames, cev);
if(missingGroups.size() > 0) {
missingNames.add(addStatusErrorMissing(missingGroups));
}
missingNames.addAll(condErrs);
/*
* sort -> Errors > Warnings > Infos and remove NOERRORS, if
......@@ -232,6 +224,122 @@ public class ENCourseNode extends AbstractAccessableCourseNode {
oneClickStatusCache = StatusDescriptionHelper.sort(missingNames);
return oneClickStatusCache;
}
private StatusDescription addStatusErrorMissing(List<String> missingObjects) {
String labelKey = missingObjects.size() == 1 ? "error.notfound.name" : "error.notfound.names";
StringBuilder missing = new StringBuilder();
for(String missingObject:missingObjects) {
if(missing.length() > 0) missing.append(", ");
missing.append(missingObject);
}
StatusDescription sd = new StatusDescription(StatusDescription.WARNING, labelKey, "solution.checkgroupmanagement",
new String[] { "NONE", missing.toString() }, PACKAGE_COND);
sd.setDescriptionForUnit(getIdent());
return sd;
}
public List<String> getMissingAreas(List<Long> areaKeys, String areaNames, CourseEditorEnv cev) {
List<String> missingNames = new ArrayList<>();
if(areaKeys == null || areaKeys.isEmpty()) {
if (areaNames != null) {
String[] areas = areaNames.split(",");
for (int i = 0; i < areas.length; i++) {
String trimmed = areas[i] != null ?
FilterFactory.getHtmlTagsFilter().filter(areas[i]).trim() : areas[i];
if (!trimmed.equals("") && !cev.existsGroup(trimmed)) {
missingNames.add(trimmed);
}
}
}
} else {
Set<Long> missingAreas = new HashSet<Long>();
List<BGArea> existingAreas = CoreSpringFactory.getImpl(BGAreaManager.class).loadAreas(areaKeys);
List<String> knowNames = new ArrayList<>();
if (areaNames != null) {
String[] areas = areaNames.split(",");
for (int i = 0; i < areas.length; i++) {
String trimmed = areas[i] != null ? FilterFactory.getHtmlTagsFilter().filter(areas[i]).trim() : areas[i];
knowNames.add(trimmed);
}
}
a_a:
for(Long areaKey:areaKeys) {
for(BGArea area:existingAreas) {
if(area.getKey().equals(areaKey)) {
String trimmed = area.getName() != null ? FilterFactory.getHtmlTagsFilter().filter(area.getName()).trim() : area.getName();
knowNames.remove(trimmed);
continue a_a;
}
}
missingAreas.add(areaKey);
}
if(missingAreas.size() > 0 ) {
if(knowNames.size() > 0) {
missingNames.addAll(knowNames);
} else {
for(Long missingArea:missingAreas) {
missingNames.add(missingArea.toString());
}
}
}
}
return missingNames;
}
public List<String> getMissingBusinessGroups(List<Long> groupKeys, String groupNames, CourseEditorEnv cev) {
List<String> missingNames = new ArrayList<>();
if(groupKeys == null || groupKeys.isEmpty()) {
if (groupNames != null) {
String[] groups = groupNames.split(",");
for (int i = 0; i < groups.length; i++) {
String trimmed = groups[i] != null ?
FilterFactory.getHtmlTagsFilter().filter(groups[i]).trim() : groups[i];
if (!trimmed.equals("") && !cev.existsGroup(trimmed)) {
missingNames.add(trimmed);
}
}
}
} else {
Set<Long> missingGroups = new HashSet<Long>();
List<BusinessGroupShort> existingGroups = CoreSpringFactory.getImpl(BusinessGroupService.class).loadShortBusinessGroups(groupKeys);
List<String> knowNames = new ArrayList<>();
if (groupNames != null) {
String[] groups = groupNames.split(",");
for (int i = 0; i < groups.length; i++) {
String trimmed = groups[i] != null ? FilterFactory.getHtmlTagsFilter().filter(groups[i]).trim() : groups[i];
knowNames.add(trimmed);
}
}
a_a:
for(Long groupKey:groupKeys) {
for(BusinessGroupShort group:existingGroups) {
if(group.getKey().equals(groupKey)) {
String trimmed = group.getName() != null ? FilterFactory.getHtmlTagsFilter().filter(group.getName()).trim() : group.getName();
knowNames.remove(trimmed);
continue a_a;
}
}
missingGroups.add(groupKey);
}
if(missingGroups.size() > 0 ) {
if(knowNames.size() > 0) {
missingNames.addAll(knowNames);
} else {
for(Long missingGroup:missingGroups) {
missingNames.add(missingGroup.toString());
}
}
}
}
return missingNames;
}
/**
* @see org.olat.course.nodes.CourseNode#getReferencedRepositoryEntry()
......
......@@ -450,29 +450,33 @@ public abstract class AbstractMemberListController extends FormBasicController i
}
protected void confirmDelete(UserRequest ureq, List<MemberView> members) {
int numOfOwners =
repoEntry == null ? businessGroupService.countMembers(businessGroup, GroupRoles.coach.name())
: repositoryService.countMembers(repoEntry, GroupRoles.owner.name());
int numOfRemovedOwner = 0;
List<Long> identityKeys = new ArrayList<Long>();
for(MemberView member:members) {
identityKeys.add(member.getIdentityKey());
if(member.getMembership().isOwner()) {
numOfRemovedOwner++;
}
}
if(numOfRemovedOwner == 0 || numOfOwners - numOfRemovedOwner > 0) {
List<Identity> ids = securityManager.loadIdentityByKeys(identityKeys);
leaveDialogBox = new MemberLeaveConfirmationController(ureq, getWindowControl(), ids);
listenTo(leaveDialogBox);
cmc = new CloseableModalController(getWindowControl(), translate("close"), leaveDialogBox.getInitialComponent(),
true, translate("edit.member"));
cmc.activate();
listenTo(cmc);
if(members.isEmpty()) {
showWarning("error.select.one.user");
} else {
showWarning("error.atleastone");
int numOfOwners =
repoEntry == null ? businessGroupService.countMembers(businessGroup, GroupRoles.coach.name())
: repositoryService.countMembers(repoEntry, GroupRoles.owner.name());
int numOfRemovedOwner = 0;
List<Long> identityKeys = new ArrayList<Long>();
for(MemberView member:members) {
identityKeys.add(member.getIdentityKey());
if(member.getMembership().isOwner()) {
numOfRemovedOwner++;
}
}
if(numOfRemovedOwner == 0 || numOfOwners - numOfRemovedOwner > 0) {
List<Identity> ids = securityManager.loadIdentityByKeys(identityKeys);
leaveDialogBox = new MemberLeaveConfirmationController(ureq, getWindowControl(), ids);
listenTo(leaveDialogBox);
cmc = new CloseableModalController(getWindowControl(), translate("close"), leaveDialogBox.getInitialComponent(),
true, translate("edit.member"));
cmc.activate();
listenTo(cmc);
} else {
showWarning("error.atleastone");
}
}
}
......@@ -489,14 +493,18 @@ public abstract class AbstractMemberListController extends FormBasicController i
}
protected void openEdit(UserRequest ureq, List<MemberView> members) {
List<Long> identityKeys = getMemberKeys(members);
List<Identity> identities = securityManager.loadIdentityByKeys(identityKeys);
editMembersCtrl = new EditMembershipController(ureq, getWindowControl(), identities, repoEntry, businessGroup);
listenTo(editMembersCtrl);
cmc = new CloseableModalController(getWindowControl(), translate("close"), editMembersCtrl.getInitialComponent(),
true, translate("edit.member"));
cmc.activate();
listenTo(cmc);
if(members.isEmpty()) {
showWarning("error.select.one.user");
} else {
List<Long> identityKeys = getMemberKeys(members);
List<Identity> identities = securityManager.loadIdentityByKeys(identityKeys);
editMembersCtrl = new EditMembershipController(ureq, getWindowControl(), identities, repoEntry, businessGroup);
listenTo(editMembersCtrl);
cmc = new CloseableModalController(getWindowControl(), translate("close"), editMembersCtrl.getInitialComponent(),
true, translate("edit.member"));
cmc.activate();
listenTo(cmc);
}
}
protected void doSearch(String search) {
......
#Mon Mar 02 09:54:04 CET 2009
create.form.title=Neue Gruppe erstellen
create.group=Gruppe erstellen
create.group.description=Erzeugen Sie eine neue Gruppe mit der unten stehenden Schaltfläche. Als Betreuer dieser Gruppe können Sie danach die Gruppenwerkzeuge freischalten, Benutzer hinzufügen oder die Gruppe veröffentlichen.
create.group.description=Erzeugen Sie eine neue Gruppe mit der unten stehenden Schaltfl\u00E4che. Als Betreuer dieser Gruppe k\u00F6nnen Sie danach die Gruppenwerkzeuge freischalten, Benutzer hinzuf\u00FCgen oder die Gruppe ver\u00F6ffentlichen.
copy.group=Kopieren
deup.members=Mitglieder bereinigen
dedup.members.typ=Rolle
......@@ -10,7 +10,7 @@ dedup.members.particpants=Teilnehmer
dedup.members.info1=Wollen Sie die Mitglieder wirklich bereinigen?
dedup.members.info2=Bei diesem Prozess werden jene Benutzer als Kursmitglieder ausgetragen, die sowohl Kurs- als auch Gruppenmitglied des Kurses sind (Duplikate).
dedup.members.info3={0} Benutzer wurden gefunden die sowohl Kursmitglieder als auch Gruppenmitglieder des Kurses sind.
dedup.members.info4=Wählen Sie ob die Bereinigung für Betreuer und/oder die Teilnehmer durchgeführt werden soll.
dedup.members.info4=W\u00E4hlen Sie ob die Bereinigung f\u00FCr Betreuer und/oder die Teilnehmer durchgef\u00FChrt werden soll.
dialog.modal.bg.delete.title=Gruppe l\u00F6schen?
dialog.modal.bg.delete.text=Wollen Sie die Gruppe "{0}" wirklich l\u00F6schen?
dialog.modal.bg.mail.text=Wollen Sie die Mitglieder per Mail benachrichtigen?
......@@ -22,8 +22,9 @@ remove.send.mail=Benachrichtigung
remove.send.mail.label=E-Mail versenden
error.atleastone=Es muss mindestens einen Besitzer im Kurs geben.
error.msg.send.no.rcps=$org.olat.modules.co\:error.msg.send.no.rcps
error.managed.group=Die gewählte Gruppe "{0}" wird von einem externen System verwaltet. Die Operation kann nicht ausgeführt werden.
error.select.one=Sie müssen mindestens eine Gruppe w\u00E4hlen.
error.managed.group=Die gew\u00E4hlte Gruppe "{0}" wird von einem externen System verwaltet. Die Operation kann nicht ausgef\u00FChrt werden.
error.select.one=Sie m\u00FCssen mindestens eine Gruppe w\u00E4hlen.
error.select.one.user=Sie m\u00FCssen mindestens einen Benutzer w\u00E4hlen.
mail.member=E-Mail
main.menu.title=Gruppen
main.menu.title.alt=Gruppen
......@@ -32,7 +33,7 @@ index.intro=In der untenstehenden Liste finden Sie alle Gruppen, an denen Sie te
index.table.nogroup=Sie sind in keiner Gruppe eingetragen.
info.group.deleted=Die Gruppe wurde gel\u00F6scht.
request.leaving.subject=Anfrage Gruppe "{0}" mit ID "{1}" zu verlassen
request.leaving.body=Sehr geehrter Gruppenbetreuer<br /><br />Ich m\u00F6chte dieser Gruppe verlasse<br /><br />Mit freundliche Grüsse<br />{3} {4}<br />\Gruppename: {0}<br />Gruppe ID:{1}<br />Gruppekurse: {2}
request.leaving.body=Sehr geehrter Gruppenbetreuer<br /><br />Ich m\u00F6chte dieser Gruppe verlasse<br /><br />Mit freundliche Gr\u00FCsse<br />{3} {4}<br />\Gruppename: {0}<br />Gruppe ID:{1}<br />Gruppekurse: {2}
menu.group.admin=Gruppenverwaltung
menu.group.admin.alt=Gruppenverwaltung
menu.index=Gruppen
......@@ -42,10 +43,10 @@ my.groups.alt=Arbeiten Sie mit Ihren Gruppen
open.groups=Ver\u00F6ffentlichte Gruppen
open.groups.alt=Arbeitsgruppen in die \u00F6ffentlich sind und an denen ich teilnehmen kann.
msg.atleastone=Es muss mindestens ein Betreuer in der Gruppe eingetragen sein.
msg.alleastone.editable.group=Sie m\u00FCssen mindestens eine Gruppe wählen, die Sie besitzen.
msg.alleastone.editable.group=Sie m\u00FCssen mindestens eine Gruppe w\u00E4hlen, die Sie besitzen.
user.notfound=Folgende Benutzer wurden nicht gefunden: {0}
open.header=Öffentliche Gruppen
open.header=\u00F6ffentliche Gruppen
open.intro=In dieser Liste finden Sie alle ver\u00F6ffentlichten Gruppen denen Sie beitreten k\u00F6nnen.
open.nogroup=Es wurden keine Gruppe gefunden die Ihren Kriterien entsprechen.
opengroups.all=Alle Gruppen
......@@ -64,7 +65,7 @@ search.waiting=Warteliste
search.public=Public group
search.all=Alle
search.none=-
search.open=Veröffentlicht
search.open=Ver\u00F6ffentlicht
search.roles=Rolle
search.yes=Ja
search.no=Nein
......@@ -103,16 +104,16 @@ table.header.role=Rolle
table.header.firstTime=Beitritt
table.header.lastTime=Zuletzt besucht
table.header.key=ID
table.header.freePlaces=Plätze
table.header.freePlaces=Pl\u00E4tze
table.header.tutorsCount=Betreuer
table.header.participantsCount=Belegt
table.header.waitingListCount=Warteliste
table.access=Beitreten
table.access.waitingList=Warteliste eintragen
table.delete=Löschen
table.delete=L\u00F6schen
table.email=E-Mail versenden
table.duplicate=Duplizieren
table.merge=Zusammenführen
table.merge=Zusammenf\u00FChren
table.users.management=Benutzer verwalten
table.config=Konfigurieren
table.leave=Verlassen
......@@ -121,13 +122,13 @@ tools.add.header=Erstellen
tools.delete.header=L\u00F6schen
tools.delete.unusedgroup=Arbeitsgruppen
action=Aktion
merge.group=Zusammenführen
merge.group=Zusammenf\u00FChren
email.group=E-Mail versenden
config.group=Konfigurieren
users.group=Benutzer verwalten
notification.mail.added.body=*** Das ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht *** \n\nSie wurden von {0} {1} ({2}) in eine Arbeitsgruppe eingeladen\: \n\nGruppenname\: $groupname\nBeschreibung\: $groupdescription\n\nSind Sie damit nicht einverstanden, so k\u00F6nnen Sie sich aus der Arbeitsgruppe wieder austragen.
notification.mail.added.self.body=*** Das ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht *** \n\n Sie haben in OLAT eine Arbeitsgruppe eröffnet\: \n\nGruppenname\: $groupname\nBeschreibung\: $groupdescription\n\nSie k\u00F6nnen die Gruppe jederzeit wieder löschen.
notification.mail.added.self.body=*** Das ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht *** \n\n Sie haben in OLAT eine Arbeitsgruppe er\u00F6ffnet\: \n\nGruppenname\: $groupname\nBeschreibung\: $groupdescription\n\nSie k\u00F6nnen die Gruppe jederzeit wieder l\u00F6schen.
notification.mail.added.self.subject=Gruppe $groupname
notification.mail.added.subject=Gruppe $groupname
notification.mail.deleted.body=*** Das ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht *** \n\n Sie wurden von {0} {1} ({2}) aus der Arbeitsgruppe ausgetragen, da sie gel\u00F6scht wurde\: \n\nGruppenname\: $groupname\nBeschreibung\: $groupdescription\n\nBei Fragen kontaktieren Sie bitte {0} {1} ({2}).
......@@ -138,18 +139,18 @@ notification.mail.removed.self.subject=Gruppe $groupname\: Sie haben sich ausget
notification.mail.removed.subject=Gruppe $groupname\: Sie wurden ausgetragen.
pending.reservations=<h4>Bestätigung Teilnahme in Gruppen und Kursen</h4>Sie wurden in die folgenden Gruppen oder Kurse eingeladen. Wählen Sie für alle aufgeführten Gruppe und Kurse die Schaltfläche "$:accept" oder "$:reject" und schliessen Sie mit "$org.olat.core:ok" ab. Sie können die Bestätigung auch zu einem späteren Zeitpunkt durchführen, wählen Sie in dem Fall "$org.olat.core:cancel".
pending.reservations=<h4>Best\u00E4tigung Teilnahme in Gruppen und Kursen</h4>Sie wurden in die folgenden Gruppen oder Kurse eingeladen. W\u00E4hlen Sie f\u00FCr alle aufgef\u00FChrten Gruppe und Kurse die Schaltfl\u00E4che "$:accept" oder "$:reject" und schliessen Sie mit "$org.olat.core:ok" ab. Sie k\u00F6nnen die Best\u00E4tigung auch zu einem sp\u00E4teren Zeitpunkt durchf\u00FChren, w\u00E4hlen Sie in dem Fall "$org.olat.core:cancel".
course.membership.creation=Kurs Beitritt
course.lastTime=Zuletzt geöffnet
course.lastTime=Zuletzt ge\u00F6ffnet
course.numOfVisits=Anzahl Kursaufrufe
home=Visitenkarte
assessment=Bewertungswerkzeug
add.member=Mitglied hinzufügen
add.member=Mitglied hinzuf\u00FCgen
edit.member=Mitglied bearbeiten
edit.members=Bearbeiten
edit.member.groups=Gruppenmitgliedschaften
import.member=Mitglieder hinzufügen
import.member=Mitglieder hinzuf\u00FCgen
......@@ -159,7 +160,7 @@ role.group.waiting=Warteliste
role.repo.owner=Besitzer
role.repo.tutor=Betreuer
role.repo.participant=Teilnehmer
role.pending=Bestätigung ausstehend
role.pending=Best\u00E4tigung ausstehend
edit.member.title=Mitgliederrechte Kurs "{0}"
......@@ -182,10 +183,10 @@ table.header.waitingList=Warteliste
reservation.coach=als Betreuer
group.used.in.course=Diese Gruppe wird verwendet in folgenden Kursen:
accept=Bestätigen
accept=Best\u00E4tigen
reject=Ablehnen
confirm.accept=Mitgliedschaft wird bestätigt
confirm.accept=Mitgliedschaft wird best\u00E4tigt
confirm.reject=Mitgliedschaft wird abgelehnt
nomembers=Es wurden keine Mitglieder gefunden die Ihren Kriterien entsprechen.
......
......@@ -45,6 +45,7 @@ error.atleastone=At least one owner is required in a course.
error.managed.group=The selected group "{0}" is managed by an external system. The operation cannot be executed.
error.msg.send.no.rcps=$org.olat.modules.co\:error.msg.send.no.rcps
error.select.one=You need to select at least one group.
error.select.one.user=You need to select at least one user.
group.access.success=Access to group is successful
group.used.in.course=This group is used in the following courses\:
hide=Hide information
......
......@@ -45,6 +45,7 @@ error.atleastone=Le cours doit avoir au moins un propri\u00E9taire.
error.managed.group=Les groupes s\u00E9lectionn\u00E9s "{0}" sont administr\u00E9s par un syst\u00E8me externe. L'op\u00E9ration ne peut pas \u00EAtre effectu\u00E9e.
error.msg.send.no.rcps=$org.olat.modules.co\:error.msg.send.no.rcps
error.select.one=Vous devez s\u00E9lectionner au moins un groupe.
error.select.one.user=Vous devez s\u00E9lectionner au moins un utilisateur.
group.access.success=L'acc\u00E8s au groupe a \u00E9t\u00E9 couronn\u00E9 de succ\u00E8s.
group.used.in.course=Ce groupe est utilis\u00E9 par les cours suivants\:
hide=Masquer les informations
......
......@@ -527,19 +527,38 @@ public class CoachingDAO {
private boolean getCoursesStatisticsUserInfosForOwner(Identity coach, Map<Long,CourseStatEntry> map) {
NativeQueryBuilder sb = new NativeQueryBuilder(1024, dbInstance);
sb.append("select")
.append(" sg_re.repositoryentry_id as re_id,")
.append(" count(distinct sg_participant.fk_identity_id) as student_id,")
.append(" count(distinct pg_initial_launch.id) as pg_id")
.append(" from o_repositoryentry sg_re ")
.append(" inner join o_re_to_group owngroup on (owngroup.fk_entry_id = sg_re.repositoryentry_id and owngroup.r_defgroup=").appendTrue().append(")")
.append(" inner join o_bs_group_member sg_coach on (sg_coach.fk_group_id=owngroup.fk_group_id and sg_coach.g_role = 'owner')")
.append(" inner join o_re_to_group togroup on (togroup.fk_entry_id = sg_re.repositoryentry_id)")
.append(" inner join o_bs_group_member sg_participant on (sg_participant.fk_group_id=togroup.fk_group_id and sg_participant.g_role='participant')")
.append(" left join o_as_user_course_infos pg_initial_launch")
.append(" on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id)")
.append(" where sg_coach.fk_identity_id=:coachKey and sg_re.accesscode >= ").append(RepositoryEntry.ACC_OWNERS)
.append(" group by sg_re.repositoryentry_id");
if(dbInstance.isMySQL()) {
sb.append("select")
.append(" sg_re.repositoryentry_id as re_id,")
.append(" count(distinct sg_participant.fk_identity_id) as student_id,")
.append(" count(distinct pg_initial_launch.id) as pg_id")
.append(" from o_repositoryentry sg_re ")
.append(" inner join o_re_to_group owngroup on (owngroup.fk_entry_id = sg_re.repositoryentry_id and owngroup.r_defgroup=").appendTrue().append(")")
.append(" inner join o_bs_group_member sg_coach on (sg_coach.fk_group_id=owngroup.fk_group_id and sg_coach.g_role = 'owner')")
.append(" inner join o_re_to_group togroup on (togroup.fk_entry_id = sg_re.repositoryentry_id)")
.append(" inner join o_bs_group_member sg_participant on (sg_participant.fk_group_id=togroup.fk_group_id and sg_participant.g_role='participant')")
.append(" left join o_as_user_course_infos pg_initial_launch")
.append(" on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id)")
.append(" where sg_coach.fk_identity_id=:coachKey and sg_re.accesscode >= ").append(RepositoryEntry.ACC_OWNERS)
.append(" group by sg_re.repositoryentry_id");
} else {
sb.append("select")
.append(" sg_re.repositoryentry_id as re_id,")
.append(" count(distinct sg_participant.fk_identity_id) as student_id,")
.append(" count(distinct pg_initial_launch.id) as pg_id")
.append(" from o_repositoryentry sg_re ")
.append(" inner join o_re_to_group togroup on (togroup.fk_entry_id = sg_re.repositoryentry_id)")
.append(" inner join o_bs_group_member sg_participant on (sg_participant.fk_group_id=togroup.fk_group_id and sg_participant.g_role='participant')")
.append(" left join o_as_user_course_infos pg_initial_launch")
.append(" on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id)")
.append(" where sg_re.accesscode >= ").append(RepositoryEntry.ACC_OWNERS).append(" and sg_re.fk_olatresource in (")
.append(" select sg_res.resource_id from o_olatresource sg_res where sg_res.resname = 'CourseModule'")
.append(" ) and exists (")
.append(" select owngroup.id from o_re_to_group owngroup inner join o_bs_group_member sg_owner on (sg_owner.fk_group_id=owngroup.fk_group_id)")
.append(" where owngroup.fk_entry_id = sg_re.repositoryentry_id and owngroup.r_defgroup=").appendTrue().append(" and sg_owner.g_role='owner' and sg_owner.fk_identity_id=:coachKey")
.append(" )")
.append(" group by sg_re.repositoryentry_id");
}
List<?> rawList = dbInstance.getCurrentEntityManager()
.createNativeQuery(sb.toString())
......@@ -669,20 +688,39 @@ public class CoachingDAO {
private boolean getStudentsStastisticInfosForOwner(IdentityRef coach, Map<Long, StudentStatEntry> map) {
NativeQueryBuilder sb = new NativeQueryBuilder(1024, dbInstance);
sb.append("select")
.append(" sg_participant.fk_identity_id as part_id,")
.append(" ").appendToArray("sg_re.repositoryentry_id").append(" as re_ids,")
.append(" ").appendToArray("pg_initial_launch.id").append(" as pg_ids")
.append(" from o_repositoryentry sg_re")
.append(" inner join o_olatresource sg_res on (sg_res.resource_id = sg_re.fk_olatresource and sg_res.resname = 'CourseModule')")
.append(" inner join o_re_to_group owngroup on (owngroup.fk_entry_id = sg_re.repositoryentry_id and owngroup.r_defgroup=").appendTrue().append(")")
.append(" inner join o_bs_group_member sg_owner on (sg_owner.fk_group_id=owngroup.fk_group_id and sg_owner.g_role = 'owner')")
.append(" inner join o_re_to_group togroup on (togroup.fk_entry_id = sg_re.repositoryentry_id)")
.append(" inner join o_bs_group_member sg_participant on (sg_participant.fk_group_id=togroup.fk_group_id and sg_participant.g_role='participant')")
.append(" left join o_as_user_course_infos pg_initial_launch")
.append(" on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id)")
.append(" where sg_owner.fk_identity_id=:coachKey and sg_re.accesscode >= ").append(RepositoryEntry.ACC_OWNERS)
.append(" group by sg_participant.fk_identity_id");
if(dbInstance.isMySQL()) {
sb.append("select")
.append(" sg_participant.fk_identity_id as part_id,")
.append(" ").appendToArray("sg_re.repositoryentry_id").append(" as re_ids,")
.append(" ").appendToArray("pg_initial_launch.id").append(" as pg_ids")
.append(" from o_repositoryentry sg_re")
.append(" inner join o_olatresource sg_res on (sg_res.resource_id = sg_re.fk_olatresource and sg_res.resname = 'CourseModule')")
.append(" inner join o_re_to_group owngroup on (owngroup.fk_entry_id = sg_re.repositoryentry_id and owngroup.r_defgroup=").appendTrue().append(")")
.append(" inner join o_bs_group_member sg_owner on (sg_owner.fk_group_id=owngroup.fk_group_id and sg_owner.g_role = 'owner')")
.append(" inner join o_re_to_group togroup on (togroup.fk_entry_id = sg_re.repositoryentry_id)")
.append(" inner join o_bs_group_member sg_participant on (sg_participant.fk_group_id=togroup.fk_group_id and sg_participant.g_role='participant')")
.append(" left join o_as_user_course_infos pg_initial_launch")
.append(" on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id)")
.append(" where sg_owner.fk_identity_id=:coachKey and sg_re.accesscode >= ").append(RepositoryEntry.ACC_OWNERS)
.append(" group by sg_participant.fk_identity_id");
} else {
sb.append("select")
.append(" sg_participant.fk_identity_id as part_id,")
.append(" ").appendToArray("sg_re.repositoryentry_id").append(" as re_ids,")
.append(" ").appendToArray("pg_initial_launch.id").append(" as pg_ids")
.append(" from o_repositoryentry sg_re")
.append(" inner join o_re_to_group togroup on (togroup.fk_entry_id = sg_re.repositoryentry_id)")
.append(" inner join o_bs_group_member sg_participant on (sg_participant.fk_group_id=togroup.fk_group_id and sg_participant.g_role='participant')")
.append(" left join o_as_user_course_infos pg_initial_launch")
.append(" on (pg_initial_launch.fk_resource_id = sg_re.fk_olatresource and pg_initial_launch.fk_identity = sg_participant.fk_identity_id)")
.append(" where sg_re.accesscode >= ").append(RepositoryEntry.ACC_OWNERS).append(" and sg_re.fk_olatresource in (")
.append(" select sg_res.resource_id from o_olatresource sg_res where sg_res.resname = 'CourseModule'")
.append(" ) and exists (")
.append(" select owngroup.id from o_re_to_group owngroup inner join o_bs_group_member sg_owner on (sg_owner.fk_group_id=owngroup.fk_group_id)")
.append(" where owngroup.fk_entry_id = sg_re.repositoryentry_id and owngroup.r_defgroup=").appendTrue().append(" and sg_owner.g_role='owner' and sg_owner.fk_identity_id=:coachKey")
.append(" )")
.append(" group by sg_participant.fk_identity_id");
}
List<?> rawList = dbInstance.getCurrentEntityManager()
.createNativeQuery(sb.toString())
......
......@@ -84,6 +84,7 @@ public class EnrollmentConfigurationPage {
By createGroupBy = By.cssSelector("div.o_button_group_right a");
browser.findElement(createGroupBy).click();
OOGraphene.waitBusy(browser);
OOGraphene.waitModalDialog(browser);
//fill the form
By nameBy = By.cssSelector(".o_sel_group_edit_title input[type='text']");
......
......@@ -57,6 +57,7 @@ public class InfoMessageCEPage {
By createBy = By.className("o_sel_course_info_create_msg");
browser.findElement(createBy).click();
OOGraphene.waitBusy(browser);
OOGraphene.waitModalDialog(browser);
return this;
}
......
......@@ -102,6 +102,7 @@ public class ForumPage {
By newThreadBy = By.className("o_sel_forum_thread_new");
browser.findElement(newThreadBy).click();
OOGraphene.waitBusy(browser);
OOGraphene.waitModalDialog(browser);
//fill the form
By titleBy = By.cssSelector("div.modal-content form div.o_sel_forum_message_title input[type='text']");
......
......@@ -49,6 +49,11 @@ public class OOGraphene {
private static final By closeBlueBoxButtonBy = By.cssSelector("div.o_alert_info div.o_sel_info_message i.o_icon.o_icon_close");
private static final By closeModalDialogButtonBy = By.cssSelector("div.modal-dialog div.modal-header button.close");
public static void waitModalDialog(WebDriver browser) {
By modalBy = By.cssSelector("div.modal-dialog div.modal-body");
waitElement(modalBy, 5, browser);
}
public static void waitBusy(WebDriver browser) {
Graphene.waitModel(browser).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until(new BusyPredicate());
}
......
......@@ -274,14 +274,9 @@ public class PortfolioPage {
* @return
*/
public PortfolioPage selectMapInEditor(String mapTitle) {
By mapNodeBy = By.cssSelector("div.o_ep_toc_editor span.o_tree_level_label_open.o_tree_l1>a");
WebElement selectedNode = null;
List<WebElement> level1Nodes = browser.findElements(mapNodeBy);
for(WebElement level1Node:level1Nodes) {
if(level1Node.getText().contains(mapTitle)) {
selectedNode = level1Node;
}
}
By mapNodeBy = By.xpath("//div[contains(@class,'o_ep_toc_editor')]//span[contains(@class,'o_tree_level_label_open')][contains(@class,'o_tree_l1')]//a//span[text()[contains(.,'" + mapTitle + "')]]");
OOGraphene.waitElement(mapNodeBy, 5, browser);
WebElement selectedNode = browser.findElement(mapNodeBy);
Assert.assertNotNull(selectedNode);
selectedNode.click();
OOGraphene.waitBusy(browser);
......@@ -290,9 +285,8 @@ public class PortfolioPage {
public PortfolioPage selectMapInEditor() {
By mapNodeBy = By.cssSelector("div.o_ep_toc_editor span.o_tree_link.o_tree_l1.o_tree_l1>a");
List<WebElement> level1Nodes = browser.findElements(mapNodeBy);
Assert.assertFalse(level1Nodes.isEmpty());
level1Nodes.get(0).click();
OOGraphene.waitElement(mapNodeBy, 5, browser);
browser.findElement(mapNodeBy).click();
OOGraphene.waitBusy(browser);
return this;
}
......@@ -320,9 +314,8 @@ public class PortfolioPage {
*/
public PortfolioPage selectFirstPageInEditor() {
By pageNodeBy = By.cssSelector("div.o_ep_toc_editor span.o_tree_level_label_leaf.o_tree_l2>a");
List<WebElement> level2Nodes = browser.findElements(pageNodeBy);
Assert.assertFalse(level2Nodes.isEmpty());
level2Nodes.get(0).click();
OOGraphene.waitElement(pageNodeBy, 5, browser);
browser.findElement(pageNodeBy).click();
OOGraphene.waitBusy(browser);
return this;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment