Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature: Add federation portals status check (#769) #769

Merged
merged 77 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
6e87b96
simplify the header component to use content instead of a new section
syphax-bouazzouni May 8, 2024
f3870cd
update dropdown component to a custom title section instead of text
syphax-bouazzouni May 8, 2024
b21d74b
update browse page to use Dropdown component not bootsrap one
syphax-bouazzouni May 8, 2024
a4759c8
add color option to square badge component
syphax-bouazzouni May 8, 2024
2733312
add text and bg colors options to ontology browse card component
syphax-bouazzouni May 9, 2024
cc6c288
add federation helper code and config sample
syphax-bouazzouni May 9, 2024
8a8bb8e
add portals filters in the browse page
syphax-bouazzouni May 9, 2024
382582b
use federation helpers to get federation ontologies information
syphax-bouazzouni May 9, 2024
6ab2e86
remove the filter using index code from submission filter as no used
syphax-bouazzouni May 9, 2024
5f8de42
refactor the filter_using_data function to be faster by using an hash
syphax-bouazzouni May 9, 2024
4dd2740
update the browse analytics cache to change depending on portals
syphax-bouazzouni May 9, 2024
692c36e
add categories and groups ids on hover to know its origin when federated
syphax-bouazzouni May 9, 2024
2910b13
use the last part of ids for browse counts independently of its origin
syphax-bouazzouni May 9, 2024
cb26cb2
remove binding.pry from final federation code
syphax-bouazzouni May 10, 2024
7879468
add an error message if one of the external portal is down
syphax-bouazzouni May 10, 2024
8d8b948
Merge branch 'development' into feature/federate-search-page
Bilelkihal Aug 29, 2024
f9f4810
display federated results in search page
Bilelkihal Aug 29, 2024
e403973
display federated search results in different colors
Bilelkihal Aug 30, 2024
0ad89fa
add portals param in federated search
Bilelkihal Sep 6, 2024
5db6602
add federation checks in search page
Bilelkihal Sep 6, 2024
e68d651
merge federated search results
Bilelkihal Sep 9, 2024
065570b
show portals names in federated search result chips in the form 'Agro…
Bilelkihal Sep 9, 2024
2a33a0d
sort federated search results by string similarity
Bilelkihal Sep 9, 2024
102b0a2
Merge branch 'development' into feature/federate-search-page
syphax-bouazzouni Sep 11, 2024
62e1cc0
fix merge development to federated search issues
Bilelkihal Sep 12, 2024
07f0e44
clean search result component
Bilelkihal Sep 12, 2024
2e5dd7b
internationalize: results from other portals in search and browse page
Bilelkihal Sep 12, 2024
d1b228a
fix performance issue in federated search
Bilelkihal Sep 12, 2024
bb96959
merge results using class id and ontology acronym
Bilelkihal Sep 13, 2024
edb6937
extract federation enabled into a helper in federated search
Bilelkihal Sep 13, 2024
d986607
refactor search result elem function
Bilelkihal Sep 13, 2024
d285722
add realtime benchmark for search federated search
Bilelkihal Sep 13, 2024
4d0f827
add portal names and colors in top of federated search results
Bilelkihal Sep 13, 2024
6f71685
make sort by string similarity not case sensitive
Bilelkihal Sep 13, 2024
37d16a8
Merge branch 'development' into feature/federate-search-page
syphax-bouazzouni Sep 19, 2024
fc8ec7e
remove duplicated federation configuration
Bilelkihal Sep 20, 2024
f7a4e47
extract portal button in home page to federation helper, fix the styl…
Bilelkihal Sep 20, 2024
f8742b6
fix icons colors in federation
Bilelkihal Sep 23, 2024
52e9b27
display a message in the federated search results when a portal is no…
Bilelkihal Sep 27, 2024
bf5fe76
disable input chips in federated search page for the portals that are…
Bilelkihal Sep 27, 2024
3366fca
show tooltip for disabled input chips in the federated search
Bilelkihal Sep 27, 2024
d2177f9
clean search controller federation code
Bilelkihal Oct 1, 2024
5c7d434
update ontologies api ruby client to the latest version of federated …
Bilelkihal Oct 1, 2024
cb8276d
fix federated browse icons colors
Bilelkihal Oct 2, 2024
d320de2
add tooltip for portal button in federated search
Bilelkihal Oct 2, 2024
02ce7cb
open external ontologies links in new tab in federated browse
Bilelkihal Oct 2, 2024
cd83029
use portal button helper in federated browse
Bilelkihal Oct 2, 2024
aacfd56
cache federation status call
Bilelkihal Oct 3, 2024
d17c31b
update chip helpers to support disabled state
Bilelkihal Oct 3, 2024
7ca6359
use turbo frame for federation input chips, and use federation portal…
Bilelkihal Oct 3, 2024
aa7913c
add skelton loading animation for federation input chips
Bilelkihal Oct 3, 2024
bf8224f
cache federation input chips separately
Bilelkihal Oct 4, 2024
d15ae62
use cached federation input chips in browse page
Bilelkihal Oct 4, 2024
6f989f6
fix browse page federation inputs section title style
Bilelkihal Oct 4, 2024
3d2a63c
initialize federation portals input chips in the home page (asynch in…
Bilelkihal Oct 4, 2024
22eeca9
Merge branch 'development' into feature/federate-search-page
syphax-bouazzouni Oct 4, 2024
701879a
clean federated search aggregator code
Bilelkihal Oct 7, 2024
965cab5
move chip skelton to components helper
Bilelkihal Oct 7, 2024
f3cb39b
internationalize portal is not responding message
Bilelkihal Oct 7, 2024
fba0daf
clean federation portal status cache method
Bilelkihal Oct 7, 2024
b4f7816
clean federation stimulus controller code
Bilelkihal Oct 8, 2024
2a21b8c
display federated browse errors as warning instead of danger (orange …
Bilelkihal Oct 8, 2024
58758a6
use federation portal status in home page portals configuration
Bilelkihal Oct 8, 2024
829736a
fix issue in federation portal status method
Bilelkihal Oct 11, 2024
080940b
Merge branch 'development' into feature/federation-portals-status
syphax-bouazzouni Oct 16, 2024
2c6d4dd
clean portal_config_tooltip method to make it more readable
Bilelkihal Oct 22, 2024
3d189b7
consider the portal as down if the api of it is not present in the co…
Bilelkihal Oct 22, 2024
f9026b9
put federation portal status vue in a helper, and remove the html fil…
Bilelkihal Oct 22, 2024
2f3027a
internationalize portals status message
Bilelkihal Oct 22, 2024
93c3133
extract federation_input_chips to a helper
Bilelkihal Oct 22, 2024
05e2f08
put init portals status in home page logic in a helper for clarity
Bilelkihal Oct 22, 2024
b93215e
change home/federation_portals_status root to status/:portal_name
Bilelkihal Oct 22, 2024
9e037a7
use dig in federation_portal_status to ensure to not raise an exception
syphax-bouazzouni Oct 22, 2024
07f8c46
move init portal status helper to federation file and fix class name
syphax-bouazzouni Oct 22, 2024
2757413
move federation helpers from application helper to federation file an…
syphax-bouazzouni Oct 22, 2024
608c867
add loading state to the chips component and use it in federation status
syphax-bouazzouni Oct 22, 2024
321b817
rename federation chip component helper name to prevent conflicts
syphax-bouazzouni Oct 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/assets/stylesheets/browse.scss
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,25 @@
margin-top: 10px;
}

.browse-federation-input-chips{
display: flex;
flex-wrap: wrap;
margin: 0 15px 15px 15px;
div {
flex-grow: 1;
}

label{
display: grid;
}
}
.browse-federation-input-chip-container{
p{
font-size: 14px;
font-weight: 400;
color: #666666;
}
}

@media only screen and (max-width: 1250px) {
.browse-first-row {
Expand Down
37 changes: 37 additions & 0 deletions app/assets/stylesheets/components/chips.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

}
.chips-container.disabled div label > span, .chips-container div label span:has(span.disabled){
opacity: 60%;
background-color: #f8f9fa !important;
}

Expand All @@ -43,3 +44,39 @@
.chips-container div label input[type="checkbox"]:checked ~ span .chips-check-icon{
display:unset;
}

.chips-container.loading div {
cursor: default;
opacity: 0.6;
}

.chips-container .skeleton {
width: 80px;
height: 36px;
background-color: #e0e0e0;
border-radius: 5px;
animation: shimmer 4s infinite;
position: relative;
overflow: hidden;
}

@keyframes shimmer {
0% {
background-position: -200px 0;
}
100% {
background-position: 200px 0;
}
}

.chips-container .skeleton::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.6) 50%, rgba(255, 255, 255, 0.2) 100%);
animation: shimmer 4s infinite;
border-radius: 5px;
}
12 changes: 11 additions & 1 deletion app/components/chips_component.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
class ChipsComponent < ViewComponent::Base

