feat: Add support to uncategorized articles (#6912)

This commit is contained in:
Tejaswini Chile
2023-05-02 15:35:26 +05:30
committed by GitHub
parent c8041392dc
commit 847d7ea082
18 changed files with 103 additions and 46 deletions

View File

@@ -1,7 +1,7 @@
class Public::Api::V1::Portals::ArticlesController < Public::Api::V1::Portals::BaseController
before_action :ensure_custom_domain_request, only: [:show, :index]
before_action :portal
before_action :set_category, except: [:index]
before_action :set_category, except: [:index, :show]
before_action :set_article, only: [:show]
layout 'portal'
@@ -16,7 +16,7 @@ class Public::Api::V1::Portals::ArticlesController < Public::Api::V1::Portals::B
private
def set_article
@article = @category.articles.find(permitted_params[:id])
@article = @portal.articles.find_by(slug: permitted_params[:article_slug])
@article.increment_view_count
@parsed_content = render_article_content(@article.content)
end
@@ -39,7 +39,7 @@ class Public::Api::V1::Portals::ArticlesController < Public::Api::V1::Portals::B
end
def permitted_params
params.permit(:slug, :category_slug, :locale, :id)
params.permit(:slug, :category_slug, :locale, :id, :article_slug)
end
def render_article_content(content)

View File

@@ -5,6 +5,7 @@ class Public::Api::V1::Portals::BaseController < PublicController
def set_locale(&)
switch_locale_with_portal(&) if params[:locale].present?
switch_locale_with_article(&) if params[:article_slug].present?
end
def switch_locale_with_portal(&)
@@ -19,4 +20,16 @@ class Public::Api::V1::Portals::BaseController < PublicController
I18n.with_locale(@locale, &)
end
def switch_locale_with_article(&)
article = Article.find_by(slug: params[:article_slug])
@locale = if article.category.present?
article.category.locale
else
'en'
end
I18n.with_locale(@locale, &)
end
end

View File

@@ -8,8 +8,8 @@ export const buildPortalArticleURL = (
portalSlug,
categorySlug,
locale,
articleId
articleSlug
) => {
const portalURL = buildPortalURL(portalSlug);
return `${portalURL}/${locale}/${categorySlug}/${articleId}`;
return `${portalURL}/articles/${articleSlug}`;
};

View File

@@ -20,9 +20,9 @@ describe('PortalHelper', () => {
hostURL: 'https://app.chatwoot.com',
helpCenterURL: 'https://help.chatwoot.com',
};
expect(buildPortalArticleURL('handbook', 'culture', 'fr', 1)).toEqual(
'https://help.chatwoot.com/hc/handbook/fr/culture/1'
);
expect(
buildPortalArticleURL('handbook', 'culture', 'fr', 'article-slug')
).toEqual('https://help.chatwoot.com/hc/handbook/articles/article-slug');
window.chatwootConfig = {};
});
});

View File

@@ -93,7 +93,7 @@ export default {
slug,
this.article.category.slug,
this.article.category.locale,
this.article.id
this.article.slug
);
},
},

View File

