o&&(n.val=o);var p;p=c.geo.origin.fixedLineage?c.geo.origin.windowOffset:{left:c.geo.origin.windowOffset.left+c.geo.window.scroll.left,top:c.geo.origin.windowOffset.top+c.geo.window.scroll.top},d.coord={left:p.left+(d.coord.left-c.geo.origin.windowOffset.left),top:p.top+(d.coord.top-c.geo.origin.windowOffset.top)},e.__sideChange(e.__instance._$tooltip,d.side),c.geo.origin.fixedLineage?e.__instance._$tooltip.css("position","fixed"):e.__instance._$tooltip.css("position",""),e.__instance._$tooltip.css({left:d.coord.left,top:d.coord.top,height:d.size.height,width:d.size.width}).find(".tooltipster-arrow").css({left:"",top:""}).css(n.prop,n.val),e.__instance._$tooltip.appendTo(e.__instance.option("parent")),e.__instance._trigger({type:"repositioned",event:b,position:d})},__sideChange:function(a,b){a.removeClass("tooltipster-bottom").removeClass("tooltipster-left").removeClass("tooltipster-right").removeClass("tooltipster-top").addClass("tooltipster-"+b)},__targetFind:function(a){var b={},c=this.__instance._$origin[0].getClientRects();if(c.length>1){var d=this.__instance._$origin.css("opacity");1==d&&(this.__instance._$origin.css("opacity",.99),c=this.__instance._$origin[0].getClientRects(),this.__instance._$origin.css("opacity",1))}if(c.length<2)b.top=Math.floor(a.geo.origin.windowOffset.left+a.geo.origin.size.width/2),b.bottom=b.top,b.left=Math.floor(a.geo.origin.windowOffset.top+a.geo.origin.size.height/2),b.right=b.left;else{var e=c[0];b.top=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil(c.length/2)-1]:c[0],b.right=Math.floor(e.top+(e.bottom-e.top)/2),e=c[c.length-1],b.bottom=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil((c.length+1)/2)-1]:c[c.length-1],b.left=Math.floor(e.top+(e.bottom-e.top)/2)}return b}}}),a});
\ No newline at end of file
diff --git a/app/assets/stylesheets/application.css.scss.erb b/app/assets/stylesheets/application.css.scss.erb
index 1b70724a0..50e44bc56 100644
--- a/app/assets/stylesheets/application.css.scss.erb
+++ b/app/assets/stylesheets/application.css.scss.erb
@@ -20,6 +20,7 @@
*= require thickbox
*= require select2
*= require trumbowyg
+ *= require flag-icon
*= require theme-variables
*/
diff --git a/app/assets/stylesheets/bioportal.scss b/app/assets/stylesheets/bioportal.scss
index 1003395d0..0e1d07131 100644
--- a/app/assets/stylesheets/bioportal.scss
+++ b/app/assets/stylesheets/bioportal.scss
@@ -1,3 +1,8 @@
+.turbo-progress-bar {
+ height: 5px;
+ background-color: var(--admin-color);
+}
+
a{
text-decoration: none !important;
}
diff --git a/app/assets/stylesheets/concepts.scss b/app/assets/stylesheets/concepts.scss
index 7f3bc860d..0c8c7a08d 100644
--- a/app/assets/stylesheets/concepts.scss
+++ b/app/assets/stylesheets/concepts.scss
@@ -18,7 +18,7 @@
}
}
-.concept_details td:nth-child(1) {
+.concept_details td:nth-child(2) {
white-space: nowrap;
}
@@ -31,3 +31,119 @@ div.synonym-change-request {
div.synonym-change-request button {
padding: 0px;
}
+.nav-link.active{
+ border-radius: 5px;
+}
+.concepts-general-details{
+ width: 870px;
+ border-radius: 5px;
+ border: 1px solid #DFDFDF;
+}
+.concepts-nav-item{
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.concepts-nav-item a{
+ margin: 12px 24px;
+ color: #888888 !important;
+ cursor: pointer;
+}
+.concepts-tabs-container{
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+.concepts-tabs{
+ display: flex;
+ justify-content: space-between;
+ width: 589px;
+}
+.concepts-active-tab a{
+ font-weight: 600;
+ color: var(--primary-color) !important;
+}
+.concepts-active-tab hr{
+ margin: 0;
+ border: 1px solid var(--primary-color);
+ border-radius: 5px;
+ display: block !important;
+ width: 100%;
+}
+.concepts-nav-item hr{
+ margin: 0;
+ display: none;
+}
+#concepts-header-line{
+ margin: 0;
+}
+.concepts-json{
+ width: 32px;
+ height: 32px;
+ border: 1px solid var(--primary-color);
+ border-radius: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ right: 40px;
+ transition: background-color ease 0.3s;
+}
+.concepts-json:hover{
+ background-color: var(--primary-color);
+
+}
+.concepts-json:hover svg path{
+ fill: white;
+}
+.concepts-content{
+ border-collapse: collapse;
+ width: 100%;
+ border-spacing: 0;
+
+}
+.concepts-content td{
+ padding: 12px 24px;
+ vertical-align: top;
+}
+.concepts-content tr:nth-child(odd) {
+ background-color: #FAFAFA;
+}
+
+.concepts-content td:first-child {
+ color: #888888;
+ width: 220px;
+}
+.concepts-content td:first-child {
+ color: #888888;
+ width: 220px;
+}
+.concepts-content a{
+ text-decoration: underline;
+ color: #888888;
+}
+.concepts-content div{
+ margin-bottom: 5px;
+}
+.concepts-raw-data{
+ margin-top: 20px;
+ border-radius: 5px;
+ border: 1px solid #DFDFDF;
+
+}
+.concepts-raw-title{
+ display: flex;
+ justify-content: space-between;
+ padding: 12px 24px;
+ color: #888888;
+ cursor: pointer;
+ font-size: 16px;
+ font-weight: 400;
+}
+.concepts-raw-title div{
+ padding: 10px 0px;
+}
+#details_content{
+ margin-top: 15px;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/themes/lirmm/flags32.scss b/app/assets/stylesheets/themes/lirmm/flags32.scss
deleted file mode 100644
index 2a7323d7c..000000000
--- a/app/assets/stylesheets/themes/lirmm/flags32.scss
+++ /dev/null
@@ -1,245 +0,0 @@
-.f32 .flag{display:inline-block;height:32px;width:32px;vertical-align:text-top;line-height:32px;background-image: image-url('flags32.png');background-repeat:no-repeat;}
-.f32 ._African_Union{background-position:0 -32px;}
-.f32 ._Arab_League{background-position:0 -64px;}
-.f32 ._ASEAN{background-position:0 -96px;}
-.f32 ._CARICOM{background-position:0 -128px;}
-.f32 ._CIS{background-position:0 -160px;}
-.f32 ._Commonwealth{background-position:0 -192px;}
-.f32 ._England{background-position:0 -224px;}
-.f32 ._European_Union{background-position:0 -256px;}
-.f32 ._Islamic_Conference{background-position:0 -288px;}
-.f32 ._Kosovo{background-position:0 -320px;}
-.f32 ._NATO{background-position:0 -352px;}
-.f32 ._Northern_Cyprus{background-position:0 -384px;}
-.f32 ._Northern_Ireland{background-position:0 -416px;}
-.f32 ._Olimpic_Movement{background-position:0 -448px;}
-.f32 ._OPEC{background-position:0 -480px;}
-.f32 ._Red_Cross{background-position:0 -512px;}
-.f32 ._Scotland{background-position:0 -544px;}
-.f32 ._Somaliland{background-position:0 -576px;}
-.f32 ._Tibet{background-position:0 -608px;}
-.f32 ._United_Nations{background-position:0 -640px;}
-.f32 ._Wales{background-position:0 -672px;}
-.f32 .ad{background-position:0 -704px;}
-.f32 .ae{background-position:0 -736px;}
-.f32 .af{background-position:0 -768px;}
-.f32 .ag{background-position:0 -800px;}
-.f32 .ai{background-position:0 -832px;}
-.f32 .al{background-position:0 -864px;}
-.f32 .am{background-position:0 -896px;}
-.f32 .an{background-position:0 -928px;}
-.f32 .ao{background-position:0 -960px;}
-.f32 .aq{background-position:0 -992px;}
-.f32 .ar{background-position:0 -1024px;}
-.f32 .as{background-position:0 -1056px;}
-.f32 .at{background-position:0 -1088px;}
-.f32 .au{background-position:0 -1120px;}
-.f32 .aw{background-position:0 -1152px;}
-.f32 .az{background-position:0 -1184px;}
-.f32 .ba{background-position:0 -1216px;}
-.f32 .bb{background-position:0 -1248px;}
-.f32 .bd{background-position:0 -1280px;}
-.f32 .be{background-position:0 -1312px;}
-.f32 .bf{background-position:0 -1344px;}
-.f32 .bg{background-position:0 -1376px;}
-.f32 .bh{background-position:0 -1408px;}
-.f32 .bi{background-position:0 -1440px;}
-.f32 .bj{background-position:0 -1472px;}
-.f32 .bm{background-position:0 -1504px;}
-.f32 .bn{background-position:0 -1536px;}
-.f32 .bo{background-position:0 -1568px;}
-.f32 .br{background-position:0 -1600px;}
-.f32 .bs{background-position:0 -1632px;}
-.f32 .bt{background-position:0 -1664px;}
-.f32 .bw{background-position:0 -1696px;}
-.f32 .by{background-position:0 -1728px;}
-.f32 .bz{background-position:0 -1760px;}
-.f32 .ca{background-position:0 -1792px;}
-.f32 .cd{background-position:0 -1824px;}
-.f32 .cf{background-position:0 -1856px;}
-.f32 .cg{background-position:0 -1888px;}
-.f32 .ch{background-position:0 -1920px;}
-.f32 .ci{background-position:0 -1952px;}
-.f32 .ck{background-position:0 -1984px;}
-.f32 .cl{background-position:0 -2016px;}
-.f32 .cm{background-position:0 -2048px;}
-.f32 .cn{background-position:0 -2080px;}
-.f32 .co{background-position:0 -2112px;}
-.f32 .cr{background-position:0 -2144px;}
-.f32 .cu{background-position:0 -2176px;}
-.f32 .cv{background-position:0 -2208px;}
-.f32 .cy{background-position:0 -2240px;}
-.f32 .cz{background-position:0 -2272px;}
-.f32 .de{background-position:0 -2304px;}
-.f32 .dj{background-position:0 -2336px;}
-.f32 .dk{background-position:0 -2368px;}
-.f32 .dm{background-position:0 -2400px;}
-.f32 .do{background-position:0 -2432px;}
-.f32 .dz{background-position:0 -2464px;}
-.f32 .ec{background-position:0 -2496px;}
-.f32 .ee{background-position:0 -2528px;}
-.f32 .eg{background-position:0 -2560px;}
-.f32 .eh{background-position:0 -2592px;}
-.f32 .er{background-position:0 -2624px;}
-.f32 .es{background-position:0 -2656px;}
-.f32 .et{background-position:0 -2688px;}
-.f32 .fi{background-position:0 -2720px;}
-.f32 .fj{background-position:0 -2752px;}
-.f32 .fm{background-position:0 -2784px;}
-.f32 .fo{background-position:0 -2816px;}
-.f32 .fr{background-position:0 -2848px;}
-.f32 .ga{background-position:0 -2880px;}
-.f32 .gb{background-position:0 -2912px;}
-.f32 .gd{background-position:0 -2944px;}
-.f32 .ge{background-position:0 -2976px;}
-.f32 .gg{background-position:0 -3008px;}
-.f32 .gh{background-position:0 -3040px;}
-.f32 .gi{background-position:0 -3072px;}
-.f32 .gl{background-position:0 -3104px;}
-.f32 .gm{background-position:0 -3136px;}
-.f32 .gn{background-position:0 -3168px;}
-.f32 .gp{background-position:0 -3200px;}
-.f32 .gq{background-position:0 -3232px;}
-.f32 .gr{background-position:0 -3264px;}
-.f32 .gt{background-position:0 -3296px;}
-.f32 .gu{background-position:0 -3328px;}
-.f32 .gw{background-position:0 -3360px;}
-.f32 .gy{background-position:0 -3392px;}
-.f32 .hk{background-position:0 -3424px;}
-.f32 .hn{background-position:0 -3456px;}
-.f32 .hr{background-position:0 -3488px;}
-.f32 .ht{background-position:0 -3520px;}
-.f32 .hu{background-position:0 -3552px;}
-.f32 .id{background-position:0 -3584px;}
-.f32 .mc{background-position:0 -3584px;}
-.f32 .ie{background-position:0 -3616px;}
-.f32 .il{background-position:0 -3648px;}
-.f32 .im{background-position:0 -3680px;}
-.f32 .in{background-position:0 -3712px;}
-.f32 .iq{background-position:0 -3744px;}
-.f32 .ir{background-position:0 -3776px;}
-.f32 .is{background-position:0 -3808px;}
-.f32 .it{background-position:0 -3840px;}
-.f32 .je{background-position:0 -3872px;}
-.f32 .jm{background-position:0 -3904px;}
-.f32 .jo{background-position:0 -3936px;}
-.f32 .jp{background-position:0 -3968px;}
-.f32 .ke{background-position:0 -4000px;}
-.f32 .kg{background-position:0 -4032px;}
-.f32 .kh{background-position:0 -4064px;}
-.f32 .ki{background-position:0 -4096px;}
-.f32 .km{background-position:0 -4128px;}
-.f32 .kn{background-position:0 -4160px;}
-.f32 .kp{background-position:0 -4192px;}
-.f32 .kr{background-position:0 -4224px;}
-.f32 .kw{background-position:0 -4256px;}
-.f32 .ky{background-position:0 -4288px;}
-.f32 .kz{background-position:0 -4320px;}
-.f32 .la{background-position:0 -4352px;}
-.f32 .lb{background-position:0 -4384px;}
-.f32 .lc{background-position:0 -4416px;}
-.f32 .li{background-position:0 -4448px;}
-.f32 .lk{background-position:0 -4480px;}
-.f32 .lr{background-position:0 -4512px;}
-.f32 .ls{background-position:0 -4544px;}
-.f32 .lt{background-position:0 -4576px;}
-.f32 .lu{background-position:0 -4608px;}
-.f32 .lv{background-position:0 -4640px;}
-.f32 .ly{background-position:0 -4672px;}
-.f32 .ma{background-position:0 -4704px;}
-.f32 .md{background-position:0 -4736px;}
-.f32 .me{background-position:0 -4768px;}
-.f32 .mg{background-position:0 -4800px;}
-.f32 .mh{background-position:0 -4832px;}
-.f32 .mk{background-position:0 -4864px;}
-.f32 .ml{background-position:0 -4896px;}
-.f32 .mm{background-position:0 -4928px;}
-.f32 .mn{background-position:0 -4960px;}
-.f32 .mo{background-position:0 -4992px;}
-.f32 .mq{background-position:0 -5024px;}
-.f32 .mr{background-position:0 -5056px;}
-.f32 .ms{background-position:0 -5088px;}
-.f32 .mt{background-position:0 -5120px;}
-.f32 .mu{background-position:0 -5152px;}
-.f32 .mv{background-position:0 -5184px;}
-.f32 .mw{background-position:0 -5216px;}
-.f32 .mx{background-position:0 -5248px;}
-.f32 .my{background-position:0 -5280px;}
-.f32 .mz{background-position:0 -5312px;}
-.f32 .na{background-position:0 -5344px;}
-.f32 .nc{background-position:0 -5376px;}
-.f32 .ne{background-position:0 -5408px;}
-.f32 .ng{background-position:0 -5440px;}
-.f32 .ni{background-position:0 -5472px;}
-.f32 .nl{background-position:0 -5504px;}
-.f32 .no{background-position:0 -5536px;}
-.f32 .np{background-position:0 -5568px;}
-.f32 .nr{background-position:0 -5600px;}
-.f32 .nz{background-position:0 -5632px;}
-.f32 .om{background-position:0 -5664px;}
-.f32 .pa{background-position:0 -5696px;}
-.f32 .pe{background-position:0 -5728px;}
-.f32 .pf{background-position:0 -5760px;}
-.f32 .pg{background-position:0 -5792px;}
-.f32 .ph{background-position:0 -5824px;}
-.f32 .pk{background-position:0 -5856px;}
-.f32 .pl{background-position:0 -5888px;}
-.f32 .pr{background-position:0 -5920px;}
-.f32 .ps{background-position:0 -5952px;}
-.f32 .pt{background-position:0 -5984px;}
-.f32 .pw{background-position:0 -6016px;}
-.f32 .py{background-position:0 -6048px;}
-.f32 .qa{background-position:0 -6080px;}
-.f32 .re{background-position:0 -6112px;}
-.f32 .ro{background-position:0 -6144px;}
-.f32 .rs{background-position:0 -6176px;}
-.f32 .ru{background-position:0 -6208px;}
-.f32 .rw{background-position:0 -6240px;}
-.f32 .sa{background-position:0 -6272px;}
-.f32 .sb{background-position:0 -6304px;}
-.f32 .sc{background-position:0 -6336px;}
-.f32 .sd{background-position:0 -6368px;}
-.f32 .se{background-position:0 -6400px;}
-.f32 .sg{background-position:0 -6432px;}
-.f32 .si{background-position:0 -6464px;}
-.f32 .sk{background-position:0 -6496px;}
-.f32 .sl{background-position:0 -6528px;}
-.f32 .sm{background-position:0 -6560px;}
-.f32 .sn{background-position:0 -6592px;}
-.f32 .so{background-position:0 -6624px;}
-.f32 .sr{background-position:0 -6656px;}
-.f32 .st{background-position:0 -6688px;}
-.f32 .sv{background-position:0 -6720px;}
-.f32 .sy{background-position:0 -6752px;}
-.f32 .sz{background-position:0 -6784px;}
-.f32 .tc{background-position:0 -6816px;}
-.f32 .td{background-position:0 -6848px;}
-.f32 .tg{background-position:0 -6880px;}
-.f32 .th{background-position:0 -6912px;}
-.f32 .tj{background-position:0 -6944px;}
-.f32 .tl{background-position:0 -6976px;}
-.f32 .tm{background-position:0 -7008px;}
-.f32 .tn{background-position:0 -7040px;}
-.f32 .to{background-position:0 -7072px;}
-.f32 .tr{background-position:0 -7104px;}
-.f32 .tt{background-position:0 -7136px;}
-.f32 .tv{background-position:0 -7168px;}
-.f32 .tw{background-position:0 -7200px;}
-.f32 .tz{background-position:0 -7232px;}
-.f32 .ua{background-position:0 -7264px;}
-.f32 .ug{background-position:0 -7296px;}
-.f32 .us{background-position:0 -7328px;}
-.f32 .uy{background-position:0 -7360px;}
-.f32 .uz{background-position:0 -7392px;}
-.f32 .va{background-position:0 -7424px;}
-.f32 .vc{background-position:0 -7456px;}
-.f32 .ve{background-position:0 -7488px;}
-.f32 .vg{background-position:0 -7520px;}
-.f32 .vi{background-position:0 -7552px;}
-.f32 .vn{background-position:0 -7584px;}
-.f32 .vu{background-position:0 -7616px;}
-.f32 .ws{background-position:0 -7648px;}
-.f32 .ye{background-position:0 -7680px;}
-.f32 .za{background-position:0 -7712px;}
-.f32 .zm{background-position:0 -7744px;}
-.f32 .zw{background-position:0 -7744px;}
\ No newline at end of file
diff --git a/app/assets/stylesheets/themes/lirmm/main.scss b/app/assets/stylesheets/themes/lirmm/main.scss
index e50dcf48d..7279f1e72 100644
--- a/app/assets/stylesheets/themes/lirmm/main.scss
+++ b/app/assets/stylesheets/themes/lirmm/main.scss
@@ -2,18 +2,11 @@
@import "annotator";
@import "app";
@import "bootstrap_overrides";
-@import "flags32";
@import "jqcloud";
@import "landscape";
@import "ontologies";
@import "recommender";
@import "search";
-@import "tooltipster.bundle.min";
-@import "plugins/tooltipster/sideTip/themes/tooltipster-sideTip-borderless.min";
-@import "plugins/tooltipster/sideTip/themes/tooltipster-sideTip-light.min";
-@import "plugins/tooltipster/sideTip/themes/tooltipster-sideTip-noir.min";
-@import "plugins/tooltipster/sideTip/themes/tooltipster-sideTip-punk.min";
-@import "plugins/tooltipster/sideTip/themes/tooltipster-sideTip-shadow.min";
/************************************
diff --git a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-borderless.min.scss b/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-borderless.min.scss
deleted file mode 100644
index 19408cb1e..000000000
--- a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-borderless.min.scss
+++ /dev/null
@@ -1 +0,0 @@
-.tooltipster-sidetip.tooltipster-borderless .tooltipster-box{border:none;background:#1b1b1b;background:rgba(10,10,10,.9)}.tooltipster-sidetip.tooltipster-borderless.tooltipster-bottom .tooltipster-box{margin-top:8px}.tooltipster-sidetip.tooltipster-borderless.tooltipster-left .tooltipster-box{margin-right:8px}.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-box{margin-left:8px}.tooltipster-sidetip.tooltipster-borderless.tooltipster-top .tooltipster-box{margin-bottom:8px}.tooltipster-sidetip.tooltipster-borderless .tooltipster-arrow{height:8px;margin-left:-8px;width:16px}.tooltipster-sidetip.tooltipster-borderless.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-arrow{height:16px;margin-left:0;margin-top:-8px;width:8px}.tooltipster-sidetip.tooltipster-borderless .tooltipster-arrow-background{display:none}.tooltipster-sidetip.tooltipster-borderless .tooltipster-arrow-border{border:8px solid transparent}.tooltipster-sidetip.tooltipster-borderless.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#1b1b1b;border-bottom-color:rgba(10,10,10,.9)}.tooltipster-sidetip.tooltipster-borderless.tooltipster-left .tooltipster-arrow-border{border-left-color:#1b1b1b;border-left-color:rgba(10,10,10,.9)}.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-arrow-border{border-right-color:#1b1b1b;border-right-color:rgba(10,10,10,.9)}.tooltipster-sidetip.tooltipster-borderless.tooltipster-top .tooltipster-arrow-border{border-top-color:#1b1b1b;border-top-color:rgba(10,10,10,.9)}.tooltipster-sidetip.tooltipster-borderless.tooltipster-bottom .tooltipster-arrow-uncropped{top:-8px}.tooltipster-sidetip.tooltipster-borderless.tooltipster-right .tooltipster-arrow-uncropped{left:-8px}
\ No newline at end of file
diff --git a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-light.min.scss b/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-light.min.scss
deleted file mode 100644
index 298c9d4a5..000000000
--- a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-light.min.scss
+++ /dev/null
@@ -1 +0,0 @@
-.tooltipster-sidetip.tooltipster-light .tooltipster-box{border-radius:3px;border:1px solid #ccc;background:#ededed}.tooltipster-sidetip.tooltipster-light .tooltipster-content{color:#666}.tooltipster-sidetip.tooltipster-light .tooltipster-arrow{height:9px;margin-left:-9px;width:18px}.tooltipster-sidetip.tooltipster-light.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow{height:18px;margin-left:0;margin-top:-9px;width:9px}.tooltipster-sidetip.tooltipster-light .tooltipster-arrow-background{border:9px solid transparent}.tooltipster-sidetip.tooltipster-light.tooltipster-bottom .tooltipster-arrow-background{border-bottom-color:#ededed;top:1px}.tooltipster-sidetip.tooltipster-light.tooltipster-left .tooltipster-arrow-background{border-left-color:#ededed;left:-1px}.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow-background{border-right-color:#ededed;left:1px}.tooltipster-sidetip.tooltipster-light.tooltipster-top .tooltipster-arrow-background{border-top-color:#ededed;top:-1px}.tooltipster-sidetip.tooltipster-light .tooltipster-arrow-border{border:9px solid transparent}.tooltipster-sidetip.tooltipster-light.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-left .tooltipster-arrow-border{border-left-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow-border{border-right-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-top .tooltipster-arrow-border{border-top-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-bottom .tooltipster-arrow-uncropped{top:-9px}.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow-uncropped{left:-9px}
\ No newline at end of file
diff --git a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-noir.min.scss b/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-noir.min.scss
deleted file mode 100644
index 39f4ca388..000000000
--- a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-noir.min.scss
+++ /dev/null
@@ -1 +0,0 @@
-.tooltipster-sidetip.tooltipster-noir .tooltipster-box{border-radius:0;border:3px solid #000;background:#fff}.tooltipster-sidetip.tooltipster-noir .tooltipster-content{color:#000}.tooltipster-sidetip.tooltipster-noir .tooltipster-arrow{height:11px;margin-left:-11px;width:22px}.tooltipster-sidetip.tooltipster-noir.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-noir.tooltipster-right .tooltipster-arrow{height:22px;margin-left:0;margin-top:-11px;width:11px}.tooltipster-sidetip.tooltipster-noir .tooltipster-arrow-background{border:11px solid transparent}.tooltipster-sidetip.tooltipster-noir.tooltipster-bottom .tooltipster-arrow-background{border-bottom-color:#fff;top:4px}.tooltipster-sidetip.tooltipster-noir.tooltipster-left .tooltipster-arrow-background{border-left-color:#fff;left:-4px}.tooltipster-sidetip.tooltipster-noir.tooltipster-right .tooltipster-arrow-background{border-right-color:#fff;left:4px}.tooltipster-sidetip.tooltipster-noir.tooltipster-top .tooltipster-arrow-background{border-top-color:#fff;top:-4px}.tooltipster-sidetip.tooltipster-noir .tooltipster-arrow-border{border-width:11px}.tooltipster-sidetip.tooltipster-noir.tooltipster-bottom .tooltipster-arrow-uncropped{top:-11px}.tooltipster-sidetip.tooltipster-noir.tooltipster-right .tooltipster-arrow-uncropped{left:-11px}
\ No newline at end of file
diff --git a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-punk.min.scss b/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-punk.min.scss
deleted file mode 100644
index 6702cf557..000000000
--- a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-punk.min.scss
+++ /dev/null
@@ -1 +0,0 @@
-.tooltipster-sidetip.tooltipster-punk .tooltipster-box{border-radius:5px;border:none;border-bottom:3px solid #f71169;background:#2a2a2a}.tooltipster-sidetip.tooltipster-punk.tooltipster-top .tooltipster-box{margin-bottom:7px}.tooltipster-sidetip.tooltipster-punk .tooltipster-content{color:#fff;padding:8px 16px}.tooltipster-sidetip.tooltipster-punk .tooltipster-arrow-background{display:none}.tooltipster-sidetip.tooltipster-punk.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#2a2a2a}.tooltipster-sidetip.tooltipster-punk.tooltipster-left .tooltipster-arrow-border{border-left-color:#2a2a2a}.tooltipster-sidetip.tooltipster-punk.tooltipster-right .tooltipster-arrow-border{border-right-color:#2a2a2a}.tooltipster-sidetip.tooltipster-punk.tooltipster-top .tooltipster-arrow-border{border-top-color:#f71169}
\ No newline at end of file
diff --git a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-shadow.min.scss b/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-shadow.min.scss
deleted file mode 100644
index 7d92926de..000000000
--- a/app/assets/stylesheets/themes/lirmm/plugins/tooltipster/sideTip/themes/tooltipster-sideTip-shadow.min.scss
+++ /dev/null
@@ -1 +0,0 @@
-.tooltipster-sidetip.tooltipster-shadow .tooltipster-box{border:none;border-radius:5px;background:#fff;box-shadow:0 0 10px 6px rgba(0,0,0,.1)}.tooltipster-sidetip.tooltipster-shadow.tooltipster-bottom .tooltipster-box{margin-top:6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-left .tooltipster-box{margin-right:6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-box{margin-left:6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-top .tooltipster-box{margin-bottom:6px}.tooltipster-sidetip.tooltipster-shadow .tooltipster-content{color:#8d8d8d}.tooltipster-sidetip.tooltipster-shadow .tooltipster-arrow{height:6px;margin-left:-6px;width:12px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-arrow{height:12px;margin-left:0;margin-top:-6px;width:6px}.tooltipster-sidetip.tooltipster-shadow .tooltipster-arrow-background{display:none}.tooltipster-sidetip.tooltipster-shadow .tooltipster-arrow-border{border:6px solid transparent}.tooltipster-sidetip.tooltipster-shadow.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-left .tooltipster-arrow-border{border-left-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-arrow-border{border-right-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-top .tooltipster-arrow-border{border-top-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-bottom .tooltipster-arrow-uncropped{top:-6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-arrow-uncropped{left:-6px}
\ No newline at end of file
diff --git a/app/assets/stylesheets/themes/lirmm/tooltipster.bundle.min.scss b/app/assets/stylesheets/themes/lirmm/tooltipster.bundle.min.scss
deleted file mode 100644
index d8f30feec..000000000
--- a/app/assets/stylesheets/themes/lirmm/tooltipster.bundle.min.scss
+++ /dev/null
@@ -1 +0,0 @@
-.tooltipster-fall,.tooltipster-grow.tooltipster-show{-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1);-moz-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-ms-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-o-transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-base{display:flex;pointer-events:none;position:absolute}.tooltipster-box{flex:1 1 auto}.tooltipster-content{box-sizing:border-box;max-height:100%;max-width:100%;overflow:auto}.tooltipster-ruler{bottom:0;left:0;overflow:hidden;position:fixed;right:0;top:0;visibility:hidden}.tooltipster-fade{opacity:0;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;-ms-transition-property:opacity;transition-property:opacity}.tooltipster-fade.tooltipster-show{opacity:1}.tooltipster-grow{-webkit-transform:scale(0,0);-moz-transform:scale(0,0);-o-transform:scale(0,0);-ms-transform:scale(0,0);transform:scale(0,0);-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-backface-visibility:hidden}.tooltipster-grow.tooltipster-show{-webkit-transform:scale(1,1);-moz-transform:scale(1,1);-o-transform:scale(1,1);-ms-transform:scale(1,1);transform:scale(1,1);-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-swing{opacity:0;-webkit-transform:rotateZ(4deg);-moz-transform:rotateZ(4deg);-o-transform:rotateZ(4deg);-ms-transform:rotateZ(4deg);transform:rotateZ(4deg);-webkit-transition-property:-webkit-transform,opacity;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform}.tooltipster-swing.tooltipster-show{opacity:1;-webkit-transform:rotateZ(0);-moz-transform:rotateZ(0);-o-transform:rotateZ(0);-ms-transform:rotateZ(0);transform:rotateZ(0);-webkit-transition-timing-function:cubic-bezier(.23,.635,.495,1);-webkit-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-moz-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-ms-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-o-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);transition-timing-function:cubic-bezier(.23,.635,.495,2.4)}.tooltipster-fall{-webkit-transition-property:top;-moz-transition-property:top;-o-transition-property:top;-ms-transition-property:top;transition-property:top;-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-fall.tooltipster-initial{top:0!important}.tooltipster-fall.tooltipster-dying{-webkit-transition-property:all;-moz-transition-property:all;-o-transition-property:all;-ms-transition-property:all;transition-property:all;top:0!important;opacity:0}.tooltipster-slide{-webkit-transition-property:left;-moz-transition-property:left;-o-transition-property:left;-ms-transition-property:left;transition-property:left;-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-moz-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-ms-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-o-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-slide.tooltipster-initial{left:-40px!important}.tooltipster-slide.tooltipster-dying{-webkit-transition-property:all;-moz-transition-property:all;-o-transition-property:all;-ms-transition-property:all;transition-property:all;left:0!important;opacity:0}@keyframes tooltipster-fading{0%{opacity:0}100%{opacity:1}}.tooltipster-update-fade{animation:tooltipster-fading .4s}@keyframes tooltipster-rotating{25%{transform:rotate(-2deg)}75%{transform:rotate(2deg)}100%{transform:rotate(0)}}.tooltipster-update-rotate{animation:tooltipster-rotating .6s}@keyframes tooltipster-scaling{50%{transform:scale(1.1)}100%{transform:scale(1)}}.tooltipster-update-scale{animation:tooltipster-scaling .6s}.tooltipster-sidetip .tooltipster-box{background:#565656;border:2px solid #000;border-radius:4px}.tooltipster-sidetip.tooltipster-bottom .tooltipster-box{margin-top:8px}.tooltipster-sidetip.tooltipster-left .tooltipster-box{margin-right:8px}.tooltipster-sidetip.tooltipster-right .tooltipster-box{margin-left:8px}.tooltipster-sidetip.tooltipster-top .tooltipster-box{margin-bottom:8px}.tooltipster-sidetip .tooltipster-content{color:#fff;line-height:18px;padding:6px 14px}.tooltipster-sidetip .tooltipster-arrow{overflow:hidden;position:absolute}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow{height:10px;margin-left:-10px;top:0;width:20px}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow{height:20px;margin-top:-10px;right:0;top:0;width:10px}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow{height:20px;margin-top:-10px;left:0;top:0;width:10px}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow{bottom:0;height:10px;margin-left:-10px;width:20px}.tooltipster-sidetip .tooltipster-arrow-background,.tooltipster-sidetip .tooltipster-arrow-border{height:0;position:absolute;width:0}.tooltipster-sidetip .tooltipster-arrow-background{border:10px solid transparent}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-background{border-bottom-color:#565656;left:0;top:3px}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-background{border-left-color:#565656;left:-3px;top:0}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-background{border-right-color:#565656;left:3px;top:0}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-background{border-top-color:#565656;left:0;top:-3px}.tooltipster-sidetip .tooltipster-arrow-border{border:10px solid transparent;left:0;top:0}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#000}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border{border-left-color:#000}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border{border-right-color:#000}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border{border-top-color:#000}.tooltipster-sidetip .tooltipster-arrow-uncropped{position:relative}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped{top:-10px}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped{left:-10px}
\ No newline at end of file
diff --git a/app/components/alert_message_component.rb b/app/components/alert_message_component.rb
index f2175b7e0..1ef3b185c 100644
--- a/app/components/alert_message_component.rb
+++ b/app/components/alert_message_component.rb
@@ -2,8 +2,10 @@
class AlertMessageComponent < ViewComponent::Base
include Turbo::FramesHelper
- def initialize(id: '', type: 'info')
+ def initialize(id: '', message: '', type: 'info', closeable: true)
@id = id
+ @message = message
@type = "alert-#{type}"
+ @closeable = closeable
end
end
diff --git a/app/components/alert_message_component/alert_message_component.html.haml b/app/components/alert_message_component/alert_message_component.html.haml
index 19c0e89f0..107ab14ac 100644
--- a/app/components/alert_message_component/alert_message_component.html.haml
+++ b/app/components/alert_message_component/alert_message_component.html.haml
@@ -1,4 +1,8 @@
-.alert.alert-dismissible.fade.show{:role => "alert", class: "#{@type}"}
- = content
- %button.close{"aria-label": "Close", "data-dismiss": "alert", type: "button", style: "background: transparent"}
- %span{"aria-hidden" => "true"} ×
\ No newline at end of file
+.alert.alert-dismissible.fade.show{:role => "alert", class: "#{@type}", style: "text-align: left"}
+ = @message
+
+ - if @closeable
+ %button.close{"aria-label": "Close", "data-dismiss": "alert", type: "button", style: "background: transparent"}
+ %span{"aria-hidden" => "true"} ×
+
+
\ No newline at end of file
diff --git a/app/components/concept_details_component.rb b/app/components/concept_details_component.rb
index 380427a3c..5ce58f703 100644
--- a/app/components/concept_details_component.rb
+++ b/app/components/concept_details_component.rb
@@ -2,6 +2,7 @@
class ConceptDetailsComponent < ViewComponent::Base
include ApplicationHelper
+ include MultiLanguagesHelper
renders_one :header
renders_many :sections
@@ -31,7 +32,11 @@ def render_properties(properties_set, ontology_acronym, &block)
if block_given?
block.call(v)
else
- get_link_for_cls_ajax(v, ontology_acronym, '_blank')
+ if v.is_a?(String)
+ get_link_for_cls_ajax(v, ontology_acronym, '_blank')
+ else
+ display_in_multiple_languages([v].to_h)
+ end
end
end
@@ -40,7 +45,7 @@ def render_properties(properties_set, ontology_acronym, &block)
#{remove_owl_notation(key)}
|
- #{" #{ajax_links.join(' ')} ".html_safe} |
+ #{" #{ajax_links.join(' ')}".html_safe} |
EOS
out += line
@@ -112,7 +117,11 @@ def concept_properties2hash(properties)
end
begin
# Try to simplify the property values, when they are a struct.
- values = properties[key].map { |v| v.string }
+ if properties[key].is_a?(OpenStruct)
+ values = language_hash(properties[key])
+ else
+ values = properties[key].map { |v| v.string }
+ end
rescue
# Each value is probably a simple datatype already.
values = properties[key]
diff --git a/app/components/concept_details_component/concept_details_component.html.haml b/app/components/concept_details_component/concept_details_component.html.haml
index e60407b13..f2741dc8a 100644
--- a/app/components/concept_details_component/concept_details_component.html.haml
+++ b/app/components/concept_details_component/concept_details_component.html.haml
@@ -1,23 +1,20 @@
- require 'cgi'
-%div.py-3.pl-3.hide-if-loading
+%div.hide-if-loading
%div.card
- %table.minimal.concept_details{cellpadding: "0", cellspacing: "0", width: "100%"}
- %tr{style:"visibility:hidden"}
- %td{style:"width:30%"}
- %td
+ %table.concepts-content
= header
%div.my-3
- .accordion.card{id: "accordion-#{@id}"}
- .card
- %div{id: "heading-#{@id}"}
- %h2.mb-0.text-right
- %button.btn.btn-link{"data-target" => "#collapse-#{@id}", "data-toggle" => "collapse"}
- %i.fas.fa-sort
- .collapse.show{id: "collapse-#{@id}", "data-parent" => "#accordion-#{@id}"}
- %table.minimal.concept_details{cellpadding: "0", cellspacing: "0", width: "100%"}
- - top_set, leftover_set, bottom_set = filter_properties(@top_keys, @bottom_keys, @exclude_keys, @concept_properties)
- = render_properties(top_set, @acronym)
- = render_properties(leftover_set, @acronym)
- - sections&.each do |section|
- = section
- = render_properties(bottom_set, @acronym)
\ No newline at end of file
+ .accordion.concepts-raw-data{id: "accordion-#{@id}"}
+ %div{id: "heading-#{@id}"}
+ %h2.mb-0.text-right
+ .concepts-raw-title{"data-target" => "#collapse-#{@id}", "data-toggle" => "collapse"}
+ %div Raw data
+ %img{src: asset_path("arrow-down.svg")}
+ .collapse{id: "collapse-#{@id}", "data-parent" => "#accordion-#{@id}"}
+ %table#concepts-content.concepts-content
+ - top_set, leftover_set, bottom_set = filter_properties(@top_keys, @bottom_keys, @exclude_keys, @concept_properties)
+ = render_properties(top_set, @acronym)
+ = render_properties(leftover_set, @acronym)
+ - sections&.each do |section|
+ = section
+ = render_properties(bottom_set, @acronym)
diff --git a/app/components/edit_submission_attribute_button_component.rb b/app/components/edit_submission_attribute_button_component.rb
new file mode 100644
index 000000000..a4ef5bbc7
--- /dev/null
+++ b/app/components/edit_submission_attribute_button_component.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class EditSubmissionAttributeButtonComponent < ViewComponent::Base
+ include ActionView::Helpers::TagHelper
+
+ def initialize(acronym: , submission_id:, attribute:, inline: false)
+ @acronym = acronym
+ @submission_id = submission_id
+ @attribute = attribute
+
+ if inline
+ @link = "ontologies_metadata_curator/#{@acronym}/submissions/#{@submission_id}?properties=#{@attribute}&inline_save=true"
+ else
+ @link = "/ontologies/#{@acronym}/submissions/#{@submission_id}/edit?properties=#{@attribute}"
+ end
+ end
+
+ def call
+ link_to @link, data: {turbo: true}, class: "btn btn-sm btn-light" do
+ content
+ end
+ end
+
+end
diff --git a/app/components/infinite_scroll_component/infinite_scroll_component.html.haml b/app/components/infinite_scroll_component/infinite_scroll_component.html.haml
index 661fe92d9..c0fd9abac 100644
--- a/app/components/infinite_scroll_component/infinite_scroll_component.html.haml
+++ b/app/components/infinite_scroll_component/infinite_scroll_component.html.haml
@@ -2,7 +2,7 @@
- if @collection && !@collection.empty?
.hide-if-loading
%div
- %ul.simpleTree{data:{controller: 'simple-tree history','simple-tree': { 'auto-click-value': auto_click? }, action: 'clicked->history#updateURL'}}
+ %ul.simpleTree{data:{controller: 'simple-tree','simple-tree': { 'auto-click-value': auto_click? }, action: 'clicked->history#updateURL'}}
%li.root
%ul
= content
diff --git a/app/components/input/language_selector_component.rb b/app/components/input/language_selector_component.rb
new file mode 100644
index 000000000..3a7ec435c
--- /dev/null
+++ b/app/components/input/language_selector_component.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class Input::LanguageSelectorComponent < ViewComponent::Base
+
+ def initialize(languages:, selected: nil, id: '', name: '' )
+ super
+ @languages = languages
+ @id = id
+ @name = languages
+ @selected = selected
+ end
+
+ def languages_options
+ values = [['All languages', 'all']]
+
+ @languages.each do |key, label|
+ option = "#{render(LanguageFieldComponent.new(value: key.to_s.downcase, label: label))}
"
+ values += [[option, key.to_s.downcase]]
+ end
+ values
+ end
+
+ def call
+ render SelectInputComponent.new(id: @id, name: @name, values: languages_options, selected: @selected, placeholder: 'Select a language')
+ end
+end
diff --git a/app/components/language_field_component.rb b/app/components/language_field_component.rb
new file mode 100644
index 000000000..2bd646a78
--- /dev/null
+++ b/app/components/language_field_component.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+require 'iso-639'
+
+class LanguageFieldComponent < ViewComponent::Base
+
+ include FlagIconsRails::Rails::ViewHelpers
+
+ def initialize(value:, label: nil)
+ super
+ @value = value
+ @lang_code = ISO_639.find(value.split('/').last)&.alpha2 || nil
+ @label = label
+ end
+
+ def lang_code
+ if @lang_code
+ @lang_code = 'gb' if @lang_code.eql?('en')
+ @lang_code
+ else
+ @value
+ end
+ end
+end
diff --git a/app/components/language_field_component/language_field_component.html.haml b/app/components/language_field_component/language_field_component.html.haml
new file mode 100644
index 000000000..3122fe9d8
--- /dev/null
+++ b/app/components/language_field_component/language_field_component.html.haml
@@ -0,0 +1,8 @@
+- if @lang_code
+ .d-flex.align-items-center
+ = flag_icon(lang_code)
+ - if @label
+ %div.ml-1
+ = @label
+- else
+ = render ChipButtonComponent.new(text: @value)
\ No newline at end of file
diff --git a/app/components/loader_component.rb b/app/components/loader_component.rb
index 493b76dbd..2f3709152 100644
--- a/app/components/loader_component.rb
+++ b/app/components/loader_component.rb
@@ -15,5 +15,4 @@ def call
end
end
end
-
end
diff --git a/app/components/select_input_component.rb b/app/components/select_input_component.rb
index 872f7f41e..c006ec266 100644
--- a/app/components/select_input_component.rb
+++ b/app/components/select_input_component.rb
@@ -2,20 +2,41 @@
class SelectInputComponent < ViewComponent::Base
- def initialize(id:, name:, values:, selected:, multiple: false)
+ def initialize(id:, name:, values:, selected: nil, multiple: false, open_to_add_values: false, data: {}, placeholder: '')
super
- @id = id
+ @id = id || ''
@name = name
@values = values
@selected = selected
@multiple = multiple
+ @open_to_add_values = open_to_add_values
+ @placeholder = placeholder
+ @data = data
end
- def options_values
- if @selected.nil? || @selected.empty?
- @selected = 0
- @values.unshift('')
- end
- options_for_select(@values, @selected)
+ def call
+ select_input_tag(@id, @values, @selected, multiple: @multiple, open_to_add_values: @open_to_add_values, placeholder: @placeholder)
+ end
+
+ private
+
+ def select_input_tag(id, values, selected, options = {})
+ multiple = options[:multiple] || false
+ open_to_add_values = options[:open_to_add_values] || false
+ placeholder = options[:placeholder] || ''
+ data = @data.merge({
+ 'select-input-multiple-value': multiple,
+ 'select-input-open-add-value': open_to_add_values
+ })
+ data[:controller] = "#{data[:controller]} select-input"
+
+ select_html_options = {
+ id: "select_#{id}",
+ placeholder: placeholder,
+ autocomplete: 'off',
+ multiple: multiple,
+ data: data
+ }
+ select_tag(id, options_for_select(values, selected), select_html_options)
end
end
diff --git a/app/components/select_input_component/select_input_component_controller.js b/app/components/select_input_component/select_input_component_controller.js
index 7fb94e380..0c6c48da3 100644
--- a/app/components/select_input_component/select_input_component_controller.js
+++ b/app/components/select_input_component/select_input_component_controller.js
@@ -1,87 +1,29 @@
import {Controller} from "@hotwired/stimulus"
-import {useChosen} from "../../javascript/mixins/useChosen";
+import {useTomSelect} from "../../javascript/mixins/useTomSelect"
export default class extends Controller {
static values = {
- other: {type: Boolean, default: true},
- multiple: {type: Boolean, default: false}
- }
+ multiple: {type: Boolean, default: false},
+ openAdd: {type: Boolean, default: false}
+ };
- static targets = ["btnValueField", "inputValueField", "selectedValues"]
connect() {
- this.initMultipleSelect()
- this.#displayOtherValueField()
- }
-
- toggleOtherValue() {
- if (this.otherValue && !this.multipleValue) {
- this.#toggle()
- }
- }
-
- addValue(event) {
- event.preventDefault()
-
- if (this.inputValueFieldTarget.value) {
- let newOption = this.inputValueFieldTarget.value;
- this.#addNewOption(newOption)
- this.#selectNewOption(newOption)
- if (!this.multipleValue) {
- this.#hideOtherValueField()
- }
- }
- }
-
-
- initMultipleSelect() {
- this.#addEmptyOption()
- useChosen(this.selectedValuesTarget, {
- width: '100%',
- search_contains: true,
- allow_single_deselect: !this.multipleValue,
- }, (event) => {
- if(this.multipleValue){
- let selected = event.target.selectedOptions
- if (selected.length === 0) {
- this.#selectEmptyOption()
- } else {
- this.#unSelectEmptyOption()
+ let myOptions = {}
+
+ myOptions = {
+ create: true,
+ render: {
+ option: (data) => {
+ return ` ${data.text}
`
+ },
+ item: (data) => {
+ return ` ${data.text}
`
}
}
- })
- }
-
- #selectEmptyOption() {
- this.emptyOption.selected = true
- this.emptyOption.disabled = false
- }
-
- #unSelectEmptyOption() {
- this.emptyOption.selected = false
- this.emptyOption.disabled = true
- }
-
- #addEmptyOption() {
- this.emptyOption = document.createElement("option")
- this.emptyOption.innerHTML = ''
- this.emptyOption.value = ''
- this.selectedValuesTarget.prepend(this.emptyOption)
- }
-
- #selectNewOption(newOption) {
- let selectedOptions = this.#selectedOptions();
-
-
- if (Array.isArray(selectedOptions)) {
- selectedOptions.push(newOption);
- } else {
- selectedOptions = [];
- selectedOptions.push(newOption)
}
- this.selectedValuesTarget.value = selectedOptions
if (this.multipleValue) {
const options = this.selectedValuesTarget.options
for (const element of options) {
@@ -90,26 +32,8 @@ export default class extends Controller {
jQuery(this.selectedValuesTarget).trigger("chosen:updated")
}
- }
-
- #addNewOption(newOption) {
- let option = document.createElement("option");
- option.value = newOption;
- option.text = newOption;
- this.selectedValuesTarget.add(option)
- }
-
- #selectedOptions() {
- if (this.multipleValue) {
- const selectedOptions = [];
- for (let option of this.selectedValuesTarget.options) {
- if (option.selected) {
- selectedOptions.push(option.value);
- }
- }
- return selectedOptions
- } else {
- return this.selectedValuesTarget.value
+ if (this.openAddValue) {
+ myOptions['create'] = true;
}
}
@@ -121,10 +45,8 @@ export default class extends Controller {
}
}
- #displayOtherValueField() {
- this.inputValueFieldTarget.value = ""
- this.btnValueFieldTarget.style.display = 'block'
- this.inputValueFieldTarget.style.display = 'block'
+ #triggerChange() {
+ document.dispatchEvent(new Event('change', {target: this.element}))
}
#hideOtherValueField() {
diff --git a/app/components/turbo_frame_component.rb b/app/components/turbo_frame_component.rb
index d25a16470..f14f587cd 100644
--- a/app/components/turbo_frame_component.rb
+++ b/app/components/turbo_frame_component.rb
@@ -28,6 +28,9 @@ def turbo_frame_html_options
@html_options[:class] += " #{out[:class]}"
end
+ if @src && !@src.empty?
+ @html_options[:src] = @src
+ end
@html_options
end
diff --git a/app/components/turbo_frame_component/turbo_frame_component.html.haml b/app/components/turbo_frame_component/turbo_frame_component.html.haml
index acedbda10..0991eb213 100644
--- a/app/components/turbo_frame_component/turbo_frame_component.html.haml
+++ b/app/components/turbo_frame_component/turbo_frame_component.html.haml
@@ -1,5 +1,5 @@
%div.d-flex.flex-column{data: {controller: 'turbo-frame-error'}}
- = turbo_frame_tag @id, src: @src , **turbo_frame_html_options do
+ = turbo_frame_tag @id, **turbo_frame_html_options do
%div.hide-if-loading
= content
%div.show-if-loading.my-auto.mx-auto
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 9559dc190..c9efe8304 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -13,6 +13,29 @@
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
+
+ before_action :set_locale
+
+ # Sets the locale based on the locale cookie or the value returned by detect_locale.
+ def set_locale
+ I18n.locale = cookies[:locale] || detect_locale
+ cookies.permanent[:locale] = I18n.locale if cookies[:locale].nil?
+ end
+
+ # Returns detedted locale based on the Accept-Language header of the request or the default locale if none is found.
+ def detect_locale
+ languages = request.headers['Accept-Language']&.split(',')
+ supported_languages = I18n.available_locales
+
+ languages.each do |language|
+ language_code = language.split(/[-;]/).first.downcase.to_sym
+ return language_code if supported_languages.include?(language_code)
+ end
+
+ return I18n.default_locale
+ end
+
+
helper :all # include all helpers, all the time
helper_method :bp_config_json, :current_license, :using_captcha?
rescue_from ActiveRecord::RecordNotFound, with: :not_found_record
@@ -421,6 +444,8 @@ def using_captcha?
def get_class(params)
+ lang = request_lang
+
if @ontology.flat?
ignore_concept_param = params[:conceptid].nil? ||
@@ -437,7 +462,7 @@ def get_class(params)
@concept.children = []
else
# Display only the requested class in the tree
- @concept = @ontology.explore.single_class({full: true}, params[:conceptid])
+ @concept = @ontology.explore.single_class({full: true, lang: lang }, params[:conceptid])
@concept.children = []
end
@root = LinkedData::Client::Models::Class.new
@@ -446,13 +471,14 @@ def get_class(params)
else
# not ignoring 'bp_fake_root' here
+ include = 'prefLabel,hasChildren,obsolete'
ignore_concept_param = params[:conceptid].nil? ||
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], lang: lang, include: include)
if @roots.nil? || @roots.empty?
LOG.add :debug, "Missing @roots for #{@ontology.acronym}"
@concept = @ontology.explore.classes.collection.first.explore.self(full: true)
@@ -465,7 +491,7 @@ def get_class(params)
# get the initial concept to display
root_child = @root.children.first
- @concept = root_child.explore.self(full: true)
+ @concept = root_child.explore.self(full: true, lang: lang)
# Some ontologies have "too many children" at their root. These will not process and are handled here.
if @concept.nil?
LOG.add :debug, "Missing class #{root_child.links.self}"
@@ -473,16 +499,16 @@ def get_class(params)
end
else
# if the id is coming from a param, use that to get concept
- @concept = @ontology.explore.single_class({full: true}, params[:conceptid])
+ @concept = @ontology.explore.single_class({full: true, lang: lang}, params[:conceptid])
if @concept.nil? || @concept.errors
LOG.add :debug, "Missing class #{@ontology.acronym} / #{params[:conceptid]}"
not_found("Missing class #{@ontology.acronym} / #{params[:conceptid]}")
end
# Create the tree
- rootNode = @concept.explore.tree(include: "prefLabel,hasChildren,obsolete", concept_schemes: params[:concept_schemes])
+ rootNode = @concept.explore.tree(include: include, concept_schemes: params[:concept_schemes], lang: lang)
if rootNode.nil? || rootNode.empty?
- @roots = @ontology.explore.roots(concept_schemes: params[:concept_schemes])
+ roots = @ontology.explore.roots(concept_schemes: params[:concept_schemes], lang: lang, include: include)
if @roots.nil? || @roots.empty?
LOG.add :debug, "Missing @roots for #{@ontology.acronym}"
@concept = @ontology.explore.classes.collection.first.explore.self(full: true)
@@ -759,6 +785,10 @@ def submission_metadata
end
helper_method :submission_metadata
+
+ def request_lang
+ helpers.request_lang
+ end
private
def not_found_record(exception)
@error_message = exception.message
diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb
index 773b7361f..ad125dd17 100644
--- a/app/controllers/collections_controller.rb
+++ b/app/controllers/collections_controller.rb
@@ -10,7 +10,7 @@ def show_label
collection_label = collection['prefLabel'] if collection
collection_label = params[:id] if collection_label.nil? || collection_label.empty?
- render LabelLinkComponent.inline(params[:id], collection_label)
+ render LabelLinkComponent.inline(params[:id], helpers.main_language_label(collection_label))
end
def show_members
@@ -18,7 +18,7 @@ def show_members
@collection = get_request_collection
page = params[:page] || '1'
@auto_click = page.to_s.eql?('1')
- @page = @collection.explore.members({page: page})
+ @page = @collection.explore.members({page: page, language: request_lang})
@concepts = @page.collection
if @ontology.nil?
ontology_not_found params[:ontology]
diff --git a/app/controllers/concepts_controller.rb b/app/controllers/concepts_controller.rb
index 2a6fcda63..20daec15c 100644
--- a/app/controllers/concepts_controller.rb
+++ b/app/controllers/concepts_controller.rb
@@ -19,7 +19,7 @@ def show_concept
@submission = get_ontology_submission_ready(@ontology)
@ob_instructions = helpers.ontolobridge_instructions_template(@ontology)
- @concept = @ontology.explore.single_class({full: true}, params[:id])
+ @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?
@@ -53,9 +53,8 @@ def show
@concept = @ontology.explore.single_class({full: true}, params[:id])
concept_not_found(params[:id]) if @concept.nil?
-
- show_uri_request # process a full call
- render :file => '/ontologies/visualize', :use_full_path => true, :layout => 'ontology'
+ @schemes = params[:concept_schemes].split(',')
+ show_ajax_request # process a full call
end
end
@@ -70,7 +69,7 @@ def show_label
return
end
- render LabelLinkComponent.inline(cls_id, concept_label(ont_id, cls_id))
+ render LabelLinkComponent.inline(cls_id, helpers.main_language_label(concept_label(ont_id, cls_id)))
end
def show_definition
@@ -113,7 +112,8 @@ def show_date_sorted_list
page: page,
sortby:'modified,created',
order:'desc,desc',
- display: 'prefLabel,modified,created'
+ display: 'prefLabel,modified,created',
+ language: request_lang
}
if @last_date
params.merge!(last_date: @last_date)
@@ -189,7 +189,7 @@ def show_ajax_request
gather_details
render :partial => 'load'
when 'children' # Children is called only for drawing the tree
- @children = @concept.explore.children(pagesize: 750, concept_schemes: @schemes.join(',')).collection || []
+ @children = @concept.explore.children(pagesize: 750, concept_schemes: @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
diff --git a/app/controllers/label_xl_controller.rb b/app/controllers/label_xl_controller.rb
index e5543aa6d..d38fd870c 100644
--- a/app/controllers/label_xl_controller.rb
+++ b/app/controllers/label_xl_controller.rb
@@ -10,7 +10,7 @@ def show_label
label_xl_label = label_xl ? label_xl['literalForm'] : nil
label_xl_label = params[:id] if label_xl_label.nil? || label_xl_label.empty?
- render LabelLinkComponent.inline(params[:id], label_xl_label)
+ render LabelLinkComponent.inline(params[:id], helpers.main_language_label(label_xl_label))
end
private
diff --git a/app/controllers/language_controller.rb b/app/controllers/language_controller.rb
new file mode 100644
index 000000000..ed1ec7c79
--- /dev/null
+++ b/app/controllers/language_controller.rb
@@ -0,0 +1,21 @@
+class LanguageController < ApplicationController
+
+ # set locale to the language selected by the user
+ def set_locale_language
+ language = params[:language].strip.downcase.to_sym
+ supported_languages = I18n.available_locales
+
+ if language
+ if supported_languages.include?(language)
+ cookies.permanent[:locale] = language
+ else
+ # in case we want to show a message if the language is not available
+ flash.now[:notice] = "#{language} translation not available"
+ logger.error flash.now[:notice]
+ end
+ end
+
+ redirect_to request.referer || root_path
+ end
+
+end
diff --git a/app/controllers/mappings_controller.rb b/app/controllers/mappings_controller.rb
index e35ef3a15..b8baeda3a 100644
--- a/app/controllers/mappings_controller.rb
+++ b/app/controllers/mappings_controller.rb
@@ -279,8 +279,8 @@ def mapping_form(mapping: nil)
end
else
mapping = LinkedData::Client::Models::Mapping.new
- @ontology_from = LinkedData::Client::Models::Ontology.find(params[:ontology_from])
- @ontology_to = LinkedData::Client::Models::Ontology.find(params[:ontology_to])
+ @ontology_from = LinkedData::Client::Models::Ontology.find_by_acronym(params[:ontology_from].split('/').last).first
+ @ontology_to = LinkedData::Client::Models::Ontology.find_by_acronym(params[:ontology_to]&.split('/')&.last).first
@concept_from = @ontology_from.explore.single_class({ full: true }, params[:conceptid_from]) if @ontology_from
if @ontology_to
@concept_to = @ontology_to.explore.single_class({ full: true }, params[:conceptid_to])
diff --git a/app/controllers/ontologies_controller.rb b/app/controllers/ontologies_controller.rb
index 07fdfe451..f4f06e92e 100644
--- a/app/controllers/ontologies_controller.rb
+++ b/app/controllers/ontologies_controller.rb
@@ -28,8 +28,7 @@ def index
@app_name = 'FacetedBrowsing'
@app_dir = '/browse'
@base_path = @app_dir
- ontologies = LinkedData::Client::Models::Ontology.all(
-include: LinkedData::Client::Models::Ontology.include_params + ',viewOf', include_views: true, display_context: false)
+ ontologies = LinkedData::Client::Models::Ontology.all(include: LinkedData::Client::Models::Ontology.include_params + ',viewOf', include_views: true, display_context: false)
ontologies_hash = Hash[ontologies.map {|o| [o.id, o] }]
@admin = session[:user] ? session[:user].admin? : false
@development = Rails.env.development?
@@ -39,8 +38,7 @@ def index
# The attributes used when retrieving the submission. We are not retrieving all attributes to be faster
browse_attributes = 'ontology,acronym,submissionStatus,description,pullLocation,creationDate,released,name,naturalLanguage,hasOntologyLanguage,hasFormalityLevel,isOfType,contact'
- submissions = LinkedData::Client::Models::OntologySubmission.all(include_views: true, display_links: false,
-display_context: false, include: browse_attributes)
+ submissions = LinkedData::Client::Models::OntologySubmission.all(include_views: true, display_links: false,display_context: false, include: browse_attributes)
submissions_map = Hash[submissions.map {|sub| [sub.ontology.acronym, sub] }]
@categories = LinkedData::Client::Models::Category.all(display_links: false, display_context: false)
@@ -234,8 +232,7 @@ def mappings
def new
@ontology = LinkedData::Client::Models::Ontology.new
- @ontologies = LinkedData::Client::Models::Ontology.all(include: 'acronym', include_views: true,
-display_links: false, display_context: false)
+ @ontologies = LinkedData::Client::Models::Ontology.all(include: 'acronym', include_views: true,display_links: false, display_context: false)
@categories = LinkedData::Client::Models::Category.all
@groups = LinkedData::Client::Models::Group.all
@user_select_list = LinkedData::Client::Models::User.all.map {|u| [u.username, u.id]}
@@ -338,7 +335,6 @@ def show
# Get the latest submission (not necessarily the latest 'ready' submission)
@submission_latest = @ontology.explore.latest_submission rescue @ontology.explore.latest_submission(include: '')
-
# Is the ontology downloadable?
@ont_restricted = ontology_restricted?(@ontology.acronym)
@@ -457,6 +453,10 @@ def widgets
private
+
+
+
+
def ontology_params
p = params.require(:ontology).permit(:name, :acronym, { administeredBy:[] }, :viewingRestriction, { acl:[] },
{ hasDomain:[] }, :isView, :viewOf, :subscribe_notifications, {group:[]})
diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb
index 661bda5ab..34956040e 100644
--- a/app/controllers/schemes_controller.rb
+++ b/app/controllers/schemes_controller.rb
@@ -10,7 +10,7 @@ def show_label
scheme_label = scheme ? scheme['prefLabel'] : params[:id]
scheme_label = scheme_label.nil? || scheme_label.empty? ? params[:id] : scheme_label
- render LabelLinkComponent.inline(params[:id], scheme_label)
+ render LabelLinkComponent.inline(params[:id], helpers.main_language_label(scheme_label))
end
private
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 98bc05f94..d4ae29d96 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -7,6 +7,21 @@
module ApplicationHelper
+ include ModalHelper, MultiLanguagesHelper
+
+ RESOLVE_NAMESPACE = {:omv => "http://omv.ontoware.org/2005/05/ontology#", :skos => "http://www.w3.org/2004/02/skos/core#", :owl => "http://www.w3.org/2002/07/owl#",
+ :rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", :rdfs => "http://www.w3.org/2000/01/rdf-schema#", :metadata => "http://data.bioontology.org/metadata/",
+ :metadata_def => "http://data.bioontology.org/metadata/def/", :dc => "http://purl.org/dc/elements/1.1/", :xsd => "http://www.w3.org/2001/XMLSchema#",
+ :oboinowl_gen => "http://www.geneontology.org/formats/oboInOwl#", :obo_purl => "http://purl.obolibrary.org/obo/",
+ :umls => "http://bioportal.bioontology.org/ontologies/umls/", :door => "http://kannel.open.ac.uk/ontology#", :dct => "http://purl.org/dc/terms/",
+ :void => "http://rdfs.org/ns/void#", :foaf => "http://xmlns.com/foaf/0.1/", :vann => "http://purl.org/vocab/vann/", :adms => "http://www.w3.org/ns/adms#",
+ :voaf => "http://purl.org/vocommons/voaf#", :dcat => "http://www.w3.org/ns/dcat#", :mod => "http://www.isibang.ac.in/ns/mod#", :prov => "http://www.w3.org/ns/prov#",
+ :cc => "http://creativecommons.org/ns#", :schema => "http://schema.org/", :doap => "http://usefulinc.com/ns/doap#", :bibo => "http://purl.org/ontology/bibo/",
+ :wdrs => "http://www.w3.org/2007/05/powder-s#", :cito => "http://purl.org/spar/cito/", :pav => "http://purl.org/pav/", :nkos => "http://w3id.org/nkos/nkostype#",
+ :oboInOwl => "http://www.geneontology.org/formats/oboInOwl#", :idot => "http://identifiers.org/idot/", :sd => "http://www.w3.org/ns/sparql-service-description#",
+ :cclicense => "http://creativecommons.org/licenses/"}
+
+
def get_apikey
unless session[:user].nil?
return session[:user].apikey
@@ -153,8 +168,8 @@ def draw_tree(root, id = nil, concept_schemes = [])
def build_tree(node, string, id, concept_schemes: [])
return string if node.children.nil? || node.children.empty?
-
- node.children.sort! { |a, b| (a.prefLabel || a.id).downcase <=> (b.prefLabel || b.id).downcase }
+
+ 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" : ''
@@ -180,19 +195,33 @@ def build_tree(node, string, id, concept_schemes: [])
end
def tree_link_to_concept(child:, ontology_acronym:, active_style:, node: nil)
+ 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)
muted_style = child.isInActiveScheme&.empty? ? 'text-muted' : ''
- href = ontology_acronym.blank? ? '#' : "/ontologies/#{child.explore.ontology.acronym}/concepts/?id=#{CGI.escape(child.id)}"
+ href = ontology_acronym.blank? ? '#' : "/ontologies/#{child.explore.ontology.acronym}/concepts/?id=#{CGI.escape(child.id)}&language=#{language}"
+
+ if child.prefLabel.nil?
+ prefLabelHTML = child.id.split('/').last
+ else
+ prefLabelLang, prefLabelHTML = select_language_label(child.prefLabel)
+ prefLabelLang = prefLabelLang.to_s.upcase
+ tooltip = prefLabelLang.eql?("@NONE") ? "" : "data-controller='tooltip' data-tooltip-position-value='right' title='#{prefLabelLang}'";
+ end
+
link = <<-EOS
-
- #{child.prefLabel ? child.prefLabel({ use_html: true }) : child.id}
+
+ #{ prefLabelHTML }
+
EOS
@@ -200,9 +229,10 @@ def tree_link_to_concept(child:, ontology_acronym:, active_style:, node: nil)
end
def tree_link_to_children(child:, concept_schemes: [])
+ language = request_lang
li_id = child.id.eql?('bp_fake_root') ? 'bp_fake_root' : short_uuid
concept_schemes = concept_schemes.map{|x| CGI.escape(x)}.join(',')
- link = "ajax_class"
+ link = "ajax_class"
""
end
@@ -464,7 +494,7 @@ def bp_ont_link(ont_acronym)
end
def bp_class_link(cls_id, ont_acronym)
- return "#{bp_ont_link(ont_acronym)}?p=classes&conceptid=#{escape(cls_id)}"
+ return "#{bp_ont_link(ont_acronym)}?p=classes&conceptid=#{escape(cls_id)}&language=#{request_lang}"
end
def bp_scheme_link(scheme_id, ont_acronym)
@@ -506,8 +536,8 @@ def get_link_for_cls_ajax(cls_id, ont_acronym, target = nil)
if cls_id.start_with?('http://') || cls_id.start_with?('https://')
link = bp_class_link(cls_id, ont_acronym)
- ajax_url = '/ajax/classes/label'
- cls_url = "/ontologies/#{ont_acronym}?p=classes&conceptid=#{CGI.escape(cls_id)}"
+ ajax_url = "/ajax/classes/label?language=#{request_lang}"
+ cls_url = "/ontologies/#{ont_acronym}?p=classes&conceptid=#{CGI.escape(cls_id)}&language=#{request_lang}"
label_ajax_link(link, cls_id, ont_acronym, ajax_url , cls_url ,target)
else
auto_link(cls_id, :all, target: '_blank')
@@ -523,14 +553,14 @@ def get_link_for_ont_ajax(ont_acronym)
def get_link_for_scheme_ajax(scheme, ont_acronym, target = '_blank')
link = bp_scheme_link(scheme, ont_acronym)
- ajax_url = '/ajax/schemes/label'
+ ajax_url = "/ajax/schemes/label?language=#{request_lang}"
scheme_url = "?p=schemes&schemeid=#{CGI.escape(scheme)}"
label_ajax_link(link, scheme, ont_acronym, ajax_url, scheme_url, target)
end
def get_link_for_collection_ajax(collection, ont_acronym, target = '_blank')
link = bp_collection_link(collection, ont_acronym)
- ajax_url = '/ajax/collections/label'
+ ajax_url = "/ajax/collections/label?language=#{request_lang}"
collection_url = "?p=collections&collectionid=#{CGI.escape(collection)}"
label_ajax_link(link, collection, ont_acronym, ajax_url, collection_url, target)
end
@@ -552,8 +582,8 @@ def get_link_for_label_xl_ajax(label_xl, ont_acronym, cls_id, modal: true)
end
###END ruby equivalent of JS code in bp_ajax_controller.
- def ontology_viewer_page_name(ontology_name, concept_name_title , page)
- ontology_name + " | " +concept_name_title + " - #{page.capitalize}"
+ def ontology_viewer_page_name(ontology_name, concept_label, page)
+ ontology_name + " | " + main_language_label(concept_label) + " - #{page.capitalize}"
end
def link_to_modal(name, options = nil, html_options = nil, &block)
@@ -607,4 +637,10 @@ def skos?
submission = @submission || @submission_latest
submission&.hasOntologyLanguage === 'SKOS'
end
+
+ def request_lang
+ lang = params[:language] || params[:lang]
+ lang = 'EN' unless lang
+ lang.upcase
+ end
end
diff --git a/app/helpers/collections_helper.rb b/app/helpers/collections_helper.rb
index b2c20a2ba..ec32c3fca 100644
--- a/app/helpers/collections_helper.rb
+++ b/app/helpers/collections_helper.rb
@@ -2,13 +2,13 @@ module CollectionsHelper
def get_collections(ontology, add_colors: false)
- collections = ontology.explore.collections
+ collections = ontology.explore.collections(language: request_lang)
generate_collections_colors(collections) if add_colors
collections
end
def get_collection(ontology, collection_uri)
- ontology.explore.collections({ include: 'all' },collection_uri)
+ ontology.explore.collections({ include: 'all', language: request_lang},collection_uri)
end
def get_collection_label(collection)
@@ -25,14 +25,15 @@ def get_collections_labels(collections, main_uri = '')
collections_labels = []
collections.each do |x|
id = x['@id']
- label = get_collection_label(x)
+ label = select_language_label(get_collection_label(x))
if id.eql? main_uri
selected_label = { 'prefLabel' => label, '@id' => id }
else
collections_labels.append( { 'prefLabel' => label, '@id' => id , 'color' => x['color'] })
end
end
- collections_labels.sort_by! { |s| s['prefLabel']}
+
+ collections_labels = sorted_labels(collections_labels)
collections_labels.unshift selected_label if selected_label
[collections_labels, selected_label]
end
@@ -47,14 +48,31 @@ def no_collections_alert
end
end
- def collection_path(collection_id = '')
- "/ontologies/#{@ontology.acronym}/collections/show?id=#{escape(collection_id)}"
+ def collection_path(collection_id = '', language = '')
+ "/ontologies/#{@ontology.acronym}/collections/show?id=#{escape(collection_id)}&language=#{language}"
end
def request_collection_id
params[:id] || params[:collection_id] || params[:concept_collection]
end
+ def sort_collections_label(collections_labels)
+ sorted_labels(collections_labels)
+ end
+
+ def link_to_collection(collection, selected_collection_id)
+ pref_label_lang, pref_label_html = get_collection_label(collection)
+ 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
+ end
+
private
def generate_collections_colors(collections)
diff --git a/app/helpers/concepts_helper.rb b/app/helpers/concepts_helper.rb
index 9d438348c..252db950d 100644
--- a/app/helpers/concepts_helper.rb
+++ b/app/helpers/concepts_helper.rb
@@ -32,7 +32,7 @@ def concept_label(ont_id, cls_id)
ontology_not_found(ont_id) unless @ontology
# Retrieve a class prefLabel or return the class ID (URI)
# - mappings may contain class URIs that are not in bioportal (e.g. obo-xrefs)
- cls = @ontology.explore.single_class(cls_id)
+ cls = @ontology.explore.single_class({language: request_lang, include: 'prefLabel'}, cls_id)
# TODO: log any cls.errors
# TODO: NCBO-402 might be implemented here, but it throws off a lot of ajax result rendering.
#cls_label = cls.prefLabel({:use_html => true}) || cls_id
@@ -50,7 +50,7 @@ def concept_date(concept)
end
def sorted_by_date_url(page = 1, last_concept = nil)
- out = "/ajax/classes/date_sorted_list?ontology=#{@ontology.acronym}&page=#{page}"
+ out = "/ajax/classes/date_sorted_list?ontology=#{@ontology.acronym}&page=#{page}&language=#{request_lang}"
out += "&last_date=#{concept_date(last_concept)}" if last_concept
out
end
diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb
index a2a34a755..7b14c5ba4 100644
--- a/app/helpers/home_helper.rb
+++ b/app/helpers/home_helper.rb
@@ -5,14 +5,11 @@
module HomeHelper
def render_footer_link(options = {})
-
- link_content = options[:text].presence
- link_content ||= image_tag(options[:img_src]) if options[:img_src].present?
- link_content ||= content_tag(:i, '', class: options[:icon]) if options[:icon].present?
-
- unless link_content.blank?
- link_to(link_content, options[:url], target: options[:target], class: options[:css_class].to_s, style: options[:text].blank? ? 'text-decoration: none' : '')
- end.to_s.html_safe
-
+ link_content = options[:text][I18n.locale] || options[:text][:en] if options[:text]
+ link_content ||= image_tag(options[:img_src]) if options[:img_src]
+ link_content ||= content_tag(:i, '', class: options[:icon]) if options[:icon]
+
+ link_to(link_content, options[:url], target: options[:target], class: options[:css_class].to_s, style: options[:text].blank? ? 'text-decoration: none' : '').html_safe if link_content
end
+
end
\ No newline at end of file
diff --git a/app/helpers/multi_languages_helper.rb b/app/helpers/multi_languages_helper.rb
new file mode 100644
index 000000000..c52f7860d
--- /dev/null
+++ b/app/helpers/multi_languages_helper.rb
@@ -0,0 +1,63 @@
+module MultiLanguagesHelper
+
+ def language_hash(concept_label)
+
+ return concept_label.first if concept_label.is_a?(Array)
+ return concept_label.to_h.reject { |key, _| %i[links context].include?(key) } if concept_label.is_a?(OpenStruct)
+
+ concept_label
+ end
+
+ def sorted_labels(labels)
+ Array(labels).sort_by { |label| label['prefLabel'].is_a?(String) ? label['prefLabel'] : label['prefLabel'].last }
+ end
+
+ def select_language_label(concept_label, platform_languages = %i[en fr])
+ concept_value = nil
+
+ concept = language_hash(concept_label)
+
+ return ['@none', concept] if concept.is_a?(String)
+
+ concept = concept.to_h
+
+ platform_languages.each do |lang|
+ if concept[lang]
+ concept_value = [lang, concept[lang]]
+ break
+ end
+ end
+
+ concept_value || concept.to_a.first
+ end
+
+ def main_language_label(label)
+ select_language_label(label)&.last
+ end
+
+ def display_in_multiple_languages(label)
+ label = language_hash(label)
+
+ if label.nil?
+ return render Display::AlertComponent.new(message: t('ontology_details.concept.no_preferred_name_for_selected_language'),
+ type: "warning",
+ closable: true)
+ end
+
+ return content_tag(:p, label) if label.is_a?(String)
+
+ raw(label.map do |key, value|
+ content_tag(:div, class: 'd-flex align-items-center') do
+ concat content_tag(:p, Array(value).join(', '), class: 'm-0')
+
+ unless key.to_s.upcase.eql?('NONE') || key.to_s.upcase.eql?('@NONE')
+ concat content_tag(:span, key.upcase, class: 'badge badge-secondary ml-1')
+ end
+ end
+ end.join)
+ end
+
+ def selected_language_label(label)
+ language_hash(label).values.first
+ end
+end
diff --git a/app/helpers/ontologies_helper.rb b/app/helpers/ontologies_helper.rb
index 6e43ba819..5a046bc0b 100644
--- a/app/helpers/ontologies_helper.rb
+++ b/app/helpers/ontologies_helper.rb
@@ -2,6 +2,9 @@ module OntologiesHelper
REST_URI = $REST_URL
API_KEY = $API_KEY
+ LANGUAGE_FILTERABLE_SECTIONS = %w[classes schemes collections instances]
+
+
def additional_details
return "" if $ADDITIONAL_ONTOLOGY_DETAILS.nil? || $ADDITIONAL_ONTOLOGY_DETAILS[@ontology.acronym].nil?
@@ -382,15 +385,40 @@ def current_section
(params[:p]) ? params[:p] : 'summary'
end
+ def link_to_section(section_title)
+ link_to(section_name(section_title) , ontology_path(@ontology.acronym, p: section_title),
+ id: "ont-#{section_title}-tab", class: "nav-link #{selected_section?(section_title) ? 'active show' : ''}",
+ data: { action: 'click->ontology-viewer-tabs#selectTab',
+ toggle: "tab", target: "#ont_#{section_title}_content", 'bp-ont-page': section_title ,
+ 'bp-ont-page-name': ontology_viewer_page_name(@ontology.name, @concept&.prefLabel || '', section_title) })
+ end
+
def selected_section?(section_title)
current_section.eql?(section_title)
end
+ def ontology_data_sections
+ LANGUAGE_FILTERABLE_SECTIONS
+ end
+
+ def ontology_data_section?(section_title = current_section)
+ ontology_data_sections.include?(section_title)
+ end
+
+ def section_data(section_title)
+ if ontology_data_section?(section_title)
+ url_value = selected_section?(section_title) ? request.fullpath : "/ontologies/#{@ontology.acronym}?p=#{section_title}"
+ { controller: "history turbo-frame" , 'turbo-frame-url-value': url_value ,action: "lang_changed->history#updateURL lang_changed->turbo-frame#updateFrame" }
+ else
+ {}
+ end
+ end
+
def lazy_load_section(section_title, &block)
if current_section.eql?(section_title)
block.call
else
- render TurboFrameComponent.new(id: section_title, src: "/ontologies/#{@ontology.acronym}?p=#{section_title}", target: '_top')
+ render TurboFrameComponent.new(id: section_title, src: "/ontologies/#{@ontology.acronym}?p=#{section_title}", target: '_top', data: {"turbo-frame-target": "frame"} )
end
end
@@ -416,5 +444,60 @@ def sections_to_show
end
sections
end
+
+
+ def language_selector_tag(name)
+ languages = languages_options
+
+ if languages.empty?
+ content_tag(:div ,data: {'ontology-viewer-tabs-target': 'languageSelector'}, style: "visibility: #{ontology_data_section? ? 'visible' : 'hidden'} ; margin-bottom: -1px;") do
+ render EditSubmissionAttributeButtonComponent.new(acronym: @ontology.acronym, submission_id: @submission_latest.submissionId, attribute: :naturalLanguage) do
+ concat "Enable multilingual display "
+ concat content_tag(:i , "", class: "fas fa-lg fa-question-circle")
+ end
+ end
+ else
+ select_tag name, languages_options, class: 'custom-select', disabled: !ontology_data_section?, style: "visibility: #{ontology_data_section? ? 'visible' : 'hidden'}; margin-bottom: -10px;", data: {'ontology-viewer-tabs-target': 'languageSelector'}
+ end
+ end
+
+ def language_selector_hidden_tag(section)
+ hidden_field_tag "language_selector_hidden_#{section}", '',
+ data: { controller: "language-change", 'language-change-section-value': section, action: "change->language-change#dispatchLangChangeEvent"}
+ end
+
+ def languages_options(submission = @submission || @submission_latest)
+ current_lang = request_lang.downcase
+ submission_lang = submission_languages(submission)
+ # Transform each language into a select option
+ submission_lang = submission_lang.map do |lang|
+ lang = lang.split('/').last.upcase
+ [lang, lang, { selected: lang.eql?(current_lang) }]
+ end
+
+ # Add the option to select all language
+ submission_lang.push(['All', 'all', { selected: current_lang.eql?('all') }])
+
+ options_for_select(submission_lang)
+ end
+
+ def display_complex_text(definitions)
+ html = ""
+ definitions.each do |definition|
+ if definition.is_a?(String)
+ html += '' + definition + '
'
+ elsif definition.respond_to?(:uri) && definition.uri
+ html += render LinkFieldComponent.new(value: definition.uri)
+ else
+ html += display_in_multiple_languages(definition)
+ end
+ end
+ return html.html_safe
+ end
+ private
+
+ def submission_languages(submission = @submission)
+ submission.naturalLanguage.map { |natural_language| natural_language["iso639"] && natural_language.split('/').last }.compact
+ end
end
diff --git a/app/helpers/schemes_helper.rb b/app/helpers/schemes_helper.rb
index 799e52b13..17973c583 100644
--- a/app/helpers/schemes_helper.rb
+++ b/app/helpers/schemes_helper.rb
@@ -1,11 +1,11 @@
module SchemesHelper
def get_schemes(ontology)
- ontology.explore.schemes
+ ontology.explore.schemes(language: request_lang)
end
def get_scheme(ontology, scheme_uri)
- ontology.explore.schemes({ include: 'all' }, scheme_uri)
+ ontology.explore.schemes({ include: 'all', language: request_lang}, scheme_uri)
end
def get_scheme_label(scheme)
@@ -24,36 +24,32 @@ def get_schemes_labels(schemes, main_uri)
schemes_labels = []
schemes.each do |x|
id = x['@id']
- label = get_scheme_label(x)
+ label = select_language_label(get_scheme_label(x))
if id.eql? main_uri
- label = "#{label} (main)" unless label.empty?
+ label[1] = "#{label[1]} (main)" unless label[0].empty?
selected_label = { 'prefLabel' => label, '@id' => id }
else
schemes_labels.append( { 'prefLabel' => label, '@id' => id })
end
end
- schemes_labels.sort_by! { |s| s['prefLabel']}
- if selected_label
- schemes_labels.unshift selected_label
- end
+ schemes_labels = sorted_labels(schemes_labels)
+ schemes_labels.unshift selected_label if selected_label
[schemes_labels, selected_label]
end
def concept_label_to_show(submission: @submission_latest)
- submission&.hasOntologyLanguage == 'SKOS' ? 'Concepts' : 'Classes'
+ submission&.hasOntologyLanguage == 'SKOS' ? 'concepts' : 'classes'
end
def section_name(section)
- if section.eql?('classes')
- concept_label_to_show(submission: @submission_latest || @submission)
- else
- section.capitalize
- end
+ section = concept_label_to_show(submission: @submission_latest || @submission) if section.eql?('classes')
+
+ t("ontology_details.sections.#{section}")
end
- def scheme_path(scheme_id = '')
- "/ontologies/#{@ontology.acronym}/schemes/show_scheme?id=#{escape(scheme_id)}"
+ def scheme_path(scheme_id = '', language = '')
+ "/ontologies/#{@ontology.acronym}/schemes/show_scheme?id=#{escape(scheme_id)}&lang=#{language}"
end
def no_main_scheme?
@@ -84,21 +80,29 @@ def schemes_data
def tree_link_to_schemes(schemes_labels, main_scheme_label, selected_scheme_id)
out = ''
- schemes_labels.sort_by { |s| [s['prefLabel']] }.each do |s|
+
+ sorted_labels(schemes_labels).each do |s|
next unless main_scheme_label.nil? || s['prefLabel'] != main_scheme_label['prefLabel']
- li = <<-EOS
-
-
- #{get_scheme_label(s)}
-
-
+ out << <<-EOS
+
+ #{link_to_scheme(s, selected_scheme_id)}
+
EOS
- out << li
end
out
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
+ end
end
diff --git a/app/javascript/application_esbuild.js b/app/javascript/application_esbuild.js
index a939c36c9..2ded13b5a 100644
--- a/app/javascript/application_esbuild.js
+++ b/app/javascript/application_esbuild.js
@@ -1,12 +1,11 @@
// Entry point for the build script in your package.json
-import { Turbo } from "@hotwired/turbo-rails"
-Turbo.session.drive = false
-import "./controllers"
-import "./component_controllers"
-
+import { Turbo } from "@hotwired/turbo-rails";
+import "./controllers";
+import "./component_controllers";
+Turbo.session.drive = false;
Turbo.setConfirmMethod((message) => {
return new Promise((resolve, reject) => {
alertify.confirm(message, (e) => {
diff --git a/app/javascript/controllers/chosen_controller.js b/app/javascript/controllers/chosen_controller.js
index 38d1a092d..3293c985f 100644
--- a/app/javascript/controllers/chosen_controller.js
+++ b/app/javascript/controllers/chosen_controller.js
@@ -61,9 +61,6 @@ export default class extends Controller {
chosenClose.style.position = "unset"
chosenClose.style.margin = "auto"
-
-
-
}
})
}
diff --git a/app/javascript/controllers/history_controller.js b/app/javascript/controllers/history_controller.js
index d339c32f8..48518c64a 100644
--- a/app/javascript/controllers/history_controller.js
+++ b/app/javascript/controllers/history_controller.js
@@ -1,5 +1,5 @@
-import {Controller} from "@hotwired/stimulus"
-import {HistoryService} from "../mixins/useHistory";
+import { Controller } from "@hotwired/stimulus"
+import { HistoryService } from "../mixins/useHistory";
// Connects to data-controller="history"
export default class extends Controller {
@@ -7,9 +7,9 @@ export default class extends Controller {
this.history = new HistoryService()
}
updateURL(event) {
- const newData = event.detail.data
- if (newData !== undefined) {
- this.history.updateHistory(document.location.pathname + document.location.search, newData)
+ const { data } = event.detail
+ if (data !== undefined && Object.keys(data).length > 0) {
+ this.history.updateHistory(document.location.pathname + document.location.search, data)
}
}
diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js
index 553504b0a..1b3f7532a 100644
--- a/app/javascript/controllers/index.js
+++ b/app/javascript/controllers/index.js
@@ -25,15 +25,24 @@ application.register("label-ajax", LabelAjaxController)
import LabelsAjaxContainerController from "./labels_ajax_container_controller"
application.register("labels-ajax-container", LabelsAjaxContainerController)
+import LanguageChangeController from "./language_change_controller"
+application.register("language-change", LanguageChangeController)
+
import LoadChartController from "./load_chart_controller"
application.register("load-chart", LoadChartController)
import MetadataDownloaderController from "./metadata_downloader_controller"
application.register("metadata-downloader", MetadataDownloaderController)
+import OntologyViewerTabsController from "./ontology_viewer_tabs_controller"
+application.register("ontology-viewer-tabs", OntologyViewerTabsController)
+
import OntoportalAutocompleteController from "./ontoportal_autocomplete_controller"
application.register("ontoportal-autocomplete", OntoportalAutocompleteController)
+import PlatformLanguageController from "./platform_language_controller"
+application.register("platform-language", PlatformLanguageController)
+
import ShowModalController from "./show_modal_controller"
application.register("show-modal", ShowModalController)
@@ -43,6 +52,12 @@ application.register("simple-tree", SimpleTreeController)
import SkosCollectionColorsController from "./skos_collection_colors_controller"
application.register("skos-collection-colors", SkosCollectionColorsController)
+import Ontology_viewer_tabs_controller from "./ontology_viewer_tabs_controller"
+application.register("ontology-viewer-tabs", Ontology_viewer_tabs_controller)
+
+import TabChangeController from "./tab_change_controller"
+application.register("tab-change", TabChangeController)
+
import TooltipController from "./tooltip_controller"
application.register("tooltip", TooltipController)
diff --git a/app/javascript/controllers/language_change_controller.js b/app/javascript/controllers/language_change_controller.js
new file mode 100644
index 000000000..ed5961b45
--- /dev/null
+++ b/app/javascript/controllers/language_change_controller.js
@@ -0,0 +1,19 @@
+import { Controller } from "@hotwired/stimulus"
+
+// Connects to data-controller="language-change"
+// This controller is used to change the language of the Concepts, Schemes and Collections
+export default class extends Controller {
+
+ dispatchLangChangeEvent() {
+ this.element.dispatchEvent(new CustomEvent('lang_changed', {
+ bubbles: true,
+ cancelable: true,
+ detail: {
+ data: {
+ language: [this.element.value]
+ }
+ }
+ }));
+ }
+
+}
diff --git a/app/javascript/controllers/ontology_viewer_tabs_controller.js b/app/javascript/controllers/ontology_viewer_tabs_controller.js
new file mode 100644
index 000000000..b5c739824
--- /dev/null
+++ b/app/javascript/controllers/ontology_viewer_tabs_controller.js
@@ -0,0 +1,47 @@
+import { Controller } from "@hotwired/stimulus"
+import {HistoryService} from "../mixins/useHistory";
+
+
+export default class extends Controller {
+
+
+ static targets = ["languageSelector"]
+ static values = {
+ languageSections: Array
+ }
+
+ connect() {
+ this.changeEvent = this.languageSelectorTarget.addEventListener("change", (e) => {
+ this.languageSectionsValue.forEach(p => {
+ let elem = document.getElementById("language_selector_hidden_"+p)
+ if(elem){
+ elem.value = e.target.value
+ elem.dispatchEvent(new Event('change'))
+ }
+ })
+ })
+ }
+
+ destroy(){
+ this.changeEvent.removeEventListener()
+ }
+
+ updateLanguageSelector(event) {
+ if(event.target.id === "ontology_viewer"){
+ let page = event.detail.data.selectedTab
+ this.#disableLanguageSelector(page)
+ }
+ }
+
+ #disableLanguageSelector(selectedSection){
+ if (this.languageSectionsValue.includes(selectedSection)){
+ this.languageSelectorTarget.removeAttribute("disabled")
+ this.languageSelectorTarget.style.visibility = 'visible'
+ } else{
+ this.languageSelectorTarget.setAttribute("disabled", true)
+ this.languageSelectorTarget.style.visibility = 'hidden'
+ }
+ }
+
+
+}
diff --git a/app/javascript/controllers/platform_language_controller.js b/app/javascript/controllers/platform_language_controller.js
new file mode 100644
index 000000000..682d8e901
--- /dev/null
+++ b/app/javascript/controllers/platform_language_controller.js
@@ -0,0 +1,21 @@
+import { Controller } from "@hotwired/stimulus"
+import { Turbo } from "@hotwired/turbo-rails";
+import { getCookie } from "../mixins/cookie";
+
+// Connects to data-controller="platform-language"
+// this controller is used to change the language of the whole platform
+export default class extends Controller {
+
+ connect() {
+ const locale = getCookie('locale');
+
+ const option = document.querySelector(`#language-select option[value="${locale}"]`);
+ option && (option.selected = true);
+
+ }
+
+ handleLangChanged(event) {
+ const userPreferedLanguage = event.target.value;
+ Turbo.visit(`/locale/${userPreferedLanguage}`, { action: "replace" });
+ }
+}
diff --git a/app/javascript/controllers/tab_change_controller.js b/app/javascript/controllers/tab_change_controller.js
new file mode 100644
index 000000000..3b0c50b3c
--- /dev/null
+++ b/app/javascript/controllers/tab_change_controller.js
@@ -0,0 +1,35 @@
+import { Controller } from "@hotwired/stimulus"
+import { showLoader } from "../mixins/showLoader";
+
+export default class extends Controller {
+
+
+ static targets = ["sections"]
+
+
+ onClick(event) {
+
+ const anchorElement = event.target.closest('a');
+
+ // add active class to the clicked tab
+
+ if (anchorElement) {
+
+ showLoader(this.sectionsTarget);
+
+ anchorElement.classList.add('active');
+
+ // remove active class from the other tabs
+ const otherTabs = anchorElement.parentElement.parentElement.querySelectorAll('a');
+ otherTabs.forEach(tab => {
+ if (tab !== anchorElement) {
+ tab.classList.remove('active');
+ }
+ });
+
+ const href = anchorElement.getAttribute('href');
+ Turbo.visit(href);
+ }
+
+ }
+}
diff --git a/app/javascript/controllers/tooltip_controller.js b/app/javascript/controllers/tooltip_controller.js
index f9bc3ca02..60fd3d7e9 100644
--- a/app/javascript/controllers/tooltip_controller.js
+++ b/app/javascript/controllers/tooltip_controller.js
@@ -1,9 +1,19 @@
-import { Controller } from "@hotwired/stimulus"
+import {Controller} from "@hotwired/stimulus"
import useTooltip from "../mixins/useTooltip";
// Connects to data-controller="tooltip"
export default class extends Controller {
- connect() {
- useTooltip(this.element)
- }
+
+ static values = {
+ position: {type: String, default: 'top'},
+ interactive: {type: Boolean, default: false}
+ }
+
+ connect() {
+ if (this.element.title && this.element.title !== '') {
+ useTooltip(this.element, {interactive: this.interactiveValue, placement: this.positionValue})
+ }
+
+ }
+
}
diff --git a/app/javascript/controllers/turbo_frame_controller.js b/app/javascript/controllers/turbo_frame_controller.js
index 821bb4fc5..41c67dd5d 100644
--- a/app/javascript/controllers/turbo_frame_controller.js
+++ b/app/javascript/controllers/turbo_frame_controller.js
@@ -1,11 +1,11 @@
-import {Controller} from "@hotwired/stimulus"
-import {HistoryService} from "../mixins/useHistory";
+import { Controller } from "@hotwired/stimulus"
+import { HistoryService } from "../mixins/useHistory";
// Connects to data-controller="turbo-frame"
export default class extends Controller {
static values = {
url: String,
- placeHolder: {type: String, default: 'Nothing loaded'},
+ placeHolder: { type: String, default: 'Nothing loaded' },
}
static targets = ['frame']
@@ -14,13 +14,17 @@ export default class extends Controller {
}
updateFrame(event) {
- const newData = event.detail.data
- const values = Object.entries(newData)[0][1]
- if (values.filter(x => x.length !== 0).length === 0) {
+ const { data } = event.detail
+ const values = Object.values(data)
+
+ // remove null and empty values
+ values.filter((value) => value !== "" || value !== undefined)
+
+ if (values.length === 0) {
this.frame.innerHTML = this.placeHolderValue
} else {
this.frame.innerHTML = ""
- this.urlValue = new HistoryService().getUpdatedURL(this.urlValue, newData);
+ this.urlValue = new HistoryService().getUpdatedURL(this.urlValue, data)
this.frame.src = this.urlValue
}
}
diff --git a/app/javascript/mixins/cookie.js b/app/javascript/mixins/cookie.js
new file mode 100644
index 000000000..5e2b5bf0d
--- /dev/null
+++ b/app/javascript/mixins/cookie.js
@@ -0,0 +1,8 @@
+export const getCookie = (name) => {
+ const cookieValue = document.cookie.match('(^|[^;]+)\\s*' + name + '\\s*=\\s*([^;]+)');
+ return cookieValue ? cookieValue.pop() : '';
+}
+
+export const setCookie = (name, value, days) => {
+ document.cookie = `${name}=${value};max-age=${days * 24 * 60 * 60}`;
+}
\ No newline at end of file
diff --git a/app/javascript/mixins/useHistory.js b/app/javascript/mixins/useHistory.js
index 24a59cbec..f84ff4133 100644
--- a/app/javascript/mixins/useHistory.js
+++ b/app/javascript/mixins/useHistory.js
@@ -1,5 +1,8 @@
export class HistoryService {
+ unWantedData = ['turbo', 'controller', 'target', 'value']
+
+
constructor() {
this.history = History
}
@@ -12,57 +15,52 @@ export class HistoryService {
return this.history.getState()
}
-
updateHistory(currentUrl, newData) {
- const state = this.#initStateFromUrl(currentUrl)
- const newUrl = this.getUpdatedURL(currentUrl, newData, state)
- this.pushState(state, state.title, newUrl)
+ const newUrl = this.getUpdatedURL(currentUrl, newData)
+ const newState = this.#initStateFromUrl(newUrl)
+ this.pushState(newState, newState.title, newUrl)
}
getUpdatedURL(currentUrl, newData) {
- const url = new URL(currentUrl, document.location.origin)
- const urlParams = url.searchParams
- this.#updateURLFromState(urlParams, this.getState())
+ const base = document.location.origin
+ const url = new URL(currentUrl, base)
+ this.#updateURLFromState(url.searchParams, this.getState().data)
+ this.#addNewDataToUrl(url, newData)
+ return url.pathname + url.search
+ }
- this.#filterUnwantedData(newData).forEach(([updatedParam, newValue]) => {
- newValue = Array.isArray(newValue) ? newValue : [newValue]
- if (newValue !== null && Array.from(newValue).length > 0) {
- urlParams.set(updatedParam, newValue.join(','))
- }
- })
+ #addNewDataToUrl(url, newData) {
+ const wantedData = this.#filterUnwantedData(newData, this.unWantedData);
- return url.pathname + url.search
+ wantedData.forEach(([updatedParam, newValue]) => {
+ if (newValue === null) {
+ url.searchParams.delete(updatedParam)
+ } else {
+ newValue = Array.isArray(newValue) ? newValue : [newValue]
+ url.searchParams.set(updatedParam, newValue.join(','))
+ }
+ });
}
- #filterUnwantedData(newData){
- const unWantedData = ['turbo', 'controller', 'target', 'value']
- return Object.entries(newData).filter(([key]) => unWantedData.filter(x => key.toLowerCase().includes(x)).length === 0)
+ #filterUnwantedData(data, unWantedData) {
+ return Object.entries(data).filter(([key]) => !unWantedData.some(uw => key.toLowerCase().includes(uw.toLowerCase())))
}
- #initStateFromUrl(currentUrl) {
+ #initStateFromUrl(currentUrl) {
const url = new URL(currentUrl, document.location.origin)
const urlParams = url.searchParams
- const oldState = this.getState().data
- let newState = oldState
- let oldValue = null
+ let newState = this.getState().data
urlParams.forEach((newVal, key) => {
- oldValue = oldState[key]
- if (oldValue === undefined) {
- newState[key] = newVal
- }
+ newState[key] = newVal
})
return newState
}
#updateURLFromState(urlParams, state) {
- let oldValue = null
- urlParams.forEach((newVal, key) => {
- oldValue = state[key]
- if (oldValue !== undefined && oldValue !== newVal) {
- urlParams.set(key, newVal)
- } else if (oldValue !== undefined) {
- state[key] = newVal
+ Object.entries(state).forEach(([key, val]) => {
+ if (key !== 'p'){
+ urlParams.set(key, val)
}
})
}
diff --git a/app/javascript/mixins/useTooltip.js b/app/javascript/mixins/useTooltip.js
index 46b44dc3e..805978000 100644
--- a/app/javascript/mixins/useTooltip.js
+++ b/app/javascript/mixins/useTooltip.js
@@ -1,3 +1,13 @@
-export default function useTooltip(elem){
- $(elem).tooltipster({theme: 'tooltipster-shadow', contentAsHTML: true})
+import tippy from 'tippy.js';
+
+export default function useTooltip(elem, params) {
+ const content = elem.title
+ elem.removeAttribute('title')
+ tippy(elem, {
+ theme: 'light-border',
+ animation: 'fade',
+ content: content,
+ allowHTML: true,
+ maxWidth: '400', ...params
+ })
}
\ No newline at end of file
diff --git a/app/views/annotator/index.html.haml b/app/views/annotator/index.html.haml
index 6c12a1f55..7b65537d2 100644
--- a/app/views/annotator/index.html.haml
+++ b/app/views/annotator/index.html.haml
@@ -1,4 +1,4 @@
-- @title = "Annotator"
+- @title= t('annotator.title')
%head
= javascript_include_tag "bp_annotator"
@@ -6,7 +6,7 @@
%div.container-fluid
%div.row
%div.col
- %h2.mt-3 Annotator
+ %h2.mt-3= t('annotator.title')
%p
= t('annotator.index.intro', site: $SITE).html_safe
= link_to(help_path(anchor: "Annotator_Tab"), id: "annotator-help", target: "_blank") do
@@ -17,90 +17,90 @@
%form
%div.form-group
= hidden_field_tag :annotation_sample_text, t('annotator.index.sample_text')
- = text_area_tag("annotation_text", nil, rows: 10, class: "form-control", placeholder: "Enter or paste text to be annotated", "aria-describedby": "annotateTextHelpBlock")
+ = text_area_tag("annotation_text", nil, rows: 10, class: "form-control", placeholder: t('annotator.enter_or_paste_text'), "aria-describedby": "annotateTextHelpBlock")
%small#annotateTextHelpBlock.form-text
- %a#insert_text_link{href: "javascript:void(0);"} insert sample text
+ %a#insert_text_link{href: "javascript:void(0);"}= t('shared.insert_sample_text')
- %a#advancedOptionsLink{:href => "javascript:void(0);"} Show advanced options >>
+ %a#advancedOptionsLink{:href => "javascript:void(0);"}= t('shared.show_advanced_options') + ">>"
%div#advanced-options-container.mt-4
%div.form-group
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("longest_only", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "longest_only"} Match longest only
+ %label.custom-control-label{for: "longest_only"}= t('annotator.filters.match_longest_only')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("whole_word_only", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "whole_word_only"} Match partial words
+ %label.custom-control-label{for: "whole_word_only"}= t('annotator.filters.match_partial_words')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("mappings", "all", false, id: "mappings_all", class: "custom-control-input")
- %label.custom-control-label{for: "mappings_all"} Include mappings
+ %label.custom-control-label{for: "mappings_all"}= t('annotator.filters.include_mappings')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("exclude_numbers", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "exclude_numbers"} Exclude numbers
+ %label.custom-control-label{for: "exclude_numbers"}= t('annotator.filters.exclude_numbers')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("exclude_synonyms", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "exclude_synonyms"} Exclude synonyms
+ %label.custom-control-label{for: "exclude_synonyms"}= t('annotator.filters.exclude_synonyms')
%div.form-group
- %label{for: "ontology_ontologyId"} Select ontologies
+ %label{for: "ontology_ontologyId"}= t('annotator.select', name: t('ontology'))
= select_tag("ontology_ontologyId", options_from_collection_for_select(@annotator_ontologies, :acronym, lambda { |ont| "#{ont.name} (#{ont.acronym})" }), |
multiple: true, class: "form-control", "aria-describedby": "selectOntologiesHelpBlock") |
- %small#selectOntologiesHelpBlock.form-text.text-muted Start typing to select ontologies or leave blank to use all
+ %small#selectOntologiesHelpBlock.form-text.text-muted= t('annotator.start_typing_to_select', type: t('ontology'))
- if @sem_type_ont
%div.form-group
- %label{for: "semantic_types"} Select UMLS semantic types
+ %label{for: "semantic_types"}= t('annotator.select', name: t('annotator.umls.semantic_types'))
= select_tag("semantic_types", options_for_select(@semantic_types_for_select), multiple: "true", class: "form-control", "aria-describedby": "selectSemanticTypesHelpBlock")
- %small#selectSemanticTypesHelpBlock.form-text.text-muted Start typing to select UMLS semantic types or leave blank to use all
+ %small#selectSemanticTypesHelpBlock.form-text.text-muted= t('annotator.start_typing_to_select', type: t('annotator.umls.semantic_types'))
%div.form-group
- %label{for: "semantic_groups"} Select UMLS semantic groups
+ %label{for: "semantic_groups"}= t('annotator.select', name: t('annotator.umls.semantic_groups'))
= select_tag("semantic_groups", options_for_select(@semantic_groups_for_select), multiple: "true", class: "form-control", "aria-describedby": "selectSemanticGroupsHelpBlock")
- %small#selectSemanticGroupsHelpBlock.form-text.text-muted Start typing to select UMLS semantic groups or leave blank to use all
+ %small#selectSemanticGroupsHelpBlock.form-text.text-muted= t('annotator.start_typing_to_select', type: t('annotator.umls.semantic_groups'))
%div.form-group
- %label{for: "class_hierarchy_max_level"} Include ancestors up to level
+ %label{for: "class_hierarchy_max_level"}= t('annotator.filters.max_hierarchy_level')
- options = [["none", 0], *(1..10).map {|i| [i, i]}, ["all", 999]]
= select_tag("class_hierarchy_max_level", options_for_select(options, 0), class: "form-control")
%div.form-group
- %label{for: "score"} Include score
+ %label{for: "score"}= t('annotator.filters.score')
- options = [["none", ""], ["old", "old"], ["cvalue", "cvalue"], ["cvalueh", "cvalueh"]]
= select_tag(:score, options_for_select(options, 0), class: "form-control", "aria-describedby": "includeScoreHelpBlock")
- %small#includeScoreHelpBlock.form-text.text-muted Score annotations following the previous 2009 NCBO measure (old) or the C-Value measure (cvalue). If hierarchy expansion is used, then prefer cvalueh.
+ %small#includeScoreHelpBlock.form-text.text-muted= t('annotator.filters.score_help')
%div.form-group
- %label{for: "score_threshold"} Filter by score threshold
+ %label{for: "score_threshold"}= t('annotator.filters.score_threshold')
= number_field_tag(:score_threshold, 0, id: "score_threshold", class: "form-control", "aria-describedby": "scoreThresholdHelpBlock")
- %small#scoreThresholdHelpBlock.form-text.text-muted Specify the minimum score value for annotations
+ %small#scoreThresholdHelpBlock.form-text.text-muted= t('annotator.filters.score_threshold_help')
%div.form-group
- %label{for: "confidence_threshold"} Filter confidence threshold
+ %label{for: "confidence_threshold"}= t('annotator.filters.confidence_threshold')
= number_field_tag(:confidence_threshold, 0, min: 0, max: 100, id: "confidence_threshold", class: "form-control", "aria-describedby": "confidenceThresholdHelpBlock")
- %small#confidenceThresholdHelpBlock.form-text.text-muted Specify the minimum position in the scoring distribution (between 1 and 100)
+ %small#confidenceThresholdHelpBlock.form-text.text-muted= t('annotator.filters.confidence_threshold_help')
- if @recognizers.length > 1
%div.form-group
- %label{for: "recognizer"} Entity recognizer
+ %label{for: "recognizer"}= t('annotator.filters.recognizer')
- default_recognizer = @recognizers.include?("mgrep") ? "mgrep" : @recognizers.first
= select_tag("recognizer", options_for_select(@recognizers.map {|r| [r, r]}, default_recognizer), class: "form-control")
%div.form-group
%div.custom-control.custom-checkbox
= check_box_tag("fast_context", :all, false, class: "custom-control-input")
- %label.custom-control-label{for: "fast_context"} FastContext
+ %label.custom-control-label{for: "fast_context"}= t('annotator.fast_context')
%small#fast_contextnHelp.form-text.text-muted= t('annotator.index.fast_context.tooltip')
%div.form-group
%div.custom-control.custom-checkbox
= check_box_tag("lemmatize", false, false, class: "custom-control-input")
- %label.custom-control-label{for: "lemmatize"} Lemmatize
- %small#lemmatize.form-text.text-muted Enable Lemmatize to lemmatize the submitted text and use a lemmatized dictionary for the annotations
+ %label.custom-control-label{for: "lemmatize"}= t('annotator.lemmatize')
+ %small#lemmatize.form-text.text-muted= t('annotator.index.lemmatize.tooltip')
%div.my-4
- = button_tag("Get annotations", type: "button", id: "annotator_button", class: "btn btn-primary btn-lg")
+ = button_tag(t('annotator.get_annotator'), type: "button", id: "annotator_button", class: "btn btn-primary btn-lg")
%span.annotator_spinner
%img{src: asset_path('spinners/spinner_000000_16px.gif')}/
%span#annotator_error.annotator_error
@@ -109,9 +109,9 @@
%div.col
#annotations_container
#result_counts
- %h4 Annotations
+ %h4= t('annotator.annotations_result')
#filter_list{:style => "font-size: 9pt; color: gray; display: none; clear: both; margin: -15px 0 5px"}
- %span#filter_title> Results are filtered by
+ %span#filter_title> #{t('annotator.results_filtered_by')}:
\
%span#filter_names
#results_error{:style => "color: red; margin-bottom: 7px;"}
@@ -119,45 +119,45 @@
%thead
%tr
%th
- Class
+ = t('class')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_classes.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_classes.bp_popup_link{:href => "javascript:void(0);"}= t('filter')
%div#classes_filter_list.bp_popup_list
%th
- Ontology
+ = t('ontology')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_ontologies.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_ontologies.bp_popup_link{:href => "javascript:void(0);"}= t('filter')
%div#ontology_filter_list.bp_popup_list
%th{class: "match_type"}
- Type
+ = t('type')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_match_type.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_match_type.bp_popup_link{:href => "javascript:void(0);"}= t('filter')
%div#match_type_filter_list.bp_popup_list
- %th UMLS Sem Type
- %th{class: "match_context"} Context
+ %th= t('umls_sem_type')
+ %th{class: "match_context"}= t('context')
%th
- Matched Class
+ = t('matched_class')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_matched_classes.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_matched_classes.bp_popup_link{:href => "javascript:void(0);"}= t('filter')
%div#matched_classes_filter_list.bp_popup_list
%th
- Matched Ontology
+ = t('matched_ontology')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_matched_ontologies.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_matched_ontologies.bp_popup_link{:href => "javascript:void(0);"}= t('filter')
%div#matched_ontology_filter_list.bp_popup_list
- %th Score
- %th Negation
- %th Experiencer
- %th Temporality
- %th Certainty
+ %th= t('score')
+ %th= t('negation')
+ %th= t('experiencer')
+ %th= t('temporality')
+ %th= t('certainty')
%tbody
%div.my-3
- %b Format results as
+ %b= t('format_results')
%div.my-3
%span#download_links_tabdelimited.link_button.ui_button
%span#download_links_json.link_button.ui_button
@@ -165,8 +165,8 @@
%span#download_links_text.link_button.ui_button
-# %span#download_links_xml.link_button.ui_button
%div.mt-3
- Reproduce these results using the
+ = link_to(t('reproduce_results'))
%span#annotator_parameters
%div.mb-4
- Additional parameters explained at
+ = t('additional_parameters')
= link_to('Annotator API documentation', "#{$REST_URL}/documentation#nav_annotator", target: "_blank")
diff --git a/app/views/collections/_collection.html.haml b/app/views/collections/_collection.html.haml
index a3310e726..914c1a8de 100644
--- a/app/views/collections/_collection.html.haml
+++ b/app/views/collections/_collection.html.haml
@@ -4,24 +4,10 @@
top_keys: %w[created modified comment note],
bottom_keys: [],
exclude_keys: %w[member]) do |c|
- = c.header do
- %tr
- %td.label
- ID
- %td
- %p
- = collection["@id"]
- %tr
- %td{nowrap: ""} Preferred Name
- %td
- %p= get_collection_label(collection)
- %tr
- %td{nowrap: ""} Members count
- %td
- %p= collection["memberCount"]
- %tr
- %td.label
- Type
- %td
- %p
- = collection["@type"]
\ No newline at end of file
+ - c.header(stripped: true) do |t|
+ - t.add_row({th: 'ID'}, {td: collection["@id"]})
+ - t.add_row({th: 'Preferred Name'}, {td: display_in_multiple_languages(get_collection_label(collection))})
+ - t.add_row({th: 'Members count'}) do |r|
+ - r.td do
+ = link_to collection["memberCount"], "/ontologies/" + @ontology.acronym + "/?p=classes&sub_menu=list&concept_collections=" + collection["@id"], 'data-turbo-frame':'_top'
+ - t.add_row({th: 'Type'}, {td: collection["@type"]})
diff --git a/app/views/collections/_list_view.html.haml b/app/views/collections/_list_view.html.haml
index 73fe49b21..bfe256748 100644
--- a/app/views/collections/_list_view.html.haml
+++ b/app/views/collections/_list_view.html.haml
@@ -5,12 +5,9 @@
no collections detected
- else
%div
- %ul.simpleTree{data:{controller: 'simple-tree history', 'simple-tree': { 'auto-click-value': "true" }, action: 'clicked->history#updateURL'}}
+ %ul.simpleTree{data:{controller: 'simple-tree', 'simple-tree': { 'auto-click-value': "true" }, action: 'clicked->history#updateURL'}}
%li.root
%ul
- - collections_labels.sort_by{|s| [s["prefLabel"]]}.each do |s|
+ - sort_collections_label(collections_labels).each do |c|
%li.doc
- %a{id: s["@id"], href: collection_path(s["@id"]),
- data: { turbo: "true", 'turbo-frame': 'collection', 'collectionid': s["@id"]},
- class: selected_collection_id.eql?(s["@id"]) ? "active" : nil }
- = get_collection_label(s)
\ No newline at end of file
+ = raw link_to_collection(c, selected_collection_id)
\ No newline at end of file
diff --git a/app/views/concepts/_details.html.haml b/app/views/concepts/_details.html.haml
index 56cea2643..d2d3fe348 100644
--- a/app/views/concepts/_details.html.haml
+++ b/app/views/concepts/_details.html.haml
@@ -1,59 +1,68 @@
= turbo_frame_tag 'concept_details' do
- schemes_keys = %w[hasTopConcept topConceptOf]
- label_xl_set = %w[skos-xl#prefLabel skos-xl#altLabel skos-xl#hiddenLabel]
+
+
= render ConceptDetailsComponent.new(id:'concept-details', acronym: @ontology.acronym,
properties: @concept.properties,
top_keys: %w[description comment],
bottom_keys: %w[disjoint subclass is_a has_part],
exclude_keys: schemes_keys + label_xl_set + ['inScheme']) do |c|
+
- c.header do
%tr
- %td{nowrap: ""} ID
+ %td{nowrap: ""}= t('ontology_details.concept.id')
%td
- %p= @concept.id
+ = @concept.id
%tr
- %td{nowrap: ""} Preferred Name
+ %td{nowrap: ""}= t('ontology_details.concept.preferred_name')
%td
%p= @concept.prefLabel({:use_html => true}).html_safe
+
+ - c.header(stripped: true) do |t|
+ - t.add_row({th: t('ontology_details.concept.id')}, {td:@concept.id})
+ - t.add_row({th: t('ontology_details.concept.preferred_name')}) do |h|
+ - h.td do
+ = display_in_multiple_languages(@concept.prefLabel)
+
- unless @concept.synonym.nil? || @concept.synonym.empty?
- %tr
- %td{nowrap: ""} Synonyms
- %td
- - for synonym in @concept.synonym
- %p= synonym
- %td
- %div.synonym-change-request
- = add_synonym_button
- = remove_synonym_button
+ - t.add_row({th: t('ontology_details.concept.synonyms')}) do |h|
+ - h.td do
+ %div.d-flex
+ %div
+ = display_in_multiple_languages(@concept.synonym)
+ %div.synonym-change-request
+ = add_synonym_button
+ = remove_synonym_button
+
+
- unless @concept.definition.nil? || @concept.definition.empty?
- %tr
- %td{nowrap: ""} Definitions
- %td
- %p= @concept.definition.join(" ")
+ - t.add_row({th: t('ontology_details.concept.definitions')}, {td: display_in_multiple_languages(@concept.definition)})
+
- if @concept.obsolete?
%tr
- %td{nowrap: ""} Obsolete
+ %td{nowrap: ""}= t('ontology_details.concept.obsolete')
%td
- %p true
+ true
- if skos?
- unless @concept.memberOf.nil? || @concept.memberOf.empty?
%tr
- %td{nowrap: ""} Member of
+ %td{nowrap: ""}= t('ontology_details.concept.member_of')
%td
%div.my-1
- @concept.memberOf.each do |v|
= raw get_link_for_collection_ajax(v, @ontology.acronym, '_blank')
- unless @concept.inScheme.nil? || @concept.inScheme.empty?
%tr
- %td{nowrap: ""} In Schemes
+ %td{nowrap: ""}= t('ontology_details.concept.in_schemes')
%td
%div.my-1
- @concept.inScheme.each do |v|
= raw get_link_for_scheme_ajax(v, @ontology.acronym, '_blank')
%tr
- %td{nowrap: ""} Type
+ %td{nowrap: ""}= t('ontology_details.concept.type')
%td
- %p= @concept.type
+ = @concept.type
- scheme_set = c.properties_set_by_keys(schemes_keys, c.concept_properties)
- label_xl_set = c.properties_set_by_keys(label_xl_set, c.concept_properties)
diff --git a/app/views/concepts/_list.html.haml b/app/views/concepts/_list.html.haml
index 83a4a27d3..dcc22d8ed 100644
--- a/app/views/concepts/_list.html.haml
+++ b/app/views/concepts/_list.html.haml
@@ -3,7 +3,7 @@
next_url: concept_list_url(@page.nextPage, request_collection_id, @ontology.acronym),
current_page: @page.page, next_page: @page.nextPage,
auto_click: @auto_click) do |c|
- - concepts = c.collection.sort_by{|concept| [concept.prefLabel || concept.id]}
+ - 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|
diff --git a/app/views/concepts/_perma_link_modal.html.haml b/app/views/concepts/_perma_link_modal.html.haml
new file mode 100644
index 000000000..4e43ba6dd
--- /dev/null
+++ b/app/views/concepts/_perma_link_modal.html.haml
@@ -0,0 +1,12 @@
+-# Modal dialog for getting a permanent link to a class (must reside in a top-level position in the document to display properly).
+%div#classPermalinkModal{class: "modal fade", tabindex: "-1", role: "dialog", aria: {labelledby: "classPermalinkLabel", hidden: "true"}}
+ %div.modal-dialog.modal-dialog-centered.modal-lg{role: "document"}
+ %div.modal-content
+ %div.modal-header
+ %h5#classPermalinkLabel.modal-title Permanent link to this class
+ %button.close{type: "button", "data-dismiss": "modal", "aria-label": "Close"}
+ %span{"aria-hidden": "true"} ×
+ %div.modal-body
+ = text_field_tag("purl_input", nil, class: "form-control")
+ %div.modal-footer
+ %button.btn.btn-secondary{"data-dismiss": "modal"} Close
\ No newline at end of file
diff --git a/app/views/concepts/_show.html.haml b/app/views/concepts/_show.html.haml
index 71f02f9a3..af69f8f2e 100644
--- a/app/views/concepts/_show.html.haml
+++ b/app/views/concepts/_show.html.haml
@@ -1,70 +1,69 @@
-= render TurboFrameComponent.new(id: 'concept_show',
- data: {controller:'labels-ajax-container', 'action': 'turbo:before-fetch-request->labels-ajax-container#abortAll', 'labels-ajax-container-label-ajax-outlet': '#concept_show a[data-controller="label-ajax"]'}) do
- / When we have an ontology with a flat hierarchy, we initially disable the tabs because we don't have a class to display
+= render TurboFrameComponent.new(id: 'concept_show', data: {controller:'labels-ajax-container', 'action': 'turbo:before-fetch-request->labels-ajax-container#abortAll', 'labels-ajax-container-label-ajax-outlet': '#concept_show a[data-controller="label-ajax"]'}) do
- if @concept.id.eql?("bp_fake_root")
%div{:style => "padding: 100px 0; font-size: larger; font-weight: bold; text-align: center;"}
Use the "Jump To" to find a class and display details, visualization, notes, and mappings
- else
- .cls-info-container
- %ul.nav.nav-tabs.tabs
- %li#details_top.nav-item
- %a.nav-link.active.py-1{:href => "#details" , data:{toggle: 'tab', target: '#details_content'}} Details
- - unless skos?
- %li#instances_top.nav-item
- %a.nav-link.py-1{:href => "#instances" , data:{toggle: 'tab', target: '#instances_content'}}
- Instances
- (
- %span#instances_count
- )
- %li#visualization_top.nav-item
- %a.nav-link.py-1{:href => "#visualization", data:{toggle: 'tab', target: '#visualization_content'}} Visualization
- %li#notes_top.nav-item
- %a.nav-link.py-1{:href => "#notes", data:{toggle: 'tab', target: '#notes_content'}}
- Notes
- %span#note_count_wrapper
- (
- %span#note_count= @notes.length
- )
- %li#mappings_top.nav-item
- %a.nav-link.py-1{:href => "#mappings", data:{toggle: 'tab', target: '#mappings_content'}}
- #{concept_label_to_show(submission: @submission)} Mappings (
- %span#mapping_count= 'loading'
+
+ %ul.nav.tabs
+ %li#details_top.nav-item
+ %a.nav-link.active.py-1{:href => "#details" , data:{toggle: 'tab', target: '#details_content'}} Details
+ - unless skos?
+ %li#instances_top.nav-item
+ %a.nav-link.py-1{:href => "#instances" , data:{toggle: 'tab', target: '#instances_content'}}
+ Instances
+ (
+ %span#instances_count
+ )
+ %li#visualization_top.nav-item
+ %a.nav-link.py-1{:href => "#visualization", data:{toggle: 'tab', target: '#visualization_content'}} Visualization
+ %li#notes_top.nav-item
+ %a.nav-link.py-1{:href => "#notes", data:{toggle: 'tab', target: '#notes_content'}}
+ Notes
+ %span#note_count_wrapper
+ (
+ %span#note_count= @notes.length
)
+ %li#mappings_top.nav-item
+ %a.nav-link.py-1{:href => "#mappings", data:{toggle: 'tab', target: '#mappings_content'}}
+ #{concept_label_to_show(submission: @submission)} Mappings (
+ %span#mapping_count= 'loading'
+ )
+
+ %a.concepts-json{:href => "#{@ontology.id}/classes/#{escape(@concept.id)}?display=all&apikey=#{get_apikey}", target: '_blank'}
+ = inline_svg_tag "json.svg"
- %li#restlink_top.nav-item
- %a.nav-link.py-1{:href => "#{@ontology.id}/classes/#{escape(@concept.id)}?display=all", :style => "margin-bottom: 1em; margin-left: 1em;", :target => "_blank"} Access #{concept_label_to_show(submission: @submission)} JSON
- - if @enable_ontolobridge
- %li#request_term_top.nav-item
- %a.nav-link.py-1{:href => "#request_term", data:{toggle: 'tab', target: '#request_term'}}
- New Term Requests
- - 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
- %i{class: "fas fa-link", aria: {hidden: "true"}}
- #contents.tab-content
- #details_content.tab-pane.active.show
- = render :partial =>'/concepts/details'
- - unless skos?
- #instances_content.tab-pane
- = render :partial =>'instances/instances' , locals: {id: "class-instances-data-table"}
- #visualization_content.tab-pane
- = render :partial =>'/concepts/biomixer'
- #notes_content.tab-pane
- = render :partial =>'/notes/list'
- #mappings_content.tab-pane
- = render TurboFrameComponent.new(id:'concept_mappings',
- src:"/ajax/mappings/get_concept_table?ontologyid=#{@ontology.acronym}&conceptid=#{CGI.escape(@concept.id)}")
- - if @enable_ontolobridge
- #request_term_content.tab-pane
- = render :partial =>'/concepts/request_term'
+ - if @enable_ontolobridge
+ %li#request_term_top.nav-item
+ %a.nav-link.py-1{:href => "#request_term", data:{toggle: 'tab', target: '#request_term'}}
+ New Term Requests
+ - 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
+ %i{class: "fas fa-link", aria: {hidden: "true"}}
+ #contents.tab-content
+ #details_content.tab-pane.active.show
+ = render :partial =>'/concepts/details'
+ - unless skos?
+ #instances_content.tab-pane
+ = render :partial =>'instances/instances' , locals: {id: "class-instances-data-table"}
+ #visualization_content.tab-pane
+ = render :partial =>'/concepts/biomixer'
+ #notes_content.tab-pane
+ = render :partial =>'/notes/list'
+ #mappings_content.tab-pane
+ = render TurboFrameComponent.new(id:'concept_mappings',
+ src:"/ajax/mappings/get_concept_table?ontologyid=#{@ontology.acronym}&conceptid=#{CGI.escape(@concept.id)}")
+ - if @enable_ontolobridge
+ #request_term_content.tab-pane
+ = render :partial =>'/concepts/request_term'
:javascript
- jQuery(document).ready(function(){
+ jQuery(document).ready(function(){
- jQuery("#classPermalinkModal").on("shown.bs.modal", function (e) {
- var currentPurl = jQuery("a.class-permalink").data("current-purl");
- jQuery("#purl_input").val(currentPurl);
- })
+ jQuery("#classPermalinkModal").on("shown.bs.modal", function (e) {
+ var currentPurl = jQuery("a.class-permalink").data("current-purl");
+ jQuery("#purl_input").val(currentPurl);
+ })
- jQuery("#purl_input").on("click", function () {
- jQuery(this).select();
- });
- });
+ jQuery("#purl_input").on("click", function () {
+ jQuery(this).select();
+ });
+ });
diff --git a/app/views/fair_score/_fair_service_header.html.haml b/app/views/fair_score/_fair_service_header.html.haml
index f4550d08b..61321623d 100644
--- a/app/views/fair_score/_fair_service_header.html.haml
+++ b/app/views/fair_score/_fair_service_header.html.haml
@@ -4,7 +4,7 @@
%span.badge.badge-pill.badge-secondary
beta
%span
- = link_to("https://github.com/agroportal/fairness", target: "_blank", "aria-label": "View fair scores definitions", title: "View fair scores definitions") do
+ = link_to("https://github.com/agroportal/fairness", target: "_blank", "aria-label": t("view_fair_scores_definitions"), title: t("view_fair_scores_definitions")) do
%i.fas.fa-lg.fa-question-circle{"aria-hidden": "true", style: "margin-left: 0.5rem"}
- = link_to(get_fairness_service_url,id: "fairness-service-url", target: "_blank", "aria-label": "Get the json version", title: "Get the json version") do
+ = link_to(get_fairness_service_url,id: "fairness-service-url", target: "_blank", "aria-label": t("get_json_version"), title: t("get_json_version")) do
%i.fas.fa-lg.fa-code{"aria-hidden": "true", style: "margin-left: 0.5rem" }
\ No newline at end of file
diff --git a/app/views/home/_fair_score_home.html.haml b/app/views/home/_fair_score_home.html.haml
index 9e83a221b..519e62cf3 100644
--- a/app/views/home/_fair_score_home.html.haml
+++ b/app/views/home/_fair_score_home.html.haml
@@ -5,22 +5,22 @@
= render partial: "fair_score/fair_service_header"
%span
%h2.p-2.badge.badge-secondary
- Average
+ = t('average')
%span.badge.badge-light
%span#fair-score-average
0 (0%)
%h2.p-2.badge.badge-secondary
- Min
+ = t('min')
%span.badge.badge-light
%span#fair-score-min
0 (0%)
%h2.p-2.badge.badge-secondary
- Max
+ = t('max')
%span.badge.badge-light
%span#fair-score-max
0 (0%)
%h2.p-2.badge.badge-secondary
- Median
+ = t('median')
%span.badge.badge-light
%span#fair-score-median
0 (0%)
@@ -33,6 +33,6 @@
%div.col-md-6.col-sm
= render partial: "shared/fair_score_radar" , locals: {data: nil }
%a.btn.btn-link{href:"/landscape#fairness_assessment"}
- See details
+ = t('see_details')
%div.col-md-6.col-sm
= render partial: "shared/fair_score_bars", locals: {data: nil}
\ No newline at end of file
diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml
index b3454de47..497235156 100644
--- a/app/views/home/index.html.haml
+++ b/app/views/home/index.html.haml
@@ -1,4 +1,4 @@
-- @title = t(".title", organization: "#{$ORG_SITE}")
+- @title = t("home.index.title", organization: "#{$ORG_SITE}")
- unless $FRONT_NOTICE.nil? || $FRONT_NOTICE.empty? || cookies[:front_page_notice_closed].eql?("true")
:javascript
@@ -19,27 +19,27 @@
%div.col
%div.px-2.py-2.pt-md-5.border-bottom.text-center
%h2
- = t(".welcome", site: "#{$SITE}")
+ = t("home.index.welcome", site: "#{$SITE}")
%small.text-muted
- = t(".tagline")
+ = t("home.index.tagline")
%div.row.search.pt-4
%div.col
%div.card-deck
-# Search for a class across ontologies
%div.card
- %div.card-header Search for a class
+ %div.card-header= t('home.search_class')
%div.card-body
= form_tag("/search", method: "get") do
%div.input-group.mb-3
- - placeholder = t(".query_placeholder")
+ - placeholder = t("home.index.query_placeholder")
= text_field_tag("query", nil, class: "form-control", placeholder: placeholder)
%div.input-group-append
= button_tag(type: "submit", class: "btn btn-primary", aria: {label: "Search for a class"}) do
%i{class: "fas fa-search fa-lg", aria: {hidden: "true"}}
- %a{:href => "/search?opt=advanced"} Advanced Search
+ %a{:href => "/search?opt=advanced"}= t("home.advanced_search")
-# Search for an ontology
%div.card
- %div.card-header Find an ontology
+ %div.card-header= t('home.find_ontology')
%div.card-body
%input#find_ontology_id{:type => "hidden"}
%div.input-group.mb-3
@@ -48,11 +48,11 @@
= button_tag(class: "btn btn-primary", onclick: "jumpToValueOntology()", aria: {label: "Find an ontology"}) do
%i{class: "fas fa-search fa-lg", aria: {hidden: "true"}}
%div.dropdown
- = button_tag("Browse Ontologies", type: "button", id: "ontologyGroupsDropdown", class: "btn btn-info dropdown-toggle", data: {toggle: "dropdown", offset: "0,10"}, aria: {haspopup: "true", expanded: "false"})
+ = button_tag(t('home.browse_ontologies'), type: "button", id: "ontologyGroupsDropdown", class: "btn btn-info dropdown-toggle", data: {toggle: "dropdown", offset: "0,10"}, aria: {haspopup: "true", expanded: "false"})
%div.dropdown-menu{"aria-labelledby": "ontologyGroupsDropdown"}
- = link_to("All", ontologies_path(), class: "dropdown-item")
+ = link_to(t('all'), ontologies_path(), class: "dropdown-item")
%div.dropdown-divider
- %h6.dropdown-header Browse by group
+ %h6.dropdown-header= t("home.browse_by_group")
- @groups.each do |group|
= link_to(group[:name], ontologies_path(filter: group[:acronym]), class: "dropdown-item")
%div.row.pt-3.statistics
@@ -60,33 +60,33 @@
%div.card-deck
-# Ontology visits
%div.card
- %div.card-header Ontology Visits #{"in full #{$SITE} " if at_slice?} (#{@analytics.date.strftime("%B %Y")})
+ %div.card-header #{t('home.ontology_visits')} #{"in full #{$SITE} " if at_slice?} (#{@analytics.date.strftime("%B %Y")})
= content_tag(:div, nil, id: "ontology-visits-chart", class: "card-body", data: {ontnames: @anal_ont_names, ontnumbers: @anal_ont_numbers}) do
%canvas#myChart
- = link_to("More", visits_path())
+ = link_to(t('more'), visits_path())
-# Ontology statistics
%div.card
- %div.card-header #{$SITE} Statistics #{"in full #{$SITE}" if at_slice?}
+ %div.card-header #{$SITE} #{t('statistics')} #{"in full #{$SITE}" if at_slice?}
%ul.list-group.list-group-flush
%li.list-group-item
%div.d-flex.justify-content-between.align-items-center
- %span Ontologies
+ %span= t('home.ontologies')
%span= number_with_delimiter(@ont_count)
%li.list-group-item
%div.d-flex.justify-content-between.align-items-center
- %span Classes
+ %span= t('home.classes')
%span= number_with_delimiter(@cls_count, :delimiter => ",")
%li.list-group-item
%div.d-flex.justify-content-between.align-items-center
- %span Individuals
+ %span= t('home.individuals')
%span= number_with_delimiter(@individuals_count, :delimiter => ",")
%li.list-group-item
%div.d-flex.justify-content-between.align-items-center
- %span Projects
+ %span= t('home.projects')
%span= LinkedData::Client::Models::Project.all.length
%li.list-group-item
%div.d-flex.justify-content-between.align-items-center
- %span Users
+ %span= t('home.users')
%span= LinkedData::Client::Models::User.all.length
- if fairness_service_enabled?
%div#fair-home.row.mt-3
@@ -96,11 +96,11 @@
%div.card-deck
-# Latest Notes
%div.card
- %div.card-header Latest Notes
+ %div.card-header= t('home.latest_notes')
%ul.list-group.list-group-flush
- if @last_notes.nil? || @last_notes.empty?
%li.list-group-item
- %span No recent notes have been submitted
+ %span= t('home.no_recent_notes')
- else
- for note in @last_notes
%li.list-group-item
@@ -118,7 +118,7 @@
- if !$ENABLE_SLICES.nil? && $ENABLE_SLICES == true && !at_slice?
-# Slices
%div.card
- %div.card-header Slices
+ %div.card-header= t("slices")
%ul.list-group.list-group-flush
- LinkedData::Client::Models::Slice.all.each_with_index do |slice, index|
- break if index == 10
@@ -127,15 +127,12 @@
%li.list-group-item
= link_to slice_name, slice_link
-
-
- - $HOME_PAGE_LOGOS.to_a.each do |home_page_logos_row|
- - unless home_page_logos_row[:links].to_a.empty?
- %div.row.pt-3
- %div.col
- %div.card-deck
- %div.card
- %div.card-header= home_page_logos_row[:title]
- %div.logos
- - home_page_logos_row[:links].to_a.each do |logo|
- = link_to(image_tag(logo[:img_src]), logo[:url], target: logo[:target])
+ - $HOME_PAGE_LOGOS.each do |key, home_page_logos_row|
+ %div.row.pt-3
+ %div.col
+ %div.card-deck
+ %div.card
+ %div.card-header= t("home.#{key}")
+ %div.logos
+ - home_page_logos_row.each do |logo|
+ = link_to(image_tag(logo[:img_src]), logo[:url], target: logo[:target])
diff --git a/app/views/landscape/index.html.haml b/app/views/landscape/index.html.haml
index 0a059e9c7..a9b105e24 100644
--- a/app/views/landscape/index.html.haml
+++ b/app/views/landscape/index.html.haml
@@ -6,87 +6,86 @@
- @title = "Landscape"
%div{:class => "container theme-showcase", :role => "main", :style => "width: 80%; display: block;", :align => "center"}
%h1{:style => "font-size: 45px;"}
- = $SITE
- Landscape
- %p Visualize data retrieved from the ontologies stored in the portal
+ = t("landscape.title", site: $SITE)
+ %p= t("landscape.intro")
%div{:class => "panel panel-success", :style => "margin-top: 2em;"}
%div{:class => "panel-heading"}
- %h3{:class => "panel-title"} Groups and categories
+ %h3{:class => "panel-title"}= t("landscape.groups_and_categories")
%div{:class => "panel-body"}
%div{:class => "row", :style => "width: 80%;"}
%div{:class => "col-md-6"}
- %h2 Ontologies by group
+ %h2= t("landscape.ontologies_by", type: t("landscape.group"))
%canvas#groupsCanvas
%div{:class => "col-md-6"}
- %h2 Ontologies by category
+ %h2= t("landscape.ontologies_by", type: t("landscape.category"))
%canvas#domainCanvas
%div{:class => "row", :style => "width: 80%; margin-top: 3em;"}
%div{:class => "col-md-7"}
- %h2 Ontologies count in each data catalog
+ %h2= t("landscape.ontologies_count_by_catalog")
%canvas#dataCatalogCanvas
%div{:class => "col-md-5"}
- %h2 Ontologies by size
+ %h2= t("landscape.ontologies_by", type: t("landscape.size"))
%canvas#sizeSlicesCanvas
%hr{:style => "margin-top: 5em; margin-bottom: 5em;"}
- %h1 Properties use
- %p The proportion of properties usage among stored ontologies.
+ %h1= t("landscape.properties_use")
+ %p= t("landscape.properties_usage_proportion")
%div#pieChartDiv
%div{:class => "row"}
%div{:class => "col-md-4"}
- %h2 Ontologies natural languages
+ %h2= t("landscape.ontologies_languages")
%div#naturalLanguagePieChartDiv
%div{:class => "col-md-4"}
- %h2 Licenses used by the ontologies
+ %h2= t("landscape.ontologies_licenses")
%div#licensePieChartDiv
%div{:class => "col-md-4"}
- %h2 Most used tools to build ontologies
+ %h2= t("landscape.ontology_tools")
%div#toolCloudChart{:style => "width: 100%; height: 500px;"}
%div#chartTooltip{:style => "width: auto; display: none;"}
- %span#chartTooltipValue none
+ %span#chartTooltipValue= t("none")
- %button#propertiesBtn{:style => "margin-top: 1em;", :type => "button", :class => "btn btn-success", :onclick => "toggleDiv('properties')"} More properties charts
+ %button#propertiesBtn{:style => "margin-top: 1em;", :type => "button", :class => "btn btn-success", :onclick => "toggleDiv('properties')"}= t("landscape.more_properties_charts")
%div#propertiesDiv{:class => "panel panel-info", :style => "margin-top: 2em;"}
%div{:class => "panel-heading"}
- %h3{:class => "panel-title"} Pie charts for properties used for the ontologies
+ %h3{:class => "panel-title"}= t("landscape.ontology_properties_pie_charts")
%div{:class => "panel-body"}
%div{:class => "row"}
%div{:class => "col-md-3"}
- %h2 prefLabel property URIs used for OWL ontologies
+ %h2= t("landscape.owl_ontology_preflabel_uris")
%div#prefLabelPropertyPieChartDiv
%div{:class => "col-md-3"}
- %h2 synonym property URIs used for OWL ontologies
+ %h2= t("landscape.owl_ontology_synonym_uris")
%div#synonymPropertyPieChartDiv
%div{:class => "col-md-3"}
- %h2 definition property URIs used for OWL ontologies
+ %h2= t("landscape.owl_ontology_definition_uris")
%div#definitionPropertyPieChartDiv
%div{:class => "col-md-3"}
- %h2 author property URIs used for OWL ontologies
+ %h2= t("landscape.owl_ontology_author_uris")
%div#authorPropertyPieChartDiv
%hr{:style => "margin-top: 5em; margin-bottom: 5em;"}
%div{:class => "panel panel-success", :style => "margin-top: 2em;"}
%div{:class => "panel-heading"}
- %h3{:class => "panel-title"} Ontologies types
+ %h3{:class => "panel-title"}= t("landscape.ontologies_properties")
%div{:class => "panel-body"}
%div{:class => "row"}
%div{:class => "col-md-4"}
- %h2 Format used
+ %h2= t("landscape.ontologies_formats")
%canvas#formatCanvas
%div{:class => "col-md-4"}
- %h2 Ontology types
+ %h2= t("landscape.ontologies_properties")
%canvas#isOfTypeCanvas
%div{:class => "col-md-4"}
- %h2 Ontology formality levels
+ %h2= t("landscape.ontology_formality_levels")
%canvas#formalityLevelCanvas
@@ -94,16 +93,16 @@
%div{:class => "panel panel-success", :style => "margin-top: 2em;"}
%div{:class => "panel-heading"}
- %h3{:class => "panel-title"} Contributors to ontologies development
+ %h3{:class => "panel-title"}= t("landscape.ontologies_contributors")
%div{:class => "panel-body"}
%div{:class => "row"}
%div{:class => "col-md-6"}
- %h1 Most active people
- %p Most mentioned people as contact, creator, contributor, curator.
+ %h1= t("landscape.most_active_people")
+ %p= t("landscape.most_mentioned_people")
%div#peopleCloudChart{:style => "width: 100%; height: 350px; margin-top: 2em; border-right: 1px solid #ccc;"}
%div{:class => "col-md-6"}
- %h1 Most active organizations
- %p Organizations that fund and endorse the greatest number of ontologies.
+ %h1= t("landscape.most_active_organizations")
+ %p= t("landscape.funding_endorsing_organizations")
%div#orgCloudChart{:style => "width: 100%; height: 350px; margin-top: 2em;"}
%hr{:style => "margin-top: 4em; margin-bottom: 4em;"}
@@ -111,23 +110,22 @@
%div{:class => "panel panel-success", :style => "margin-top: 2em;"}
%div{:class => "panel-heading"}
%h3{:class => "panel-title"}
- Ontologies activity on
- = $SITE
+ = t("landscape.ontologies_activity_on", site: $SITE)
%div{:class => "panel-body"}
%div{:class => "row"}
%div{:class => "col-md-6"}
- %h1 Most active people as reviewer
- %p People that posted notes, review and projects
+ %h1= t("landscape.most_active_people_as_reviewer")
+ %p= t("landscape.most_mentioned_people_as_reviewer")
%div#notesPeopleCloudChart{:style => "width: 100%; height: 350px; margin-top: 2em; border-right: 1px solid #ccc;"}
%div{:class => "col-md-6"}
- %h1 Most active ontologies
- %p Ontologies that have notes, review and projects
+ %h1= t("landscape.most_active_ontologies")
+ %p= t("landscape.ontologies_with_notes_reviews_projects")
%div#notesOntologiesCloudChart{:style => "width: 100%; height: 350px; margin-top: 2em;"}
%hr{:style => "margin-top: 5em; margin-bottom: 5em;"}
- %h1 Ontology relations network
- %p{:style => "margin-bottom: 1em;"} Relations between ontologies stored in the portal
+ %h1= t("landscape.ontology_relations_network")
+ %p{:style => "margin-bottom: 1em;"}= t("landscape.relations_between_stored_ontologies")
%div{:style => "display: flex;"}
%div{:style => "text-align: left; width: 23em;"}
@@ -135,7 +133,7 @@
= check_box_tag "selectedRelations[]", relation, true, :id => relation
= label_tag relation, relation
%br
- %button{:type => "button", :class => "btn btn-success", :onclick => "buildNetwork(ontologyRelationsArray)", :style => "margin-bottom: 1em;"} Filter Network
+ %button{:type => "button", :class => "btn btn-success", :onclick => "buildNetwork(ontologyRelationsArray)", :style => "margin-bottom: 1em;"}= t("landscape.filter_network")
%div{:style => "width: 100%;"}
%div#networkContainer{:style => "height: 80vh; width: 100%; border:1px solid #cecece;"}
@@ -144,13 +142,13 @@
-if fairness_service_enabled?
%hr{:style => "margin-top: 5em; margin-bottom: 5em;"}
%h1
- Ontology FAIRness Evaluator (O’FAIRe)
+ = t("landscape.ontology_fairness_evaluator")
%div#fairness_assessment.p-2
= render partial: "fair_score_landscape"
%hr{:style => "margin-top: 5em; margin-bottom: 5em;"}
%div
- %h1 Average metrics
+ %h1= t("landscape.average_metrics")
%table.minimal.align-right{width: "30%", style: "margin-bottom: 3em;"}
%tbody
- for metric in @metrics_average
diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb
index 730a85af5..90a471cd0 100644
--- a/app/views/layouts/_header.html.erb
+++ b/app/views/layouts/_header.html.erb
@@ -16,10 +16,8 @@
<%if @title.nil?%><%=$ORG_SITE%><%else%><%="#{@title} | #{$ORG_SITE}"%><%end%>
-
-
<%= stylesheet_link_tag "https://use.fontawesome.com/releases/v5.2.0/css/all.css", integrity: "sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ", crossorigin: "anonymous" %>
<%= stylesheet_link_tag "application" %>
diff --git a/app/views/layouts/_ontology_viewer.html.haml b/app/views/layouts/_ontology_viewer.html.haml
index 709267865..f401a4cd7 100644
--- a/app/views/layouts/_ontology_viewer.html.haml
+++ b/app/views/layouts/_ontology_viewer.html.haml
@@ -1,11 +1,6 @@
- content_section = current_section
-- concept_title = @concept.nil? ? "" : " - #{@concept.prefLabel} - Classes"
-- @title = "#{@ontology.name}#{concept_title}"
+- @title = ontology_viewer_page_name(@ontology.name, @concept&.prefLabel || '', content_section)
-- sub = @submission_latest
-- details_available = true
-- if sub.nil? || (sub.respond_to?(:status) && sub.status == 404)
- - details_available = false
= render :partial =>'layouts/header'
%div#bd
@@ -36,89 +31,38 @@
jQuery(document).data().bp.ont_viewer.concept_name_title = (jQuery(document).data().bp.ont_viewer.concept_name == "") ?
"" : " - " + jQuery(document).data().bp.ont_viewer.concept_name;
- var nav_ont = function (link) {
- const page = jQuery(link).attr("data-bp-ont-page");
- const page_name = jQuery(link).attr("data-bp-ont-page-name");
- History.pushState({p: page}, page_name + " | " + jQuery(document).data().bp.ont_viewer.org_site, "?p=" + page);
- }
-
- jQuery(document).ready(() => {
- jQuery("#navbar-ontology a").on("click", function (e) {
- e.preventDefault();
- nav_ont(this)
- });
- })
= render TurboModalComponent.new(id: 'application_modal')
- -# Modal dialog for getting a permanent link to a class (must reside in a top-level position in the document to display properly).
- %div#classPermalinkModal{class: "modal fade", tabindex: "-1", role: "dialog", aria: {labelledby: "classPermalinkLabel", hidden: "true"}}
- %div.modal-dialog.modal-dialog-centered.modal-lg{role: "document"}
- %div.modal-content
- %div.modal-header
- %h5#classPermalinkLabel.modal-title Permanent link to this class
- %button.close{type: "button", "data-dismiss": "modal", "aria-label": "Close"}
- %span{"aria-hidden": "true"} ×
- %div.modal-body
- = text_field_tag("purl_input", nil, class: "form-control")
- %div.modal-footer
- %button.btn.btn-secondary{"data-dismiss": "modal"} Close
+ = render partial: 'concepts/perma_link_modal'
= render partial: 'kgcl_dialogs'
- -# A header of sorts to display ontology name and subset of details.
%div.row.pt-md-3.pb-md-2
%div.col
- %div.ont-info-bar.rounded
- %div
- %h4
- = link_to(@ontology.name, ontology_path(@ontology.acronym))
- %div
- - if (details_available && !sub.released.nil?)
- %span.text-muted
- Last uploaded:
- = l(Date.parse(sub.creationDate), format: :monthfull_day_year)
- %div.ont-info-links
- - unless (@ontology.summaryOnly || @ont_restricted || @submission_latest.nil?)
- = link_to(@submission_latest.id + "/download?apikey=#{get_apikey}", "aria-label": "Download latest version", title: "Download latest version") do
- %i.fas.fa-lg.fa-download{"aria-hidden": true}
- - if details_available
- - if $PURL_ENABLED
- = link_to(@ontology.purl, "aria-label": "BioPortal PURL", title: "BioPortal PURL", target: "_blank") do
- %i.fas.fa-lg.fa-link{"aria-hidden": true}
- = link_to(sub.homepage, "aria-label": "Ontology home page", title: "Ontology home page", target: "_blank") do
- %i.fas.fa-lg.fa-home{"aria-hidden": true}
- - unless sub.documentation.nil?
- = link_to(sub.documentation, "aria-label": "Ontology documentation", title: "Ontology documentation", target: "_blank") do
- %i.fas.fa-lg.fa-book-reader{"aria-hidden": true}
- - unless sub.publication.nil?
- = link_to(sub.publication, "aria-label": "Ontology publications", title: "Ontology publications", target: "_blank") do
- %i.fas.fa-lg.fa-book{"aria-hidden": true}
- - if @ontology.admin?(session[:user])
- = link_to(edit_ontology_path(@ontology.acronym), "aria-label": "Edit ontology details", title: "Edit ontology details") do
- %i.fas.fa-lg.fa-user-edit
+ = render partial: 'layouts/ontology_viewer/header'
- %div.row.pb-4
+ %div.row.pb-4{data: {controller: 'ontology-viewer-tabs', 'ontology-viewer-tabs-language-sections-value': ontology_data_sections }}
%div.col
+ - sections = sections_to_show
%div.card
%div.card-header
- - sections = sections_to_show
- -# Tabbed navigation bar for ontology content sections
- %ul.nav.nav-tabs.card-header-tabs{id: "navbar-ontology", role: "tablist"}
- - sections.each do |section|
- %li.nav-item
- = link_to(section_name(section) , ontology_path(@ontology.acronym, p: section),
- id: "ont-#{section}-tab", class: "nav-link #{selected_section?(section) ? 'active show' : ''}",
- data: {toggle: "tab", target: "#ont_#{section}_content", 'bp-ont-page': section ,
- 'bp-ont-page-name': ontology_viewer_page_name(@ontology.name, @concept&.prefLabel || '', section) })
+ %div{style: "display: flex; justify-content: space-between;"}
+ %ul.nav.nav-tabs.card-header-tabs{id: "navbar-ontology", role: "tablist"}
+ - sections.each do |section|
+ %li.nav-item
+ = link_to_section(section)
+ %div
+ = language_selector_tag(:language_selector)
%div.card-body
%div.tab-content
- sections.each do |section|
- %div.tab-pane{id: "ont_#{section}_content", class: selected_section?(section) ? 'active show' : ''}
- = lazy_load_section(section) do
- - yield
+ %div.tab-pane{id: "ont_#{section}_content", class: selected_section?(section) ? 'active show' : '', data: section_data(section)}
+ = language_selector_hidden_tag(section) if ontology_data_section?(section)
+ = lazy_load_section(section) { yield }
+
= render partial: "layouts/footer"
diff --git a/app/views/layouts/_topnav.html.haml b/app/views/layouts/_topnav.html.haml
index 8c3e73e76..4ae87baeb 100644
--- a/app/views/layouts/_topnav.html.haml
+++ b/app/views/layouts/_topnav.html.haml
@@ -6,36 +6,41 @@
%div#topNavigationToggler.navbar-collapse.collapse.justify-content-between
%ul.navbar-nav
%li.nav-item
- = link_to("Browse", ontologies_path(), class: "nav-link")
+ = link_to(t('layout.header.browse'), ontologies_path(), class: "nav-link")
%li.nav-item
- = link_to("Search", "/search", class: "nav-link")
+ = link_to(t('layout.header.search'), "/search", class: "nav-link")
%li.nav-item
- = link_to("Mappings", mappings_path(), class: "nav-link")
+ = link_to(t('layout.header.mappings'), mappings_path(), class: "nav-link")
%li.nav-item
- = link_to("Recommender", recommender_index_path, class: "nav-link")
+ = link_to(t('layout.header.recommender'), recommender_index_path, class: "nav-link")
%li.nav-item
- = link_to("Annotator", annotator_index_path(), class: "nav-link")
+ = link_to(t('layout.header.annotator'), annotator_index_path(), class: "nav-link")
- if $NCBO_ANNOTATORPLUS_ENABLED == true
%li.nav-item
- = link_to("NCBO Annotator+", '/ncbo_annotatorplus', class: "nav-link")
+ = link_to(t('layout.header.ncbo_annotator_plus'), '/ncbo_annotatorplus', class: "nav-link")
%li.nav-item
- = link_to("Projects", projects_path(), class: "nav-link")
+ = link_to(t('layout.header.projects'), projects_path(), class: "nav-link")
%li.nav-item
- = link_to("Landscape", '/landscape', class: "nav-link")
+ = link_to(t('layout.header.landscape'), '/landscape', class: "nav-link")
-if (!session[:user].nil? && session[:user].admin?)
%li.nav-item
- = link_to("Admin", admin_index_path, class: "nav-link")
+ = link_to(t('layout.header.admin'), admin_index_path, class: "nav-link")
%ul.navbar-nav
+ %li.nav-item{ style: "margin-right: 10px;" }
+ %select#language-select.form-control{ data: { controller: "platform-language", action: "change->platform-language#handleLangChanged" } }
+ %option{ value: "en" } English
+ %option{ value: "fr" } Français
+
- if session[:user].nil?
%li.nav-item
- = link_to("Login", login_index_path(redirect: request.original_url), class: "btn btn-bp-login mr-md-2")
+ = link_to(t(:_login), login_index_path(redirect: request.original_url), class: "btn btn-bp-login mr-md-2")
- else
-# Account menu
%li.nav-item.dropdown
= link_to("#", id: "accountMenuDropdownLink", class: "nav-link dropdown-toggle", role: "button", data: {toggle: "dropdown"}, aria: {haspopup: "true", expanded: "false"}) do
= session[:user].username
%div.dropdown-menu.dropdown-menu-right{aria: {labelledby: "accountMenuDropdownLink"}}
- = link_to("Account Settings", "/account", class: "dropdown-item")
+ = link_to(t(:_account_setting), "/account", class: "dropdown-item")
- unless session[:ontologies].nil?
%div.dropdown-divider
%h6.dropdown-header Recently Viewed
@@ -48,9 +53,9 @@
= link_to("#", id: "supportMenuDropdownLink", class: "nav-link dropdown-toggle", role: "button", data: {toggle: "dropdown"}, aria: {haspopup: "true", expanded: "false"}) do
Support
%div.dropdown-menu.dropdown-menu-right{aria: {labelledby: "supportMenuDropdownLink"}}
- = link_to("Submit Feedback", feedback_path(location: encode_param(request.url)), id: "submitFeedbackMenuItem", class: "dropdown-item pop_window")
+ = link_to(t(:submit_feedback), feedback_path(location: encode_param(request.url)), id: "submitFeedbackMenuItem", class: "dropdown-item pop_window")
%div.dropdown-divider
%h6.dropdown-header Documentation
- = link_to("Help", "#{$WIKI_HELP_PAGE}", target: "_blank", class: "dropdown-item")
- = link_to("Release Notes", "#{$RELEASE_NOTES}", target: "_blank", class: "dropdown-item")
- = link_to("Publications", $PUBLICATIONS_URL, target: "_blank", class: "dropdown-item")
+ = link_to(t(:_help), "#{$WIKI_HELP_PAGE}", target: "_blank", class: "dropdown-item")
+ = link_to(t(:_release_notes), "#{$RELEASE_NOTES}", target: "_blank", class: "dropdown-item")
+ = link_to(t(:_publications), $PUBLICATIONS_URL, target: "_blank", class: "dropdown-item")
diff --git a/app/views/layouts/ontology_viewer/_header.html.haml b/app/views/layouts/ontology_viewer/_header.html.haml
new file mode 100644
index 000000000..bc5e094da
--- /dev/null
+++ b/app/views/layouts/ontology_viewer/_header.html.haml
@@ -0,0 +1,34 @@
+- sub = @submission_latest
+- details_available = true
+- if sub.nil? || (sub.respond_to?(:status) && sub.status == 404)
+ - details_available = false
+-# A header of sorts to display ontology name and subset of details.
+%div.ont-info-bar.rounded
+ %div
+ %h4
+ = link_to(@ontology.name, ontology_path(@ontology.acronym))
+ %div
+ - if (details_available && !sub.released.nil?)
+ %span.text-muted
+ = t('ontology_details.header.last_uploaded')
+ = l(Date.parse(sub.creationDate), format: :monthfull_day_year)
+ %div.ont-info-links
+ - unless (@ontology.summaryOnly || @ont_restricted || @submission_latest.nil?)
+ = link_to(@submission_latest.id + "/download?apikey=#{get_apikey}", "aria-label": "Download latest version", title: "Download latest version") do
+ %i.fas.fa-lg.fa-download{"aria-hidden": true}
+ - if details_available
+ - if $PURL_ENABLED
+ = link_to(@ontology.purl, "aria-label": "BioPortal PURL", title: "BioPortal PURL", target: "_blank") do
+ %i.fas.fa-lg.fa-link{"aria-hidden": true}
+ = link_to(sub.homepage, "aria-label": "Ontology home page", title: "Ontology home page", target: "_blank") do
+ %i.fas.fa-lg.fa-home{"aria-hidden": true}
+ - unless sub.documentation.nil?
+ = link_to(sub.documentation, "aria-label": "Ontology documentation", title: "Ontology documentation", target: "_blank") do
+ %i.fas.fa-lg.fa-book-reader{"aria-hidden": true}
+ - unless sub.publication.nil?
+ - sub.publication.each do |pub|
+ = link_to(pub, "aria-label": "Ontology publications", title: "Ontology publications", target: "_blank") do
+ %i.fas.fa-lg.fa-book{"aria-hidden": true}
+ - if @ontology.admin?(session[:user])
+ = link_to(edit_ontology_path(@ontology.acronym), "aria-label": "Edit ontology details", title: "Edit ontology details") do
+ %i.fas.fa-lg.fa-user-edit
\ No newline at end of file
diff --git a/app/views/mappings/_concept_mappings_selector.html.haml b/app/views/mappings/_concept_mappings_selector.html.haml
index 19b8bafae..b091cacfd 100644
--- a/app/views/mappings/_concept_mappings_selector.html.haml
+++ b/app/views/mappings/_concept_mappings_selector.html.haml
@@ -2,13 +2,13 @@
#headingTwo.card-header
%h2.mb-0
%button.btn.btn-link.btn-block.text-left.collapsed{"data-target" => "#collapseTwo", "data-toggle" => "collapse", :type => "button"}
- Find mappings of a class/concept
- = link_to(Rails.configuration.settings.links[:mappings], id: "mappings-help", "aria-label": "View mappings help") do
+ = t('mappings.find_mappings')
+ = link_to(Rails.configuration.settings.links[:mappings], id: "mappings-help", "aria-label": t('view_mappings_help')) do
%i.fas.fa-question-circle.fa-lg{"aria-hidden": "true"}
#collapseTwo.collapse{"data-parent" => "#accordionExample"}
.card-body
%div
- = render partial: 'shared/concept_picker', locals: {name: :concept_mapping_selector, concept_label: '', ontology_acronym: 'all', include_definition: true }
+ = render partial: 'shared/concept_picker', locals: {name: :concept_mapping_selector, concept_label: '', ontology_acronym: t('all'), include_definition: true }
%div.mt-1
= render TurboFrameComponent.new(id:'concept_mappings')
:javascript
diff --git a/app/views/mappings/_ontology_mappings.html.haml b/app/views/mappings/_ontology_mappings.html.haml
index 357784b8e..3e0689d94 100644
--- a/app/views/mappings/_ontology_mappings.html.haml
+++ b/app/views/mappings/_ontology_mappings.html.haml
@@ -9,10 +9,10 @@
.card-body
%div#mappings_select
- if @options.empty?
- No mappings available
+ = t('mappings.no_mappings_available')
- else
- = select('search', 'ontologies', @options, {:include_blank => ""},{:onchange=>"loadMappings(this.value);", "data-placeholder".to_sym => "Select an Ontology", autocomplete: "off"})
+ = select('search', 'ontologies', @options, {:include_blank => ""},{:onchange=>"loadMappings(this.value);", "data-placeholder".to_sym => t('select_ontologies_list'), autocomplete: "off"})
#mapping_load
%img{src: asset_path("jquery.simple.tree/spinner.gif")}/
- Loading mappings...
+ = t('mappings.loading_mappings')
#mappingCount{style:'min-height: 300px;'}
diff --git a/app/views/mappings/index.html.haml b/app/views/mappings/index.html.haml
index 438f3658f..15304b414 100644
--- a/app/views/mappings/index.html.haml
+++ b/app/views/mappings/index.html.haml
@@ -1,10 +1,10 @@
-- @title = "Mappings"
-%div#mappings_container.container-fluid.py-4
- %h1.my-1 Mappings
+- @title= t('mappings.title')
+%div#mappings_container.container-fluid.py-4.flex-grow-1
+ %h1.my-1= t('mappings.title')
%div#mappings_uploader.my-2
- = link_to_modal "Upload mappings" , "/mappings/loader", class: "btn btn-primary btn-block",
- data: { show_modal_title_value: "Mappings bulk load", show_modal_size_value: 'modal-xl'}
+ = link_to_modal t('mappings.upload_mappings') , "/mappings/loader", class: "btn btn-primary btn-block",
+ data: { show_modal_title_value: t('mappings.mappings_bulk_load'), show_modal_size_value: 'modal-xl'}
%hr.my-3.w-100
#accordionExample.accordion
= render partial: 'ontology_mappings'
diff --git a/app/views/ncbo_annotatorplus/index.html.haml b/app/views/ncbo_annotatorplus/index.html.haml
index ba1315f02..7b24e1126 100644
--- a/app/views/ncbo_annotatorplus/index.html.haml
+++ b/app/views/ncbo_annotatorplus/index.html.haml
@@ -1,4 +1,4 @@
-- @title = "NCBO Annotator +"
+- @title = t('nbco_annotatosplus.index.title')
%head
= javascript_include_tag "bp_annotator"
@@ -6,7 +6,7 @@
%div.container-fluid.annotator
%div.row
%div.col
- %h2.mt-3 NCBO Annotator +
+ %h2.mt-3= t('nbco_annotatosplus.index.title')
%p
= t('nbco_annotatosplus.index.intro', organization: $ORG).html_safe
= link_to(help_path(anchor: "Annotator_Tab"), id: "annotator-help", target: "_blank") do
@@ -17,82 +17,82 @@
%form
%div.form-group
= hidden_field_tag :annotation_sample_text, t('nbco_annotatosplus.index.sample_text')
- = text_area_tag("annotation_text", nil, rows: 10, class: "form-control", placeholder: "Enter or paste text to be annotated", "aria-describedby": "annotateTextHelpBlock")
+ = text_area_tag("annotation_text", nil, rows: 10, class: "form-control", placeholder: t('nbco_annotatosplus.enter_paste_text_to_annotate'), "aria-describedby": "annotateTextHelpBlock")
%small#annotateTextHelpBlock.form-text
- %a#insert_text_link{href: "javascript:void(0);"} insert sample text
+ %a#insert_text_link{href: "javascript:void(0);"}= t('nbco_annotatosplus.insert_sample_text')
- %a#advancedOptionsLink{:href => "javascript:void(0);"} Show advanced options >>
+ %a#advancedOptionsLink{:href => "javascript:void(0);"}= t('nbco_annotatosplus.show_advanced_options') >>
%div#advanced-options-container.mt-4
%div.form-group
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("longest_only", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "longest_only"} Match longest only
+ %label.custom-control-label{for: "longest_only"}= t('nbco_annotatosplus.match_longest_only')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("whole_word_only", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "whole_word_only"} Match partial words
+ %label.custom-control-label{for: "whole_word_only"}= t('nbco_annotatosplus.match_partial_words')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("mappings", "all", false, id: "mappings_all", class: "custom-control-input")
- %label.custom-control-label{for: "mappings_all"} Include mappings
+ %label.custom-control-label{for: "mappings_all"}= t('nbco_annotatosplus.include_mappings')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("exclude_numbers", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "exclude_numbers"} Exclude numbers
+ %label.custom-control-label{for: "exclude_numbers"}= t('nbco_annotatosplus.exclude_numbers')
%div.custom-control.custom-checkbox.custom-control-inline
= check_box_tag("exclude_synonyms", "all", false, class: "custom-control-input")
- %label.custom-control-label{for: "exclude_synonyms"} Exclude synonyms
+ %label.custom-control-label{for: "exclude_synonyms"}= t('nbco_annotatosplus.exclude_synonyms')
%div.form-group
- %label{for: "ontology_ontologyId"} Select ontologies
+ %label{for: "ontology_ontologyId"}= t('nbco_annotatosplus.select_ontologies_list')
= select_tag "ontology_ontologyId", options_for_select(@ontologies_for_select), multiple: true, data: { placeholder: "Click here to select ontologies" }, class: "form-control", "aria-describedby": "selectOntologiesHelpBlock"
- %small#selectOntologiesHelpBlock.form-text.text-muted Start typing to select ontologies or leave blank to use all
+ %small#selectOntologiesHelpBlock.form-text.text-muted= t('nbco_annotatosplus.select_ontologies')
- if @sem_type_ont
%div.form-group
- %label{for: "semantic_types"} Select UMLS semantic types
+ %label{for: "semantic_types"}= t('nbco_annotatosplus.select', t('nbco_annotatosplus.umls.semantic_types'))
= select_tag("semantic_types", options_for_select(@semantic_types_for_select), multiple: "true", class: "form-control", "aria-describedby": "selectSemanticTypesHelpBlock")
- %small#selectSemanticTypesHelpBlock.form-text.text-muted Start typing to select UMLS semantic types or leave blank to use all
+ %small#selectSemanticTypesHelpBlock.form-text.text-muted= t('nbco_annotatosplus.start_typing_to_select', t('nbco_annotatosplus.umls.semantic_types'))
%div.form-group
- %label{for: "semantic_groups"} Select UMLS semantic groups
+ %label{for: "semantic_groups"}= t('nbco_annotatosplus.select', t('nbco_annotatosplus.umls.semantic_groups'))
= select_tag("semantic_groups", options_for_select(@semantic_groups_for_select), multiple: "true", class: "form-control", "aria-describedby": "selectSemanticGroupsHelpBlock")
- %small#selectSemanticGroupsHelpBlock.form-text.text-muted Start typing to select UMLS semantic groups or leave blank to use all
+ %small#selectSemanticGroupsHelpBlock.form-text.text-muted= t('nbco_annotatosplus.start_typing_to_select', t('nbco_annotatosplus.umls.semantic_groups'))
%div.form-group
- %label{for: "class_hierarchy_max_level"} Include ancestors up to level:
+ %label{for: "class_hierarchy_max_level"}= t('nbco_annotatosplus.include_ancestors_up_to_level') + ":"
- options = [["none", 0], *(1..10).map {|i| [i, i]}, ["all", 999]]
= select_tag("class_hierarchy_max_level", options_for_select(options, 0), class: "form-control")
%div.form-group
- %label{for: "score"} Include score:
+ %label{for: "score"}= t('nbco_annotatosplus.include_score') + ":"
- options = [["none", ""], ["old", "old"], ["cvalue", "cvalue"], ["cvalueh", "cvalueh"]]
= select_tag(:score, options_for_select(options, 0), class: "form-control", "aria-describedby": "includeScoreHelpBlock")
- %small#includeScoreHelpBlock.form-text.text-muted Score annotations following the previous 2009 NCBO measure (old) or the C-Value measure (cvalue). If hierarchy expansion is used, then prefer cvalueh.
+ %small#includeScoreHelpBlock.form-text.text-muted= t('nbco_annotatosplus.score_help')
%div.form-group
- %label{for: "score_threshold"} Filter by score threshold:
+ %label{for: "score_threshold"}= t('nbco_annotatosplus.filters.score_threshold') + ":"
= number_field_tag(:score_threshold, 0, id: "score_threshold", class: "form-control", "aria-describedby": "scoreThresholdHelpBlock")
- %small#scoreThresholdHelpBlock.form-text.text-muted Specify the minimum score value for annotations
+ %small#scoreThresholdHelpBlock.form-text.text-muted= t('nbco_annotatosplus.filters.score_threshold_help')
%div.form-group
- %label{for: "confidence_threshold"} Filter confidence threshold:
+ %label{for: "confidence_threshold"}= t('nbco_annotatosplus.filters.confidence_threshold') + ":"
= number_field_tag(:confidence_threshold, 0, min: 0, max: 100, id: "confidence_threshold", class: "form-control", "aria-describedby": "confidenceThresholdHelpBlock")
- %small#confidenceThresholdHelpBlock.form-text.text-muted Specify the minimum position in the scoring distribution (between 1 and 100)
+ %small#confidenceThresholdHelpBlock.form-text.text-muted= t('nbco_annotatosplus.filters.confidence_threshold_help')
- if @recognizers.length > 1
%div.form-group
- %label{for: "recognizer"} Entity recognizer:
+ %label{for: "recognizer"}= t('nbco_annotatosplus.recognizer') + ":"
- default_recognizer = @recognizers.include?("mgrep") ? "mgrep" : @recognizers.first
= select_tag("recognizer", options_for_select(@recognizers.map {|r| [r, r]}, default_recognizer), class: "form-control")
%div.form-group
%div.custom-control.custom-checkbox
= check_box_tag("fast_context", :all, false, class: "custom-control-input")
- %label.custom-control-label{for: "fast_context"} FastContext
- %small#fast_contextnHelp.form-text.text-muted Enable FastContext to detect : if a concept has been negated (affirmed, negated), who experienced the found concept (patient, other), when the annotated concept occurred (recent, historical, hypothetical), and/or if the annotated concept is uncertain (certain, uncertain).
+ %label.custom-control-label{for: "fast_context"}= t('nbco_annotatosplus.fast_context.title')
+ %small#fast_contextnHelp.form-text.text-muted= t('nbco_annotatosplus.fast_context.help')
%div.my-4
= button_tag("Get annotations", type: "button", id: "annotator_button", class: "btn btn-primary btn-lg")
@@ -104,9 +104,9 @@
%div.col
#annotations_container
#result_counts
- %h4 Annotations
+ %h4= t('nbco_annotatosplus.annotations')
#filter_list{:style => "font-size: 9pt; color: gray; display: none; clear: both; margin: -15px 0 5px"}
- %span#filter_title> Results are filtered by:
+ %span#filter_title> #{t('nbco_annotatosplus.filters.by.title') + " :"}:
\
%span#filter_names
#results_error{:style => "color: red; margin-bottom: 7px;"}
@@ -114,45 +114,45 @@
%thead
%tr
%th
- Class
+ = t('nbco_annotatosplus.filters.by.class')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_classes.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_classes.bp_popup_link{:href => "javascript:void(0);"}= t('nbco_annotatosplus.filters.by.filter')
%div#classes_filter_list.bp_popup_list
%th
- Ontology
+ = t('nbco_annotatosplus.filters.by.ontology')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_ontologies.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_ontologies.bp_popup_link{:href => "javascript:void(0);"}= t('nbco_annotatosplus.filters.by.filter')
%div#ontology_filter_list.bp_popup_list
%th{class: "match_type"}
- Type
+ = t('nbco_annotatosplus.filters.by.match_type')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_match_type.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_match_type.bp_popup_link{:href => "javascript:void(0);"}= t('nbco_annotatosplus.filters.by.filter')
%div#match_type_filter_list.bp_popup_list
- %th UMLS Sem Type
- %th{class: "match_context"} Context
+ %th= t('nbco_annotatosplus.filters.by.umls_sem_type')
+ %th{class: "match_context"}= t('nbco_annotatosplus.filters.by.match_context')
%th
- Matched Class
+ = t('nbco_annotatosplus.filters.by.matched_class')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_matched_classes.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_matched_classes.bp_popup_link{:href => "javascript:void(0);"}= t('nbco_annotatosplus.filters.by.filter')
%div#matched_classes_filter_list.bp_popup_list
%th
- Matched Ontology
+ = t('nbco_annotatosplus.filters.by.matched_ontology')
%span.popup_container
%span.bp_popup_link_container
- %a#filter_matched_ontologies.bp_popup_link{:href => "javascript:void(0);"} filter
+ %a#filter_matched_ontologies.bp_popup_link{:href => "javascript:void(0);"}= t('nbco_annotatosplus.filters.by.filter')
%div#matched_ontology_filter_list.bp_popup_list
- %th Score
- %th Negation
- %th Experiencer
- %th Temporality
- %th Certainty
+ %th= t('nbco_annotatosplus.filters.by.score')
+ %th= t('nbco_annotatosplus.filters.by.negation')
+ %th= t('nbco_annotatosplus.filters.by.experiencer')
+ %th= t('nbco_annotatosplus.filters.by.temporality')
+ %th= t('nbco_annotatosplus.filters.by.certainty')
%tbody
%div.my-3
- %b Format results as:
+ %b= t('nbco_annotatosplus.filters.format_results_as') + ":"
%div.my-3
%span#download_links_tabdelimited.link_button.ui_button
%span#download_links_json.link_button.ui_button
@@ -160,8 +160,8 @@
%span#download_links_text.link_button.ui_button
-# %span#download_links_xml.link_button.ui_button
%div.mt-3
- Reproduce these results using the
+ =t('nbco_annotatosplus.filters.reproduce_results_using')
%span#annotator_parameters
%div.mb-4
- Additional parameters explained at
+ =t('nbco_annotatosplus.filters.additional_parameters_explained_at')
= link_to('Annotator API documentation', "#{$REST_URL}/documentation#nav_annotator", target: "_blank")
diff --git a/app/views/ontologies/_additional_metadata.html.haml b/app/views/ontologies/_additional_metadata.html.haml
index dab2314de..ed48690b5 100644
--- a/app/views/ontologies/_additional_metadata.html.haml
+++ b/app/views/ontologies/_additional_metadata.html.haml
@@ -1,6 +1,6 @@
-# Additional Metadata pane
%section.ont-metadata-card.ont-additional-metadata-card
%header.pb-2.font-weight-bold
- Additional Metadata
+ = t('ontology_details.metadata.additional_metadata')
%table.table.table-sm
= raw additional_metadata(@submission_latest) unless @submission_latest.nil?
diff --git a/app/views/ontologies/_treeview.html.haml b/app/views/ontologies/_treeview.html.haml
index 1f5573c75..47ac0e041 100644
--- a/app/views/ontologies/_treeview.html.haml
+++ b/app/views/ontologies/_treeview.html.haml
@@ -1,6 +1,6 @@
= turbo_frame_tag 'concepts_tree_view' do
#tree_wrapper.hide-if-loading
- %ul.simpleTree{data:{controller: 'simple-tree history',
+ %ul.simpleTree{data:{controller: 'simple-tree',
'simple-tree': { 'auto-click-value': "#{autoCLick}" },
action: 'clicked->history#updateURL'}}
%li.root
diff --git a/app/views/ontologies/browse.html.erb b/app/views/ontologies/browse.html.erb
index c35fdd01c..69d99663a 100644
--- a/app/views/ontologies/browse.html.erb
+++ b/app/views/ontologies/browse.html.erb
@@ -3,12 +3,12 @@
-
Ontologies loading
-
please wait...
+
<%= t('ontologies.loading') %>
+
<%= t('ontologies.please_wait') %>
- Browse
+ <%= t('browse') %>
<%= t('ontologies.intro').html_safe %>
<%= link_to(Rails.configuration.settings.links[:help_ontology_browse], id: 'ontology-browse-help',
@@ -19,27 +19,27 @@
- Welcome admin
This coloring indicates admin-only features
+ <%= t('ontologies.welcome_admin') %>
<%= t('ontologies.admin_help') %>
-
Debug Info
- types: {{facets.types.active}}
- artifacts: {{facets.artifacts.active}}
- formats: {{facets.formats.active}}
- groups: {{facets.groups.active}}
- categories: {{facets.categories.active}}
- Selected ontologies: {{visible_ont_count}}
+ <%= t('ontologies.debug_info') %>
+ <%= t('types') %>: {{facets.types.active}}
+ <%= t('artifacts') %>: {{facets.artifacts.active}}
+ <%= t('formats') %>: {{facets.formats.active}}
+ <%= t('groups') %>: {{facets.groups.active}}
+ <%= t('categories') %>: {{facets.categories.active}}
+ <%= t('selected_ontologies') %>: {{visible_ont_count}}
<%if session[:user].nil?%>
- Submit New Ontology
+ <%= t('ontologies.submit_new_ontology') %>
<%else%>
- Submit New Ontology
+ <%= t('ontologies.submit_new_ontology') %>
<%end%>
@@ -47,7 +47,7 @@
Retrieve the attr value in browse_attributes and set it in the @ontologies in app/controllers/ontologies_controller.rb
Define possibles values for the attr in config/enforced_attribute_values.rb-->
-
Entry Type
+
<%= t('ontologies.entry_type') %>
@@ -61,7 +61,7 @@
-
Uploaded in the Last
+
<%= t('ontologies.uploaded_in_the_last') %>
-
Category
+
<%= t('category') %>
@@ -84,7 +84,7 @@
-
Group
+
<%= t('group') %>
@@ -96,7 +96,7 @@