Commit 54d706ee authored by Samuel GAIST's avatar Samuel GAIST

Merge branch '531-532-exp-table-issues' into 'master'

Fix report's experiment table name/URL construction & restrictions

Closes #531 and #532

See merge request !297
parents 9f85138c adf3d65c
Pipeline #33459 passed with stages
in 23 minutes and 31 seconds
......@@ -51,6 +51,7 @@ class BasicReportSerializer(serializers.ModelSerializer):
author = serializers.SerializerMethodField()
experiments = serializers.SerializerMethodField()
experiment_access_map = serializers.SerializerMethodField()
analyzers_access_map = serializers.SerializerMethodField()
analyzer = serializers.SerializerMethodField()
html_description = serializers.SerializerMethodField()
add_url = serializers.SerializerMethodField()
......@@ -93,6 +94,16 @@ class BasicReportSerializer(serializers.ModelSerializer):
obj.experiments.iterator()))
return access_map
def get_analyzers_access_map(self, obj):
user = self.context['request'].user
access_map = list()
for exp in obj.experiments.iterator():
# find analyzer
analyzers = exp.blocks.filter(analyzer=True)
if len(analyzers) > 0:
access_map.append(analyzers[0].algorithm.accessibility_for(user)[0])
return access_map
def get_analyzer(self, obj):
if obj.analyzer is not None:
return obj.analyzer.fullname()
......@@ -125,7 +136,7 @@ class FullReportSerializer(BasicReportSerializer):
class Meta(BasicReportSerializer.Meta):
fields = ['name', 'number', 'short_description', 'description', 'is_owner', 'author','status', 'creation_date', 'publication_date', 'experiments', 'analyzer', 'content', 'html_description', 'experiment_access_map']
fields = ['name', 'number', 'short_description', 'description', 'is_owner', 'author','status', 'creation_date', 'publication_date', 'experiments', 'analyzer', 'content', 'html_description', 'experiment_access_map', 'analyzers_access_map']
#----------------------------------------------------------
......
......@@ -40,14 +40,33 @@ angular.module('reportApp')
scope.ReportService = ReportService;
scope.domId = `experiments-table`;
scope.getAnalyzerFromExpName = ExperimentsService.getAnalyzerFromExpName;
scope.getAnalyzerShortName = (expName) => {
const name = scope.getAnalyzerFromExpName(expName);
return name.split('/').slice(1).join('/');
};
scope.getExpUrl = UrlService.getExperimentUrl;
scope.getBlockUrl = UrlService.getBlockUrl;
scope.getDatabaseUrl = UrlService.getDatabaseUrl;
scope.getExperimentListPath = UrlService.getExperimentListPath;
scope.isViewmode = UrlService.isViewmode;
//expNames are either the full experiment names, or just the last segment
scope.expNames = ExperimentsService.experimentNames;
scope.exps = ExperimentsService.experiments;
scope.getFullExpName = (expName) => {
if(ReportService.experiments.includes(expName)){
return expName;
} else {
return ReportService.experiments.find(n => n.split('/').pop() === expName);
}
};
scope.getNoUserExpName = (eName) => {
let expName = scope.getFullExpName(eName);
const noUserName = expName.split('/').slice(1).join('/');
return noUserName;
};
scope.getAccessMap = (expName) => ReportService.accessMap[scope.getFullExpName(expName)];
scope.getAnalyzerAccessMap = (expName) => ReportService.analyzerAccessMap[scope.getFullExpName(expName)];
scope.groups = GroupsService.groups;
......@@ -62,15 +81,15 @@ angular.module('reportApp')
ExperimentsService.deleteExperiment(expName);
};
const getUnusedExperiments = (expNames, groups) => {
const usedExps = Array.from(new Set([].concat.apply([], groups.map(g => g.experiments))));
const unusedExps = expNames.filter(n => !usedExps.includes(n));
scope.unusedExps = unusedExps;
};
const getUnusedExperiments = (expNames, groups) => {
const usedExps = Array.from(new Set([].concat.apply([], groups.map(g => g.experiments))));
const unusedExps = expNames.filter(n => !usedExps.includes(n));
scope.unusedExps = unusedExps;
};
scope.$watchCollection('expNames', (names) => {getUnusedExperiments(names, scope.groups);});
scope.$watch('groups', (gs) => {getUnusedExperiments(scope.expNames, gs);}, true);
getUnusedExperiments(scope.expNames, scope.groups);
scope.$watchCollection('expNames', (names) => {getUnusedExperiments(names, scope.groups);});
scope.$watch('groups', (gs) => {getUnusedExperiments(scope.expNames, gs);}, true);
getUnusedExperiments(scope.expNames, scope.groups);
},
template: `
<div id='{{ domId }}' class='panel panel-default'>
......@@ -120,7 +139,7 @@ angular.module('reportApp')
</td>
<td ng-if='!isViewmode()'>
<span
ng-if='unusedExps.includes(expName)'
ng-if='unusedExps.includes(expName)'
style='cursor: help;'
title="Experiment needs to be added to a group">
<i class="fa fa-flag fa-lg text-warning"></i>
......@@ -131,14 +150,20 @@ angular.module('reportApp')
{{ groups[0].aliases[expName] }}
</span>
</td>
<td><a href='{{ getExpUrl(expName) }}'>{{ expName }}</a></td>
<td>
<a ng-if='getAccessMap(expName)' href='{{ getExpUrl(getFullExpName(expName)) }}'>{{ getFullExpName(expName) }}</a>
<span ng-if='!getAccessMap(expName)' title='experiment not accessible for current user'>{{ getNoUserExpName(expName) }}</span>
</td>
<td>
<span ng-repeat='db in getExpDatabases(expName) track by db'>
<a href='{{ getDatabaseUrl(db.split("@")[0]) }}'>{{ db }}</a>
&nbsp;
</span>
</td>
<td>{{ getAnalyzerFromExpName(expName) }}</td>
<td>
<a ng-if='getAnalyzerAccessMap(expName)' href='{{ getBlockUrl(getAnalyzerFromExpName(expName)) }}'>{{ getAnalyzerFromExpName(expName) }}</a>
<span ng-if='!getAnalyzerAccessMap(expName)' title='analyzer not accessible for current user'>{{ getAnalyzerShortName(expName) }}</a>
</td>
</tr>
</tbody>
</table>
......
......@@ -36,8 +36,16 @@ angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService',
scope.experiments = ExperimentsService.experiments;
scope.dropdownId = `${scope.group.name}_exp_add_dropdown`;
scope.accessMap = ReportService.accessMap;
scope.getAnalyzerShortName = () => {
return scope.group.analyzer.split('/').slice(1).join('/');
};
scope.analyzerIsAccessible = () => ReportService.analyzerAccessMap[scope.group.experiments[0]];
scope.getExpName = (expName) => scope.experiments[expName] ? expName : expName.split('/').pop();
scope.getNoUserExpName = (expName) => {
const noUserName = expName.split('/').slice(1).join('/');
return noUserName;
};
const getExp = (expName) => scope.experiments[expName] || scope.experiments[expName.split('/').pop()];
// find experiments that are not in the group but are
......@@ -105,7 +113,9 @@ angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService',
</div>
</div>
<i style='margin-left: 5px;' ng-if='group.analyzer.length > 0'>
Analyzer: <a href='{{ getBlockUrl(group.analyzer) }}'>{{ group.analyzer }}</a>
Analyzer:
<a ng-if='analyzerIsAccessible()' href='{{ getBlockUrl(group.analyzer) }}'>{{ group.analyzer }}</a>
<span ng-if='!analyzerIsAccessible()' title='analyzer not accessible for current user'>{{ getAnalyzerShortName() }}</a>
</i>
</h4>
</div>
......@@ -139,8 +149,8 @@ angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService',
<td ng-if='!isViewmode()'><input ng-model='group.aliases[expName]' ng-model-options="{ debounce: 500 }"></input></td>
<td ng-if='isViewmode()'><span>{{ group.aliases[expName] }}</span></td>
<td>
<a ng-if='accessMap[expName]' href='{{ getExpUrl(expName) }}'>{{ getExpName(expName) }}</a>
<i ng-if='!accessMap[expName]'><small>experiment not accessible for current user</small></i>
<a ng-if='accessMap[expName]' href='{{ getExpUrl(expName) }}'>{{ expName }}</a>
<span ng-if='!accessMap[expName]' title='experiment not accessible for current user'>{{ getNoUserExpName(expName) }}</span>
</td>
<td>
<span ng-repeat='db in getExpDatabases(expName)'>
......
......@@ -284,10 +284,13 @@ angular.module('reportApp')
<tbody>
<tr ng-repeat="exp in group.experiments | orderBy:sortFunc:sortField.isReversed">
<td ng-repeat='field in fields'>
<a ng-if='$index == 0 && getExperimentUrl(exp) && accessMap[exp]' href='{{ getExperimentUrl(exp) }}'>
<a ng-if='$index == 0 && accessMap[exp]' href='{{ getExperimentUrl(exp) }}'>
{{ getFieldVal(exp, field) }}
</a>
<span ng-if='!$index == 0 || !getExperimentUrl(exp) || !accessMap[exp]'>
<span ng-if='$index == 0 && !accessMap[exp]' title='experiment not accessible for current user'>
{{ getFieldVal(exp, field) }}
</span>
<span ng-if='$index != 0'>
{{ getFieldVal(exp, field) }}
</span>
</td>
......
......@@ -35,6 +35,9 @@ angular.module('reportApp').factory('ReportService', ['GroupsService', 'plotterF
rs.number = undefined;
rs.author = undefined;
rs.name = undefined;
rs.experiments = undefined;
rs.accessMap = undefined;
rs.analyzerAccessMap = undefined;
rs.plotters = [];
rs.defaultPlotters = [];
......@@ -50,8 +53,9 @@ angular.module('reportApp').factory('ReportService', ['GroupsService', 'plotterF
rs.number = report.number;
rs.author = report.author;
rs.name = report.name.split('/').length > 1 ? report.name.split('/')[1] : null;
rs.accessMap = report.experiments.reduce((o, expName, i) =>
({...o, [expName]: report.experiment_access_map[i]}), {});
rs.accessMap = report.experiments.reduce((o, expName, i) => ({...o, [expName]: report.experiment_access_map[i]}), {});
rs.analyzerAccessMap = report.experiments.reduce((o, expName, i) => ({...o, [expName]: report.analyzers_access_map[i]}), {});
rs.experiments = report.experiments;
// start up our GroupsService
GroupsService.loadGroups(report.content.groups);
......
......@@ -892,6 +892,7 @@ class EditableReportRetrievalTestCase(ReportTestCase):
"creation_date": self.report.creation_date.isoformat(),
"publication_date": None,
"experiment_access_map": [],
"analyzers_access_map": [],
"experiments": [],
"content": {},
"analyzer": None,
......@@ -944,6 +945,7 @@ class LockedReportRetrievalTestCase(ReportTestCase):
"creation_date": self.report.creation_date.isoformat(),
"publication_date": None,
"experiment_access_map": [True],
"analyzers_access_map": [True],
"experiments": [self.experiment_analyzer1.fullname()],
"content": {},
"analyzer": None,
......@@ -992,6 +994,7 @@ class PublishedReportRetrievalTestCase(ReportTestCase):
"creation_date": self.report.creation_date.isoformat(),
"publication_date": self.report.publication_date.isoformat(),
"experiment_access_map": [False],
"analyzers_access_map": [True],
"experiments": [self.experiment_analyzer1.fullname()],
"content": {},
"analyzer": None,
......@@ -1014,6 +1017,7 @@ class PublishedReportRetrievalTestCase(ReportTestCase):
"creation_date": self.report.creation_date.isoformat(),
"publication_date": self.report.publication_date.isoformat(),
"experiment_access_map": [True],
"analyzers_access_map": [True],
"experiments": [self.experiment_analyzer1.fullname()],
"content": {},
"analyzer": None,
......@@ -1036,6 +1040,7 @@ class PublishedReportRetrievalTestCase(ReportTestCase):
"author": self.johndoe.username,
"status": "published",
"experiment_access_map": [False],
"analyzers_access_map": [True],
"creation_date": self.report.creation_date.isoformat(),
"publication_date": self.report.publication_date.isoformat(),
"experiments": [self.experiment_analyzer1.fullname()],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment