From 2fb90c5602875b001836b1564a93b1c5993c5aff Mon Sep 17 00:00:00 2001 From: JiveDig Date: Fri, 29 Dec 2023 10:46:55 -0500 Subject: [PATCH 001/118] Adds filter for facet the block editor for posts For https://github.com/10up/ElasticPress/issues/3775 --- includes/classes/Feature/Facets/Facets.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/includes/classes/Feature/Facets/Facets.php b/includes/classes/Feature/Facets/Facets.php index 7e7ee46e77..ba237b2e82 100644 --- a/includes/classes/Feature/Facets/Facets.php +++ b/includes/classes/Feature/Facets/Facets.php @@ -111,12 +111,23 @@ public function __construct() { public function setup() { global $pagenow; - // This feature should not run while in the editor. - if ( in_array( $pagenow, [ 'post-new.php', 'post.php' ], true ) ) { - return; - } - foreach ( $this->types as $type => $class ) { + /** + * Filter if facet should be enabled in the editor. + * + * @hook ep_facet_enabled_in_editor + * @since TBD + * @param {bool} $enabled If enabled + * @param {string} $type The facet type + * @return {bool} If enabled or not + */ + $enabled = apply_filters( 'ep_facet_enabled_in_editor', false, $type ); + + // Skip if this feature should not run while in the post editor. + if ( in_array( $pagenow, [ 'post-new.php', 'post.php' ], true ) && ! $enabled ) { + continue; + } + $this->types[ $type ]->setup(); } From e6b329e4706079864073ce9c0d0ea35fe919fb20 Mon Sep 17 00:00:00 2001 From: Mike Hemberger Date: Fri, 29 Dec 2023 10:59:51 -0500 Subject: [PATCH 002/118] Typecast variable --- includes/classes/Feature/Facets/Facets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/classes/Feature/Facets/Facets.php b/includes/classes/Feature/Facets/Facets.php index ba237b2e82..14ab0957c3 100644 --- a/includes/classes/Feature/Facets/Facets.php +++ b/includes/classes/Feature/Facets/Facets.php @@ -124,7 +124,7 @@ public function setup() { $enabled = apply_filters( 'ep_facet_enabled_in_editor', false, $type ); // Skip if this feature should not run while in the post editor. - if ( in_array( $pagenow, [ 'post-new.php', 'post.php' ], true ) && ! $enabled ) { + if ( in_array( $pagenow, [ 'post-new.php', 'post.php' ], true ) && ! (bool) $enabled ) { continue; } From 23f8b07220cae908d81c70514897004cbe31af36 Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Wed, 3 Jan 2024 16:37:11 +1100 Subject: [PATCH 003/118] WIP: Updated synonyms UI. --- assets/js/synonyms/apps/synonyms-settings.js | 132 ++++++++ .../js/synonyms/components/SynonymsEditor.js | 127 -------- .../synonyms/components/editors/SolrEditor.js | 61 ++-- assets/js/synonyms/components/hyponyms.js | 197 ++++++++++++ .../js/synonyms/components/list-table-row.js | 68 ++++ assets/js/synonyms/components/list-table.js | 142 ++++++++ assets/js/synonyms/components/replacements.js | 236 ++++++++++++++ .../synonyms/components/shared/edit-panel.js | 24 ++ assets/js/synonyms/components/shared/tab.js | 22 ++ assets/js/synonyms/components/synonyms.js | 157 +++++++++ assets/js/synonyms/config.js | 15 + assets/js/synonyms/context.js | 31 -- assets/js/synonyms/index.js | 36 ++- assets/js/synonyms/provider.js | 302 ++++++++++++++++++ assets/js/synonyms/reducers/editorReducer.js | 145 --------- assets/js/synonyms/style.css | 76 +++++ assets/js/synonyms/utils.js | 2 +- includes/classes/Feature/Search/Synonyms.php | 8 + 18 files changed, 1428 insertions(+), 353 deletions(-) create mode 100644 assets/js/synonyms/apps/synonyms-settings.js delete mode 100644 assets/js/synonyms/components/SynonymsEditor.js create mode 100644 assets/js/synonyms/components/hyponyms.js create mode 100644 assets/js/synonyms/components/list-table-row.js create mode 100644 assets/js/synonyms/components/list-table.js create mode 100644 assets/js/synonyms/components/replacements.js create mode 100644 assets/js/synonyms/components/shared/edit-panel.js create mode 100644 assets/js/synonyms/components/shared/tab.js create mode 100644 assets/js/synonyms/components/synonyms.js create mode 100644 assets/js/synonyms/config.js delete mode 100644 assets/js/synonyms/context.js create mode 100644 assets/js/synonyms/provider.js delete mode 100644 assets/js/synonyms/reducers/editorReducer.js create mode 100644 assets/js/synonyms/style.css diff --git a/assets/js/synonyms/apps/synonyms-settings.js b/assets/js/synonyms/apps/synonyms-settings.js new file mode 100644 index 0000000000..3548c131fc --- /dev/null +++ b/assets/js/synonyms/apps/synonyms-settings.js @@ -0,0 +1,132 @@ +/** + * WordPress dependencies. + */ +import { Button, Panel, PanelBody, PanelHeader, TabPanel } from '@wordpress/components'; +import { WPElement } from '@wordpress/element'; + +import { __, sprintf } from '@wordpress/i18n'; + +/** + * Internal dependencies. + */ +import { useSynonymsSettings } from '../provider'; +import Tab from '../components/shared/tab'; +import Hyponyms from '../components/hyponyms'; +import Replacements from '../components/replacements'; +import SolrEditor from '../components/editors/SolrEditor'; +import Synonyms from '../components/synonyms'; + +/** + * Synonyms editor component. + * + * @returns {WPElement} Synonyms editor component. + */ +const SynonymsEditor = () => { + const { hyponyms, isSolr, replacements, synonyms, switchEditor } = useSynonymsSettings(); + + /** + * Handle clicking the editor switch button. + * + * @returns {void} + */ + const onClick = () => { + switchEditor(); + }; + + /** + * Handles submitting the form. + * + * @returns {void} + */ + const onSubmit = () => { + return null; + }; + + /** + * Tabs. + */ + const tabs = [ + { + name: 'synonyms', + title: ( + !s.valid)}> + {sprintf(__('Synonyms (%d)', 'elasticpress'), synonyms.length)} + + ), + }, + { + name: 'hyponyms', + title: ( + !s.valid)}> + {sprintf(__('Hyponyms (%d)', 'elasticpress'), hyponyms.length)} + + ), + }, + { + name: 'replacements', + title: ( + !s.valid)}> + {sprintf(__('Replacements (%d)', 'elasticpress'), replacements.length)} + + ), + }, + ]; + + return ( + <> + + +

