Commit 1b943c1a authored by Ryan Herbert's avatar Ryan Herbert
Browse files

autocomplete.js, info.js, tag.py, *.html multiple group tags

tags can now be queried and auto-completed by multiple group_ids. This
is in order to better manage tag auto-completion for samples added to multiple groups as well as auto-completion for search bars
parent a6e165bf
......@@ -30,7 +30,7 @@ function VidjilAutoComplete(datasource) {
this.datasource = datasource;
this.isLoadingData = {};
this.cachedData = {};
this.loadedGroup = -1;
this.loadedGroups = [];
VidjilAutoComplete.instance = this;
......@@ -55,15 +55,27 @@ VidjilAutoComplete.isLoading = function(data) {
VidjilAutoComplete.prototype = {
initCache : function(at) {
this.cachedData[at] = {};
if (!this.cachedData[at]) {
this.cachedData[at] = {};
}
},
clearCache : function() {
this.cachedData = {};
},
isLoaded : function(group_id) {
return this.loadedGroup == group_id;
isLoaded : function(group_ids) {
// this.loadedGroups is sorted on assignment
if (this.loadedGroups.length !== group_ids.length) {
return false;
}
var sorted_groups = group_ids.sort();
for (var i = 0; i < this.loadedGroups.length; i++) {
if (this.loadedGroups[i] !== sorted_groups[i]) {
return false;
}
}
return true;
},
setupAtWho: function(input) {
......@@ -102,10 +114,10 @@ VidjilAutoComplete.prototype = {
const isLoaded = this.isLoaded.bind(this);
var callbacks = {
filter : function(query, data, searchKey) {
var group_id = this.$inputor.data('group-id');
if (VidjilAutoComplete.isLoading(data) || !isLoaded(group_id)) {
var group_ids = this.$inputor.data('group-ids');
if (VidjilAutoComplete.isLoading(data) || !isLoaded(group_ids)) {
this.$inputor.atwho('load', this.at, VidjilAutoComplete.defaultLoadingData);
fetchData(this.$inputor, this.at, group_id);
fetchData(this.$inputor, this.at, group_ids);
return data;
}
return $.fn.atwho.default.callbacks.filter(query, data, searchKey);
......@@ -126,37 +138,70 @@ VidjilAutoComplete.prototype = {
return callbacks;
},
fetchData : function($input, at, group_id) {
fetchData : function($input, at, group_ids) {
var self = this;
if (this.isLoadingData[at]) return;
this.isLoadingData[at] = true;
if (this.cachedData[at][group_id]) {
this.loadData($input, at, this.cachedData[at][group_id], group_id);
} else {
var uncached = [];
for (var i = 0; i < group_ids.length; i++) {
var group_id = group_ids[i];
if (!this.cachedData[at][group_id]) {
uncached.push(group_id);
//this.loadData($input, at, this.cachedData[at][group_id], group_id);
}
}
if (uncached.length > 0) {
$.ajax({
type: "GET",
data: {
group_id: group_id
group_ids: JSON.stringify(uncached)
},
timeout: 5000,
crossDomain: true,
url: self.datasource,
success: function (data) {
var my_data = JSON.parse(data);
self.loadData($input, at, my_data, group_id);
self.cacheData(at, my_data, uncached);
self.loadData($input, at, group_ids);
},
error: function (request, status, error) {
self.isLoadingData[at] = false;
}
});
} else {
this.loadData($input, at, group_ids);
}
},
loadData : function($input, at, data, group_id) {
cacheData : function(at, data, group_ids) {
for (var i = 0; i < group_ids.length; i++) {
var group_id = group_ids[i];
this.cachedData[at][group_id] = data[group_id] ? data[group_id] : [];
}
},
loadData : function($input, at, group_ids) {
this.isLoadingData[at] = false;
this.cachedData[at][group_id] = data;
this.loadedGroup = group_id;
$input.atwho('load', at, data);
this.loadedGroups = group_ids.sort();
var loaded_data = [];
for (var i = 0; i < this.loadedGroups.length; i++) {
loaded_data = loaded_data.concat(this.cachedData[at][this.loadedGroups[i]]);
}
// remove duplicates
var seen = [];
loaded_data = loaded_data.filter(function(elem) {
var res = seen.indexOf(elem['name']);
if (res < 0) {
seen.push(elem['name']);
}
return res;
});
$input.atwho('load', at, loaded_data);;
// This trigger at.js again
// otherwise we would be stuck with loading until the user types
return $input.trigger('keyup');
......
......@@ -318,7 +318,7 @@ Info.prototype = {
textarea.innerHTML = info ;
textarea.setAttribute('placeholder', placeholder);
$(textarea).data('group-id', this.m.group_id);
$(textarea).data('group-ids', [this.m.group_id]);
$(textarea).data('needs-atwho', true);
$(textarea).on('focus', function() {
new VidjilAutoComplete().setupAtWho(this);
......
......@@ -170,6 +170,9 @@ def all():
request.vars["filter"] = ""
search, tags = parse_search(request.vars["filter"])
group_ids = [int(g.id) for g in get_group_list(auth)]
parent_group_ids = [int(g.id) for f in auth.get_user_group_parents()]
group_ids = group_ids + parent_group_ids
list = SampleSetList(type, page, step, tags=tags)
list.load_creator_names()
......@@ -204,6 +207,7 @@ def all():
return dict(query = result,
fields = fields,
helper = helper,
group_ids = group_ids,
isAdmin = isAdmin,
reverse = False,
step = step,
......
from controller_utils import error_message
import json
if request.env.http_origin:
response.headers['Access-Control-Allow-Origin'] = request.env.http_origin
......@@ -6,10 +7,11 @@ if request.env.http_origin:
response.headers['Access-Control-Max-Age'] = 86400
def auto_complete():
if "group_id" not in request.vars:
return error_message("missing group id")
if "group_ids" not in request.vars:
return error_message("missing group ids")
prefix = get_tag_prefix()
tags = get_tags(db, request.vars["group_id"])
group_ids = json.loads(request.vars["group_ids"])
tags = get_tags(db, group_ids)
return tags_to_json(tags)
......@@ -86,7 +86,7 @@ class SampleSetList():
(db.auth_group.id == db.auth_permission.group_id)
& (db[self.type].id.belongs(self.element_ids))
).select(
db[self.type].id, db.auth_group.role
db[self.type].id, db.auth_group.role, db.auth_group.id
)
for i, row in enumerate(query) :
self.elements[row[self.type].id].group_list.append(row.auth_group.role.replace('user_','u'))
......
......@@ -93,21 +93,24 @@ def register_tags(db, table, record_id, text, group_id, reset=False):
tag_extractor = TagExtractor(tag_prefix, db)
tags = tag_extractor.execute(table, record_id, text, group_id, reset)
def get_tags(db, group_id):
def get_tags(db, group_ids):
return db((db.tag.id == db.group_tag.tag_id) &
(db.group_tag.group_id == group_id)
).select(db.tag.ALL)
(db.group_tag.group_id.belongs(group_ids))
).select(db.group_tag.group_id, db.tag.ALL)
def tags_to_json(tags):
tag_list = []
tag_map = {}
prefix = get_tag_prefix()
for tag in tags:
for row in tags:
group_id = row.group_tag.group_id
if group_id not in tag_map:
tag_map[group_id] = []
tag_dict = {}
tag_dict['id'] = tag.id
tag_dict['name'] = tag.name
tag_list.append(tag_dict)
tag_dict['id'] = row.tag.id
tag_dict['name'] = row.tag.name
tag_map[group_id].append(tag_dict)
return json.dumps(tag_list)
return json.dumps(tag_map)
def parse_search(search_string):
split = search_string.split()
......
......@@ -32,7 +32,7 @@
</tr>
<tr>
<td><label for="patient_info" id="patient_info__label">Info: </label></td>
<td><textarea onfocus="$(this).data('group-id', $('#group_select option:selected').val()); new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" class="text" cols="40" id="patient_info" name="info" rows="10"></textarea></td>
<td><textarea onfocus="$(this).data('group-ids', [$('#group_select option:selected').val()]); new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" class="text" cols="40" id="patient_info" name="info" rows="10"></textarea></td>
<td></td>
</tr>
<tr>
......
......@@ -30,7 +30,7 @@ info = db.patient[request.vars["id"]]
</tr>
<tr>
<td> <label for="patient_info" id="patient_info__label">Info: </label> </td>
<td> <textarea onfocus="new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" data-group-id="{{=group_id}}" class="text" cols="40" id="patient_info" name="info" rows="10">{{=info.info}}</textarea> </td>
<td> <textarea onfocus="new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" data-group-ids="[{{=group_id}}]" class="text" cols="40" id="patient_info" name="info" rows="10">{{=info.info}}</textarea> </td>
<td></td>
</tr>
<tr>
......
......@@ -27,7 +27,7 @@
</tr>
<tr>
<td><label for="run_info" id="run_info__label">Info: </label></td>
<td><textarea onfocus="$(this).data('group-id', $('#group_select option:selected').val()); new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" class="text" cols="40" id="run_info" name="info" rows="10"></textarea></td>
<td><textarea onfocus="$(this).data('group-ids', [$('#group_select option:selected').val()]); new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" class="text" cols="40" id="run_info" name="info" rows="10"></textarea></td>
<td></td>
</tr>
<tr>
......
......@@ -25,7 +25,7 @@ info = db.run[request.vars["id"]]
</tr>
<tr>
<td> <label for="run_info" id="run_info__label">Info: </label> </td>
<td> <textarea onfocus="new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" data-group-id="{{=group_id}}" class="text" cols="40" id="run_info" name="info" rows="10">{{=info.info}}</textarea> </td>
<td> <textarea onfocus="new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" data-group-ids="[{{=group_id}}]" class="text" cols="40" id="run_info" name="info" rows="10">{{=info.info}}</textarea> </td>
<td></td>
</tr>
<tr>
......
......@@ -17,7 +17,7 @@
</tr>
<tr>
<td><label for="sample_set_info" id="sample_set_info__label">Info: </label></td>
<td><textarea onfocus="$(this).data('group-id', $('#group_select option:selected').val()); new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" class="text" cols="40" id="sample_set_info" name="info" rows="10"></textarea></td>
<td><textarea onfocus="$(this).data('group-ids', [$('#group_select option:selected').val()]); new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" class="text" cols="40" id="sample_set_info" name="info" rows="10"></textarea></td>
<td></td>
</tr>
<tr>
......
......@@ -15,7 +15,7 @@ info = db.generic[request.vars["id"]]
</tr>
<tr>
<td> <label for="sample_set_info" id="sample_set_info__label">Info: </label> </td>
<td> <textarea onfocus="new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" data-group-id="{{=group_id}}" class="text" cols="40" id="sample_set_info" name="info" rows="10">{{=info.info}}</textarea> </td>
<td> <textarea onfocus="new VidjilAutoComplete().setupAtWho(this);" data-needs-atwho="true" data-group-ids="[{{=group_id}}]" class="text" cols="40" id="sample_set_info" name="info" rows="10">{{=info.info}}</textarea> </td>
<td></td>
</tr>
<tr>
......
Supports Markdown
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