Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Align Bioportal and AgroPortal - part 4 - Independent scrolling and Concept tree autoscroll to selected node and UI bug fixes #27

2 changes: 0 additions & 2 deletions app/assets/javascripts/bp_mappings.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ function loadMappings(value) {
}
]
});
jQuery(".mappings.index a.facebox").facebox();
});
}

Expand Down Expand Up @@ -144,4 +143,3 @@ function deleteMappings() {
}
});
}

4 changes: 4 additions & 0 deletions app/assets/stylesheets/bioportal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
background-color: var(--admin-color);
}

.tabs-container .tab-items > div button{
color: var(--primary-color) !important
}

a{
text-decoration: none !important;
}
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/components/tabs_container.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
transition: opacity 0.3s ease;

a, button {
color: #5e5e5e !important;
color: #5e5e5e;
border: none;
background: none;
}
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/theme-variables.scss.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<% themes = {
"agroportal" => { primary: "#3CB371", hover: "#41C67C", secondary: "#ffc107", light: "#F1F6FA" },
"stageportal" => { primary: "#37AEA0", hover: "#3BBDAE", secondary: "#ffc107", light: "#ECF7F6" },
"bioportal" => { primary: "#76A7CC", hover: "#6B96B7", secondary: "#ffc107", light: "#F0F5F6" },
"bioportal" => { primary: "#234979", hover: "#6B96B7", secondary: "#ffc107", light: "#F0F5F6" },
"ontoportal" => { primary: "#5499a4", hover: "#6B96B7", secondary: "#ffc107", light: "#F1F6FA" },
"testportal" => { primary: "#5499a4", hover: "#6B96B7", secondary: "#ffc107", light: "#F1F6FA" }
} %>
Expand Down
5 changes: 5 additions & 0 deletions app/assets/stylesheets/tree.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/********************
## TREE VIEW
*********************/
#tree_wrapper {
max-height: 70vh;
overflow-y: scroll;
}

div.tree_error {
background: none repeat scroll 0 0 lightYellow;
font-weight: 600;
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def build_tree(node, string, id, submission)
node.children.sort! { |a, b| (a.prefLabel || a.id).downcase <=> (b.prefLabel || b.id).downcase }
for child in node.children
if child.id.eql?(id)
active_style = "class='active'"
active_style = "class='tree-link active'"
else
active_style = ""
end
Expand Down
138 changes: 86 additions & 52 deletions app/javascript/controllers/simple_tree_controller.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,94 @@
import {Controller} from "@hotwired/stimulus"
import {useSimpleTree} from "../mixins/useSimpleTree";

const TREE_VIEW_PAGES = ['classes', 'properties', 'schemes', 'collections', 'instances']

export default class extends Controller {
connect() {
if (this.element.getAttribute('simple-tree-data-initial') == 0) {
return;



static values = {
autoClick: { type: Boolean, default: false }
}
this.simpleTreeCollection = useSimpleTree(this.element,
this.#afterClick.bind(this),
this.#afterAjaxError.bind(this),
this.#beforeAjax.bind(this)
);
this.#onClickTooManyChildrenInit();
this.element.setAttribute('simple-tree-data-initial', 0);
}

#onClickTooManyChildrenInit(){
jQuery(".too_many_children_override").live('click', (event) => {
event.preventDefault();
let result = jQuery(event.target).closest("ul");
result.html("<img src='/images/tree/spinner.gif'>");
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("<div style='background: #eeeeee; padding: 5px; width: 80%;'>Problem getting children. <a href='" + jQuery(this).attr('href') + "' class='too_many_children_override'>Try again</a></div>");

connect() {
if (this.element.getAttribute('simple-tree-data-initial') == 0) {
return;
}
});
});
}

#afterClick(node) {
const page_name = $(node.context).attr("data-bp-ont-page-name")
const conf = jQuery(document).data().bp.ont_viewer
const concept_id = jQuery(node).children("a").attr("id")
History.pushState({
p: "classes",
conceptid: concept_id
}, page_name + " | " + conf.org_site,
'?p=classes&conceptid=' + concept_id)
}

