Skip to content

Commit 21007bd

Browse files
feat: add show author option to portal settings and update related views (#225)
* feat: add show author option to portal settings and update related views * fix: update portal reference to use local variable for show author condition * feat: enhance show_author handling in portal config and add related tests
1 parent c026ee2 commit 21007bd

File tree

9 files changed

+92
-4
lines changed

9 files changed

+92
-4
lines changed

app/controllers/api/v1/accounts/portals_controller.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def create
2323

2424
def update
2525
ActiveRecord::Base.transaction do
26-
@portal.update!(portal_params.merge(live_chat_widget_params)) if params[:portal].present?
26+
@portal.update!(merged_portal_params.merge(live_chat_widget_params)) if params[:portal].present?
2727
# @portal.custom_domain = parsed_custom_domain
2828
process_attached_logo if params[:blob_id].present?
2929
rescue ActiveRecord::RecordInvalid => e
@@ -79,10 +79,20 @@ def permitted_params
7979
def portal_params
8080
params.require(:portal).permit(
8181
:id, :color, :custom_domain, :header_text, :homepage_link,
82-
:name, :page_title, :slug, :archived, { config: [:default_locale, { allowed_locales: [] }] }
82+
:name, :page_title, :slug, :archived, { config: [:default_locale, :show_author, { allowed_locales: [] }] }
8383
)
8484
end
8585

86+
def merged_portal_params
87+
update_params = portal_params.to_h
88+
if update_params.key?('config')
89+
base_config = @portal.config.is_a?(Hash) ? @portal.config : {}
90+
incoming_config = update_params['config']
91+
update_params['config'] = incoming_config.is_a?(Hash) ? base_config.merge(incoming_config) : base_config
92+
end
93+
update_params
94+
end
95+
8696
def live_chat_widget_params
8797
permitted_params = params.permit(:inbox_id)
8898
return {} unless permitted_params.key?(:inbox_id)

app/javascript/dashboard/components-next/HelpCenter/Pages/PortalSettingsPage/PortalBaseSettings.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Input from 'dashboard/components-next/input/Input.vue';
1515
import Avatar from 'dashboard/components-next/avatar/Avatar.vue';
1616
import ComboBox from 'dashboard/components-next/combobox/ComboBox.vue';
1717
import ColorPicker from 'dashboard/components-next/colorpicker/ColorPicker.vue';
18+
import Switch from 'dashboard/components-next/switch/Switch.vue';
1819
1920
const props = defineProps({
2021
activePortal: {
@@ -45,6 +46,7 @@ const state = reactive({
4546
liveChatWidgetInboxId: '',
4647
logoUrl: '',
4748
avatarBlobId: '',
49+
showAuthor: true,
4850
});
4951
5052
const originalState = reactive({ ...state });
@@ -117,6 +119,7 @@ watch(
117119
homePageLink: newVal.homepage_link,
118120
slug: newVal.slug,
119121
liveChatWidgetInboxId: newVal.inbox?.id || '',
122+
showAuthor: newVal.config?.show_author !== false,
120123
});
121124
if (newVal.logo) {
122125
const {
@@ -149,6 +152,7 @@ const handleUpdatePortal = () => {
149152
homepage_link: state.homePageLink,
150153
blob_id: state.avatarBlobId,
151154
inbox_id: state.liveChatWidgetInboxId,
155+
config: { show_author: state.showAuthor },
152156
};
153157
emit('updatePortal', portal);
154158
};
@@ -335,6 +339,21 @@ const handleAvatarDelete = () => {
335339
<ColorPicker v-model="state.widgetColor" />
336340
</div>
337341
</div>
342+
<div
343+
class="grid items-start justify-between w-full gap-2 grid-cols-[200px,1fr]"
344+
>
345+
<label
346+
class="text-sm font-medium whitespace-nowrap py-2.5 text-n-slate-12"
347+
>
348+
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.SHOW_AUTHOR.LABEL') }}
349+
</label>
350+
<div class="flex flex-col gap-1 py-2.5">
351+
<Switch v-model="state.showAuthor" />
352+
<span class="text-xs text-n-slate-11">
353+
{{ t('HELP_CENTER.PORTAL_SETTINGS.FORM.SHOW_AUTHOR.HELP_TEXT') }}
354+
</span>
355+
</div>
356+
</div>
338357
<div class="flex justify-end w-full gap-2">
339358
<Button
340359
:label="t('HELP_CENTER.PORTAL_SETTINGS.FORM.SAVE_CHANGES')"

app/javascript/dashboard/i18n/locale/en/helpCenter.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,10 @@
747747
"BRAND_COLOR": {
748748
"LABEL": "Brand color"
749749
},
750+
"SHOW_AUTHOR": {
751+
"LABEL": "Show article authors",
752+
"HELP_TEXT": "Display author information on category pages"
753+
},
750754
"SAVE_CHANGES": "Save changes"
751755
},
752756
"CONFIGURATION_FORM": {

app/javascript/dashboard/i18n/locale/pt_BR/helpCenter.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,10 @@
747747
"BRAND_COLOR": {
748748
"LABEL": "Cor da Marca"
749749
},
750+
"SHOW_AUTHOR": {
751+
"LABEL": "Mostrar autores dos artigos",
752+
"HELP_TEXT": "Exibir informações de autoria nas páginas de categorias"
753+
},
750754
"SAVE_CHANGES": "Salvar Alterações"
751755
},
752756
"CONFIGURATION_FORM": {

app/models/portal.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ class Portal < ApplicationRecord
4444

4545
scope :active, -> { where(archived: false) }
4646

47-
CONFIG_JSON_KEYS = %w[allowed_locales default_locale website_token].freeze
47+
CONFIG_JSON_KEYS = %w[allowed_locales default_locale website_token show_author].freeze
48+
49+
def show_author?
50+
!ActiveModel::Type::Boolean.new.cast(config['show_author']).equal?(false)
51+
end
4852

4953
def file_base_data
5054
{

app/views/api/v1/accounts/portals/_portal.json.jbuilder

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ json.config do
1515
json.partial! 'api/v1/models/portal_config', formats: [:json], locale: locale, portal: portal
1616
end
1717
end
18+
json.show_author portal.show_author?
1819
end
1920

2021
if portal.channel_web_widget

app/views/public/api/v1/portals/_category-block.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@
4646
</div>
4747
<div class="flex justify-between flex-row items-center <%= !@is_plain_layout_enabled && 'px-2' %>">
4848
<div class="flex flex-row items-center gap-1">
49+
<% if portal.show_author? %>
4950
<%= render "public/api/v1/portals/authors", category: category, show_expanded: false %>
5051
<span class="text-slate-600 dark:text-slate-400"></span>
52+
<% end %>
5153
<span class="text-sm font-medium text-slate-600 dark:text-slate-400"><%= render 'public/api/v1/portals/article_count', article_count: category.articles.published.order(position: :asc).size %></span>
5254
</div>
5355
<div>

app/views/public/api/v1/portals/categories/_category-hero.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
<% end %>
2323
</div>
2424
<div class="flex flex-row items-center gap-1">
25+
<% if portal.show_author? %>
2526
<%= render "public/api/v1/portals/authors", category: category, show_expanded: true %>
2627
<span class="text-slate-600 dark:text-slate-400"></span>
28+
<% end %>
2729
<span class="flex items-center text-base text-slate-600 dark:text-slate-400 font-medium"><%= render 'public/api/v1/portals/article_count', article_count: category.articles.published.size %></span>
2830
</div>
2931
</div>

spec/controllers/api/v1/accounts/portals_controller_spec.rb

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,49 @@
131131
json_response = response.parsed_body
132132
expect(json_response['name']).to eql(portal_params[:portal][:name])
133133
expect(json_response['config']).to eql({ 'allowed_locales' => [{ 'articles_count' => 0, 'categories_count' => 0, 'code' => 'en' },
134-
{ 'articles_count' => 0, 'categories_count' => 0, 'code' => 'es' }] })
134+
{ 'articles_count' => 0, 'categories_count' => 0, 'code' => 'es' }],
135+
'show_author' => true })
136+
end
137+
138+
it 'persists show_author as false when explicitly set' do
139+
put "/api/v1/accounts/#{account.id}/portals/#{portal.slug}",
140+
params: { portal: { config: { show_author: false } } },
141+
headers: admin.create_new_auth_token,
142+
as: :json
143+
144+
expect(response).to have_http_status(:success)
145+
json_response = response.parsed_body
146+
expect(json_response['config']['show_author']).to be(false)
147+
148+
portal.reload
149+
expect(portal.show_author?).to be(false)
150+
end
151+
152+
it 'preserves show_author when updating other portal fields' do
153+
portal.update!(config: portal.config.merge('show_author' => false))
154+
155+
put "/api/v1/accounts/#{account.id}/portals/#{portal.slug}",
156+
params: { portal: { name: 'renamed_portal' } },
157+
headers: admin.create_new_auth_token,
158+
as: :json
159+
160+
expect(response).to have_http_status(:success)
161+
portal.reload
162+
expect(portal.show_author?).to be(false)
163+
expect(portal.name).to eql('renamed_portal')
164+
end
165+
166+
it 'preserves show_author when updating only allowed_locales' do
167+
portal.update!(config: portal.config.merge('show_author' => false))
168+
169+
put "/api/v1/accounts/#{account.id}/portals/#{portal.slug}",
170+
params: { portal: { config: { allowed_locales: %w[en fr] } } },
171+
headers: admin.create_new_auth_token,
172+
as: :json
173+
174+
expect(response).to have_http_status(:success)
175+
portal.reload
176+
expect(portal.show_author?).to be(false)
135177
end
136178

137179
it 'archive portal' do

0 commit comments

Comments
 (0)