renders_one :count
def initialize(id:nil, name:, label: nil, value: nil, checked: false, tooltip: nil)
def initialize(id:nil, name:, label: nil, value: nil, checked: false, tooltip: nil, disabled: false, loading: false)
@id = id || name
@name = name
@value = value || 'true'
@checked = checked
@label = label || @value
@tooltip = tooltip
@disabled = disabled
@loading = loading
end

def checked?
@checked
end

def disabled_class_name
@disabled ? 'disabled' : ''
end

def loading_class_name
@loading ? 'loading' : ''
end
end
20 changes: 12 additions & 8 deletions app/components/chips_component/chips_component.html.haml
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
.chips-container{class: @disabled ? 'disabled' : '', 'data-controller': 'tooltip', title: @tooltip}
.chips-container{class: "#{disabled_class_name} #{loading_class_name}", 'data-controller': 'tooltip', title: @tooltip}
%div
%label{:for => "chips-#{@id}-check"}
%input{:id => "chips-#{@id}-check", :name => @name, :type => "checkbox", :value => @value, checked: checked?, disabled: @disabled}
%span
= inline_svg_tag 'check.svg', class: 'chips-check-icon'
%div
= @label
= count
- if @loading
%label
%span.skeleton
- else
%label{:for => "chips-#{@id}-check"}
%input{:id => "chips-#{@id}-check", :name => @name, :type => "checkbox", :value => @value, checked: checked?, disabled: @disabled}
%span
= inline_svg_tag 'check.svg', class: 'chips-check-icon'
%div
= @label
= count
1 change: 0 additions & 1 deletion app/controllers/concerns/search_aggregator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ def search_result_elem(class_object, ontology_acronym, title)
result
end


