Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ static public void setInstance(LaboratoryService instance)

abstract public void registerTabbedReportFilterProvider(TabbedReportFilterProvider provider);

abstract public List<TabbedReportFilterProvider> getTabbedReportFilterProviderProviders(final Container c, final User u);

public static enum NavItemCategory
{
samples(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,13 @@ public JSONObject toJSON(Container c, User u)
return null;
}

inferColumnsFromTable(ti);
inferColumnsFromTable(ti, c, u);
JSONObject json = super.toJSON(c, u);

json.put("schemaName", getSchemaName());
json.put("queryName", getQueryName());
String viewName = getDefaultViewName(c, getOwnerKey());

// TODO: should we always override here?
if (getViewName() != null)
{
viewName = getViewName();
Expand Down
58 changes: 15 additions & 43 deletions laboratory/api-src/org/labkey/api/laboratory/TabbedReportItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.labkey.api.data.ColumnInfo;
import org.labkey.api.data.Container;
import org.labkey.api.data.PropertyManager;
import org.labkey.api.data.TableInfo;
import org.labkey.api.laboratory.query.TabbedReportFilterProvider;
import org.labkey.api.query.FieldKey;
import org.labkey.api.security.User;
import org.labkey.api.util.PageFlowUtil;

import java.util.HashMap;
import java.util.Map;

/**
Expand All @@ -43,10 +43,11 @@ public class TabbedReportItem extends AbstractNavItem

protected FieldKey _subjectIdFieldKey = null;
protected FieldKey _sampleDateFieldKey = null;
protected FieldKey _overlappingProjectsFieldKey = null;
protected FieldKey _allProjectsFieldKey = null;
private final Map<String, FieldKey> _additionalKeys = new HashMap<>();

public static final String OVERRIDES_PROP_KEY = "laboratory.tabItemOverride";
public static final String FILTER_PROP_KEY = "laboratory.tabItemFilterOverride";

protected static final Logger _log = LogManager.getLogger(TabbedReportItem.class);

public TabbedReportItem(DataProvider provider, String name, String label, String reportCategory)
Expand Down Expand Up @@ -94,24 +95,18 @@ public JSONObject toJSON(Container c, User u)
if (_sampleDateFieldKey != null)
json.put("dateFieldName", _sampleDateFieldKey);

if (_overlappingProjectsFieldKey != null)
{
json.put("overlappingProjectsFieldName", _overlappingProjectsFieldKey.toString());
json.put("overlappingProjectsFieldKeyArray", new JSONArray(_overlappingProjectsFieldKey.getParts()));
}

if (_allProjectsFieldKey != null)
{
json.put("allProjectsFieldName", _allProjectsFieldKey.toString());
json.put("allProjectsFieldKeyArray", new JSONArray(_allProjectsFieldKey.getParts()));
}
JSONObject keys = new JSONObject();
_additionalKeys.forEach((name, fk) -> {
keys.put(name, fk.toString());
});
json.put("additionalFieldKeys", keys);

json.put("reportType", getReportType());

return json;
}

protected void inferColumnsFromTable(TableInfo ti)
protected void inferColumnsFromTable(TableInfo ti, Container c, User u)
{
for (ColumnInfo ci : ti.getColumns())
{
Expand All @@ -125,17 +120,9 @@ else if (_sampleDateFieldKey == null && LaboratoryService.SAMPLEDATE_CONCEPT_URI
}
}

if (_overlappingProjectsFieldKey == null || _allProjectsFieldKey == null)
for (TabbedReportFilterProvider p : LaboratoryService.get().getTabbedReportFilterProviderProviders(c, u))
{
FieldKey overlapKey = FieldKey.fromString("overlappingProjectsPivot");
FieldKey allKey = FieldKey.fromString("allProjectsPivot");

Map<FieldKey, ColumnInfo> colMap = _queryCache.getColumns(ti, PageFlowUtil.set(overlapKey, allKey));
if (_overlappingProjectsFieldKey == null && colMap.containsKey(overlapKey))
_overlappingProjectsFieldKey = colMap.get(overlapKey).getFieldKey();

if (_allProjectsFieldKey == null && colMap.containsKey(allKey))
_allProjectsFieldKey = colMap.get(allKey).getFieldKey();
_additionalKeys.putAll(p.getAdditionalFieldKeys(ti, this, _additionalKeys));
}
}

Expand Down Expand Up @@ -169,24 +156,9 @@ public void setSampleDateFieldKey(FieldKey sampleDateFieldKey)
_sampleDateFieldKey = sampleDateFieldKey;
}

public FieldKey getOverlappingProjectsFieldKey()
{
return _overlappingProjectsFieldKey;
}

public void setOverlappingProjectsFieldKey(FieldKey overlappingProjectsFieldKey)
{
_overlappingProjectsFieldKey = overlappingProjectsFieldKey;
}

public FieldKey getAllProjectsFieldKey()
{
return _allProjectsFieldKey;
}

public void setAllProjectsFieldKey(FieldKey allProjectsFieldKey)
public void setKeyOverride(String name, FieldKey key)
{
_allProjectsFieldKey = allProjectsFieldKey;
_additionalKeys.put(name, key);
}

public void setVisible(boolean visible)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
package org.labkey.api.laboratory.query;

import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;
import org.labkey.api.collections.CaseInsensitiveHashMap;
import org.labkey.api.data.Container;
import org.labkey.api.data.ContainerType;
import org.labkey.api.data.PropertyManager;
import org.labkey.api.data.TableInfo;
import org.labkey.api.laboratory.NavItem;
import org.labkey.api.laboratory.TabbedReportItem;
import org.labkey.api.module.Module;
import org.labkey.api.query.FieldKey;
import org.labkey.api.security.User;
import org.labkey.api.view.template.ClientDependency;

import java.util.Collection;
import java.util.Map;

public interface TabbedReportFilterProvider
{
boolean isAvailable(Container c, User u);
default boolean isAvailable(Container c, User u)
{
return c.getActiveModules().contains(getOwningModule());
}

Module getOwningModule();

Collection<ClientDependency> getClientDependencies();

Expand All @@ -17,4 +33,41 @@ public interface TabbedReportFilterProvider
String getLabel();

String getInputValue();

default JSONObject toJSON(Container c, User u)
{
JSONObject ret = new JSONObject();
ret.put("xtype", getXType());
ret.put("label", getLabel());
ret.put("inputValue", getInputValue());
ret.put("isAvailable", isAvailable(c, u));
ret.put("isVisible", isVisible(c, u));
ret.put("key", getPropertyManagerKey());

return ret;
}

default boolean isVisible(Container c, User u)
{
Container targetContainer = c.getContainerFor(ContainerType.DataType.navVisibility);
if (getOwningModule() != null)
{
if (!targetContainer.getActiveModules().contains(getOwningModule()))
return false;
}

Map<String, String> map = new CaseInsensitiveHashMap<>(PropertyManager.getProperties(targetContainer, NavItem.PROPERTY_CATEGORY));
if (map.containsKey(getPropertyManagerKey()))
return Boolean.parseBoolean(map.get(getPropertyManagerKey()));

return true;
}

default String getPropertyManagerKey()
{
return "tabReportFilterProvider||" + getClass().getSimpleName() + "||" + getLabel();
}

@NotNull
Map<String, FieldKey> getAdditionalFieldKeys(TableInfo ti, TabbedReportItem tri, Map<String, FieldKey> overrides);
}
45 changes: 42 additions & 3 deletions laboratory/resources/web/laboratory/panel/ItemVisibilityPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,55 @@ Ext4.define('Laboratory.panel.ItemVisibilityPanel', {
this.results = results;

for (var i in Laboratory.ITEM_CATEGORY){
if (Laboratory.ITEM_CATEGORY[i].name == Laboratory.ITEM_CATEGORY.settings.name)
if (Laboratory.ITEM_CATEGORY[i].name === Laboratory.ITEM_CATEGORY.settings.name)
continue;

this.renderSection(Laboratory.ITEM_CATEGORY[i].name, Laboratory.ITEM_CATEGORY[i].label);
}

if (this.results.tabbedReportFilterProviderProviders) {
this.renderTabbedReportFilterProviderProviders(this.results.tabbedReportFilterProviderProviders)
}
},

renderTabbedReportFilterProviderProviders: function(items) {
this.remove(this.down('#loading'));

var cfg = {
xtype: 'container',
border: false,
defaults: {
border: false
},
style: 'margin-bottom: 20px;',
itemCategory: 'tabbedReportFilterTypes',
items: [{
html: '<b>Tabbed Report Filter Types</b>',
style: 'padding-bottom: 5px;'
}]
}

var sectionItems = [];
Ext4.each(items, function(item){
sectionItems.push({
xtype: 'checkbox',
width: 800,
style: 'margin-left: 5px;',
navItem: item,
boxLabel: item.label,
checked: item.isVisible,
itemCategory: 'tabbedReportFilterTypes'
});
}, this);

sectionItems = LDK.Utils.sortByProperty(sectionItems, 'boxLabel');
cfg.items = cfg.items.concat(sectionItems);
this.add(cfg);
},

renderSection: function(name, label){
var items = this.results[name];
var showReportCategory = name == 'tabbedReports';
var showReportCategory = name === 'tabbedReports';

this.remove(this.down('#loading'));

Expand Down Expand Up @@ -92,7 +131,7 @@ Ext4.define('Laboratory.panel.ItemVisibilityPanel', {
//if items are marked as children of this item, toggle their visibility.
//this is primarily used for reports
field.up('form').getForm().getFields().each(function(item){
if (item.navItem && item.navItem.ownerKey == field.navItem.key){
if (item.navItem && item.navItem.ownerKey === field.navItem.key){
item.setValue(val);
}
}, this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ Ext4.define('Laboratory.panel.ProjectFilterType', {

var filters = this.getFilters();
var report = tab.report;
var projectFieldName = (filters.projectFilterMode === 'overlappingProjects') ? report.overlappingProjectsFieldName : report.allProjectsFieldName;
var projectFieldName = (filters.projectFilterMode === 'overlappingProjects') ? report.additionalFieldKeys?.overlappingProjectsFieldKey : report.additionalFieldKeys?.allProjectsFieldKey;
if (!projectFieldName){
if (filters.projectFilterMode === 'overlappingProjects' && !report.overlappingProjectsFieldName){
projectFieldName = report.allProjectsFieldName;
if (filters.projectFilterMode === 'overlappingProjects' && !report.additionalFieldKeys?.overlappingProjectsFieldKey){
projectFieldName = report.additionalFieldKeys?.allProjectsFieldKey;

if (projectFieldName)
Ext4.Msg.alert('Warning', 'This reports supports project filtering, but cannot filter by overlapping projects, since it lacks a properly configured date field. All animals assigned to the project will be shown');
Expand Down Expand Up @@ -125,7 +125,7 @@ Ext4.define('Laboratory.panel.ProjectFilterType', {
},

validateReportForFilterType: function(report){
if (!report.allProjectsFieldName){
if (!report.additionalFieldKeys?.allProjectsFieldKey){
return 'This report cannot be used with the selected filter type, because the report does not contain a field with project information';
}

Expand Down
40 changes: 30 additions & 10 deletions laboratory/src/org/labkey/laboratory/LaboratoryController.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.labkey.api.laboratory.assay.AssayImportMethod;
import org.labkey.api.laboratory.assay.AssayParser;
import org.labkey.api.laboratory.query.ContainerIncrementingTable;
import org.labkey.api.laboratory.query.TabbedReportFilterProvider;
import org.labkey.api.laboratory.security.LaboratoryAdminPermission;
import org.labkey.api.module.Module;
import org.labkey.api.module.ModuleHtmlView;
Expand Down Expand Up @@ -1567,22 +1568,29 @@ public ApiResponse execute(JsonDataForm form, BindException errors)
for (String key : json.keySet())
{
String providerName = AbstractNavItem.inferDataProviderNameFromKey(key);
DataProvider provider = LaboratoryService.get().getDataProvider(providerName);

//for some types, no DataProvider, was explicitly registered, such as many assays
//in these cases we cannot infer the owning module.
if (provider != null && provider.getOwningModule() != null)
if ("tabReportFilterProvider".equals(providerName))
{
// Ignore
}
else
{
if (!activeModules.contains(provider.getOwningModule()))
DataProvider provider = LaboratoryService.get().getDataProvider(providerName);

//for some types, no DataProvider, was explicitly registered, such as many assays
//in these cases we cannot infer the owning module.
if (provider != null && provider.getOwningModule() != null)
{
toActivate.add(provider.getOwningModule());
if (!activeModules.contains(provider.getOwningModule()))
{
toActivate.add(provider.getOwningModule());
}
}
}

map.put(key, json.get(key) == null ? null : String.valueOf(json.get(key)));
}

if (toActivate.size() > 0)
if (!toActivate.isEmpty())
{
toActivate.addAll(activeModules);
getContainer().setActiveModules(toActivate);
Expand Down Expand Up @@ -1819,6 +1827,16 @@ public ApiResponse execute(GetDataItemsForm form, BindException errors)
results.put(LaboratoryService.NavItemCategory.misc.name(), json);
}

List<JSONObject> json = new ArrayList<>();
for (TabbedReportFilterProvider item : LaboratoryService.get().getTabbedReportFilterProviderProviders(getContainer(), getUser()))
{
if (form.isIncludeAll() || item.isAvailable(getContainer(), getUser()))
{
json.add(item.toJSON(getContainer(), getUser()));
}
}
results.put("tabbedReportFilterProviderProviders", json);

results.put("success", true);

return new ApiSimpleResponse(results);
Expand Down Expand Up @@ -2347,8 +2365,10 @@ public ModelAndView getView(Object form, BindException errors) throws Exception
JspView<Object> view = new JspView<>("/org/labkey/laboratory/view/dataBrowser.jsp", form);
view.setTitle("Data Browser");
view.setHidePageTitle(true);
//view.setFrame(WebPartView.FrameType.NONE);
//getPageConfig().setTemplate(PageConfig.Template.None);

LaboratoryServiceImpl.get().getTabbedReportFilterProviderProviders(getContainer(), getUser()).forEach(p -> {
p.getClientDependencies().forEach(view::addClientDependency);
});

return view;
}
Expand Down
Loading