Skip to content

Commit

Permalink
Fixed #11 ; fixed #10 : multiple subtemplates
Browse files Browse the repository at this point in the history
#11 : removed hidden triples from published records' visualization (app.py); fixed the script for retrieving previously added hidden triples (queries.py, mapping.py); introduced a control algorithm to avoid templates' issues, e.g.: fields can't be both hidden and mandatory (main.js, template.html).
#10 : improved graphical visualisation (main.css, main.js); fixed the function for handling multiple inner sub-records
  • Loading branch information
Sebastiano-G committed Feb 19, 2024
1 parent bfb78a6 commit 4785e2f
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 29 deletions.
2 changes: 1 addition & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ def GET(self, name):
title = "No title"
properties = {field["label"]:[field["property"], field["type"]] for field in fields if 'property' in field}
data_labels = { field['label']:v for k,v in data.items() \
for field in fields if k == field['id']}
for field in fields if k == field['id'] and field['hidden'] == 'False' }
except Exception as e:
pass

Expand Down
31 changes: 19 additions & 12 deletions mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,17 @@ def inputToRDF(recordData, userID, stage, knowledge_extraction, graphToClear=Non
if to_be_saved:
for binding in to_be_saved['results']['bindings']:
subject = URIRef(binding['subject']['value'])
for predicate, obj in binding.items():
if predicate != 'subject':
if obj['type'] == 'uri':
object_ = URIRef(obj['value'])
else:
object_ = Literal(obj['value'])
wd.add((subject, URIRef(predicate), object_))

for predicate_obj, inner_dict in binding.items():
if predicate_obj.endswith('_property'):
predicate = URIRef(inner_dict['value'])
obj_value = binding[predicate_obj.replace("_property", "")]['value']
obj_type = binding[predicate_obj.replace("_property", "")]['type']
obj = URIRef(obj_value) if obj_type == "uri" else Literal(obj_value, datatype="http://www.w3.org/2001/XMLSchema#string")
label = binding[predicate_obj.replace("_property", "") + "_label"]['value'] if predicate_obj.replace("_property", "") + "_label" in binding else None
wd.add((subject, URIRef(predicate), obj))
print(subject, predicate, obj, label)
if label:
wd.add((obj, RDFS.label, Literal(label, datatype="http://www.w3.org/2001/XMLSchema#string")))
queries.clearGraph(graphToClear)
wd.add(( URIRef(base+graph_name+'/'), PROV.generatedAtTime, Literal(datetime.datetime.now(),datatype=XSD.dateTime) ))
wd.add(( URIRef(base+graph_name+'/'), URIRef('http://dbpedia.org/ontology/currentStatus'), Literal(stage, datatype="http://www.w3.org/2001/XMLSchema#string") ))
Expand Down Expand Up @@ -196,6 +199,7 @@ def inputToRDF(recordData, userID, stage, knowledge_extraction, graphToClear=Non
# SUBTEMPLATE
elif field['type']=="Subtemplate":
subrecords = process_subrecords(recordData, field['id']) if not subrecords_dict else subrecords_dict
print("SUBRECORDS!!!!!!!!!!!!!!!\n", subrecords)
if field['id'] in subrecords:
for subrecord_idx, subrecord in subrecords[field['id']].items():
ID = str(int(time.time() * 1000))
Expand Down Expand Up @@ -244,9 +248,12 @@ def process_subrecords(data, id):
for inner_subrecord in inner_subrecords:
inner_subrecord_split = inner_subrecord.split('__')
inner_prefix, inner_num = inner_subrecord_split[0], inner_subrecord_split[-1]
add_results[inner_prefix] = {
inner_num: process_subrecords(data, inner_subrecord)
}
if inner_prefix in add_results:
add_results[inner_prefix][inner_num] = process_subrecords(data, inner_subrecord)
else:
add_results[inner_prefix] = {
inner_num: process_subrecords(data, inner_subrecord)
}
else:
imported_values = [import_key for import_key in data.keys() if import_key.startswith(key + "-")]
for imported_value in imported_values:
Expand All @@ -258,7 +265,7 @@ def process_subrecords(data, id):
results[prefix] = { num: add_results }
elif data[id] != "":
for el in data[id].split(','):
results[el.split('-')[0]] = data[el]
results[el.split('__')[0]] = data[el]
return results

def find_label(tpl, subrecord, alternative_label):
Expand Down
2 changes: 1 addition & 1 deletion queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ def saveHiddenTriples(graph, tpl):

results = []
hidden_fields = [field for field in fields if field['hidden'] == 'True']
patterns = [ 'OPTIONAL {?subject <'+hidden_field['property']+'> ?'+hidden_field['id']+'.}. ' if hidden_field['value'] in ['Literal','Date','gYearMonth','gYear','URL'] else 'OPTIONAL {?subject <'+hidden_field['property']+'> ?'+hidden_field['id']+'. ?'+hidden_field['id']+' rdfs:label ?'+hidden_field['id']+'_label .} .' for hidden_field in hidden_fields if 'value' in hidden_field and hidden_field['hidden'] == 'True']
patterns = [ 'OPTIONAL {?subject <'+hidden_field['property']+'> ?'+hidden_field['id']+'. ?subject ?'+hidden_field['id']+'_property ?'+hidden_field['id']+'}. ' if hidden_field['value'] in ['Literal','Date','gYearMonth','gYear','URL'] else 'OPTIONAL {?subject <'+hidden_field['property']+'> ?'+hidden_field['id']+'. ?'+hidden_field['id']+' rdfs:label ?'+hidden_field['id']+'_label . ?subject ?'+hidden_field['id']+'_property ?'+hidden_field['id']+'}.' for hidden_field in hidden_fields if 'value' in hidden_field and hidden_field['hidden'] == 'True']
if patterns != []:
patterns_string = ''.join(patterns)
queryNGraph = '''
Expand Down
8 changes: 8 additions & 0 deletions static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,14 @@ button#showTemplates {
width: 42%;
}

input[subtemplate]+.fa-plus-circle {
right: 45px; position: absolute; top: 20px;
}

.form_row .fa-edit, .form_row .fa-trash-alt {
color: rgba(100,23,180,1); cursor: pointer;
}

/* extra */
.fa-plus-circle, .fa-eye, .fa-trash{color: rgba(100,23,180,1); cursor: pointer;}
.link_btn, .btn {white-space: nowrap;}
Expand Down
74 changes: 63 additions & 11 deletions static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ $(document).ready(function() {
};
});

// check templates' constraints
$("#updateTemplate").on('click', function(e) {
e.preventDefault();

// make sure the primary key is mandatory
var primary_key = $('.disambiguate[checked="checked"');
primary_key.parent().parent().find('input[id*="mandatory"]').attr("checked", "checked");

// prevent mandatory fields to be hidden
var mandatory_fields = $('input[type="checkbox"][id*="mandatory"][checked="checked"]');
mandatory_fields.each(function() {
var hidden_field_checkbox = $(this).parent().parent().find('input[type="checkbox"][id*="hidden"]');
if (hidden_field_checkbox.attr('checked') == 'checked') {
Swal.fire({ title:"Hidden fields cannot be mandatory"});
return false;
};
});
Swal.fire({ title: 'Saved!'});
setTimeout(function() { document.getElementById('templateForm').submit();}, 500);
});

// disable forms
$(".disabled").attr("disabled","disabled");

Expand Down Expand Up @@ -354,7 +375,7 @@ $(document).ready(function() {
$(this).parent().parent().hide();
});
var field_name = $(this).parent().prev().text();
$(this).parent().append("<i class='fas fa-plus-circle' onclick='create_subrecord(`" + subtemplate_class + "`,`"+field_name+"`,this)'></i>");
$(this).after("<i class='fas fa-plus-circle' onclick='create_subrecord(`" + subtemplate_class + "`,`"+field_name+"`,$(this))'></i>");
});

});
Expand Down Expand Up @@ -1302,6 +1323,7 @@ function create_subrecord(resource_class, field_name, el) {
// SAVE
save_subrecord_btn.on('click', function(e) {
// generate a tag
console.log("RQWEQ")
var tag_label = subrecord_form.find('.disambiguate').val() || (field_name + "-" + $(".tag-subrecord[class~='"+resource_class+"']").length + 1);
var subinputs = [];
subrecord_form.find('input:not(.btn)').each(function() {
Expand All @@ -1311,7 +1333,8 @@ function create_subrecord(resource_class, field_name, el) {
});
var subrecord_index = $("[subtemplate='"+resource_class+"']").parent().parent().find('.tag-subrecord').length + 1;
var subrecord_id = $("[subtemplate='"+resource_class+"']").attr('id') + "__" + subrecord_index;
$(el).after("<br/><span id='"+subrecord_id+"-tag' class='tag-subrecord "+resource_class+"'>" + tag_label + "</span><i class='far fa-edit' onclick='modify_subrecord(\""+subrecord_id+"\", keep=true)'></i><i class='far fa-trash-alt' onclick='modify_subrecord(\""+subrecord_id+"\", keep=false)'></i>");
console.log(el);
el.after("<br/><span id='"+subrecord_id+"-tag' class='tag-subrecord "+resource_class+"'>" + tag_label + "</span><i class='far fa-edit' onclick='modify_subrecord(\""+subrecord_id+"\", keep=true)'></i><i class='far fa-trash-alt' onclick='modify_subrecord(\""+subrecord_id+"\", keep=false)'></i>");
$('#recordForm').append("<input type='hidden' name='"+subrecord_id+"' id='"+subrecord_id+"' value='"+subinputs.toString()+"'></input>");

// hide_subform
Expand Down Expand Up @@ -1353,31 +1376,60 @@ function modify_subrecord(sub_id, keep) {
// remove all inputs
var inner_inputs = $('#'+sub_id).val().split(",");
delete_inner_subrecord(inner_inputs); // collect nested inputs and remove them
$('#'+sub_id+'-tag').next('i').remove();
$('#'+sub_id+'-tag').next('i').remove();
$('#'+sub_id+'-tag').remove();
$('#'+sub_id).remove();
}
else {
// recollect the first level nested inputs to be displayed
var inner_inputs = $('#'+sub_id).val().split(",");

// recreate subrecord_section
var field_name = $('#'+sub_id+'-tag').parent().prev().text();
var el = $('#'+sub_id+'-tag').prev('.fa-plus-circle');
var el = $('#'+sub_id+'-tag').prevAll('.fa-plus-circle').first();
console.log(el);
create_subrecord(original_subtemplate_class, field_name, el);

for (let i=0; i<inner_inputs.length; i++) {
console.log(inner_inputs[i])
var input = $('#'+inner_inputs[i]);
var shortened_id = inner_inputs[i].split("__").slice(0, -1).join("__");
var new_input = $('.subform_section [id*="'+shortened_id+'__"]');
if (input.val() !== "") {
new_input.replaceWith(input.show());
// FINISH HERE:
/* still need to add a system to recreate inner-subrecords and all those fields associated with a tag (e.g. Entity) */
new_input.replaceWith(input.show());
if ($('input[type="hidden"][name*="'+inner_inputs[i]+'-"]').length) {
var imported_values = $('input[type="hidden"][name*="'+inner_inputs[i]+'-"]');
imported_values.each(function() {
var id = $(this).attr('name').split("-")[0];
var values = $(this).attr('value').split(",");
var value_code = values[0];
var value_string = decodeURIComponent(values[1]);
var tag = "<span class='tag "+value_code+"' data-input='"+id+"' data-id='"+value_code+"'>"+value_string+"</span>";
var hidden_input = $(this).detach();
input.after(tag, hidden_input);
})
} else if ($('input[id*="'+inner_inputs[i]+'__"]')) {
var inner_subrecords = $('input[id*="'+inner_inputs[i]+'__"]');
inner_subrecords.each(function() {
var inner_subrecord_fields = $(this).val().split(',');
var primary_key = "";
for (let i=0; i<inner_subrecord_fields.length; i++){
if ($('#'+inner_subrecord_fields[i]).hasClass('disambiguate')) {
primary_key = $('#'+inner_subrecord_fields[i]).val();
}
}
if (primary_key === "") {
var inner_field_name = $('#'+inner_inputs[i]).prev('span').attr('data-original-title')
var num = $(this).attr('id').split('__')[-1];
var primary_key = inner_field_name+ "-" + num;
}
var resource_class = $('#'+inner_inputs[i]).attr('subtemplate');
var tag = "<span id='"+$(this).attr('id')+"-tag' class='tag-subrecord "+resource_class+"'>" + primary_key + "</span><i class='far fa-edit' onclick='modify_subrecord(\""+$(this).attr('id')+"\", keep=true)'></i><i class='far fa-trash-alt' onclick='modify_subrecord(\""+$(this).attr('id')+"\", keep=false)'></i>"
$('#'+inner_inputs[i]).after(tag);
})
}
}
}
$('#'+sub_id+'-tag').next('i').remove();
$('#'+sub_id+'-tag').next('i').remove();
$('#'+sub_id+'-tag').remove();
$('#'+sub_id).remove();
}

function delete_inner_subrecord(inner_inputs) {
Expand Down
10 changes: 6 additions & 4 deletions templates/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ <h3 class="col-md-12 col-sm-12">$res_name</h3>
<section class="sortable homeheading col-md-12 col-lg-12 col-sm-12">
$if f:
$for field in f:
<section class="block_field">
$ hidden_style = "style=opacity:0.6" if 'hidden' in field and field["hidden"] == "True" else ""
<section class="block_field" $hidden_style>
$ id = field["id"]
$if field['type'] != "KnowledgeExtractor":
<!-- TYPE -->
Expand Down Expand Up @@ -223,15 +224,15 @@ <h3 class="col-md-12 col-sm-12">$res_name</h3>
</section>
<!-- mandatory fields -->
<section class="row">
$ checked_mandatory = "checked=checked" if 'mandatory'in field and field["mandatory"] == "True" else ""
$ checked_mandatory = "checked=checked" if 'mandatory' in field and field["mandatory"] == "True" else ""
<label class="left col-md-11 col-sm-6" for="mandatory__$id">make this value mandatory</label>
<input $checked_mandatory type="checkbox" id="mandatory__$id" name="mandatory__$id">
</section>
<!-- hidden fields -->
<section class="row">
$ checked_hidden = "checked=checked" if 'hidden'in field and field["hidden"] == "True" else ""
$ checked_hidden = "checked=checked" if 'hidden' in field and field["hidden"] == "True" else ""
<label class="left col-md-11 col-sm-6" for="hidden__$id">hide this field from the front-end view</label>
<input $checked_hidden type="checkbox" id="hidden__$id" name="hidden__$id">
<input $checked_hidden type="checkbox" id="hidden__$id" name="hidden__$id" onclick="hide_field(this)">
</section>
</section>
$else:
Expand Down Expand Up @@ -311,3 +312,4 @@ <h5>Knowledge Extraction</h5>
</section>

</section>
<script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>

0 comments on commit 4785e2f

Please sign in to comment.