def ontology_name_acronym(ontologies, selected_acronym)
ontology = ontologies.select { |x| x.acronym.eql?(selected_acronym.split('/').last) }.first
"#{ontology.name} (#{ontology.acronym})" if ontology
Expand Down
9 changes: 9 additions & 0 deletions app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,15 @@ def annotator_recommender_form
end
end

def federation_portals_status
@name = params[:name]
@acronym = params[:acronym]
@key = params[:portal_name]
@checked = params[:checked].eql?('true')
@portal_up = federation_portal_status(portal_name: @key.downcase.to_sym)
render inline: helpers.federation_chip_component(@key, @name, @acronym, @checked, @portal_up)
end

private

# Dr. Musen wants 5 specific groups to appear first, sorted by order of importance.
Expand Down
1 change: 1 addition & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -551,4 +551,5 @@ def categories_select(id: nil, name: nil, selected: 'None')
categories_for_select = LinkedData::Client::Models::Category.all.map{|x| ["#{x.name} (#{x.acronym})", x.id]}.unshift(["None", ''])
render Input::SelectComponent.new(id: id, name: name, value: categories_for_select, selected: selected, multiple: true)
end

end
18 changes: 14 additions & 4 deletions app/helpers/components_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ def alert_component(message, type: "info")
render Display::AlertComponent.new(type: type, message: message)
end

