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

PCH Related Posts: Add advanced search #3117

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion build/content-helper/dashboard-widget.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '8c7ccdbe52c4ca11726b');
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '702d33b9b16df125f837');
2 changes: 1 addition & 1 deletion build/content-helper/dashboard-widget.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/content-helper/editor-sidebar-rtl.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/content-helper/editor-sidebar.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '8f1a8e633d9114a34892');
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '7a267e22b7547f9aa284');
2 changes: 1 addition & 1 deletion build/content-helper/editor-sidebar.css

Large diffs are not rendered by default.

35 changes: 12 additions & 23 deletions build/content-helper/editor-sidebar.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/loader.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('wp-hooks', 'wp-i18n'), 'version' => 'b681bb9905652ac12735');
<?php return array('dependencies' => array('wp-hooks', 'wp-i18n'), 'version' => 'ecf94842061bea03d54b');
2 changes: 1 addition & 1 deletion build/loader.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ export interface TitleSuggestionsSettings {
* @since 3.14.3
*/
export interface RelatedPostsSettings {
FilterBy: string;
FilterValue: string;
Metric: Metric;
Open: boolean;
Period: Period;
Expand Down
2 changes: 1 addition & 1 deletion src/content-helper/common/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface AnalyticsApiOptionalQueryParams extends ApiPeriodRange {
limit?: number;
page?: number;
author?: string;
tag?: string;
tag?: string[];
section?: string;
segment?: string;
}
Expand Down
10 changes: 5 additions & 5 deletions src/content-helper/common/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,17 @@ export enum PostFilterType {
Author = 'author',
Section = 'section',
Tag = 'tag',
Unavailable = 'unavailable'
}

/**
* Defines the structure of Post filters.
*
* @since 3.11.0
* @since 3.18.0
*/
export interface PostFilter {
type: PostFilterType;
value: string;
export interface PostFilters {
author: string;
section: string;
tags: string[];
}

/**
Expand Down
11 changes: 1 addition & 10 deletions src/content-helper/editor-sidebar/editor-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import {
} from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import domReady from '@wordpress/dom-ready';
import { PluginSidebar } from '../../@types/gutenberg/wrapper';
import { useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { chartBar as ChartIcon } from '@wordpress/icons';
import { registerPlugin } from '@wordpress/plugins';
import { PluginSidebar } from '../../@types/gutenberg/wrapper';

/**
* Internal dependencies
Expand All @@ -27,7 +27,6 @@ import {
import {
Metric,
Period,
PostFilterType,
isInEnum,
} from '../common/utils/constants';
import { getContentHelperPermissions } from '../common/utils/permissions';
Expand Down Expand Up @@ -79,8 +78,6 @@ export const getSettingsFromJson = ( settingsJson: string = '' ): SidebarSetting
VisibleDataPoints: [ 'views', 'visitors', 'avgEngaged', 'recirculation' ],
},
RelatedPosts: {
FilterBy: PostFilterType.Unavailable,
FilterValue: '',
Metric: Metric.Views,
Open: false,
Period: Period.Days7,
Expand Down Expand Up @@ -136,12 +133,6 @@ export const getSettingsFromJson = ( settingsJson: string = '' ): SidebarSetting
if ( typeof mergedSettings.RelatedPosts !== 'object' ) {
mergedSettings.RelatedPosts = defaultSettings.RelatedPosts;
}
if ( ! isInEnum( mergedSettings.RelatedPosts.FilterBy, PostFilterType ) ) {
mergedSettings.RelatedPosts.FilterBy = defaultSettings.RelatedPosts.FilterBy;
}
if ( typeof mergedSettings.RelatedPosts.FilterValue !== 'string' ) {
mergedSettings.RelatedPosts.FilterValue = defaultSettings.RelatedPosts.FilterValue;
}
if ( ! isInEnum( mergedSettings.RelatedPosts.Metric, Metric ) ) {
mergedSettings.RelatedPosts.Metric = defaultSettings.RelatedPosts.Metric;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,151 +3,25 @@
*/
import {
ComboboxControl,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
FormTokenField,
} from '@wordpress/components';
import { ComboboxControlOption } from '@wordpress/components/build-types/combobox-control/types';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { PostFilter, PostFilterType } from '../../common/utils/constants';
import { __ } from '@wordpress/i18n';
import { PostFilters, PostFilterType } from '../../common/utils/constants';
import { SidebarPostData } from '../editor-sidebar';

/**
* Defines the props structure for FilterTypes.
*
* @since 3.14.0
*/
type FilterTypesProps = {
filter: PostFilter;
label?: string;
onFilterTypeChange: ( selection: string ) => void;
postData: SidebarPostData;
};

/**
* Returns the filter types ToggleGroupControl component.
*
* @since 3.14.0
*
* @param {FilterTypesProps} props The component's props.
*/
const FilterTypes = (
{ filter, label, postData, ...props }: Readonly<FilterTypesProps>
): React.JSX.Element => {
return (
<div className="related-posts-filter-types">
<ToggleGroupControl
__nextHasNoMarginBottom
__next40pxDefaultSize
label={ label ? label : __( 'Filter by', 'wp-parsely' ) }
value={ filter.type }
onChange={ ( value ) => props.onFilterTypeChange( value as string ) }
isBlock
>
{ postData.tags.length >= 1 && (
<ToggleGroupControlOption
value={ PostFilterType.Tag }
label={ __( 'Tag', 'wp-parsely' ) }
/>
) }
{ postData.categories.length >= 1 && (
<ToggleGroupControlOption
value={ PostFilterType.Section }
label={ __( 'Section', 'wp-parsely' ) }
/>
) }
{ postData.authors.length >= 1 && (
<ToggleGroupControlOption
value={ PostFilterType.Author }
label={ __( 'Author', 'wp-parsely' ) }
/>
) }
</ToggleGroupControl>
</div>
);
};

/**
* Defines the props structure for FilterValues.
*
* @since 3.14.0
*/
type FilterValuesProps = {
filter: PostFilter;
label?: string;
onFilterValueChange: ( selection: string | null | undefined ) => void;
postData: SidebarPostData;
}

/**
* Returns the filter values ComboboxControl component.
*
* @since 3.14.0
*
* @param {FilterValuesProps} props The component's props.
*/
const FilterValues = ( {
filter,
label,
postData,
...props
}: Readonly<FilterValuesProps> ): React.JSX.Element => {
/**
* Returns the options that will populate the ComboboxControl.
*
* @since 3.11.0
*
* @return {ComboboxControlOption[]} The resulting ComboboxControl options.
*/
const getOptions = (): ComboboxControlOption[] => {
if ( PostFilterType.Tag === filter.type ) {
return postData.tags.map( ( tag: string ) => ( {
value: tag, label: tag,
} ) );
}

if ( PostFilterType.Section === filter.type ) {
return postData.categories.map( ( section: string ) => ( {
value: section, label: section,
} ) );
}

if ( PostFilterType.Author === filter.type ) {
return postData.authors.map( ( author: string ) => ( {
value: author, label: author,
} ) );
}

return [];
};

return (
<div className="related-posts-filter-values">
<ComboboxControl
__next40pxDefaultSize
allowReset={ true }
label={ label }
onChange={ ( selection ) => props.onFilterValueChange( selection ) }
options={ getOptions() }
value={ filter.value }
/>
</div>
);
};

/**
* Defines the props structure for FilterControls.
*
* @since 3.14.0
*/
type FilterControlsProps = {
filter: PostFilter;
filters: PostFilters;
label?: string;
onFilterTypeChange: ( selection: string ) => void;
onFilterValueChange: ( selection: string | null | undefined ) => void;
onFiltersChange: ( selection: string | null | undefined, type:PostFilterType ) => void;
postData: SidebarPostData;
}

Expand All @@ -159,67 +33,65 @@ type FilterControlsProps = {
* @param {FilterControlsProps} props The component's props.
*/
export const RelatedPostsFilterSettings = ( {
filter,
filters,
postData,
label,
...props
}: Readonly<FilterControlsProps> ): React.JSX.Element | null => {
/**
* Returns whether the filter settings should be displayed.
*
* @since 3.14.4
*
* @return {boolean} Whether the filter settings should be displayed.
*/
const shouldDisplayFilterTypes = (): boolean => {
// Display only when there is data for at least two filters.
return ( postData.authors.length > 0 && postData.categories.length > 0 ) ||
( postData.authors.length > 0 && postData.tags.length > 0 ) ||
( postData.tags.length > 0 && postData.categories.length > 0 )
;
};

/**
* Returns whether the filter values ComboboxControl should be displayed.
*
* @since 3.11.0
*
* @return {boolean} Whether to display the filter values ComboboxControl.
*/
const shouldDisplayFilterValues = (): boolean => {
if (
( PostFilterType.Tag === filter.type && postData.tags.length > 1 ) ||
( PostFilterType.Section === filter.type && postData.categories.length > 1 ) ||
( PostFilterType.Author === filter.type && postData.authors.length > 1 )
) {
return true;
}

return false;
};

if ( ! shouldDisplayFilterTypes() && ! shouldDisplayFilterValues() ) {
if ( 0 === postData.authors.length &&
0 === postData.categories.length &&
0 === postData.tags.length
) {
return null;
}

const authorOptions = postData.authors.map( ( author: string ) => ( {
value: author, label: author,
} ) );

const sectionOptions = postData.categories.map( ( section: string ) => ( {
value: section, label: section,
} ) );

return (
<div className="related-posts-filter-settings">
{ shouldDisplayFilterTypes() &&
<FilterTypes
filter={ filter }
label={ label }
onFilterTypeChange={ props.onFilterTypeChange }
postData={ postData }
{ postData.authors.length >= 1 && (
<ComboboxControl
__next40pxDefaultSize
allowReset={ true }
placeholder={ __( 'Author', 'wp-parsely' ) }
onChange={ ( selection ) => props.onFiltersChange(
selection, PostFilterType.Author
) }
options={ authorOptions }
value={ filters.author }
/>
) }
{ postData.categories.length >= 1 && (
<ComboboxControl
__next40pxDefaultSize
allowReset={ true }
placeholder={ __( 'Section', 'wp-parsely' ) }
onChange={ ( selection ) => props.onFiltersChange(
selection, PostFilterType.Section
) }
options={ sectionOptions }
value={ filters.section }
/>
}
{ shouldDisplayFilterValues() &&
<FilterValues
filter={ filter }
label={ ! shouldDisplayFilterTypes() ? label : undefined }
onFilterValueChange={ props.onFilterValueChange }
postData={ postData }
) }
{ postData.tags.length >= 1 && (
<FormTokenField
__experimentalShowHowTo={ false } // Hide help text.
__next40pxDefaultSize
label={ '' } // Hide label.
placeholder={ __( 'Tags', 'wp-parsely' ) }
onChange={ ( selection ) => props.onFiltersChange(
selection.toString(), PostFilterType.Tag
) }
value={ filters.tags }
suggestions={ postData.tags }
maxLength={ 5 }
/>
}
) }
</div>
);
};
Loading
Loading