+ {__( + 'Synonyms enable more flexible search results that show relevant results even without an exact match. Synonyms can be defined as a sets where all words are synonyms for each other, or as alternatives where searches for the primary word will also match the rest, but no vice versa.', + 'elasticpress', + )} +

+ + {!isSolr ? ( + + + + {({ name }) => { + switch (name) { + case 'hyponyms': + return ; + case 'replacements': + return ; + case 'synonyms': + default: + return ; + } + }} + + + + ) : ( + + +

{__('Advanced Synonym Editor', 'elasticpress')}

+
+ +

+ {__( + "When you add Sets and Alternatives above, we reduce them to SolrSynonyms which Elasticsearch can understand. If you are an advanced user, you can edit synonyms directly using Solr synonym formatting. This is beneficial if you want to import a large dictionary of synonyms, or want to export this site's synonyms for use on another site.", + 'elasticpress', + )} +

+ +
+
+ )} + + + + ); +}; + +export default SynonymsEditor; diff --git a/assets/js/synonyms/components/SynonymsEditor.js b/assets/js/synonyms/components/SynonymsEditor.js deleted file mode 100644 index 16de25e638..0000000000 --- a/assets/js/synonyms/components/SynonymsEditor.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * WordPress dependencies. - */ -import { useContext, useEffect, WPElement } from '@wordpress/element'; - -/** - * Internal dependencies. - */ -import { State, Dispatch } from '../context'; -import AlterativesEditor from './editors/AlternativesEditor'; -import SetsEditor from './editors/SetsEditor'; -import SolrEditor from './editors/SolrEditor'; - -/** - * Synonyms editor component. - * - * @returns {WPElement} Synonyms component - */ -const SynonymsEditor = () => { - const state = useContext(State); - const dispatch = useContext(Dispatch); - const { alternatives, sets, isSolrEditable, isSolrVisible, dirty, submit } = state; - const { - pageHeading, - pageDescription, - pageToggleAdvanceText, - pageToggleSimpleText, - alternativesTitle, - alternativesDescription, - setsTitle, - setsDescription, - solrTitle, - solrDescription, - submitText, - } = window.epSynonyms.i18n; - - /** - * Checks if the form is valid. - * - * @param {object} _state Current state. - * @returns {boolean} If the form is valid - */ - const isValid = (_state) => { - return [..._state.sets, ..._state.alternatives].reduce((valid, item) => { - return !valid ? valid : item.valid; - }, true); - }; - - /** - * Handles submitting the form. - */ - const handleSubmit = () => { - if (isSolrEditable) { - dispatch({ type: 'REDUCE_SOLR_TO_STATE' }); - } - - dispatch({ type: 'VALIDATE_ALL' }); - dispatch({ type: 'REDUCE_STATE_TO_SOLR' }); - dispatch({ type: 'SUBMIT' }); - }; - - /** - * Handle toggling the editor type. - */ - const handleToggleAdvance = () => { - if (isSolrEditable) { - dispatch({ type: 'REDUCE_SOLR_TO_STATE' }); - } else { - dispatch({ type: 'REDUCE_STATE_TO_SOLR' }); - } - - dispatch({ type: 'SET_SOLR_EDITABLE', data: !isSolrEditable }); - }; - - useEffect(() => { - if (submit && !dirty && isValid(state)) { - document.querySelector('.wrap form').submit(); - } - }, [submit, dirty, state]); - - return ( - <> -

- {pageHeading}{' '} - -

-

{pageDescription}

- - {!isSolrEditable && ( - <> -
-

{`${setsTitle} (${sets.length})`}

-

{setsDescription}

- -
-
-

{`${alternativesTitle} (${alternatives.length})`}

-

{alternativesDescription}

- -
- - )} - -
- {isSolrVisible &&

{solrTitle}

} - {isSolrVisible &&

{solrDescription}

} - -
- - - -
- -
- - ); -}; - -export default SynonymsEditor; diff --git a/assets/js/synonyms/components/editors/SolrEditor.js b/assets/js/synonyms/components/editors/SolrEditor.js index 1631f58a67..b713e7fc9b 100644 --- a/assets/js/synonyms/components/editors/SolrEditor.js +++ b/assets/js/synonyms/components/editors/SolrEditor.js @@ -1,12 +1,14 @@ /** * WordPress dependencies. */ -import { useContext, WPElement } from '@wordpress/element'; +import { TextareaControl } from '@wordpress/components'; +import { WPElement } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies. */ -import { State, Dispatch } from '../../context'; +import { useSynonymsSettings } from '../../provider'; /** * Synonym Inspector @@ -14,47 +16,24 @@ import { State, Dispatch } from '../../context'; * @returns {WPElement} SolrEditor Component */ const SolrEditor = () => { - const state = useContext(State); - const dispatch = useContext(Dispatch); - const { alternatives, isSolrEditable, isSolrVisible, sets, solr } = state; - const { - synonymsTextareaInputName, - solrInputHeading, - solrAlternativesErrorMessage, - solrSetsErrorMessage, - } = window.epSynonyms.i18n; + const { solr, updateSolr } = useSynonymsSettings(); + + /** + * Handle changes to the Solr synonyms value. + * + * @param {Event} value Textarea control value. + */ + const onChange = (value) => { + updateSolr(value); + }; return ( -
-
-

- {solrInputHeading} -

-
-