Permalink
Browse files

Merge pull request #210 from numeroteca/taxonomies

Closes taxonomies brnach
  • Loading branch information...
numeroteca committed Jul 16, 2018
2 parents 2af25c4 + 66e7e3e commit 39284fdb188860306f33f15ea74e8ac5a293ba1a
Showing with 660 additions and 56 deletions.
  1. BIN app/assets/images/icon-edit.png
  2. +1 −0 app/assets/javascripts/application.js
  3. +32 −4 app/assets/javascripts/coding.js
  4. +20 −0 app/assets/javascripts/highlighted_area.js
  5. +10 −0 app/assets/javascripts/utils.js
  6. +3 −3 app/assets/stylesheets/application.css
  7. +7 −0 app/assets/stylesheets/coding.css.scss
  8. +5 −2 app/controllers/coding_controller.rb
  9. +45 −0 app/controllers/taxonomies_controller.rb
  10. +52 −0 app/controllers/taxonomy_options_controller.rb
  11. +15 −2 app/controllers/threads_controller.rb
  12. +9 −7 app/models/highlighted_area.rb
  13. +5 −0 app/models/taxonomy.rb
  14. +16 −0 app/models/taxonomy_classification.rb
  15. +7 −0 app/models/taxonomy_option.rb
  16. +57 −1 app/models/threadx.rb
  17. +6 −0 app/models/threadx_taxonomy.rb
  18. +5 −4 app/views/coding/display.html.erb
  19. +38 −17 app/views/coding/process_images.html.erb
  20. +10 −9 app/views/layouts/application.html.erb
  21. +45 −0 app/views/taxonomies/edit.html.erb
  22. +40 −0 app/views/taxonomies/index.html.erb
  23. +22 −0 app/views/taxonomies/new.html.erb
  24. +20 −0 app/views/taxonomy_options/_form.html.erb
  25. +38 −0 app/views/taxonomy_options/edit.html.erb
  26. +47 −0 app/views/taxonomy_options/index.html.erb
  27. +19 −6 app/views/threads/edit.html.erb
  28. +13 −0 app/views/threads/new.html.erb
  29. +5 −0 config/routes.rb
  30. +9 −0 db/migrate/20180705090755_create_taxonomies.rb
  31. +10 −0 db/migrate/20180705090834_create_taxonomy_options.rb
  32. +10 −0 db/migrate/20180706092346_create_threadx_taxonomies.rb
  33. +11 −0 db/migrate/20180706092525_create_taxonomy_classifications.rb
  34. +28 −1 db/schema.rb
