mirror of
https://github.com/astuto/astuto.git
synced 2025-12-15 19:27:52 +01:00
Add setting to show in filter by status only statuses present in board posts (#411)
This commit is contained in:
committed by
GitHub
parent
675a8709ef
commit
cab2229e09
@@ -4,4 +4,8 @@
|
||||
|
||||
scroll-margin-top: 96px;
|
||||
}
|
||||
|
||||
.generalSiteSettingsSubmit {
|
||||
@extend .mb-4;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
class BoardsController < ApplicationController
|
||||
include ApplicationHelper
|
||||
include BoardsHelper
|
||||
|
||||
before_action :authenticate_user!, only: [:create, :update, :update_order, :destroy]
|
||||
|
||||
@@ -12,6 +13,7 @@ class BoardsController < ApplicationController
|
||||
def show
|
||||
@board = Board.friendly.find(params[:id])
|
||||
@page_title = @board.name
|
||||
@post_statuses_to_show_in_filter = get_post_statuses_to_show_in_filter
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
class StaticPagesController < ApplicationController
|
||||
include BoardsHelper
|
||||
|
||||
skip_before_action :load_tenant_data, only: [:showcase, :pending_tenant, :blocked_tenant]
|
||||
before_action :allow_iframe_embedding, only: [:embedded_roadmap]
|
||||
|
||||
@@ -7,6 +9,7 @@ class StaticPagesController < ApplicationController
|
||||
|
||||
if @board
|
||||
@page_title = @board.name
|
||||
@post_statuses_to_show_in_filter = get_post_statuses_to_show_in_filter
|
||||
render 'boards/show'
|
||||
else
|
||||
@page_title = t('roadmap.title')
|
||||
|
||||
9
app/helpers/boards_helper.rb
Normal file
9
app/helpers/boards_helper.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
module BoardsHelper
|
||||
def get_post_statuses_to_show_in_filter
|
||||
if Current.tenant.tenant_setting.hide_unused_statuses_in_filter_by_status
|
||||
@board.posts.map(&:post_status_id).uniq
|
||||
else
|
||||
PostStatus.pluck(:id) << nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -23,6 +23,7 @@ interface Props {
|
||||
currentUserFullName: string;
|
||||
tenantSetting: ITenantSetting;
|
||||
componentRenderedAt: number;
|
||||
postStatusesToShowInFilter: Array<number>;
|
||||
authenticityToken: string;
|
||||
posts: PostsState;
|
||||
postStatuses: PostStatusesState;
|
||||
@@ -96,6 +97,7 @@ class BoardP extends React.Component<Props> {
|
||||
currentUserFullName,
|
||||
tenantSetting,
|
||||
componentRenderedAt,
|
||||
postStatusesToShowInFilter,
|
||||
authenticityToken,
|
||||
posts,
|
||||
postStatuses,
|
||||
@@ -140,14 +142,19 @@ class BoardP extends React.Component<Props> {
|
||||
/>
|
||||
</>
|
||||
}
|
||||
<PostStatusFilter
|
||||
postStatuses={postStatuses.items}
|
||||
areLoading={postStatuses.areLoading}
|
||||
error={postStatuses.error}
|
||||
{
|
||||
postStatusesToShowInFilter.length > 0 &&
|
||||
<PostStatusFilter
|
||||
postStatuses={postStatuses.items.filter(postStatus => postStatusesToShowInFilter.includes(postStatus.id))}
|
||||
areLoading={postStatuses.areLoading}
|
||||
error={postStatuses.error}
|
||||
|
||||
currentFilter={filters.postStatusIds}
|
||||
handleFilterClick={handlePostStatusFilterChange}
|
||||
/>
|
||||
currentFilter={filters.postStatusIds}
|
||||
handleFilterClick={handlePostStatusFilterChange}
|
||||
|
||||
showNoStatusFilter={postStatusesToShowInFilter.includes(null)}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
{ tenantSetting.show_powered_by && <PoweredByLink /> }
|
||||
|
||||
@@ -15,6 +15,8 @@ interface Props {
|
||||
|
||||
handleFilterClick(postStatusId: number): void;
|
||||
currentFilter: Array<number>;
|
||||
|
||||
showNoStatusFilter?: boolean;
|
||||
}
|
||||
|
||||
const PostStatusFilter = ({
|
||||
@@ -24,6 +26,8 @@ const PostStatusFilter = ({
|
||||
|
||||
handleFilterClick,
|
||||
currentFilter,
|
||||
|
||||
showNoStatusFilter = true,
|
||||
}: Props) => (
|
||||
<SidebarBox title={I18n.t('board.filter_box.title')} customClass="postStatusFilterContainer">
|
||||
{
|
||||
@@ -39,13 +43,18 @@ const PostStatusFilter = ({
|
||||
/>
|
||||
))
|
||||
}
|
||||
<PostStatusListItem
|
||||
name={I18n.t('common.no_status')}
|
||||
color='black'
|
||||
|
||||
handleClick={() => handleFilterClick(0)}
|
||||
isCurrentFilter={currentFilter.includes(0)}
|
||||
/>
|
||||
{
|
||||
showNoStatusFilter &&
|
||||
<PostStatusListItem
|
||||
name={I18n.t('common.no_status')}
|
||||
color='black'
|
||||
|
||||
handleClick={() => handleFilterClick(0)}
|
||||
isCurrentFilter={currentFilter.includes(0)}
|
||||
/>
|
||||
}
|
||||
|
||||
{ areLoading ? <Spinner /> : null }
|
||||
{ error ? <DangerText>{error}</DangerText> : null }
|
||||
</SidebarBox>
|
||||
|
||||
@@ -17,6 +17,7 @@ interface Props {
|
||||
currentUserFullName: string;
|
||||
tenantSetting: ITenantSetting;
|
||||
componentRenderedAt: number;
|
||||
postStatusesToShowInFilter: Array<number>;
|
||||
authenticityToken: string;
|
||||
}
|
||||
|
||||
@@ -37,6 +38,7 @@ class BoardRoot extends React.Component<Props> {
|
||||
currentUserFullName,
|
||||
tenantSetting,
|
||||
componentRenderedAt,
|
||||
postStatusesToShowInFilter,
|
||||
authenticityToken,
|
||||
} = this.props;
|
||||
|
||||
@@ -49,6 +51,7 @@ class BoardRoot extends React.Component<Props> {
|
||||
currentUserFullName={currentUserFullName}
|
||||
tenantSetting={tenantSetting}
|
||||
componentRenderedAt={componentRenderedAt}
|
||||
postStatusesToShowInFilter={postStatusesToShowInFilter}
|
||||
authenticityToken={authenticityToken}
|
||||
/>
|
||||
</Provider>
|
||||
|
||||
@@ -40,6 +40,7 @@ export interface ISiteSettingsGeneralForm {
|
||||
collapseBoardsInHeader: string;
|
||||
showVoteCount: boolean;
|
||||
showVoteButtonInBoard: boolean;
|
||||
hideUnusedStatusesInFilterByStatus: boolean;
|
||||
showPoweredBy: boolean;
|
||||
}
|
||||
|
||||
@@ -69,6 +70,7 @@ interface Props {
|
||||
collapseBoardsInHeader: string,
|
||||
showVoteCount: boolean,
|
||||
showVoteButtonInBoard: boolean,
|
||||
hideUnusedStatusesInFilterByStatus: boolean,
|
||||
showPoweredBy: boolean,
|
||||
authenticityToken: string
|
||||
): Promise<any>;
|
||||
@@ -107,6 +109,7 @@ const GeneralSiteSettingsP = ({
|
||||
collapseBoardsInHeader: originForm.collapseBoardsInHeader,
|
||||
showVoteCount: originForm.showVoteCount,
|
||||
showVoteButtonInBoard: originForm.showVoteButtonInBoard,
|
||||
hideUnusedStatusesInFilterByStatus: originForm.hideUnusedStatusesInFilterByStatus,
|
||||
showPoweredBy: originForm.showPoweredBy,
|
||||
},
|
||||
});
|
||||
@@ -129,6 +132,7 @@ const GeneralSiteSettingsP = ({
|
||||
data.collapseBoardsInHeader,
|
||||
data.showVoteCount,
|
||||
data.showVoteButtonInBoard,
|
||||
data.hideUnusedStatusesInFilterByStatus,
|
||||
data.showPoweredBy,
|
||||
authenticityToken
|
||||
).then(res => {
|
||||
@@ -344,7 +348,7 @@ const GeneralSiteSettingsP = ({
|
||||
className="selectPicker"
|
||||
>
|
||||
<option value={TENANT_SETTING_LOGO_LINKS_TO_ROOT_PAGE}>
|
||||
{ I18n.t('site_settings.general.logo_links_to_root_page') }
|
||||
{ I18n.t('site_settings.general.logo_links_to_root_page') } ({watch('rootBoardId') === '0' ? I18n.t('roadmap.title') : boards.find(board => board.id === Number(watch('rootBoardId')))?.name})
|
||||
</option>
|
||||
<option value={TENANT_SETTING_LOGO_LINKS_TO_CUSTOM_URL}>
|
||||
{ I18n.t('site_settings.general.logo_links_to_custom_url') }
|
||||
@@ -414,6 +418,16 @@ const GeneralSiteSettingsP = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="formGroup">
|
||||
<div className="checkboxSwitch">
|
||||
<input {...register('hideUnusedStatusesInFilterByStatus')} type="checkbox" id="hide_unused_statuses_in_filter_by_status_checkbox" />
|
||||
<label htmlFor="hide_unused_statuses_in_filter_by_status_checkbox">{ getLabel('tenant_setting', 'hide_unused_statuses_in_filter_by_status') }</label>
|
||||
<SmallMutedText>
|
||||
{ I18n.t('site_settings.general.hide_unused_statuses_in_filter_by_status_help') }
|
||||
</SmallMutedText>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="formGroup">
|
||||
<div className="checkboxSwitch">
|
||||
<input {...register('showPoweredBy')} type="checkbox" id="show_powered_by_checkbox" />
|
||||
@@ -424,7 +438,7 @@ const GeneralSiteSettingsP = ({
|
||||
|
||||
<br />
|
||||
|
||||
<Button onClick={() => null} disabled={!isDirty}>
|
||||
<Button onClick={() => null} disabled={!isDirty} className="generalSiteSettingsSubmit">
|
||||
{I18n.t('common.buttons.update')}
|
||||
</Button>
|
||||
</form>
|
||||
@@ -445,4 +459,4 @@ const GeneralSiteSettingsP = ({
|
||||
);
|
||||
}
|
||||
|
||||
export default GeneralSiteSettingsP;
|
||||
export default GeneralSiteSettingsP;
|
||||
@@ -33,6 +33,7 @@ const mapDispatchToProps = (dispatch: any) => ({
|
||||
collapseBoardsInHeader: TenantSettingCollapseBoardsInHeader,
|
||||
showVoteCount: boolean,
|
||||
showVoteButtonInBoard: boolean,
|
||||
hideUnusedStatusesInFilterByStatus: boolean,
|
||||
showPoweredBy: boolean,
|
||||
authenticityToken: string
|
||||
): Promise<any> {
|
||||
@@ -52,6 +53,7 @@ const mapDispatchToProps = (dispatch: any) => ({
|
||||
collapse_boards_in_header: collapseBoardsInHeader,
|
||||
show_vote_count: showVoteCount,
|
||||
show_vote_button_in_board: showVoteButtonInBoard,
|
||||
hide_unused_statuses_in_filter_by_status: hideUnusedStatusesInFilterByStatus,
|
||||
show_powered_by: showPoweredBy,
|
||||
},
|
||||
locale,
|
||||
|
||||
@@ -61,6 +61,7 @@ interface ITenantSetting {
|
||||
show_vote_count?: boolean;
|
||||
show_vote_button_in_board?: boolean;
|
||||
show_roadmap_in_header?: boolean;
|
||||
hide_unused_statuses_in_filter_by_status?: boolean;
|
||||
show_powered_by?: boolean;
|
||||
collapse_boards_in_header?: TenantSettingCollapseBoardsInHeader;
|
||||
logo_links_to?: TenantSettingLogoLinksTo;
|
||||
|
||||
@@ -12,12 +12,13 @@ class TenantSettingPolicy < ApplicationPolicy
|
||||
:feedback_approval_policy,
|
||||
:show_vote_count,
|
||||
:show_vote_button_in_board,
|
||||
:hide_unused_statuses_in_filter_by_status,
|
||||
:show_powered_by,
|
||||
:logo_links_to,
|
||||
:logo_custom_url,
|
||||
:show_roadmap_in_header,
|
||||
:collapse_boards_in_header,
|
||||
:custom_css
|
||||
:custom_css,
|
||||
]
|
||||
else
|
||||
[]
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
currentUserFullName: user_signed_in? ? current_user.full_name_or_email : '',
|
||||
tenantSetting: @tenant_setting,
|
||||
componentRenderedAt: Time.now.to_i,
|
||||
postStatusesToShowInFilter: @post_statuses_to_show_in_filter,
|
||||
authenticityToken: form_authenticity_token
|
||||
}
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
brandDisplaySetting: @tenant_setting.brand_display,
|
||||
showVoteCount: @tenant_setting.show_vote_count,
|
||||
showVoteButtonInBoard: @tenant_setting.show_vote_button_in_board,
|
||||
hideUnusedStatusesInFilterByStatus: @tenant_setting.hide_unused_statuses_in_filter_by_status,
|
||||
showPoweredBy: @tenant_setting.show_powered_by,
|
||||
rootBoardId: @tenant_setting.root_board_id.to_s,
|
||||
customDomain: @tenant.custom_domain,
|
||||
|
||||
@@ -133,6 +133,7 @@ en:
|
||||
feedback_approval_policy: 'Feedback approval policy'
|
||||
show_vote_count: 'Show vote count to users'
|
||||
show_vote_button_in_board: 'Show vote buttons in board page'
|
||||
hide_unused_statuses_in_filter_by_status: 'Hide unused statuses in filter by status'
|
||||
show_powered_by: 'Show "Powered by Astuto"'
|
||||
root_board_id: 'Root page'
|
||||
logo_links_to: 'Logo links to'
|
||||
|
||||
@@ -206,6 +206,7 @@ en:
|
||||
custom_domain_learn_more: 'Learn how to configure a custom domain'
|
||||
show_vote_count_help: 'If you enable this setting, users will be able to see the vote count of posts. This may incentivize users to vote on already popular posts, leading to a snowball effect.'
|
||||
show_vote_button_in_board_help: 'If you enable this setting, users will be able to vote posts from the board page. This may incentivize users to vote on more posts, leading to a higher number of votes but of lower significance.'
|
||||
hide_unused_statuses_in_filter_by_status_help: 'If you enable this setting, only statuses that are assigned to at least one post in that board will be shown in the filter by status sidebar filter.'
|
||||
boards:
|
||||
title: 'Boards'
|
||||
empty: 'There are no boards. Create one below!'
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddHideUnusedStatusesInFilterByStatusToTenantSettings < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :tenant_settings, :hide_unused_statuses_in_filter_by_status, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2024_09_16_140807) do
|
||||
ActiveRecord::Schema.define(version: 2024_09_17_140122) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -185,6 +185,7 @@ ActiveRecord::Schema.define(version: 2024_09_16_140807) do
|
||||
t.boolean "use_browser_locale", default: false, null: false
|
||||
t.integer "logo_links_to", default: 0, null: false
|
||||
t.string "logo_custom_url"
|
||||
t.boolean "hide_unused_statuses_in_filter_by_status", default: false, null: false
|
||||
t.index ["tenant_id"], name: "index_tenant_settings_on_tenant_id"
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user