From 1fb1be3ddc231f8760b84dd1109a3baae252e0ae Mon Sep 17 00:00:00 2001 From: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com> Date: Thu, 20 Oct 2022 05:39:32 +0530 Subject: [PATCH 01/27] feat: Add search functionality for public portal (#5683) Co-authored-by: Pranav Raj S --- .../api/v1/portals/articles_controller.rb | 4 +- app/javascript/packs/portal.js | 21 ++- app/javascript/portal/api/article.js | 14 ++ .../portal/components/PublicArticleSearch.vue | 129 ++++++++++++++++++ .../portal/components/PublicSearchInput.vue | 60 ++++++++ .../portal/components/SearchSuggestions.vue | 103 ++++++++++++++ app/javascript/portal/portalHelpers.js | 5 + .../shared/components/FluentIcon/icons.json | 3 +- app/views/layouts/portal.html.erb | 13 ++ .../api/v1/models/_article.json.jbuilder | 8 ++ .../public/api/v1/portals/_footer.html.erb | 2 +- .../public/api/v1/portals/_header.html.erb | 2 +- .../public/api/v1/portals/_hero.html.erb | 9 +- .../api/v1/portals/articles/index.html.erb | 9 +- config/locales/en.yml | 8 ++ config/routes.rb | 1 + 16 files changed, 378 insertions(+), 13 deletions(-) create mode 100644 app/javascript/portal/api/article.js create mode 100644 app/javascript/portal/components/PublicArticleSearch.vue create mode 100644 app/javascript/portal/components/PublicSearchInput.vue create mode 100644 app/javascript/portal/components/SearchSuggestions.vue diff --git a/app/controllers/public/api/v1/portals/articles_controller.rb b/app/controllers/public/api/v1/portals/articles_controller.rb index 0dfa2ea9b..ae0fb2b6a 100644 --- a/app/controllers/public/api/v1/portals/articles_controller.rb +++ b/app/controllers/public/api/v1/portals/articles_controller.rb @@ -1,7 +1,7 @@ class Public::Api::V1::Portals::ArticlesController < PublicController before_action :ensure_custom_domain_request, only: [:show, :index] before_action :portal - before_action :set_category + before_action :set_category, except: [:index] before_action :set_article, only: [:show] layout 'portal' @@ -20,7 +20,7 @@ class Public::Api::V1::Portals::ArticlesController < PublicController end def set_category - @category = @portal.categories.find_by!(slug: params[:category_slug]) + @category = @portal.categories.find_by!(slug: params[:category_slug]) if params[:category_slug].present? end def portal diff --git a/app/javascript/packs/portal.js b/app/javascript/packs/portal.js index 2f7736deb..5c1867658 100644 --- a/app/javascript/packs/portal.js +++ b/app/javascript/packs/portal.js @@ -3,8 +3,10 @@ // a relevant structure within app/javascript and only use these pack files to reference // that code so that it will be compiled. +import Vue from 'vue'; import Rails from '@rails/ujs'; import Turbolinks from 'turbolinks'; +import PublicArticleSearch from '../portal/components/PublicArticleSearch.vue'; import { navigateToLocalePage } from '../portal/portalHelpers'; @@ -13,4 +15,21 @@ import '../portal/application.scss'; Rails.start(); Turbolinks.start(); -document.addEventListener('DOMContentLoaded', navigateToLocalePage); +const initPageSetUp = () => { + navigateToLocalePage(); + const isSearchContainerAvailable = document.querySelector('#search-wrap'); + if (isSearchContainerAvailable) { + new Vue({ + components: { PublicArticleSearch }, + template: '', + }).$mount('#search-wrap'); + } +}; + +document.addEventListener('DOMContentLoaded', () => { + initPageSetUp(); +}); + +document.addEventListener('turbolinks:load', () => { + initPageSetUp(); +}); diff --git a/app/javascript/portal/api/article.js b/app/javascript/portal/api/article.js new file mode 100644 index 000000000..d28f53c88 --- /dev/null +++ b/app/javascript/portal/api/article.js @@ -0,0 +1,14 @@ +import axios from 'axios'; + +class ArticlesAPI { + constructor() { + this.baseUrl = ''; + } + + searchArticles(portalSlug, locale, query) { + let baseUrl = `${this.baseUrl}/hc/${portalSlug}/${locale}/articles.json?query=${query}`; + return axios.get(baseUrl); + } +} + +export default new ArticlesAPI(); diff --git a/app/javascript/portal/components/PublicArticleSearch.vue b/app/javascript/portal/components/PublicArticleSearch.vue new file mode 100644 index 000000000..4ced0665b --- /dev/null +++ b/app/javascript/portal/components/PublicArticleSearch.vue @@ -0,0 +1,129 @@ + + + + diff --git a/app/javascript/portal/components/PublicSearchInput.vue b/app/javascript/portal/components/PublicSearchInput.vue new file mode 100644 index 000000000..5183f3293 --- /dev/null +++ b/app/javascript/portal/components/PublicSearchInput.vue @@ -0,0 +1,60 @@ + + + diff --git a/app/javascript/portal/components/SearchSuggestions.vue b/app/javascript/portal/components/SearchSuggestions.vue new file mode 100644 index 000000000..838d4ba7e --- /dev/null +++ b/app/javascript/portal/components/SearchSuggestions.vue @@ -0,0 +1,103 @@ + + + diff --git a/app/javascript/portal/portalHelpers.js b/app/javascript/portal/portalHelpers.js index d31d1b6ba..647059b73 100644 --- a/app/javascript/portal/portalHelpers.js +++ b/app/javascript/portal/portalHelpers.js @@ -1,8 +1,13 @@ export const navigateToLocalePage = () => { const allLocaleSwitcher = document.querySelector('.locale-switcher'); + if (!allLocaleSwitcher) { + return false; + } + const { portalSlug } = allLocaleSwitcher.dataset; allLocaleSwitcher.addEventListener('change', event => { window.location = `/hc/${portalSlug}/${event.target.value}/`; }); + return false; }; diff --git a/app/javascript/shared/components/FluentIcon/icons.json b/app/javascript/shared/components/FluentIcon/icons.json index 20981ed5c..27a81344f 100644 --- a/app/javascript/shared/components/FluentIcon/icons.json +++ b/app/javascript/shared/components/FluentIcon/icons.json @@ -11,6 +11,7 @@ "link-outline": "M9.25 7a.75.75 0 0 1 .11 1.492l-.11.008H7a3.5 3.5 0 0 0-.206 6.994L7 15.5h2.25a.75.75 0 0 1 .11 1.492L9.25 17H7a5 5 0 0 1-.25-9.994L7 7h2.25ZM17 7a5 5 0 0 1 .25 9.994L17 17h-2.25a.75.75 0 0 1-.11-1.492l.11-.008H17a3.5 3.5 0 0 0 .206-6.994L17 8.5h-2.25a.75.75 0 0 1-.11-1.492L14.75 7H17ZM7 11.25h10a.75.75 0 0 1 .102 1.493L17 12.75H7a.75.75 0 0 1-.102-1.493L7 11.25h10H7Z", "more-vertical-outline": "M12 7.75a1.75 1.75 0 1 1 0-3.5 1.75 1.75 0 0 1 0 3.5ZM12 13.75a1.75 1.75 0 1 1 0-3.5 1.75 1.75 0 0 1 0 3.5ZM10.25 18a1.75 1.75 0 1 0 3.5 0 1.75 1.75 0 0 0-3.5 0Z", "open-outline": "M6.25 4.5A1.75 1.75 0 0 0 4.5 6.25v11.5c0 .966.783 1.75 1.75 1.75h11.5a1.75 1.75 0 0 0 1.75-1.75v-4a.75.75 0 0 1 1.5 0v4A3.25 3.25 0 0 1 17.75 21H6.25A3.25 3.25 0 0 1 3 17.75V6.25A3.25 3.25 0 0 1 6.25 3h4a.75.75 0 0 1 0 1.5h-4ZM13 3.75a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 .75.75v6.5a.75.75 0 0 1-1.5 0V5.56l-5.22 5.22a.75.75 0 0 1-1.06-1.06l5.22-5.22h-4.69a.75.75 0 0 1-.75-.75Z", + "search-outline": "M10 2.75a7.25 7.25 0 0 1 5.63 11.819l4.9 4.9a.75.75 0 0 1-.976 1.134l-.084-.073-4.901-4.9A7.25 7.25 0 1 1 10 2.75Zm0 1.5a5.75 5.75 0 1 0 0 11.5 5.75 5.75 0 0 0 0-11.5Z", "send-outline": "M5.694 12 2.299 3.272c-.236-.607.356-1.188.942-.982l.093.04 18 9a.75.75 0 0 1 .097 1.283l-.097.058-18 9c-.583.291-1.217-.244-1.065-.847l.03-.096L5.694 12 2.299 3.272 5.694 12ZM4.402 4.54l2.61 6.71h6.627a.75.75 0 0 1 .743.648l.007.102a.75.75 0 0 1-.649.743l-.101.007H7.01l-2.609 6.71L19.322 12 4.401 4.54Z", - "sign-out-outline": ["M8.502 11.5a1.002 1.002 0 1 1 0 2.004 1.002 1.002 0 0 1 0-2.004Z","M12 4.354v6.651l7.442-.001L17.72 9.28a.75.75 0 0 1-.073-.976l.073-.084a.75.75 0 0 1 .976-.073l.084.073 2.997 2.997a.75.75 0 0 1 .073.976l-.073.084-2.996 3.004a.75.75 0 0 1-1.134-.975l.072-.085 1.713-1.717-7.431.001L12 19.25a.75.75 0 0 1-.88.739l-8.5-1.502A.75.75 0 0 1 2 17.75V5.75a.75.75 0 0 1 .628-.74l8.5-1.396a.75.75 0 0 1 .872.74Zm-1.5.883-7 1.15V17.12l7 1.236V5.237Z","M13 18.501h.765l.102-.006a.75.75 0 0 0 .648-.745l-.007-4.25H13v5.001ZM13.002 10 13 8.725V5h.745a.75.75 0 0 1 .743.647l.007.102.007 4.251h-1.5Z"] + "sign-out-outline": ["M8.502 11.5a1.002 1.002 0 1 1 0 2.004 1.002 1.002 0 0 1 0-2.004Z", "M12 4.354v6.651l7.442-.001L17.72 9.28a.75.75 0 0 1-.073-.976l.073-.084a.75.75 0 0 1 .976-.073l.084.073 2.997 2.997a.75.75 0 0 1 .073.976l-.073.084-2.996 3.004a.75.75 0 0 1-1.134-.975l.072-.085 1.713-1.717-7.431.001L12 19.25a.75.75 0 0 1-.88.739l-8.5-1.502A.75.75 0 0 1 2 17.75V5.75a.75.75 0 0 1 .628-.74l8.5-1.396a.75.75 0 0 1 .872.74Zm-1.5.883-7 1.15V17.12l7 1.236V5.237Z", "M13 18.501h.765l.102-.006a.75.75 0 0 0 .648-.745l-.007-4.25H13v5.001ZM13.002 10 13 8.725V5h.745a.75.75 0 0 1 .743.647l.007.102.007 4.251h-1.5Z"] } diff --git a/app/views/layouts/portal.html.erb b/app/views/layouts/portal.html.erb index 533c32d10..071fde9ee 100644 --- a/app/views/layouts/portal.html.erb +++ b/app/views/layouts/portal.html.erb @@ -17,6 +17,7 @@ By default, it renders: + <%= javascript_pack_tag 'portal' %> <%= stylesheet_pack_tag 'portal' %> <%= csrf_meta_tags %> @@ -35,4 +36,16 @@ By default, it renders: + diff --git a/app/views/public/api/v1/models/_article.json.jbuilder b/app/views/public/api/v1/models/_article.json.jbuilder index 994c6c029..f9f7c3694 100644 --- a/app/views/public/api/v1/models/_article.json.jbuilder +++ b/app/views/public/api/v1/models/_article.json.jbuilder @@ -13,6 +13,14 @@ if article.portal.present? end end +if article.category.present? + json.category do + json.id article.category.id + json.slug article.category.slug + json.locale article.category.locale + end +end + json.views article.views if article.author.present? diff --git a/app/views/public/api/v1/portals/_footer.html.erb b/app/views/public/api/v1/portals/_footer.html.erb index cd69a4fe4..2d0533b78 100644 --- a/app/views/public/api/v1/portals/_footer.html.erb +++ b/app/views/public/api/v1/portals/_footer.html.erb @@ -2,7 +2,7 @@ diff --git a/app/views/public/api/v1/portals/_header.html.erb b/app/views/public/api/v1/portals/_header.html.erb index b7b1cbad2..59065d012 100644 --- a/app/views/public/api/v1/portals/_header.html.erb +++ b/app/views/public/api/v1/portals/_header.html.erb @@ -22,7 +22,7 @@