#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("<span class='expansion_error'>Error, please try again");
this.simpleTreeCollection = useSimpleTree(this.element,
this.#afterClick.bind(this),
this.#afterAjaxError.bind(this),
this.#beforeAjax.bind(this)
);

this.#onClickTooManyChildrenInit();
this.element.setAttribute('simple-tree-data-initial', 0);
this.#centerTreeView()
}
this.simpleTreeCollection[0].option.animate = true;
}

#beforeAjax(node) {
node.parent().children(".expansion_error").remove();
}
}
#centerTreeView() {
setTimeout(() => {
const location = window.location.href;

const isTreeViewPage = TREE_VIEW_PAGES.some(param => location.includes(`p=${param}`));

if (isTreeViewPage) {
const activeElem = this.element.querySelector('.tree-link.active');

if (activeElem) {
activeElem.scrollIntoView({block: 'center'});
window.scrollTo({top: 0});

if (this.autoClickValue) {
activeElem.click();
}
}

this.#onClickTooManyChildrenInit();
}
}, 0);
}

#onClickTooManyChildrenInit() {
jQuery(".too_many_children_override").live('click', (event) => {
event.preventDefault();
let result = jQuery(event.target).closest("ul");
result.html("<img src='/images/tree/spinner.gif'>");
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("<div style='background: #eeeeee; padding: 5px; width: 80%;'>Problem getting children. <a href='" + jQuery(this).attr('href') + "' class='too_many_children_override'>Try again</a></div>");
}
});
});
}

#afterClick(node) {
const page_name = $(node.context).attr("data-bp-ont-page-name")
const conf = jQuery(document).data().bp.ont_viewer
const concept_id = jQuery(node).children("a").attr("id")
History.pushState({
p: "classes",
conceptid: concept_id
}, page_name + " | " + conf.org_site,
'?p=classes&conceptid=' + concept_id)
}

#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("<span class='expansion_error'>Error, please try again");
}
this.simpleTreeCollection[0].option.animate = true;
}

#beforeAjax(node) {
node.parent().children(".expansion_error").remove();
}
}
2 changes: 1 addition & 1 deletion app/views/change_requests/_node_obsoletion.html.haml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
= form_with scope: :node_obsoletion, url: change_requests_path, data: {turbo: true}, class: 'mb-5' do |f|
= form_with scope: :node_obsoletion, url: change_requests_path, data: {turbo: true, turbo_frame: '_top'}, class: 'mb-5' do |f|
= hidden_field_tag 'concept_id', @concept_id
= hidden_field_tag 'concept_label', @concept_label
= hidden_field_tag 'github_id', @user.githubId
Expand Down
4 changes: 2 additions & 2 deletions app/views/concepts/_details.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
= link_to('Obsolete class',
change_requests_node_obsoletion_path(concept_id: @concept.id, concept_label: @concept.prefLabel,
ont_acronym: @ontology.acronym),
class: 'dropdown-item', 'data-turbo': 'true', 'data-turbo-stream': 'true')
class: 'dropdown-item', 'data-turbo': 'true', 'data-turbo-stream': 'true', 'data-turbo-frame': '_top')
= link_to('Rename class',
change_requests_node_rename_path(concept_id: @concept.id, concept_label: @concept.prefLabel,
ont_acronym: @ontology.acronym),
class: 'dropdown-item', 'data-turbo': 'true', 'data-turbo-stream': 'true')
class: 'dropdown-item', 'data-turbo': 'true', 'data-turbo-stream': 'true','data-turbo-frame': '_top')
%div{'data-controller': 'change-requests'}
%div{id: 'addProposalFormDiv', 'data-change-requests-target': 'addProposalForm'}