def chips_component(id: , name: , label: , value: , checked: false , tooltip: nil, &block)
def chips_component(id: , name: , label: , value: , checked: false , tooltip: nil, disabled: false, &block)
content_tag(:div, data: { controller: 'tooltip' }, title: tooltip) do
check_input(id: id, name: name, value: value, label: label, checked: checked, &block)
check_input(id: id, name: name, value: value, label: label, checked: checked, disabled: disabled, &block)
end
end

def group_chip_component(id: nil, name: , object: , checked: , value: nil, title: nil, &block)
def group_chip_component(id: nil, name: , object: , checked: , value: nil, title: nil, disabled: false, &block)
title ||= object["name"]
value ||= (object["value"] || object["acronym"] || object["id"])

chips_component(id: id || value, name: name, label: object["acronym"],
checked: checked,
value: value, tooltip: title, &block)
value: value, tooltip: title, disabled: disabled, &block)
end
alias :category_chip_component :group_chip_component

Expand Down Expand Up @@ -292,4 +292,14 @@ def form_cancel_button
end
end

def chips_skelton
syphax-bouazzouni marked this conversation as resolved.
Show resolved Hide resolved
content_tag(:div, class: 'chips-container loading') do
content_tag(:div) do
content_tag(:label) do
content_tag(:span, '', class: 'skeleton')
end
end
end
end

end
55 changes: 55 additions & 0 deletions app/helpers/federation_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,59 @@ def federation_external_class?(class_object)
end


def federation_portal_status(portal_name: nil)
Rails.cache.fetch("federation_portal_up_#{portal_name}", expires_in: 2.hours) do
portal_api = federated_portals&.dig(portal_name,:api)
return false unless portal_api
portal_up = false
begin
response = Faraday.new(url: portal_api) do |f|
f.adapter Faraday.default_adapter
f.request :url_encoded
f.options.timeout = 20
f.options.open_timeout = 20
end.head
portal_up = response.success?
rescue StandardError => e
Rails.logger.error("Error checking portal status for #{portal_name}: #{e.message}")
end
portal_up
end
end

def federation_chip_component(key, name, acronym, checked, portal_up)
render TurboFrameComponent.new(id:"federation_portals_status_#{key}") do
content_tag(:div, style: "cursor: default;") do
title = "#{!portal_up ? "#{key.humanize.gsub('portal', 'Portal')} #{t('federation.not_responding')}" : ''}"
group_chip_component(name: name,
object: { "acronym" => acronym, "value" => key },
checked: checked,
title: title ,
disabled: !portal_up)
end
end
end

def federation_input_chips(name: nil)
federated_portals.map do |key, config|
turbo_frame_component = TurboFrameComponent.new(
id: "federation_portals_status_#{key}",
src: "status/#{key}?name=#{name}&acronym=#{config[:name]}&checked=#{request_portals.include?(key.to_s)}"
)

content_tag :div do
render(turbo_frame_component) do |container|
container.loader do
render ChipsComponent.new(name: '', loading: true, tooltip: t('federation.check_status', portal: key.to_s.humanize.gsub('portal', 'Portal')))
end
end
end
end.join.html_safe
end

def init_federation_portals_status
content_tag(:div, class: 'd-none') do
federation_input_chips
end
end
end
14 changes: 12 additions & 2 deletions app/helpers/home_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@ def format_number_abbreviated(number)
end

