diff --git a/app/assets/stylesheets/bioportal.scss b/app/assets/stylesheets/bioportal.scss
index a00e324f2..49d079975 100644
--- a/app/assets/stylesheets/bioportal.scss
+++ b/app/assets/stylesheets/bioportal.scss
@@ -651,6 +651,7 @@ div.tree_error {
#bd ul.simpleTree li{
margin-left:-10px;
+ padding: 5px 0 0 10px;
}
#bd ul.simpleTree{
@@ -668,6 +669,22 @@ div.tree_error {
overflow:auto;
border: 1px solid #444444;
*/
+ a.tree-link {
+ display: inline-block;
+ padding: 5px;
+ }
+
+ a.tree-link.active {
+ cursor: default;
+ background-color: var(--light-color);
+ font-weight: bold;
+ border-radius: 2px;
+ }
+
+ .tree-border-left{
+ border-left: 2px dotted #eee;
+ margin-left: 6px;
+ }
}
.simpleTree li {
list-style: none;
diff --git a/app/components/tree_infinite_scroll_component/tree_infinite_scroll_component.html.haml b/app/components/tree_infinite_scroll_component/tree_infinite_scroll_component.html.haml
index cbaaba03a..386fa14dd 100644
--- a/app/components/tree_infinite_scroll_component/tree_infinite_scroll_component.html.haml
+++ b/app/components/tree_infinite_scroll_component/tree_infinite_scroll_component.html.haml
@@ -4,10 +4,8 @@
current_page: @current_page, next_page: @next_page) do |c|
%div
- %ul.simpleTree{data:{controller: 'simple-tree','simple-tree': { 'auto-click-value': auto_click? }, action: 'clicked->history#updateURL'}}
- %li.root
- %ul
- = content
+ = render TreeViewComponent.new(id: nil, auto_click: auto_click?) do
+ = content
- c.error do
%div.text-wrap
diff --git a/app/components/tree_link_component.rb b/app/components/tree_link_component.rb
new file mode 100644
index 000000000..17334ea57
--- /dev/null
+++ b/app/components/tree_link_component.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+class TreeLinkComponent < ViewComponent::Base
+ include MultiLanguagesHelper
+ include ComponentsHelper
+
+ def initialize(child:, href:, children_href: , selected_child: , data: {}, muted: false, target_frame: nil)
+ @child = child
+ @selected_child = selected_child
+ @active_style = child.id.eql?(selected_child&.id) && 'active'
+ #@icons = child.relation_icon(node)
+ @muted_style = muted ? 'text-muted' : ''
+ @href = href
+ @children_link = children_href
+ if @child.prefLabel.nil?
+ @pref_label_html = child.id.split('/').last
+ else
+ pref_label_lang, @pref_label_html = select_language_label(@child.prefLabel)
+ pref_label_lang = pref_label_lang.to_s.upcase
+ @tooltip = pref_label_lang.eql?("@NONE") ? "" : pref_label_lang
+ end
+ @data ||= { controller: 'tooltip', 'tooltip-position-value': 'right', turbo: true, 'turbo-frame': target_frame, action: 'click->simple-tree#select'}
+
+ @data.merge!(data) do |_, old, new|
+ "#{old} #{new}"
+ end
+ end
+
+
+ # This gives a very hacky short code to use to uniquely represent a class
+ # based on its parent in a tree. Used for unique ids in HTML for the tree view
+ def short_uuid
+ rand(36 ** 8).to_s(36)
+ end
+
+ # TDOD check where used
+ def child_id
+ @child.id.to_s.split('/').last
+ end
+
+ def open?
+ @child.expanded? ? 'open' : ''
+ end
+
+ def border_left
+ !@child.hasChildren && 'pl-3 tree-border-left'
+ end
+
+ def li_id
+ @child.id.eql?('bp_fake_root') ? 'bp_fake_root' : short_uuid
+ end
+
+
+ def open_children_link
+ return unless @child.hasChildren
+ if @child.expanded?
+ tree_close_icon
+ else
+ content_tag('turbo_frame', id: "#{child_id}_open_link") do
+ link_to @children_link,
+ data: { turbo: true, turbo_frame: "#{child_id + '_childs'}" } do
+ content_tag(:i, nil, class: "fas fa-chevron-right")
+ end
+ end
+ end
+
+ end
+
+end
diff --git a/app/components/tree_link_component/tree_link_component.html.haml b/app/components/tree_link_component/tree_link_component.html.haml
new file mode 100644
index 000000000..2bf3815b0
--- /dev/null
+++ b/app/components/tree_link_component/tree_link_component.html.haml
@@ -0,0 +1,10 @@
+%li{id:li_id , class: open?}
+ = open_children_link
+ %a{id: @child.id, data: @data, title: @tooltip,
+ href: @href, class: "tree-link #{@muted_style} #{@active_style} #{border_left} #{open?}"}
+ = @pref_label_html
+
+ - if @child.hasChildren && !@child.expanded?
+ = render TurboFrameComponent.new(id: "#{child_id}_childs")
+ - elsif @child.expanded?
+ = content
\ No newline at end of file
diff --git a/app/components/tree_view_component.rb b/app/components/tree_view_component.rb
new file mode 100644
index 000000000..54e03c129
--- /dev/null
+++ b/app/components/tree_view_component.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+class TreeViewComponent < ViewComponent::Base
+ include Turbo::FramesHelper
+ include ComponentsHelper
+
+ renders_many :children, TreeLinkComponent
+
+ def initialize(id:, auto_click: false, sub_tree: false, **html_options)
+ @id = id
+ @auto_click = auto_click
+ @html_options = html_options
+ @sub_tree = sub_tree
+ end
+
+ private
+
+ def sub_tree?
+ @sub_tree
+ end
+
+ def tree_container(&block)
+ if sub_tree?
+ content_tag(:ul, capture(&block), class: 'pl-2 tree-border-left')
+ else
+ content_tag(:div, class: 'tree_wrapper hide-if-loading') do
+ content_tag(:ul, capture(&block), class: 'simpleTree root', data: { controller: 'simple-tree',
+ 'simple-tree-auto-click-value': "#{auto_click?}",
+ action: 'clicked->history#updateURL' })
+ end
+ end
+ end
+
+ def auto_click?
+ @auto_click.to_s
+ end
+
+ # TDOD check where used
+ def child_id(child)
+ child.id.to_s.split('/').last
+ end
+
+end
+
\ No newline at end of file
diff --git a/app/components/tree_view_component/tree_view_component.html.haml b/app/components/tree_view_component/tree_view_component.html.haml
new file mode 100644
index 000000000..c8b47d1a4
--- /dev/null
+++ b/app/components/tree_view_component/tree_view_component.html.haml
@@ -0,0 +1,9 @@
+%turbo-frame{id: "#{@id}", **@html_options}
+ = tree_container do
+ - children.each do |child|
+ = child
+ = content
+
+
+
+
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 1420356bb..d01e9348f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -157,12 +157,6 @@ def to_param(name) # Paramaterizes URLs without encoding
end
end
- def undo_param(name) #Undo Paramaterization
- unless name.nil?
- name.to_s.gsub('_'," ")
- end
- end
-
def bp_config_json
# For config settings, see
# config/bioportal_config.rb
@@ -188,22 +182,6 @@ def bp_config_json
config.to_json
end
- def remote_file_exists?(url)
- begin
- url = URI.parse(url)
-
- if url.kind_of?(URI::FTP)
- check = check_ftp_file(url)
- else
- check = check_http_file(url)
- end
-
- rescue
- return false
- end
-
- check
- end
def rest_url
# Split the URL into protocol and path parts
@@ -308,15 +286,6 @@ def redirect_to_home # Redirect to Home Page
redirect_to "/"
end
- def redirect_to_history # Redirects to the correct tab through the history system
- if session[:redirect].nil?
- redirect_to_home
- else
- tab = find_tab(session[:redirect][:ontology])
- session[:redirect]=nil
- redirect_to uri_url(:ontology=>tab.ontology_id,:conceptid=>tab.concept)
- end
- end
def redirect_new_api(class_view = false)
# Hack to make ontologyid and conceptid work in addition to id and ontology params
@@ -373,24 +342,6 @@ def authorize_and_redirect
end
end
- # Verifies that a user owns an object
- def authorize_owner(id=nil)
- if id.nil?
- id = params[:id].to_i
- end
-
- id.map! {|i| i.to_i} if id.kind_of?(Array)
-
- if session[:user].nil?
- redirect_to_home
- else
- if id.kind_of?(Array)
- redirect_to_home if !session[:user].admin? && !id.include?(session[:user].id.to_i)
- else
- redirect_to_home if !session[:user].admin? && !session[:user].id.to_i.eql?(id)
- end
- end
- end
def authorize_admin
admin = session[:user] && session[:user].admin?
@@ -405,41 +356,7 @@ def ontology_restricted?(acronym)
restrict_downloads = $NOT_DOWNLOADABLE
restrict_downloads.include? acronym
end
- # updates the 'history' tab with the current selected concept
- def update_tab(ontology, concept)
- array = session[:ontologies] || []
- found = false
- for item in array
- if item.ontology_id.eql?(ontology.id)
- item.concept=concept
- found=true
- end
- end
-
- unless found
- array << History.new(ontology.id, ontology.name, ontology.acronym, concept)
- end
-
- session[:ontologies]=array
- end
-
- # Removes a 'history' tab
- def remove_tab(ontology_id)
- array = session[:ontologies]
- array.delete(find_tab(ontology_id))
- session[:ontologies]=array
- end
- # Returns a specific 'history' tab
- def find_tab(ontology_id)
- array = session[:ontologies]
- for item in array
- if item.ontology_id.eql?(ontology_id)
- return item
- end
- end
- return nil
- end
def check_delete_mapping_permission(mappings)
# ensure mappings is an Array of mappings (some calls may provide only a single mapping instance)
@@ -463,13 +380,13 @@ def using_captcha?
def get_class(params)
lang = request_lang
-
+
if @ontology.flat?
ignore_concept_param = params[:conceptid].nil? ||
- params[:conceptid].empty? ||
- params[:conceptid].eql?("root") ||
- params[:conceptid].eql?("bp_fake_root")
+ params[:conceptid].empty? ||
+ params[:conceptid].eql?("root") ||
+ params[:conceptid].eql?("bp_fake_root")
if ignore_concept_param
# Don't display any classes in the tree
@concept = LinkedData::Client::Models::Class.new
@@ -491,19 +408,19 @@ def get_class(params)
# not ignoring 'bp_fake_root' here
include = 'prefLabel,hasChildren,obsolete'
ignore_concept_param = params[:conceptid].nil? ||
- params[:conceptid].empty? ||
- params[:conceptid].eql?("root")
+ params[:conceptid].empty? ||
+ params[:conceptid].eql?("root")
if ignore_concept_param
# get the top level nodes for the root
# TODO_REV: Support views? Replace old view call: @ontology.top_level_classes(view)
- @roots = @ontology.explore.roots(concept_schemes: params[:concept_schemes])
+ @roots = @ontology.explore.roots(concept_schemes: params[:concept_schemes])
if @roots.nil? || @roots.empty?
LOG.add :debug, "Missing @roots for #{@ontology.acronym}"
classes = @ontology.explore.classes.collection
@concept = classes.first.explore.self(full: true) if classes.first
return
end
-
+
@root = LinkedData::Client::Models::Class.new(read_only: true)
@root.children = @roots.sort{|x,y| (x.prefLabel || "").downcase <=> (y.prefLabel || "").downcase}
@@ -569,17 +486,7 @@ def get_simplified_ontologies_hash()
return simple_ontologies
end
- def get_ontology_details(ont_uri)
- # Note the simplify_ontology_model will cache individual ontology data.
- begin
- ont_model = LinkedData::Client::Models::Ontology.find(ont_uri)
- ont = simplify_ontology_model(ont_model)
- rescue Exception => e
- LOG.add :error, e.message
- return nil
- end
- return ont
- end
+
def simplify_classes(classes)
# Simplify the classes batch service data for the UI
diff --git a/app/controllers/concepts_controller.rb b/app/controllers/concepts_controller.rb
index 6cd525453..c8c734e34 100644
--- a/app/controllers/concepts_controller.rb
+++ b/app/controllers/concepts_controller.rb
@@ -3,6 +3,8 @@
class ConceptsController < ApplicationController
include MappingsHelper
include ConceptsHelper
+ include TurboHelper
+
layout 'ontology'
def show_concept
@@ -21,9 +23,9 @@ def show_concept
@ob_instructions = helpers.ontolobridge_instructions_template(@ontology)
@concept = @ontology.explore.single_class({full: true, language: request_lang}, params[:id])
@instances_concept_id = @concept.id
-
concept_not_found(params[:id]) if @concept.nil?
- gather_details
+ @notes = @concept.explore.notes
+
render :partial => 'show'
end
@@ -40,22 +42,22 @@ def show
@ontology = LinkedData::Client::Models::Ontology.find_by_acronym(params[:ontology]).first
@ob_instructions = helpers.ontolobridge_instructions_template(@ontology)
- if request.xhr?
- display = params[:callback].eql?('load') ? {full: true} : {display: "prefLabel"}
- @concept = @ontology.explore.single_class(display, params[:id])
- concept_not_found(params[:id]) if @concept.nil?
- @schemes = params[:concept_schemes]&.split(',')
- show_ajax_request # process an ajax call
- else
- # Get the latest 'ready' submission, or fallback to any latest submission
- # TODO: change the logic here if the fallback will crash the visualization
+ # Get the latest 'ready' submission, or fallback to any latest submission
+ # TODO: change the logic here if the fallback will crash the visualization
@submission = get_ontology_submission_ready(@ontology) # application_controller
@concept = @ontology.explore.single_class({full: true}, params[:id])
- concept_not_found(params[:id]) if @concept.nil?
- @schemes = params[:concept_schemes].split(',')
- show_ajax_request # process a full call
- end
+ concept_not_found(params[:id]) if @concept.nil?
+ @schemes = params[:concept_schemes].split(',')
+
+ @concept.children = @concept.explore.children(pagesize: 750, concept_schemes: Array(@schemes).join(','), language: request_lang, display: 'prefLabel,obsolete,hasChildren').collection || []
+ @concept.children.sort! { |x, y| (x.prefLabel || "").downcase <=> (y.prefLabel || "").downcase } unless @concept.children.empty?
+ render turbo_stream: [
+ replace(helpers.child_id(@concept) + '_open_link') { helpers.tree_close_icon },
+ replace(helpers.child_id(@concept) + '_childs') do
+ helpers.concepts_tree_component(@concept, @concept, @ontology.acronym, Array(@schemes), request_lang, sub_tree: true)
+ end
+ ]
end
def show_label
@@ -94,9 +96,11 @@ def show_tree
@ontology = LinkedData::Client::Models::Ontology.find_by_acronym(params[:ontology]).first
if @ontology.nil?
ontology_not_found(params[:ontology])
- else
+ else
get_class(params) #application_controller
- render partial: 'ontologies/treeview', locals: { autoCLick: params[:auto_click] || true }
+ render inline: helpers.concepts_tree_component(@root, @concept,
+ @ontology.acronym, params[:concept_schemes].split(','), request_lang,
+ id: 'concepts_tree_view', auto_click: params[:auto_click] || true)
end
end
@@ -180,39 +184,12 @@ def biomixer
render partial: "biomixer", layout: false
end
-# PRIVATE -----------------------------------------
-private
-
- def show_ajax_request
- case params[:callback]
- when 'load' # Load pulls in all the details of a node
- gather_details
- render :partial => 'load'
- when 'children' # Children is called only for drawing the tree
- @children = @concept.explore.children(pagesize: 750, concept_schemes: Array(@schemes).join(','), language: request_lang, display: 'prefLabel,obsolete,hasChildren').collection || []
- @children.sort! { |x, y| (x.prefLabel || "").downcase <=> (y.prefLabel || "").downcase } unless @children.empty?
- render :partial => 'child_nodes'
- end
- end
- # gathers the full set of data for a node
- def show_uri_request
- gather_details
- build_tree
- end
+ private
- def gather_details
- @notes = @concept.explore.notes
- update_tab(@ontology, @concept.id) #updates the 'history' tab with the current node
- end
- def build_tree
- # find path to root
- rootNode = @concept.explore.tree(include: "prefLabel,hasChildren,obsolete,subClassOf")
- @root = LinkedData::Client::Models::Class.new(read_only: true)
- @root.children = rootNode unless rootNode.nil?
- end
+
def filter_concept_with_no_date(concepts)
concepts.filter { |c| !concept_date(c).nil?}
end
diff --git a/app/controllers/history_controller.rb b/app/controllers/history_controller.rb
deleted file mode 100644
index 687839df5..000000000
--- a/app/controllers/history_controller.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class HistoryController < ApplicationController
-
- def remove # removes a 'history' tab
- remove_tab(undo_param(params[:ontology]))
- render :text =>"success"
- end
-
- def update # updates the 'history' tab to point to the new node
- ontology = DataAccess.getOntology(params[:ontology])
- update_tab(ontology,params[:concept])
- render :text =>"success"
- end
-
-
-end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e03ed69cb..fe240100e 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -185,82 +185,8 @@ def draw_note_tree_leaves(notes,level,output,key)
end
end
- def draw_tree(root, acronym, id = nil, concept_schemes = nil)
- id = root.children.first.id if id.nil?
-
- # TODO: handle tree view for obsolete classes, e.g. 'http://purl.obolibrary.org/obo/GO_0030400'
- raw build_tree(root, '', id, acronym, concept_schemes: concept_schemes)
- end
-
- def build_tree(node, string, id, acronym, concept_schemes: nil)
-
- return string if node.children.nil? || node.children.empty?
-
- node.children.sort! { |a, b| (main_language_label(a.prefLabel) || a.id).downcase <=> (main_language_label(a.prefLabel) || b.id).downcase }
- node.children.each do |child|
- active_style = child.id.eql?(id) ? "active" : ''
-
- # This fake root will be present at the root of "flat" ontologies, we need to keep the id intact
-
- if child.id.eql?('bp_fake_root')
- string << tree_link_to_concept(child: child, ontology_acronym: acronym,
- active_style: active_style, node: node, skos: !concept_schemes.nil?)
- else
- string << tree_link_to_concept(child: child, ontology_acronym: acronym,
- active_style: active_style, node: node, skos: !concept_schemes.nil?)
- if child.hasChildren && !child.expanded?
- string << tree_link_to_children(child: child, acronym: acronym, concept_schemes: concept_schemes)
- elsif child.expanded?
- string << '
'
- build_tree(child, string, id, acronym, concept_schemes: concept_schemes)
- string << '
'
- end
- string << ''
- end
- end
- string
- end
-
- def tree_link_to_concept(child:, ontology_acronym:, active_style:, node: nil, skos: false)
- language = request_lang
- li_id = child.id.eql?('bp_fake_root') ? 'bp_fake_root' : short_uuid
- open = child.expanded? ? "class='open'" : ''
- #icons = child.relation_icon(node) removed because slow
- muted_style = skos && Array(child.isInActiveScheme).empty? ? 'text-muted' : nil
- muted_title = muted_style && !child.obsolete? ? "title='is not in a scheme'" : nil
- href = ontology_acronym.blank? ? '#' : "/ontologies/#{ontology_acronym}/concepts/?id=#{CGI.escape(child.id)}&language=#{language}"
-
- if child.prefLabel.nil?
- pref_label_html = child.id.split('/').last
- else
- pref_label_lang, pref_label_html = select_language_label(child.prefLabel)
- pref_label_lang = pref_label_lang.to_s.upcase
- tooltip = pref_label_lang.eql?("@NONE") ? "" : "data-controller='tooltip' data-tooltip-position-value='right' title='#{pref_label_lang}'";
- end
-
- link = <<-EOS
-
- #{ pref_label_html }
-
- EOS
- "#{link}"
- end
-
-
- def tree_link_to_children(child:, acronym: ,concept_schemes: nil)
- language = request_lang
- li_id = child.id.eql?('bp_fake_root') ? 'bp_fake_root' : short_uuid
- concept_schemes = "&concept_schemes=#{concept_schemes.map{|x| CGI.escape(x)}.join(',')}" if concept_schemes
-
- link = "ajax_class"
- ""
+ def child_id(child)
+ child.id.to_s.split('/').last
end
def loading_spinner(padding = false, include_text = true)
@@ -272,11 +198,7 @@ def loading_spinner(padding = false, include_text = true)
end
end
- # This gives a very hacky short code to use to uniquely represent a class
- # based on its parent in a tree. Used for unique ids in HTML for the tree view
- def short_uuid
- rand(36**8).to_s(36)
- end
+
def help_icon(link, html_attribs = {})
html_attribs["title"] ||= "Help"
diff --git a/app/helpers/components_helper.rb b/app/helpers/components_helper.rb
index c67209696..dfb275d5b 100644
--- a/app/helpers/components_helper.rb
+++ b/app/helpers/components_helper.rb
@@ -1,4 +1,21 @@
module ComponentsHelper
+
+ def tree_link(child:, selected_concept: , href: ,concept_schemes: nil, data: {}, muted: false, target_frame: nil)
+ selected = child.id.eql?(selected_concept.id)
+
+ render TreeLinkComponent.new(child: child, href: href,
+ active_style: selected && 'active',
+ concept_schemes: concept_schemes, muted: muted,
+ data: data, target_frame: target_frame
+ ) do
+
+ end
+ end
+
+ def tree_close_icon
+ content_tag(:i, nil, class: "fas fa-chevron-down text-primary", data:{action:'click->simple-tree#toggleChildren'})
+ end
+
def info_tooltip(text)
render Display::InfoTooltipComponent.new(text: text)
end
diff --git a/app/helpers/concepts_helper.rb b/app/helpers/concepts_helper.rb
index 4418e6d52..c8087e365 100644
--- a/app/helpers/concepts_helper.rb
+++ b/app/helpers/concepts_helper.rb
@@ -1,5 +1,35 @@
# frozen_string_literal: true
module ConceptsHelper
+
+ def concept_tree_child_data(acronym, child, concept_schemes, data, language)
+ href = child.id.eql?('bp_fake_root') ? '#' : "/ontologies/#{acronym}/concepts/?id=#{CGI.escape(child.id)}&language=#{language}"
+ children_link = "/ajax_concepts/#{acronym}/?conceptid=#{CGI.escape(child.id)}&concept_schemes=#{concept_schemes.join(',')}&language=#{language}"
+ data = {
+ conceptid: child.id,
+ 'active-collections-value': child.isInActiveCollection || [],
+ 'collections-value': child.memberOf || [],
+ 'skos-collection-colors-target': 'collection',
+ }.merge(data)
+ [children_link, data, href]
+ end
+ def concepts_tree_component(root, selected_concept, acronym, concept_schemes, language, sub_tree: false, id: nil, data: {}, auto_click: false)
+ root.children.sort! { |a, b| (a.prefLabel || a.id).downcase <=> (b.prefLabel || b.id).downcase }
+
+ render TreeViewComponent.new(id: id, sub_tree: sub_tree, auto_click: auto_click) do |tree_child|
+ root.children.each do |child|
+ children_link, data, href = concept_tree_child_data(acronym, child, concept_schemes, data, language)
+
+ tree_child.child(child: child, href: href,
+ children_href: children_link, selected_child: selected_concept,
+ muted: child.isInActiveScheme&.empty?,
+ target_frame: 'concept_show',
+ data: data) do
+ concepts_tree_component(child, selected_concept, acronym, concept_schemes, language, sub_tree: true)
+ end
+ end
+ end
+ end
+
def exclude_relation?(relation_to_check, ontology = nil)
excluded_relations = %w[type rdf:type [R] SuperClass InstanceCount]
@@ -79,22 +109,25 @@ def same_period?(year, month, date)
year.eql?(date.year) && month.eql?(date.strftime('%B'))
end
- def concepts_li_list(concepts)
+ def concepts_li_list(concepts, auto_click: false)
out = ''
concepts.each do |concept|
- out += tree_link_to_concept(child: concept, ontology_acronym: @ontology.acronym, active_style: '')
+ children_link, data, href = concept_tree_child_data(@ontology.acronym, concept, [], {}, request_lang)
+ out += render TreeLinkComponent.new(child: concept, href: href,
+ children_href: '#', selected_child: concept.id.eql?(concepts.first.id) && auto_click ? concept : nil,
+ target_frame: 'concept_show', data: data)
end
out
end
- def render_concepts_by_dates
+ def render_concepts_by_dates(auto_click: false)
return if @concepts_year_month.empty?
first_year, first_month_concepts = @concepts_year_month.shift
first_month, first_concepts = first_month_concepts.shift
out = ''
if same_period?(first_year, first_month, @last_date)
- out += "#{concepts_li_list(first_concepts)}
"
+ out += "#{concepts_li_list(first_concepts, auto_click: auto_click)}
"
else
tmp = {}
tmp[first_month] = first_concepts
@@ -107,7 +140,7 @@ def render_concepts_by_dates
@concepts_year_month.each do |year, month_concepts|
month_concepts.each do |month, concepts|
out += " #{month + ' ' + year.to_s}"
- out += concepts_li_list(concepts)
+ out += concepts_li_list(concepts, auto_click: auto_click)
out += "
"
end
end
diff --git a/app/helpers/schemes_helper.rb b/app/helpers/schemes_helper.rb
index 3e024feec..8a3e9a013 100644
--- a/app/helpers/schemes_helper.rb
+++ b/app/helpers/schemes_helper.rb
@@ -5,7 +5,7 @@ def get_schemes(ontology)
end
def get_scheme(ontology, scheme_uri)
- ontology.explore.schemes({ include: 'all', language: request_lang}, scheme_uri)
+ ontology.explore.schemes({ include: 'all', language: request_lang }, scheme_uri)
end
def get_scheme_label(scheme)
@@ -22,14 +22,14 @@ def get_schemes_labels(schemes, main_uri)
selected_label = nil
schemes_labels = []
- schemes.each do |x|
+ schemes.each do |x|
id = x['@id']
label = select_language_label(get_scheme_label(x))
if id.eql? main_uri
label[1] = "#{label[1]} (main)" unless label[0].empty?
selected_label = { 'prefLabel' => label, '@id' => id }
else
- schemes_labels.append( { 'prefLabel' => label, '@id' => id })
+ schemes_labels.append({ 'prefLabel' => label, '@id' => id })
end
end
@@ -45,7 +45,7 @@ def concept_label_to_show(submission: @submission_latest)
def section_name(section)
section = concept_label_to_show(submission: @submission_latest || @submission) if section.eql?('classes')
section
- #t("ontology_details.sections.#{section}" , section)
+ # t("ontology_details.sections.#{section}" , section)
end
def scheme_path(scheme_id = '', language = '')
@@ -65,6 +65,7 @@ def no_main_scheme_alert
'no main scheme defined in the URI attribute'
end
end
+
def no_schemes_alert
render Display::AlertComponent.new do
"#{@ontology.acronym} does not contain schemes (skos:ConceptScheme)"
@@ -72,37 +73,71 @@ def no_schemes_alert
end
def schemes_data
- schemes_labels, main_scheme = get_schemes_labels(@schemes,@submission.URI)
- selected_scheme = @schemes.select{ |s| params[:concept_schemes]&.split(',')&.include?(s['@id']) }
+ schemes_labels, main_scheme = get_schemes_labels(@schemes, @submission.URI)
+ selected_scheme = @schemes.select { |s| params[:concept_schemes]&.split(',')&.include?(s['@id']) }
selected_scheme = selected_scheme.empty? ? [main_scheme] : selected_scheme
[schemes_labels, main_scheme, selected_scheme]
end
- def tree_link_to_schemes(schemes_labels, main_scheme_label, selected_scheme_id)
- out = ''
+ def scheme_tree_root(schemes_labels, main_scheme_label, selected_scheme_id)
+ selected_scheme = nil
+ schemes = sorted_labels(schemes_labels).map do |s|
+ next nil unless main_scheme_label.nil? || s['prefLabel'] != main_scheme_label['prefLabel']
+ scheme = OpenStruct.new(s)
+ scheme.prefLabel = Array(get_scheme_label(s)).last
+ scheme.id = scheme['@id']
+ selected_scheme = scheme if scheme.id.eql?(selected_scheme_id)
+ scheme
+ end.compact
+
+
+ main_scheme = nil
+ if main_scheme_label.nil?
+ children = schemes
+ else
+ main_scheme = OpenStruct.new(main_scheme_label)
+ main_scheme.prefLabel = Array(get_scheme_label(main_scheme_label)).last
+ main_scheme.children = schemes
+ main_scheme.id = main_scheme['@id']
+ main_scheme['expanded?'] = true
+ main_scheme['hasChildren'] = true
+ children = [main_scheme]
+ end
+ root = OpenStruct.new
+ root.children = children
- sorted_labels(schemes_labels).each do |s|
- next unless main_scheme_label.nil? || s['prefLabel'] != main_scheme_label['prefLabel']
+ [root, selected_scheme || main_scheme || root.children.first]
+ end
- out << <<-EOS
-
- #{link_to_scheme(s, selected_scheme_id)}
-
- EOS
- end
- out
+ def scheme_tree_child_data(scheme, data, language)
+ href = scheme_path(scheme['@id'], language) rescue ''
+ data = {
+ schemeid: (scheme['@id'] rescue ''),
+ }.merge(data)
+ [data, href]
end
- def link_to_scheme(scheme, selected_scheme_id)
- pref_label_lang, pref_label_html = get_scheme_label(scheme)
- tooltip = pref_label_lang.to_s.eql?('@none') ? '' : "data-controller='tooltip' data-tooltip-position-value='right' title='#{pref_label_lang.upcase}'"
- <<-EOS
-
- #{pref_label_html}
-
- EOS
+ def scheme_tree_component(root, selected_scheme, language = request_lang, id: nil, data: {}, sub_tree: false, auto_click: false)
+ root.children.sort! { |a, b| (a.prefLabel || a.id).downcase <=> (b.prefLabel || b.id).downcase }
+
+ render TreeViewComponent.new(id: id, auto_click: auto_click, sub_tree: sub_tree) do |tree_child|
+ root.children.each do |child|
+ next if child.nil?
+ data, href = scheme_tree_child_data(child, data, language)
+
+ tree_child.child(child: child, href: href,
+ children_href: '#', selected_child: selected_scheme,
+ target_frame: 'scheme',
+ data: data) do
+ scheme_tree_component(child, selected_scheme, language, sub_tree: true)
+ end
+ end
+ end
end
+
+
+
end
+
+
+
diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js
index 8d4ea6942..a722c875e 100644
--- a/app/javascript/controllers/index.js
+++ b/app/javascript/controllers/index.js
@@ -64,8 +64,7 @@ application.register("show-filter-count", ShowFilterCountController)
import ShowModalController from "./show_modal_controller"
application.register("show-modal", ShowModalController)
-import SimpleTreeController from "./simple_tree_controller"
-application.register("simple-tree", SimpleTreeController)
+
import SkosCollectionColorsController from "./skos_collection_colors_controller"
application.register("skos-collection-colors", SkosCollectionColorsController)
@@ -84,3 +83,6 @@ application.register("turbo-frame", TurboFrameController)
import TurboFrameErrorController from "./turbo_frame_error_controller"
application.register("turbo-frame-error", TurboFrameErrorController)
+
+import SimpleTreeController from "./simple_tree_controller"
+application.register("simple-tree", SimpleTreeController)
diff --git a/app/javascript/controllers/simple_tree_controller.js b/app/javascript/controllers/simple_tree_controller.js
index bcc04cc7a..d1f9ea4f4 100644
--- a/app/javascript/controllers/simple_tree_controller.js
+++ b/app/javascript/controllers/simple_tree_controller.js
@@ -1,76 +1,61 @@
-import {Controller} from "@hotwired/stimulus"
-import {useSimpleTree} from "../mixins/useSimpleTree";
-
+import { Controller } from '@hotwired/stimulus'
// Connects to data-controller="simple-tree"
export default class extends Controller {
- static values = {
- autoClick: {type: Boolean, default: false}
- }
-
- connect() {
- this.simpleTreeCollection = useSimpleTree(this.element,
- this.#afterClick.bind(this),
- this.#afterAjaxError.bind(this),
- this.#beforeAjax.bind(this)
- )
-
-
- this.simpleTreeCollection.ready(() => {
- let activeElem = this.element.querySelector('a.active')
- if (activeElem) {
- $(this.element).scrollTo($(activeElem))
-
- if (this.autoClickValue) {
- activeElem.click()
- }
- }
-
-
- })
+ static values = {
+ autoClick: { type: Boolean, default: false }
+ }
- this.#onClickTooManyChildrenInit()
- }
-
- #onClickTooManyChildrenInit() {
- jQuery(".too_many_children_override").live('click', (event) => {
- event.preventDefault();
- let result = jQuery(event.target).closest("ul");
- result.html("
");
- jQuery.ajax({
- url: jQuery(event.target).attr('href'),
- context: result,
- success: function (data) {
- this.html(data);
- this.simpleTreeCollection.get(0).setTreeNodes(this);
- },
- error: function () {
- this.html("");
- }
- });
- });
- }
-
- #afterClick(node) {
- this.element.dispatchEvent(new CustomEvent('clicked', {
- detail: {
- node: node,
- data: {...node.context.dataset}
+ connect () {
+ let activeElem = this.element.querySelector('a.active')
+ if (activeElem) {
+ $(this.element).scrollTo($(activeElem))
- }
- }))
+ if (this.autoClickValue) {
+ activeElem.click()
+ }
}
-
- #afterAjaxError(node) {
- this.simpleTreeCollection[0].option.animate = false;
- this.simpleTreeCollection.get(0).nodeToggle(node.parent()[0]);
- if (node.parent().children(".expansion_error").length === 0) {
- node.parent().append("Error, please try again");
+ this.#onClickTooManyChildrenInit()
+ }
+
+ select (event) {
+ this.element.querySelector('a.active')?.classList.toggle('active')
+ event.currentTarget.classList.toggle('active')
+ this.#afterClick(event.currentTarget)
+ }
+
+ toggleChildren (event) {
+ event.preventDefault()
+ event.target.classList.toggle('fa-chevron-right')
+ event.target.classList.toggle('fa-chevron-down')
+ event.target.nextElementSibling.nextElementSibling.classList.toggle('hidden')
+ }
+
+ #onClickTooManyChildrenInit () {
+ jQuery('.too_many_children_override').live('click', (event) => {
+ event.preventDefault()
+ let result = jQuery(event.target).closest('ul')
+ result.html('
')
+ jQuery.ajax({
+ url: jQuery(event.target).attr('href'),
+ context: result,
+ success: function (data) {
+ this.html(data)
+ this.simpleTreeCollection.get(0).setTreeNodes(this)
+ },
+ error: function () {
+ this.html('')
}
- this.simpleTreeCollection[0].option.animate = true;
- }
-
- #beforeAjax(node) {
- node.parent().children(".expansion_error").remove();
- }
+ })
+ })
+ }
+
+ #afterClick (node) {
+ this.element.dispatchEvent(new CustomEvent('clicked', {
+ detail: {
+ node: node,
+ data: { ...node.dataset }
+ }, bubbles: true
+ }))
+ }
}
diff --git a/app/javascript/controllers/skos_collection_colors_controller.js b/app/javascript/controllers/skos_collection_colors_controller.js
index bef363873..e2c5d4794 100644
--- a/app/javascript/controllers/skos_collection_colors_controller.js
+++ b/app/javascript/controllers/skos_collection_colors_controller.js
@@ -31,7 +31,7 @@ export default class extends Controller {
collectionTargetConnected(collectionElem) {
- if (this.selected.length > 0) {
+ if (this.selected && this.selected.length > 0) {
this.#updateColorsTags(collectionElem)
}
}
diff --git a/app/javascript/mixins/useHistory.js b/app/javascript/mixins/useHistory.js
index f84ff4133..4fd271b94 100644
--- a/app/javascript/mixins/useHistory.js
+++ b/app/javascript/mixins/useHistory.js
@@ -1,6 +1,6 @@
export class HistoryService {
- unWantedData = ['turbo', 'controller', 'target', 'value']
+ unWantedData = ['turbo', 'controller', 'target', 'value', 'action']
constructor() {
diff --git a/app/views/collections/_list_view.html.haml b/app/views/collections/_list_view.html.haml
index bfe256748..5071f262e 100644
--- a/app/views/collections/_list_view.html.haml
+++ b/app/views/collections/_list_view.html.haml
@@ -5,9 +5,11 @@
no collections detected
- else
%div
- %ul.simpleTree{data:{controller: 'simple-tree', 'simple-tree': { 'auto-click-value': "true" }, action: 'clicked->history#updateURL'}}
- %li.root
- %ul
- - sort_collections_label(collections_labels).each do |c|
- %li.doc
- = raw link_to_collection(c, selected_collection_id)
\ No newline at end of file
+ = render TreeViewComponent.new(id: nil, auto_click: true) do |tree_child|
+ - sort_collections_label(collections_labels).each do |collection|
+ - scheme = OpenStruct.new(collection)
+ - scheme.prefLabel = Array(get_collection_label(collection)).last
+ - scheme.id = scheme['@id']
+ - tree_child.child(child: scheme, href: collection_path(collection['@id'], request_lang),
+ children_href: '#', selected_child: scheme.id.eql?(selected_collection_id) ? scheme : nil,
+ target_frame: 'collection', data: {collectionid: collection['@id']})
diff --git a/app/views/concepts/_child_nodes.html.haml b/app/views/concepts/_child_nodes.html.haml
deleted file mode 100644
index 0137fa40a..000000000
--- a/app/views/concepts/_child_nodes.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-- output =""
-- for child in @children
- - output << tree_link_to_concept(child: child, ontology_acronym: @ontology.acronym, active_style: '', node: @concept, skos: !@schemes.nil?)
- - if child.hasChildren
- - output << tree_link_to_children(child: child, acronym: @ontology.acronym, concept_schemes: @schemes)
- - output << ""
-= raw output
diff --git a/app/views/concepts/_date_sorted_list.html.haml b/app/views/concepts/_date_sorted_list.html.haml
index 517b37590..95e79bf6e 100644
--- a/app/views/concepts/_date_sorted_list.html.haml
+++ b/app/views/concepts/_date_sorted_list.html.haml
@@ -1,6 +1,6 @@
= render TreeInfiniteScrollComponent.new(id: 'concepts_date_sorted_list',
collection: @concepts, next_url: sorted_by_date_url(@page.nextPage, @concepts.last),
current_page: @page.page, next_page: @page.nextPage) do |c|
- = render_concepts_by_dates
+ = render_concepts_by_dates(auto_click: @page.page.eql?(1))
- c.error do
The Classes/Concepts didn't define creation or modifications dates with dcterms
diff --git a/app/views/concepts/_list.html.haml b/app/views/concepts/_list.html.haml
index 34f4e9679..4a3c55a41 100644
--- a/app/views/concepts/_list.html.haml
+++ b/app/views/concepts/_list.html.haml
@@ -5,9 +5,11 @@
auto_click: @auto_click) do |c|
- concepts = c.collection.sort_by{|concept| [concept.prefLabel&.capitalize || concept.id]}
- if concepts && !concepts.empty?
- = raw tree_link_to_concept(child: concepts.shift, ontology_acronym: @ontology.acronym, active_style: c.auto_click? ? 'active' : '')
- concepts.each do |concept|
- = raw tree_link_to_concept(child: concept, ontology_acronym: @ontology.acronym, active_style: '')
+ - children_link, data, href = concept_tree_child_data(@ontology.acronym, concept, [], {}, request_lang)
+ = render TreeLinkComponent.new(child: concept, href: href,
+ children_href: '#', selected_child: concept.id.eql?(concepts.first.id) && c.auto_click? ? concept : nil,
+ target_frame: 'concept_show', data: data)
- c.error do
The Collection didn't define any member
diff --git a/app/views/ontologies/_treeview.html.haml b/app/views/ontologies/_treeview.html.haml
deleted file mode 100644
index 86f1abdc0..000000000
--- a/app/views/ontologies/_treeview.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-= turbo_frame_tag 'concepts_tree_view' do
- #tree_wrapper.hide-if-loading
- %ul.simpleTree{data:{controller: 'simple-tree',
- 'simple-tree': { 'auto-click-value': "#{autoCLick}" },
- action: 'clicked->history#updateURL'}}
- %li.root
- %ul
- = draw_tree(@root, params[:ontology], @concept.id, params[:concept_schemes]&.split(','))
-
-
diff --git a/app/views/ontologies/concepts_browsers/_concepts_tree.html.haml b/app/views/ontologies/concepts_browsers/_concepts_tree.html.haml
index fb23ac593..54d32eb5e 100644
--- a/app/views/ontologies/concepts_browsers/_concepts_tree.html.haml
+++ b/app/views/ontologies/concepts_browsers/_concepts_tree.html.haml
@@ -15,7 +15,7 @@
data: {action: 'changed->skos-collection-colors#updateCollectionTags' ,
'chosen-enable-colors-value': 'true'}}
-# Class tree
- %div#sd_content.card.p-1.py-3{style: 'overflow-y: scroll; height: 60vh;'}
+ %div#sd_content.px-1{style: 'overflow-y: scroll; height: 60vh;'}
- if skos? && @roots&.empty?
%div.text-wrap
= render Display::AlertComponent.new do
@@ -24,4 +24,4 @@
- concept_schemes = skos? ? "&concept_schemes=#{params[:concept_schemes]}" : ''
= render TurboFrameComponent.new(id: 'concepts_tree_view',
src: "/ajax/classes/treeview?ontology=#{@ontology.acronym}&conceptid=#{escape(@concept.id)}#{concept_schemes}&auto_click=false&language=#{request_lang}",
- data: {'turbo-frame-target': 'frame'})
\ No newline at end of file
+ data: {'turbo-frame-target': 'frame'})
\ No newline at end of file
diff --git a/app/views/schemes/_tree_view.html.haml b/app/views/schemes/_tree_view.html.haml
index d707d5655..80908351e 100644
--- a/app/views/schemes/_tree_view.html.haml
+++ b/app/views/schemes/_tree_view.html.haml
@@ -1,4 +1,3 @@
-
- if no_schemes?
%div
= no_schemes_alert
@@ -8,13 +7,6 @@
- if main_scheme_label.nil?
= no_main_scheme_alert
%div
- %ul.simpleTree{data:{controller: 'simple-tree', action: 'clicked->history#updateURL'}}
- %li.root
- %ul
- - if main_scheme_label.nil?
- = raw tree_link_to_schemes(schemes_labels ,main_scheme_label, selected_scheme_id)
- - else
- %li.open
- = raw link_to_scheme(main_scheme_label, selected_scheme_id)
- %ul
- = raw tree_link_to_schemes(schemes_labels ,main_scheme_label, selected_scheme_id)
\ No newline at end of file
+ - root, selected_scheme = scheme_tree_root(schemes_labels, main_scheme_label, selected_scheme_id)
+ = scheme_tree_component(root, selected_scheme, auto_click: true)
+