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

OO-3955: add group filter to the coach view in participant folder

parent 690534fa
No related branches found
No related tags found
No related merge requests found
Showing
with 151 additions and 39 deletions
...@@ -219,24 +219,28 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere ...@@ -219,24 +219,28 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere
protected void renderHeaderSearch(Renderer renderer, StringOutput sb, FlexiTableElementImpl ftE, URLBuilder ubu, Translator translator, protected void renderHeaderSearch(Renderer renderer, StringOutput sb, FlexiTableElementImpl ftE, URLBuilder ubu, Translator translator,
RenderResult renderResult, String[] args) { RenderResult renderResult, String[] args) {
if(ftE.isSearchEnabled()) { if(ftE.isSearchEnabled() || ftE.getExtendedFilterButton() != null) {
Form theForm = ftE.getRootForm(); Form theForm = ftE.getRootForm();
String dispatchId = ftE.getFormDispatchId(); String dispatchId = ftE.getFormDispatchId();
boolean searchInput = ftE.getSearchElement() != null;
sb.append("<div class='o_table_search input-group o_noprint'>"); sb.append("<div class='o_table_search input-group o_noprint'>");
renderFormItem(renderer, sb, ftE.getSearchElement(), ubu, translator, renderResult, args); if(searchInput) {
sb.append("<div class='input-group-btn'>"); renderFormItem(renderer, sb, ftE.getSearchElement(), ubu, translator, renderResult, args);
// reset quick search sb.append("<div class='input-group-btn'>");
String id = ftE.getSearchElement().getFormDispatchId(); // reset quick search
sb.append("<a href=\"javascript:jQuery('#").append(id).append("').val('');") String id = ftE.getSearchElement().getFormDispatchId();
.append(FormJSHelper.getXHRFnCallFor(theForm, dispatchId, 1, true, true, true, sb.append("<a href=\"javascript:jQuery('#").append(id).append("').val('');")
new NameValuePair("reset-search", "true"))) .append(FormJSHelper.getXHRFnCallFor(theForm, dispatchId, 1, true, true, true,
.append("\" class='btn o_reset_quick_search'><i class='o_icon o_icon_remove_filters'> </i></a>"); new NameValuePair("reset-search", "true")))
.append("\" class='btn o_reset_quick_search'><i class='o_icon o_icon_remove_filters'> </i></a>");
renderFormItem(renderer, sb, ftE.getSearchButton(), ubu, translator, renderResult, args);
if(ftE.getExtendedSearchButton() != null) { renderFormItem(renderer, sb, ftE.getSearchButton(), ubu, translator, renderResult, args);
renderFormItem(renderer, sb, ftE.getExtendedSearchButton(), ubu, translator, renderResult, args); if(ftE.getExtendedSearchButton() != null) {
renderFormItem(renderer, sb, ftE.getExtendedSearchButton(), ubu, translator, renderResult, args);
}
} }
StringBuilder filterIndication = new StringBuilder(); StringBuilder filterIndication = new StringBuilder();
if(ftE.getExtendedFilterButton() != null) { if(ftE.getExtendedFilterButton() != null) {
ftE.getSelectedExtendedFilters().forEach(filter -> { ftE.getSelectedExtendedFilters().forEach(filter -> {
...@@ -246,10 +250,10 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere ...@@ -246,10 +250,10 @@ public abstract class AbstractFlexiTableRenderer extends DefaultComponentRendere
renderFormItem(renderer, sb, ftE.getExtendedFilterButton(), ubu, translator, renderResult, args); renderFormItem(renderer, sb, ftE.getExtendedFilterButton(), ubu, translator, renderResult, args);
} }
sb.append("</div>"); sb.append("</div>", searchInput);// close the div input-group-btn
sb.append("</div>"); sb.append("</div>");
if(filterIndication.length() > 0) { if(filterIndication.length() > 0) {
sb.append("<div class='o_table_tools_indications'>").append(filterIndication) sb.append("<div class='o_table_tools_indications").append("_filter_only", !searchInput).append("'>").append(filterIndication)
// remove filter // remove filter
.append("<a href=\"javascript:") .append("<a href=\"javascript:")
.append(FormJSHelper.getXHRFnCallFor(theForm, dispatchId, 1, true, true, true, .append(FormJSHelper.getXHRFnCallFor(theForm, dispatchId, 1, true, true, true,
......
...@@ -81,7 +81,13 @@ public class ExtendedFilterController extends FormBasicController { ...@@ -81,7 +81,13 @@ public class ExtendedFilterController extends FormBasicController {
Object uobject = link.getUserObject(); Object uobject = link.getUserObject();
if(uobject instanceof FlexiTableFilter) { if(uobject instanceof FlexiTableFilter) {
FlexiTableFilter filter = (FlexiTableFilter)uobject; FlexiTableFilter filter = (FlexiTableFilter)uobject;
filter.setSelected(!filter.isSelected()); if(filter.isShowAll()) {
for(FlexiTableFilter f:filters) {
f.setSelected(false);
}
} else {
filter.setSelected(!filter.isSelected());
}
} }
} }
fireEvent(ureq, Event.DONE_EVENT); fireEvent(ureq, Event.DONE_EVENT);
......
...@@ -612,7 +612,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle ...@@ -612,7 +612,7 @@ public class FlexiTableElementImpl extends FormItemImpl implements FlexiTableEle
extendedFilterButton.setElementCssClass("o_sel_flexi_extendedsearch"); extendedFilterButton.setElementCssClass("o_sel_flexi_extendedsearch");
} else { } else {
extendedFilterButton = null; extendedFilterButton = null;
extendedFilters = null; this.extendedFilters = null;
} }
} }
......
<ul class="list-unstyled"> <ul class="o_dropdown list-unstyled">
#foreach($filter in $filters) #foreach($filter in $filters)
#if($filter.filter.filter == "oo-spacer-xx")
<li class='divider'></li>
#else
<li>#if($filter.selected)<i class="o_icon o_icon_check"> </i> #end$r.render($filter.componentName)</li> <li>#if($filter.selected)<i class="o_icon o_icon_check"> </i> #end$r.render($filter.componentName)</li>
#end
#end #end
</ul> </ul>
\ No newline at end of file
...@@ -63,7 +63,9 @@ import org.olat.course.nodes.pf.ui.PFRunController; ...@@ -63,7 +63,9 @@ import org.olat.course.nodes.pf.ui.PFRunController;
import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.environment.CourseEnvironment;
import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupRef;
import org.olat.group.BusinessGroupService; import org.olat.group.BusinessGroupService;
import org.olat.group.manager.BusinessGroupRelationDAO;
import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryEntryRelationType; import org.olat.repository.RepositoryEntryRelationType;
import org.olat.repository.RepositoryService; import org.olat.repository.RepositoryService;
...@@ -96,6 +98,8 @@ public class PFManager { ...@@ -96,6 +98,8 @@ public class PFManager {
@Autowired @Autowired
private RepositoryService repositoryService; private RepositoryService repositoryService;
@Autowired @Autowired
private BusinessGroupRelationDAO businessGroupRelationDao;
@Autowired
private RepositoryEntryRelationDAO repositoryEntryRelationDao; private RepositoryEntryRelationDAO repositoryEntryRelationDao;
@Autowired @Autowired
private UserManager userManager; private UserManager userManager;
...@@ -559,18 +563,28 @@ public class PFManager { ...@@ -559,18 +563,28 @@ public class PFManager {
/** /**
* Gets the participants for different group or course coaches as TableModel. * Gets the participants for different group or course coaches as TableModel.
* *
* @param id the identity * @param id The identity of the user who searches
* @param pfNode * @param pfNode The course element
* @param userPropertyHandlers * @param userPropertyHandlers The list of properties to hold
* @param locale * @param locale The locale
* @param courseEnv * @param courseEnv The course environment
* @param admin * @param admin If the user is an administrator
* @return the participants * @return the participants The list of dropbox
*/ */
public List<DropBoxRow> getParticipants (Identity id, PFCourseNode pfNode, List<UserPropertyHandler> userPropertyHandlers, public List<DropBoxRow> getParticipants(Identity id, PFCourseNode pfNode, List<UserPropertyHandler> userPropertyHandlers,
Locale locale, CourseEnvironment courseEnv, boolean admin) { Locale locale, CourseEnvironment courseEnv, boolean admin) {
List<Identity> identityList = getParticipants(id, courseEnv, admin); List<Identity> identityList = getParticipants(id, courseEnv, admin);
return getParticipants(pfNode, userPropertyHandlers, locale, identityList, courseEnv);
}
public List<DropBoxRow> getParticipants(List<BusinessGroupRef> businessGroupRefs, PFCourseNode pfNode, List<UserPropertyHandler> userPropertyHandlers,
Locale locale, CourseEnvironment courseEnv) {
List<Identity> identityList = businessGroupRelationDao.getMembers(businessGroupRefs, GroupRoles.participant.name());
return getParticipants(pfNode, userPropertyHandlers, locale, identityList, courseEnv);
}
private List<DropBoxRow> getParticipants(PFCourseNode pfNode, List<UserPropertyHandler> userPropertyHandlers,
Locale locale, List<Identity> identityList, CourseEnvironment courseEnv) {
Set<Identity> duplicates = new HashSet<>(); Set<Identity> duplicates = new HashSet<>();
List<DropBoxRow> participants = new ArrayList<>(identityList.size()); List<DropBoxRow> participants = new ArrayList<>(identityList.size());
......
...@@ -34,6 +34,7 @@ import org.olat.core.gui.components.Component; ...@@ -34,6 +34,7 @@ import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.flexible.FormItem; 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.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableSortOptions; import org.olat.core.gui.components.form.flexible.elements.FlexiTableSortOptions;
import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
...@@ -43,6 +44,7 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFle ...@@ -43,6 +44,7 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFle
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableSearchEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer; import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.TextFlexiCellRenderer; import org.olat.core.gui.components.form.flexible.impl.elements.table.TextFlexiCellRenderer;
...@@ -57,6 +59,7 @@ import org.olat.core.gui.media.MediaResource; ...@@ -57,6 +59,7 @@ import org.olat.core.gui.media.MediaResource;
import org.olat.core.id.Identity; import org.olat.core.id.Identity;
import org.olat.core.id.Roles; import org.olat.core.id.Roles;
import org.olat.core.id.UserConstants; import org.olat.core.id.UserConstants;
import org.olat.core.util.StringHelper;
import org.olat.core.util.resource.OresHelper; import org.olat.core.util.resource.OresHelper;
import org.olat.course.nodes.PFCourseNode; import org.olat.course.nodes.PFCourseNode;
import org.olat.course.nodes.pf.manager.FileSystemExport; import org.olat.course.nodes.pf.manager.FileSystemExport;
...@@ -65,6 +68,10 @@ import org.olat.course.nodes.pf.manager.PFView; ...@@ -65,6 +68,10 @@ import org.olat.course.nodes.pf.manager.PFView;
import org.olat.course.nodes.pf.ui.DropBoxTableModel.DropBoxCols; import org.olat.course.nodes.pf.ui.DropBoxTableModel.DropBoxCols;
import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.environment.CourseEnvironment;
import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.run.userview.UserCourseEnvironmentImpl;
import org.olat.group.BusinessGroup;
import org.olat.group.BusinessGroupRef;
import org.olat.group.model.BusinessGroupRefImpl;
import org.olat.resource.OLATResource; import org.olat.resource.OLATResource;
import org.olat.user.HomePageConfig; import org.olat.user.HomePageConfig;
import org.olat.user.HomePageDisplayController; import org.olat.user.HomePageDisplayController;
...@@ -108,9 +115,9 @@ public class PFCoachController extends FormBasicController implements Controller ...@@ -108,9 +115,9 @@ public class PFCoachController extends FormBasicController implements Controller
@Autowired @Autowired
private UserManager userManager; private UserManager userManager;
@Autowired @Autowired
private BaseSecurityModule securityModule;
@Autowired
private BaseSecurity securityManager; private BaseSecurity securityManager;
@Autowired
private BaseSecurityModule securityModule;
public PFCoachController(UserRequest ureq, WindowControl wControl, PFCourseNode sfNode, public PFCoachController(UserRequest ureq, WindowControl wControl, PFCourseNode sfNode,
UserCourseEnvironment userCourseEnv, PFView pfView) { UserCourseEnvironment userCourseEnv, PFView pfView) {
...@@ -193,6 +200,8 @@ public class PFCoachController extends FormBasicController implements Controller ...@@ -193,6 +200,8 @@ public class PFCoachController extends FormBasicController implements Controller
} else if ("firstName".equals(se.getCommand()) || "lastName".equals(se.getCommand())) { } else if ("firstName".equals(se.getCommand()) || "lastName".equals(se.getCommand())) {
doOpenHomePage(ureq, currentObject.getIdentity()); doOpenHomePage(ureq, currentObject.getIdentity());
} }
} else if(event instanceof FlexiTableSearchEvent) {
loadModel(true);
} }
} }
} }
...@@ -270,10 +279,10 @@ public class PFCoachController extends FormBasicController implements Controller ...@@ -270,10 +279,10 @@ public class PFCoachController extends FormBasicController implements Controller
dropboxTable.setSelectAllEnable(true); dropboxTable.setSelectAllEnable(true);
dropboxTable.setExportEnabled(true); dropboxTable.setExportEnabled(true);
dropboxTable.setSortSettings(options); dropboxTable.setSortSettings(options);
initFilters();
dropboxTable.setAndLoadPersistedPreferences(ureq, "participant-folder_coach_" + pfView.name()); dropboxTable.setAndLoadPersistedPreferences(ureq, "participant-folder_coach_" + pfView.name());
dropboxTable.setEmtpyTableMessageKey("table.empty"); dropboxTable.setEmtpyTableMessageKey("table.empty");
FormLayoutContainer buttonGroupLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); FormLayoutContainer buttonGroupLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
buttonGroupLayout.setElementCssClass("o_button_group"); buttonGroupLayout.setElementCssClass("o_button_group");
...@@ -283,8 +292,45 @@ public class PFCoachController extends FormBasicController implements Controller ...@@ -283,8 +292,45 @@ public class PFCoachController extends FormBasicController implements Controller
uploadAllLink = uifactory.addFormLink("upload.link", buttonGroupLayout, Link.BUTTON); uploadAllLink = uifactory.addFormLink("upload.link", buttonGroupLayout, Link.BUTTON);
} }
private void initFilters() {
List<FlexiTableFilter> groupFilters = new ArrayList<>();
List<BusinessGroup> coachedGroups = null;
if(userCourseEnv.isAdmin()) {
coachedGroups = courseEnv.getCourseGroupManager().getAllBusinessGroups();
} else if(userCourseEnv instanceof UserCourseEnvironmentImpl) {
UserCourseEnvironmentImpl uce = (UserCourseEnvironmentImpl)userCourseEnv;
coachedGroups = uce.getCoachedGroups();
}
if(coachedGroups != null) {
for(BusinessGroup coachedGroup:coachedGroups) {
String groupName = StringHelper.escapeHtml(coachedGroup.getName());
groupFilters.add(new FlexiTableFilter(groupName, coachedGroup.getKey().toString(), "o_icon o_icon_group"));
}
}
if(!groupFilters.isEmpty()) {
groupFilters.add(FlexiTableFilter.SPACER);
groupFilters.add(new FlexiTableFilter(translate("show.all"), "", true));
dropboxTable.setExtendedFilterButton(translate("filter.groups"), groupFilters);
}
}
private void loadModel(boolean full) { private void loadModel(boolean full) {
List<DropBoxRow> rows = pfManager.getParticipants(getIdentity(), pfNode, userPropertyHandlers, getLocale(), courseEnv, userCourseEnv.isAdmin()); List<FlexiTableFilter> extendedFilters = dropboxTable.getSelectedExtendedFilters();
List<DropBoxRow> rows;
if(extendedFilters == null || extendedFilters.isEmpty() || extendedFilters.get(0).isShowAll()) {
rows = pfManager.getParticipants(getIdentity(), pfNode, userPropertyHandlers, getLocale(), courseEnv, userCourseEnv.isAdmin());
} else {
List<BusinessGroupRef> businessGroups = new ArrayList<>(extendedFilters.size());
for(FlexiTableFilter extendedFilter:extendedFilters) {
if(StringHelper.isLong(extendedFilter.getFilter())) {
businessGroups.add(new BusinessGroupRefImpl(Long.parseLong(extendedFilter.getFilter())));
}
}
rows = pfManager.getParticipants(businessGroups, pfNode, userPropertyHandlers, getLocale(), courseEnv);
}
tableModel.setObjects(rows); tableModel.setObjects(rows);
dropboxTable.reset(full, full, true); dropboxTable.reset(full, full, true);
flc.contextPut("hasParticipants", tableModel.getRowCount() > 0); flc.contextPut("hasParticipants", tableModel.getRowCount() > 0);
......
...@@ -10,6 +10,7 @@ limit.count=Anzahl der einstellbaren Dokumente einschr\u00E4nken ...@@ -10,6 +10,7 @@ limit.count=Anzahl der einstellbaren Dokumente einschr\u00E4nken
limit.count.info=Sie k\u00F6nnen nur insgesamt {0} Dokumente einstellen. limit.count.info=Sie k\u00F6nnen nur insgesamt {0} Dokumente einstellen.
limit.count.coach.info=Sobald die max. Anzahl Dokumente erreicht ist, k\u00F6nnen die Teilnehmer nicht mehr Verschieben, Kopieren, Zippen oder Entzippen. limit.count.coach.info=Sobald die max. Anzahl Dokumente erreicht ist, k\u00F6nnen die Teilnehmer nicht mehr Verschieben, Kopieren, Zippen oder Entzippen.
file.count=Limite file.count=Limite
filter.groups=Gruppen
alter.file=L\u00F6schen und \u00DCberschreiben von Dokumenten erlauben alter.file=L\u00F6schen und \u00DCberschreiben von Dokumenten erlauben
time.frame=Zeitfenster f\u00FCr Abgabe festlegen time.frame=Zeitfenster f\u00FCr Abgabe festlegen
date.start=von date.start=von
...@@ -53,3 +54,4 @@ preview.limit=Dokumentenlimite aktiviert ...@@ -53,3 +54,4 @@ preview.limit=Dokumentenlimite aktiviert
preview.timeframe=Zeitfenster preview.timeframe=Zeitfenster
preview.info=Ein Beispiel finden Sie untenstehend: preview.info=Ein Beispiel finden Sie untenstehend:
preview.header=Konfiguration f\u00FCr den simulierten Benutzer preview.header=Konfiguration f\u00FCr den simulierten Benutzer
show.all=Alle anzeigen
...@@ -10,6 +10,7 @@ limit.count=Limit number of uploadable documents ...@@ -10,6 +10,7 @@ limit.count=Limit number of uploadable documents
limit.count.info=You may only upload or create {0} files total. limit.count.info=You may only upload or create {0} files total.
limit.count.coach.info=As soon as the maximum number of files is reached, participants cannot move, copy, zip or unzip anymore. limit.count.coach.info=As soon as the maximum number of files is reached, participants cannot move, copy, zip or unzip anymore.
file.count=Limit file.count=Limit
filter.groups=Groups
alter.file=Enable overwrite/delete of uploaded documents alter.file=Enable overwrite/delete of uploaded documents
time.frame=Limit upload to time interval time.frame=Limit upload to time interval
date.start=from date.start=from
...@@ -52,4 +53,5 @@ preview.return=Coach Returnbox enabled ...@@ -52,4 +53,5 @@ preview.return=Coach Returnbox enabled
preview.limit=Filelimit active preview.limit=Filelimit active
preview.timeframe=Time interval preview.timeframe=Time interval
preview.info=An example is shown below: preview.info=An example is shown below:
preview.header=Configuration folder for simulated user preview.header=Configuration folder for simulated user
\ No newline at end of file show.all=Show all
\ No newline at end of file
...@@ -321,6 +321,30 @@ public class BusinessGroupRelationDAO { ...@@ -321,6 +321,30 @@ public class BusinessGroupRelationDAO {
return members.getResultList(); return members.getResultList();
} }
public List<Identity> getMembers(List<? extends BusinessGroupRef> groups, String... roles) {
if(groups == null || groups.isEmpty()) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select ident from businessgroup as bgroup ")
.append(" inner join bgroup.baseGroup as baseGroup")
.append(" inner join baseGroup.members as membership")
.append(" inner join membership.identity as ident")
.append(" inner join fetch ident.user as identUser")
.append(" where bgroup.key in (:businessGroupKeys) and membership.role in (:roles)");
List<String> roleList = GroupRoles.toList(roles);
List<Long> groupKeys = new ArrayList<>(groups.size());
for(BusinessGroupRef group:groups) {
groupKeys.add(group.getKey());
}
return dbInstance.getCurrentEntityManager()
.createQuery(sb.toString(), Identity.class)
.setParameter("businessGroupKeys", groupKeys)
.setParameter("roles", roleList)
.getResultList();
}
public List<Long> getMemberKeys(List<? extends BusinessGroupRef> groups, String... roles) { public List<Long> getMemberKeys(List<? extends BusinessGroupRef> groups, String... roles) {
if(groups == null || groups.isEmpty()) return Collections.emptyList(); if(groups == null || groups.isEmpty()) return Collections.emptyList();
......
...@@ -141,7 +141,7 @@ a.o_orderby, a.o_orderby:hover { ...@@ -141,7 +141,7 @@ a.o_orderby, a.o_orderby:hover {
margin-left: 6px; margin-left: 6px;
} }
.o_table_tools_indications { .o_table_tools_indications, .o_table_tools_indications_filter_only {
margin-left: 10px; margin-left: 10px;
padding-top:3px; padding-top:3px;
font-size:80%; font-size:80%;
......
...@@ -117,6 +117,16 @@ ul.o_dropdown { ...@@ -117,6 +117,16 @@ ul.o_dropdown {
background-color: $dropdown-link-hover-bg; background-color: $dropdown-link-hover-bg;
} }
} }
> li > i.o_icon_check {
display: inline-block;
padding-left: 14px;
}
> li > i.o_icon_check + a {
display: inline-block;
padding-left: 5px;
}
} }
/* SCORM module */ /* SCORM module */
......
source diff could not be displayed: it is too large. Options to address this: view the blob.
source diff could not be displayed: it is too large. Options to address this: view the blob.
source diff could not be displayed: it is too large. Options to address this: view the blob.
source diff could not be displayed: it is too large. Options to address this: view the blob.
source diff could not be displayed: it is too large. Options to address this: view the blob.
source diff could not be displayed: it is too large. Options to address this: view the blob.
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