def portal_config_tooltip(portal_name, &block)
title = render TurboFrameComponent.new(id: "portal_config_tooltip_#{portal_name&.downcase}", src: "/config?portal=#{portal_name&.downcase}", style: "width: 600px !important; max-height: 300px; overflow: scroll")
portal_id = portal_name&.downcase
title = if federation_portal_status(portal_name: portal_id)
render(
TurboFrameComponent.new(
id: "portal_config_tooltip_#{portal_id}",
src: "/config?portal=#{portal_id}",
style: "width: 600px !important; max-height: 300px; overflow: scroll"
)
)
end
render Display::InfoTooltipComponent.new(text: title, interactive: true) do
capture(&block)
end
end

def discover_ontologies_button
render Buttons::RegularButtonComponent.new(id: 'discover-ontologies-button', value: t('home.discover_ontologies_button'), variant: "secondary", state: "regular", href: "/ontologies") do |btn|
btn.icon_right do
Expand All @@ -43,4 +52,5 @@ def home_ontoportal_description
content_tag(:div, t('home.ontoportal_description', ontoportal_link: ontoportal_link, github_link: github_link).html_safe, style: "margin-bottom: 20px")
end


end
4 changes: 2 additions & 2 deletions app/helpers/inputs_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def number_input(name: , label: '', value: )
value: value)
end

def check_input(id:, name:, value:, label: '', checked: false, &block)
render ChipsComponent.new(name: name, id: id, label: label, value: value, checked: checked) do |c|
def check_input(id:, name:, value:, label: '', checked: false, disabled: false, &block)
render ChipsComponent.new(name: name, id: id, label: label, value: value, checked: checked, disabled: disabled) do |c|
if block_given?
capture(c, &block)
end
Expand Down
3 changes: 2 additions & 1 deletion app/views/home/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,12 @@
%a{href:logo[:url], target: "_blanc"}
%img{src: asset_path(logo[:img_src])}

= init_federation_portals_status

:javascript
function submitAnnotator(){
document.getElementById("annotator_submit").click()
}
function submitRecommender(){
document.getElementById("recommender_submit").click()
}

5 changes: 2 additions & 3 deletions app/views/ontologies/browser/browse.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@
= render LoaderComponent.new(small:true)
.browse-federation-input-chip-container
= render DropdownContainerComponent.new(id: "browse-portal-filter", is_open: !request_portals.empty?, title: t('federation.results_from_external_portals')) do
.browse-filter-checks-container.px-1
- federated_portals.each do |key, config|
= group_chip_component(name: "portals", object: { "acronym" => config[:name], "value" => key }, checked: request_portals.include?(key.to_s), title: '')
.px-1.browse-federation-input-chips
= federation_input_chips(name: "portals")

.browse-second-row
.browse-search-bar
Expand Down
3 changes: 1 addition & 2 deletions app/views/search/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
.title
= t('federation.results_from_external_portals')
.field.d-flex
- federated_portals.each do |key, config|
= group_chip_component(name: "portals[]", object: { "acronym" => config[:name], "value" => key }, checked: request_portals.include?(key.to_s), title: '')
= federation_input_chips(name: "portals[]")
.right
.filter-container
.title
Expand Down
3 changes: 2 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1506,4 +1506,5 @@ en:
federation:
results_from_external_portals: Results from external portals
from: from
not_responding: is not responding.
not_responding: is not responding.
check_status: Checking %{portal} availability
2 changes: 1 addition & 1 deletion config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1544,4 +1544,4 @@ fr:
results_from_external_portals: Résultats provenant de portails externes
from: de
not_responding: ne répond pas.

check_status: Vérification de la disponibilité de %{portal}
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
end

get '' => 'home#index'
get 'status/:portal_name', to: 'home#federation_portals_status'

match 'sparql_proxy', to: 'admin#sparql_endpoint', via: [:get, :post]

Expand Down
Loading