Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
95 changes: 71 additions & 24 deletions assets/src/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ const selection = new SelectionArea({
el.classList.remove('selected');
}
}).on('stop', ({store, event}) => {
selection.keepSelection()
selection.keepSelection();
$(store.selected).addClass('selected');
$(store.changed.removed).removeClass('selected');
});


$("body").on('contextmenu', function(ev) {
hideTags();
});
Expand Down Expand Up @@ -155,6 +156,7 @@ function filterChange(ev){
});
requestArray = [];
scrollPageNum = 1;
imagesOutstanding = 0;
let filters = getFilters();
updateQuery(filters);
loadPage(scrollPageNum)
Expand Down Expand Up @@ -185,6 +187,34 @@ function filterByLabel(label_name){
function getSelectedWrapper(){
return selection.getSelection();
}

function selectAllVisible(){
let visibleImgs = [];
$("#roi-container img").each(function(i){
let obj = this;
selection.deselect(obj);
if(checkInView(obj, true)){
visibleImgs.push(obj);
}
})
selection.clearSelection();
selection.select(visibleImgs);
selection.keepSelection();
}
function checkInView(elem,partial)
{
var container = $("#main-panel");
var contHeight = container.height();
var contTop = container.scrollTop();
var contBottom = contTop + contHeight ;

var elemTop = $(elem).offset().top - container.offset().top;
var elemBottom = elemTop + $(elem).height();
var isTotal = (elemTop >= 0 && elemBottom <=contHeight);
var isPart = ((elemTop < 0 && elemBottom > 0 ) || (elemTop > 0 && elemTop <= container.height())) && partial ;

return isTotal || isPart ;
}
$("#add_to_collection_form").on('submit', function(ev){
ev.preventDefault();
addCollectionSubmit();
Expand Down Expand Up @@ -264,13 +294,13 @@ function applyLabelSubmit(){
};
let lastHiddenROIs = [];
function apply_label_callback(evt){
let selected_rois = getSelectedWrapper();
for (let i=0; i<selected_rois.length; i++){
if($("#apply_label_hide").is(':checked')){
$(selected_rois[i]).fadeOut();
}else{
$(selected_rois[i]).fadeTo(200, 0.2).fadeTo(200, 1).fadeTo(200, 0.2).fadeTo(200, 1);
}
let selected_rois = [...getSelectedWrapper()];
if($("#apply_label_hide").is(':checked')){
$(selected_rois).fadeOut();
selection.deselect(selected_rois);
selection.clearSelection();
}else{
$(selected_rois).fadeTo(200, 0.2).fadeTo(200, 1).fadeTo(200, 0.2).fadeTo(200, 1);
}

if($("#apply_label_hide").is(':checked')){
Expand All @@ -280,6 +310,20 @@ function apply_label_callback(evt){
}
}

$("#unhide-last-form").on('submit', function(ev){
ev.preventDefault();
let last = lastHiddenROIs.pop();
if(last){
$(last).fadeIn();
selection.select(last);
selection.keepSelection();
}
if(lastHiddenROIs.length==0){
$("#unhide_last").addClass("disabled");
}
});


let REGEX_ALPHANUMERIC = /^[a-zA-Z0-9_ ]+$/i;
$("#add-label-form").on("keyup", function(ev){
testField(REGEX_ALPHANUMERIC, $("#add-label-form"), $('#add_label_text'));
Expand Down Expand Up @@ -310,7 +354,6 @@ function get_labels_callback(r){
}
}
function buildLabelSelect(){

let $filter_label = $('#filter-label');
let $apply_label_select = $('#apply_label_select');
$filter_label.empty();
Expand Down Expand Up @@ -399,31 +442,32 @@ function prevLabelLoop($ele){
}

}

$(document).on('keypress', function(event) {
function platformCtrlKey(event){
const macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'];
if(macosPlatforms.indexOf(window.navigator.platform)!=-1){
if(event.metaKey) return true;
}else{
if(event.ctrlKey) return true;
}
return false
}
$(document).on('keydown', function(event) {
if ($(event.target).closest("input,textarea")[0]) {
return;
}
let key = event.key.toUpperCase();
if(key == 'N'){
nextLabel();
}else if(platformCtrlKey(event) && key == 'A'){
event.preventDefault();
selectAllVisible();
}else if( key ==='P'){
prevLabel();
}else if( key ==='ENTER'){
$("#apply-label-form").trigger('submit');
}
});

$("#unhide-last-form").on('submit', function(ev){
ev.preventDefault();
let last = lastHiddenROIs.pop();
if(last){
$(last).fadeIn();
}
if(lastHiddenROIs){
$("#unhide_last").addClass("disabled");
}
});

$("#add-label-form").on('submit', function(ev){
ev.preventDefault();
Expand All @@ -441,7 +485,6 @@ function add_label_callback(r){
if(r.created){
showMessage("Label created");
}else{

showError("Label already exists");
}
getLabels();
Expand Down Expand Up @@ -603,6 +646,7 @@ function imageLoaded(evt) {
$image.css("visibility", "visible")

imagesOutstanding--;

if(imagesOutstanding==0){
allowLoad = true;
showLoader(false);
Expand Down Expand Up @@ -649,8 +693,7 @@ function handleRoiAjax(r) {

morePages = r.has_next_page;
}
$(window).on("load", function() {
});

let allowLoad = true;
function onScroll(){
if(morePages&&allowLoad){
Expand Down Expand Up @@ -683,6 +726,10 @@ $('.largeOptionSetSelectionTag').select2({
tags:true
});

$("#apply_label_select").on('select2:open', () => {
document.querySelector('.select2-search__field').focus();
});

$(document).foundation();

getLabels();
Expand Down
27 changes: 7 additions & 20 deletions manage/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,35 +70,22 @@ def profile(request, id=None):

@staff_required
def edit_user(request, id=None):
if id:
user = get_object_or_404(User, pk=id)
else:
user = User()

user = User.objects.filter(pk=id).first()
form = UserForm(instance=user)

try:
annotator_form = AnnotatorForm(instance=user.annotator)
except:
user.annotator = Annotator()
if user:
annotator_form = AnnotatorForm(instance=user.annotator)
user.save()
else:
annotator_form = AnnotatorForm()

if request.method == "POST":
form = UserForm(request.POST, instance=user)

annotator_form = AnnotatorForm(request.POST, instance=user.annotator)


if form.is_valid():
user = form.save(commit=False)

new_password = form.cleaned_data["new_password"]
if new_password:
user.password = make_password(new_password)

user.save()
form.instance.password = make_password(new_password)

user = form.save()
annotator_form = AnnotatorForm(request.POST, instance=user.annotator)
if annotator_form.is_valid():
annotator_form.save()
return redirect(reverse("manage:users"))
Expand Down
31 changes: 30 additions & 1 deletion static/css/app.css

Large diffs are not rendered by default.

140 changes: 115 additions & 25 deletions static/js/app.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions static/js/app.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion templates/manage/edit_user.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</div>
<div class="grid-x grid-padding-x padding-top-1 align-center">
<div class="cell medium-10 large-8">
<h1>{% if user.id %}Edit{% else %}Create New{% endif %} User</h1>
<h1>{% if user %}Edit{% else %}Create New{% endif %} User</h1>
</div>
</div>
<div class="grid-x align-center">
Expand Down
3 changes: 2 additions & 1 deletion web/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ def get_labels(request):
collection_name = request.POST.get('collection')

if collection_name is None:
labels = Label.objects.all().order_by('name')
label_values = Label.objects.all().order_by('name').values('name')
labels = [{'label_name': i["name"], 'has_winning': True} for i in label_values] # mark all labels as has_winning for _all
else:
rc = get_object_or_404(ImageCollection, name=collection_name)
labels = rc.labels(check_if_has_winning=True) # This is currently our switch to enable/disable skipping empty labels
Expand Down