Binary file not shown.
@@ -68,6 +68,7 @@
//= require spin.min
//= require utils
// require_tree .
$(function() {
@@ -98,13 +98,28 @@ $(document).ready(function () {
});
function addCloseAreaBehaviors(){
function addIconsAreaBehaviors(){
if (pageData.allowedToCode) {
$(".ha-close-icon").on("click",function() {
ha_id = $(this).parent('div').attr("id");
$('#' + ha_id).hide();
HighlightedAreas.removeOne(ha_id);
});
$(".ha-edit-icon").on("click",function() {
ha_id = $(this).parent('div').attr("id").replace("ha_", '');
pageData.currentHighlightedArea = ha_id; // remember the current highlighted area id
setModalValuesToHighlightedArea(ha_id)
$('#coding_topics').modal({backdrop:false});
});
}
}
function setModalValuesToHighlightedArea(cssId){
ha = HighlightedAreas.getByCssId(cssId);
$("#codes").val(ha.code_id);
for (i = 0; i < ha.taxonomy_ids.length; i++) {
$("#taxonomy_" + ha.taxonomy_ids[i]).val(ha.taxonomy_option_ids[i]);
}
}
@@ -129,6 +144,16 @@ function markAsNothingToCode(){
function setCodeOnHighlightedArea(highlightedAreaCssId) {
ha = HighlightedAreas.getByCssId(highlightedAreaCssId);
ha.code_id = $("#codes").val();
ha.taxonomy_ids = []
ha.taxonomy_option_ids = []
taxonomy_list = $(".js-taxonomy-classification")
for (i = 0; i < taxonomy_list.length; i++) {
taxonomy_id = taxonomy_list[i].getAttribute('data-taxonomy')
ha.taxonomy_ids.push(taxonomy_id);
ha.taxonomy_option_ids.push($("#taxonomy_" + taxonomy_id).val());
}
HighlightedAreas.save(ha);
renderHighlightedAreas();
}
@@ -185,7 +210,7 @@ function renderHighlightedAreas () {
}
}
renderNothingToCode();
addCloseAreaBehaviors();
addIconsAreaBehaviors();
}
// API for tracking modified status
@@ -231,6 +256,9 @@ function renderHighlightedArea(ha) {
if (pageData.allowedToCode) {
var close_icon = $('<div id="close_' + ha.cssid + '" class="ha-close-icon"><img id="close_img_' + ha.cssid + '" src="/assets/icon-close.png" title="Remove area" alt="Remove area icon"/></div>');
close_icon.appendTo(ha_elt);
var edit_icon = $('<div id="edit_' + ha.cssid + '" class="ha-edit-icon"><img id="edit_img_' + ha.cssid + '" src="/assets/icon-edit.png" title="Edit area classification" alt="Edit area icon"/></div>');
edit_icon.appendTo(ha_elt);
}
ha_elt.attr('id', 'ha_' + ha.cssid);
@@ -278,10 +306,10 @@ function highlightingArea(img, selection) {
img_id = getCurrentImageId();
code_id = '';
ha = HighlightedAreas.add(current_user, current_user_hash, img_id, code_id, screenToNatural(selection));
if( $("#codes option").length == 1) { // if only one topic, default to that one
if( $("#codes option").length == 1 && $('.js-taxonomy-classification').length == 0) { // if only one topic with no taxonomies, default to that one
setCodeOnHighlightedArea( ha.cssid );
} else {
// display the coding box, to ask the user to choose a code
// display the coding box, to ask the user to choose a code and taxonomies
pageData.currentHighlightedArea = ha.cssid; // remember the current highlighted area id
$('#coding_topics').modal({backdrop:false});
}
@@ -36,6 +36,13 @@ var HighlightedAreas = {
$(tag).attr('name', 'img_id_'+cssid).val(img_id).appendTo(ha_elt);
$(tag).attr('name', 'id_'+cssid).val(0).appendTo(ha_elt);
$(tag).attr('name', 'code_id_'+cssid).val(code_id).appendTo(ha_elt);
taxonomy_list = $(".js-taxonomy-classification")
for (i = 0; i < taxonomy_list.length; i++) {
taxonomy_id = taxonomy_list[i].getAttribute('data-taxonomy');
$(tag).attr({ 'name': 'taxonomy_options_' + cssid + '[]',
'id': 'taxonomy_options_' + cssid + '_' + taxonomy_id,
'data-taxonomy': taxonomy_id }).val('').appendTo(ha_elt);
}
$(tag).attr('name', 'username_'+cssid).val(username).appendTo(ha_elt);
$(tag).attr('name', 'hash_'+cssid).val(hash).appendTo(ha_elt);
$(tag).attr('name', 'x1_'+cssid).val(roundedSelection.x1).appendTo(ha_elt);
@@ -62,6 +69,11 @@ var HighlightedAreas = {
$("[name='width_"+cssid+"']").val(ha.width);
$("[name='height_"+cssid+"']").val(ha.height);
$("[name='deleted_"+cssid+"']").val(ha.deleted);
for (i = 0; i < ha.taxonomy_ids.length; i++) {
$("#taxonomy_options_" + cssid + "_" + ha.taxonomy_ids[i]).val(ha.taxonomy_option_ids[i]);
}
setModified();
},
@@ -99,6 +111,14 @@ var HighlightedAreas = {
ha.img_width = $("[name='img_width_"+cssid+"']").val();
ha.img_height = $("[name='img_height_"+cssid+"']").val();
ha.deleted = $("[name='deleted_"+cssid+"']").val();
ha.taxonomy_ids = []
ha.taxonomy_option_ids = []
taxonomy_list = $(".js-taxonomy-classification")
for (i = 0; i < taxonomy_list.length; i++) {
taxonomy_id = taxonomy_list[i].getAttribute('data-taxonomy')
ha.taxonomy_ids.push(taxonomy_id);
ha.taxonomy_option_ids.push($("#taxonomy_options_"+cssid+"_" +taxonomy_id).val());
}
return ha;
},
@@ -0,0 +1,10 @@
$(document).ready(function () {
$(".js-toggle-elements").click(function(){
show_id = $(this).data('show');
hide_id = $(this).data('hide');
$('#'+show_id).show();
$('#'+hide_id).hide();
});
});
@@ -44,10 +44,10 @@
#datavis .images .span1{
margin-left: 0;
}
.thumb-img-coded {
.thumb-img-coded {
opacity: 0.3;
}
.thumb-img-no-coded {
.thumb-img-no-coded {
opacity: 0.7;
}
.custom-link{
@@ -71,7 +71,7 @@
padding: 5px 20px 10px;
}
#pre-menu{
margin-top:6px;
margin-top:6px;
}
#pre-menu li a {
display: block!important;
@@ -132,6 +132,13 @@ ul.thread-coposite-labels li.inactive {
right: 0px;
top: 0px;
}
.ha-edit-icon {
cursor:pointer;
width: 20px;
position: absolute;
right: 23px;
top: 0px;
}
#embedded_footer{
position: absolute;
right: 0px;
@@ -3,10 +3,11 @@ class CodingController < ApplicationController
# render the coding view
def process_images
@thread = Threadx.find_by_thread_name params[:thread_name]
@highlighted_areas = @thread.highlighted_areas
@thread = Threadx.includes(taxonomies: :taxonomy_options).find_by_thread_name params[:thread_name]
@highlighted_areas = @thread.highlighted_areas.includes(:taxonomy_options)
@allowed_to_code = @thread.allowed_to_code? current_user
@images = @thread.images_by_date # while coding we want to go day by day, NOT media by media
@taxonomies = @thread.taxonomies
end
# process the submitted highlighted area from the coding view, and redirect to the display
@@ -38,6 +39,7 @@ def process_highlighted_areas
y1: params["y1_#{ha_name}"].to_i, x2: params["x2_#{ha_name}"].to_i,
y2: params["y2_#{ha_name}"].to_i, width: params["width_#{ha_name}"].to_i,
height: params["height_#{ha_name}"].to_i)
ha.taxonomy_options = TaxonomyOption.where(id: params["taxonomy_options_#{ha_name}"]) if params["taxonomy_options_#{ha_name}"].present?
else
# Updating an existing area
ha = @thread.highlighted_areas.find(params["id_#{ha_name}"])
@@ -52,6 +54,7 @@ def process_highlighted_areas
y1: params["y1_#{ha_name}"].to_i, x2: params["x2_#{ha_name}"].to_i,
y2: params["y2_#{ha_name}"].to_i, width: params["width_#{ha_name}"].to_i,
height: params["height_#{ha_name}"].to_i)
ha.taxonomy_options = TaxonomyOption.where(id: params["taxonomy_options_#{ha_name}"]) if params["taxonomy_options_#{ha_name}"].present?
end
end
end
@@ -0,0 +1,45 @@
class TaxonomiesController < ApplicationController
before_filter :authenticate_admin!
def index
@taxonomies = Taxonomy.includes(:taxonomy_options).all
end
def new
@taxonomy = Taxonomy.new
end
def edit
@taxonomies = Taxonomy.includes(:taxonomy_options).all
@taxonomy = Taxonomy.find(params[:id])
end
def create
@taxonomy = Taxonomy.new(params[:taxonomy])
if @taxonomy.save
redirect_to taxonomy_taxonomy_options_url(@taxonomy.id), notice: 'Taxonomy was successfully created.'
else
render action: "new"
end
end
def update
@taxonomy = Taxonomy.find(params[:id])
if @taxonomy.update_attributes(params[:taxonomy])
redirect_to taxonomies_url
else
@taxonomies = Taxonomy.includes(:taxonomy_options).all
render action: "edit"
end
end
def destroy
@taxonomy = Taxonomy.find(params[:id])
@taxonomy.destroy
redirect_to taxonomies_url
end
end
@@ -0,0 +1,52 @@
class TaxonomyOptionsController < ApplicationController
before_filter :authenticate_admin!
before_filter :load_taxonomy, only: [:index, :destroy, :create, :edit, :update]
before_filter :load_taxonomy_option, only: [:destroy, :edit, :update]
before_filter :load_taxonomy_options, only: [:index, :edit]
def index
end
def edit
end
def create
@taxonomy_option = @taxonomy.taxonomy_options.new(params[:taxonomy_option])
if @taxonomy_option.save
redirect_to taxonomy_taxonomy_options_url(@taxonomy)
else
redirect_to taxonomy_taxonomy_options_url(@taxonomy), alert: "Error: #{@taxonomy_option.errors[:value].first}"
end
end
def update
if @taxonomy_option.update_attributes(params[:taxonomy_option])
redirect_to taxonomy_taxonomy_options_url(@taxonomy)
else
load_taxonomy_options
render action: "edit"
end
end
def destroy
@taxonomy_option.destroy
redirect_to taxonomy_taxonomy_options_url(@taxonomy)
end
private
def load_taxonomy
@taxonomy = Taxonomy.find(params[:taxonomy_id])
end
def load_taxonomy_option
@taxonomy_option = @taxonomy.taxonomy_options.find(params[:id])
end
def load_taxonomy_options
@taxonomy_options = @taxonomy.taxonomy_options
end
end
@@ -57,6 +57,7 @@ def new
@users = User.hashes
@usernames = User.pluck(:username)
@collaborators = @thread.collaborators.pluck(:username)
@taxonomies = Taxonomy.includes(:taxonomy_options).all
end
# create action is responsible of processing the submited new form, and create the thread object in the database and handle the validation
@@ -77,6 +78,8 @@ def create
# formatting the newspapers_names hash as mentioned above
@thread.media = Media.where(:id=>params[:media])
@thread.taxonomies = Taxonomy.where(id: params[:taxonomies])
# For any submitted new thread, it should pass the following conditons to be saved to the db
# (@thread.valid?) this conditions is used to check if the instantiated thread, is passing the validations in the threadx model class
# (params[:media] != nil) and this condtions to be sure that the thread is submitted with more than one newspaper selected
@@ -89,7 +92,7 @@ def create
# iterating over the submitted topics, and create a code object for each one. Then add this object to the codes array to assign it to the thread
number_of_codes.times do |n|
code_name = params["topic_name_#{n}"]
unless code_name.empty?
unless code_name.blank?
codes << Code.create!({:code_text => code_name,
:code_description => params["topic_description_#{n}"],
:color => params["topic_color_#{n}"]})
@@ -121,6 +124,7 @@ def create
@users = User.hashes
@usernames = User.pluck(:username)
@collaborators = @thread.collaborators.pluck(:username)
@taxonomies = Taxonomy.includes(:taxonomy_options).all
# send some params back to the view, to tell the user about what is missing
if params["topic_name_1"] == ""
@@ -155,6 +159,7 @@ def edit
@users = User.hashes
@usernames = User.pluck(:username)
@collaborators = @thread.collaborators.pluck(:username)
@taxonomies = Taxonomy.includes(:taxonomy_options).all
end
@@ -170,7 +175,7 @@ def update
@thread.media = Media.where(:id=>params[:media])
#@thread.codes = params[:codes]
@thread.taxonomies = Taxonomy.where(id: params[:taxonomies])
if @thread.update_attributes(params[:threadx])
@@ -303,6 +308,14 @@ def export
end
end
def raw
@thread = Threadx.find_by_thread_name params[:thread_name]
respond_to do |format|
format.json { render :json => @thread.raw_areas_data.to_json }
end
end
#To export the results to a spreadsheet using the gem rODF
def results_to_ods(results)
spreadsheet = ODF::Spreadsheet.new
Oops, something went wrong.

0 comments on commit 39284fd

Please sign in to comment.