Expand Down
6 changes: 4 additions & 2 deletions app/views/concepts/_show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
Class Mappings (
%span#mapping_count= @mappings.size
)
- if $PURL_ENABLED
= link_to("#classPermalinkModal", class: "class-permalink nav-link", title: "Get a permanent link to this class", aria: {label: "Get a permanent link to this class"}, data: {toggle: "modal", current_purl: "#{@current_purl}"}) do
- if Rails.configuration.settings.purl[:enabled]
= link_to("#classPermalinkModal", class: "class-permalink py-1", title: "Get a link to this page",
aria: {label: "Get a link to this page"},
data: {"bs-toggle": "modal", current_purl: "#{@current_purl}"}) do
%i{class: "fas fa-link", aria: {hidden: "true"}}
#contents.tab-content
#details_content.tab-pane.active.show
Expand Down
2 changes: 1 addition & 1 deletion app/views/mappings/_count.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
%td
= link_to(mapping_count[:target_ontology][:name],
mapping_path(id: @ontology.acronym, target: mapping_count[:target_ontology][:id]),
class: 'facebox')
class: 'facebox', 'data-turbo': false)
%td
= number_with_delimiter(mapping_count[:count], delimiter: ',')

Expand Down
20 changes: 11 additions & 9 deletions app/views/mappings/_mapping_table.html.haml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
-# called from mappings_controller in several ways:
-# 1. mappings_controller::get_concept_table via /app/views/mappings/_concept_mappings.html.haml
-# 2. directly from mappings_controller::get_concept_table
-#NOTES on control over mapping deletion:
-#deleteMappings() is a callback that is called by "#delete_mappings_button" created below.
-#The appearance of that button is controlled by updateMappingDeletePermissions(), which
-#relies on @delete_mapping_permission in /app/views/mappings/_mapping_table.html.haml; which,
-#in turn, is set by /app/controllers/application_controller.check_delete_mapping_permission()
-# NOTES on control over mapping deletion:
-# deleteMappings() is a callback that is called by "#delete_mappings_button" created below.
-# The appearance of that button is controlled by updateMappingDeletePermissions(), which
-# relies on @delete_mapping_permission in /app/views/mappings/_mapping_table.html.haml; which,
-# in turn, is set by /app/controllers/application_controller.check_delete_mapping_permission()
-#
-# The delete mappings button display is controlled by JS on page ready (see bp_mappings.js)
-# check_box_tag(name, value = "1", checked = false, options = {})
Expand All @@ -14,7 +14,8 @@
%table#concept_mappings_table.zebra
%thead
%tr
%th.delete_mappings_column Delete
- if session[:user]
%th.delete_mappings_column Delete
%th Mapping To
%th Ontology
%th Source
Expand All @@ -28,9 +29,10 @@
- ont_acronym = cls.links['ontology'].split("/").last
- map_id = map.id.to_s.split("/").last
%tr.human{id: map_id}
%td.delete_mappings_column
- if map.id && !map.id.empty? && session[:user] && (session[:user].id.to_i == map.creator || session[:user].admin?)
= check_box_tag :delete_mapping_checkbox, map.id
- if session[:user]
%td.delete_mappings_column
- if map.id && !map.id.empty? && (session[:user].id.to_i == map.creator || session[:user].admin?)
= check_box_tag :delete_mapping_checkbox, map.id
%td
= link_to cls.id, ontology_path(id: ont_acronym, p: 'classes', conceptid: cls.id)
%td
Expand Down
5 changes: 0 additions & 5 deletions app/views/ontologies/_treeview.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,3 @@
%li.root
%ul
= draw_tree(@root, @concept.id)

:javascript
jQuery(document).ready(function () {
jQuery("#sd_content").scrollTo(jQuery('a.active'));
})
13 changes: 12 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ en:
A class that the authors of the ontology have flagged as being obsolete and which they recommend that people not use. These classes
are often left in ontologies (rather than removing them entirely) so that existing systems that depend on them will continue to function.

ontology_details:
sections:
classes: Classes
summary: Summary
properties: Properties
instances: Instances
notes: Notes
mappings: Mappings
widgets: Widgets
sparql: Sparql
concepts: Concepts

projects:
index:
intro: Browse a selection of projects that use %{site} resources
Expand All @@ -88,4 +100,3 @@ en:

mappings:
intro: Browse mappings between classes in different ontologies

Loading