@@ -86,7 +86,7 @@ export default {
methods: {
generateArticleUrl(article) {
return `/hc/${article.portal.slug}/${article.category.locale}/${article.category.slug}/${article.id}`;
return `/hc/${article.portal.slug}/articles/${article.slug}`;
},
handleKeyboardEvent(e) {
this.processKeyDownEvent(e);

View File

@@ -41,7 +41,7 @@ class Article < ApplicationRecord
inverse_of: :associated_articles,
optional: true
belongs_to :account
belongs_to :category
belongs_to :category, optional: true
belongs_to :portal
belongs_to :author, class_name: 'User'
@@ -49,7 +49,6 @@ class Article < ApplicationRecord
before_validation :ensure_article_slug
validates :account_id, presence: true
validates :category_id, presence: true
validates :author_id, presence: true
validates :title, presence: true
validates :content, presence: true

View File

@@ -1,4 +1,5 @@
json.id article.id
json.slug article.slug
json.title article.title
json.content article.content
json.description article.description

View File

@@ -1,7 +1,7 @@
<section class="bg-white lg:container w-full py-6 px-4 flex flex-col h-full">
<div class="flex justify-between items-center w-full">
<h3 class="text-xl text-slate-900 font-semibold subpixel-antialiased leading-relaxed hover:underline">
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/<%= category.slug %>">
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>">
<%= category.name %>
</a>
</h3>
@@ -18,7 +18,7 @@
<% category.articles.published.order(position: :asc).take(5).each do |article| %>
<a
class="text-slate-800 hover:underline leading-8"
href="/hc/<%= portal.slug %>/<%= category.locale %>/<%= category.slug %>/<%= article.id %>"
href="/hc/<%= portal.slug %>/articles/<%= article.slug %>"
>
<div class="flex justify-between content-center my-1 -mx-1 p-1 rounded-lg hover:bg-slate-25">
<%= article.title %>
@@ -42,7 +42,7 @@
</div>
<div>
<a
href="/hc/<%= portal.slug %>/<%= category.locale %>/<%= category.slug %>"
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>"
class="flex flex-row items-center text-base font-medium text-woot-500 hover:underline mt-4"
style="color: <%= portal.color %>"
>

View File

@@ -0,0 +1,35 @@
<section class="bg-white lg:container w-full py-6 px-4 flex flex-col h-full">
<div class="flex justify-between items-center w-full">
<h3 class="text-xl text-slate-900 font-semibold subpixel-antialiased leading-relaxed hover:underline">
<%= category %>
</h3>
<span class="text-slate-500">
<%= render 'public/api/v1/portals/article_count', article_count: portal.articles.published.where(category_id: nil).size %>
</span>
</div>
<div class="py-4 w-full mt-2 flex-grow">
<% portal.articles.published.where(category_id: nil).order(position: :asc).take(5).each do |article| %>
<a
class="text-slate-800 hover:underline leading-8"
href="/hc/<%= portal.slug %>/articles/<%= article.slug %>"
>
<div class="flex justify-between content-center my-1 -mx-1 p-1 rounded-lg hover:bg-slate-25">
<%= article.title %>
<span class="flex items-center">
<svg
class="w-4 h-4 fill-current text-slate-700"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path
d="M8.47 4.22a.75.75 0 0 0 0 1.06L15.19 12l-6.72 6.72a.75.75 0 1 0 1.06 1.06l7.25-7.25a.75.75 0 0 0 0-1.06L9.53 4.22a.75.75 0 0 0-1.06 0Z"
/>
</svg>
</span>
</div>
</a>
<% end %>
</div>
</section>

View File

@@ -13,21 +13,23 @@
<div class="bg-gradient-to-b from-white to-slate-50">
<div class="max-w-5xl px-8 lg:px-4 pt-8 pb-16 mx-auto space-y-4 w-full">
<div>
<a
class="text-slate-700 hover:underline leading-8 text-sm font-medium"
href="/hc/<%= @portal.slug %>/<%= @article.category.locale %>"
>
<%= I18n.t('public_portal.common.home') %>
</a>
<span class="text-xs text-slate-600 px-1">/</span>
<a
class="text-slate-700 hover:underline leading-8 text-sm font-medium"
href="/hc/<%= @portal.slug %>/<%= @article.category.locale %>/<%= @article.category.slug %>"
>
<%= @article.category.name %>
</a>
</div>
<% if @article.category.present? %>
<div>
<a
class="text-slate-700 hover:underline leading-8 text-sm font-medium"
href="/hc/<%= @portal.slug %>/<%= @article.category.locale %>"
>
<%= I18n.t('public_portal.common.home') %>
</a>
<span class="text-xs text-slate-600 px-1">/</span>
<a
class="text-slate-700 hover:underline leading-8 text-sm font-medium"
href="/hc/<%= @portal.slug %>/<%= @article.category.locale %>/categories/<%= @article.category.slug %>"
>
<%= @article.category.name %>
</a>
</div>
<% end %>
<h1 class="text-3xl font-bold md:tracking-normal leading-snug md:text-5xl text-slate-900">
<%= @article.title %>
</h1>

View File

@@ -2,7 +2,7 @@
<section class="bg-white lg:container w-full py-6 px-4 flex flex-col h-full">
<div class="flex justify-between items-center w-full">
<h3 class="text-xl text-slate-900 font-semibold subpixel-antialiased leading-relaxed hover:underline"">
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/<%= category.slug %>">
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>">
<%= category.name %>
</a>
</h3>
@@ -20,7 +20,7 @@
<div class="flex justify-between content-center h-8 my-1">
<a
class="text-slate-800 hover:underline leading-8"
href="/hc/<%= portal.slug %>/<%= category.locale %>/<%= category.slug %>/<%= article.id %>"
href="/hc/<%= portal.slug %>/articles/<%= article.slug %>"
>
<%= article.title %>
</a>
@@ -45,7 +45,7 @@
</div>
<div>
<a
href="/hc/<%= portal.slug %>/<%= category.locale %>/<%= category.slug %>"
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>"
class="flex flex-row items-center text-base font-medium text-woot-600 hover:text-slate-900 hover:underline mt-4"
>
<%= I18n.t('public_portal.common.view_all_articles') %>

View File

@@ -35,7 +35,7 @@
<% @category.articles.published.order(:position).each do |article| %>
<a
class="text-slate-800 flex justify-between content-center mb-4 py-2"
href="/hc/<%= @portal.slug %>/<%= @category.locale %>/<%= @category.slug %>/<%= article.id %>"
href="/hc/<%= @portal.slug %>/articles/<%= article.slug %>"
>
<div>
<p class="font-medium mb-2 hover:underline"><%= article.title %></p>

View File

@@ -5,4 +5,10 @@
<%= render "public/api/v1/portals/category-block", category: category, portal: @portal %>
<% end %>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-x-32 gap-y-0 lg:gap-y-12">
<% if @portal.articles.where(status: :published, category_id: nil).order(position: :asc) %>
<%= render "public/api/v1/portals/uncategorized-block", category: "Uncategorized", portal: @portal %>
<% end %>
</div>
</div>