Skip to content

Commit

Permalink
Merge pull request #3814 from 10up/feature/synonyms
Browse files Browse the repository at this point in the history
Updated Synonyms UI
  • Loading branch information
felipeelia committed Apr 12, 2024
2 parents 1fcc214 + 54f26d1 commit 2dadd92
Show file tree
Hide file tree
Showing 40 changed files with 2,526 additions and 957 deletions.
15 changes: 8 additions & 7 deletions .wp-env.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,26 @@
],
"mappings": {
".htaccess": "./tests/cypress/wordpress-files/.htaccess",
"wp-content/mu-plugins/disable-welcome-guide.php": "./tests/cypress/wordpress-files/test-mu-plugins/disable-welcome-guide.php",
"wp-content/mu-plugins/skip-wp-lookup.php": "./tests/cypress/wordpress-files/test-mu-plugins/skip-wp-lookup.php",
"wp-content/mu-plugins/unique-index-name.php": "./tests/cypress/wordpress-files/test-mu-plugins/unique-index-name.php",
"wp-content/plugins/auto-meta-mode.php": "./tests/cypress/wordpress-files/test-plugins/auto-meta-mode.php",
"wp-content/mu-plugins/disable-welcome-guide.php": "./tests/cypress/wordpress-files/test-mu-plugins/disable-welcome-guide.php",
"wp-content/plugins/cpt-and-custom-tax.php": "./tests/cypress/wordpress-files/test-plugins/cpt-and-custom-tax.php",
"wp-content/plugins/custom-instant-results-template.php": "./tests/cypress/wordpress-files/test-plugins/custom-instant-results-template.php",
"wp-content/plugins/custom-headers-for-autosuggest.php": "./tests/cypress/wordpress-files/test-plugins/custom-headers-for-autosuggest.php",
"wp-content/plugins/fake-new-activation.php": "./tests/cypress/wordpress-files/test-plugins/fake-new-activation.php",
"wp-content/plugins/open-instant-results-with-buttons.php": "./tests/cypress/wordpress-files/test-plugins/open-instant-results-with-buttons.php",
"wp-content/plugins/unsupported-server-software.php": "./tests/cypress/wordpress-files/test-plugins/unsupported-server-software.php",
"wp-content/plugins/unsupported-elasticsearch-version.php": "./tests/cypress/wordpress-files/test-plugins/unsupported-elasticsearch-version.php",
"wp-content/plugins/shorten-autosave.php": "./tests/cypress/wordpress-files/test-plugins/shorten-autosave.php",
"wp-content/plugins/fake-log-messages.php": "./tests/cypress/wordpress-files/test-plugins/fake-log-messages.php",
"wp-content/plugins/disable-fuzziness.php": "./tests/cypress/wordpress-files/test-plugins/disable-fuzziness.php",
"wp-content/plugins/enable-debug-bar.php": "./tests/cypress/wordpress-files/test-plugins/enable-debug-bar.php",
"wp-content/plugins/fake-log-messages.php": "./tests/cypress/wordpress-files/test-plugins/fake-log-messages.php",
"wp-content/plugins/fake-new-activation.php": "./tests/cypress/wordpress-files/test-plugins/fake-new-activation.php",
"wp-content/plugins/filter-instant-results-per-page.php": "./tests/cypress/wordpress-files/test-plugins/filter-instant-results-per-page.php",
"wp-content/plugins/filter-instant-results-args-schema.php": "./tests/cypress/wordpress-files/test-plugins/filter-instant-results-args-schema.php",
"wp-content/plugins/filter-autosuggest-navigate-callback.php": "./tests/cypress/wordpress-files/test-plugins/filter-autosuggest-navigate-callback.php",
"wp-content/plugins/open-instant-results-with-buttons.php": "./tests/cypress/wordpress-files/test-plugins/open-instant-results-with-buttons.php",
"wp-content/plugins/shorten-autosave.php": "./tests/cypress/wordpress-files/test-plugins/shorten-autosave.php",
"wp-content/plugins/show-comments-and-terms.php": "./tests/cypress/wordpress-files/test-plugins/show-comments-and-terms.php",
"wp-content/plugins/sync-error.php": "./tests/cypress/wordpress-files/test-plugins/sync-error.php",
"wp-content/plugins/unsupported-server-software.php": "./tests/cypress/wordpress-files/test-plugins/unsupported-server-software.php",
"wp-content/plugins/unsupported-elasticsearch-version.php": "./tests/cypress/wordpress-files/test-plugins/unsupported-elasticsearch-version.php",
"wp-content/uploads/content-example.xml": "./tests/cypress/wordpress-files/test-docs/content-example.xml"
}
}
Expand Down
33 changes: 20 additions & 13 deletions assets/js/settings-screen/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies.
*/
import { SnackbarList } from '@wordpress/components';
import { createSlotFill, SlotFillProvider, SnackbarList } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { createContext, useContext, useMemo, WPElement } from '@wordpress/element';
import { store as noticeStore } from '@wordpress/notices';
Expand All @@ -12,6 +12,7 @@ import { store as noticeStore } from '@wordpress/notices';
import './style.css';

const Context = createContext();
const { Fill, Slot } = createSlotFill('SettingsPageAction');

/**
* ElasticPress Settings Screen provider component.
Expand All @@ -32,26 +33,32 @@ export const SettingsScreenProvider = ({ children, title }) => {

const contextValue = useMemo(
() => ({
ActionSlot: Fill,
createNotice,
removeNotice,
}),
[createNotice, removeNotice],
);

return (
<Context.Provider value={contextValue}>
<div className="ep-settings-page">
<div className="ep-settings-page__wrap">
<h1 className="ep-settings-page__title">{title}</h1>
{children}
<SlotFillProvider>
<Context.Provider value={contextValue}>
<div className="ep-settings-page">
<div className="ep-settings-page__wrap">
<header className="ep-settings-page__header">
<h1 className="ep-settings-page__title">{title}</h1>
<Slot />
</header>
{children}
</div>
<SnackbarList
className="ep-settings-page__snackbar-list"
notices={notices}
onRemove={(notice) => removeNotice(notice)}
/>
</div>
<SnackbarList
className="ep-settings-page__snackbar-list"
notices={notices}
onRemove={(notice) => removeNotice(notice)}
/>
</div>
</Context.Provider>
</Context.Provider>
</SlotFillProvider>
);
};

Expand Down
10 changes: 10 additions & 0 deletions assets/js/settings-screen/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
max-width: 800px;
}

.ep-settings-page__header {
align-items: center;
display: flex;
justify-content: space-between;

& button {
margin-top: 5px;
}
}

.ep-settings-page__snackbar-list {
bottom: 40px;
left: 0;
Expand Down
2 changes: 2 additions & 0 deletions assets/js/sync-ui/components/previous-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export default ({ failures, method, stateDatetime, status, trigger }) => {
return __('Automatic sync after settings change.', 'elasticpress');
case 'install':
return __('Automatic sync after installation.', 'elasticpress');
case 'synonyms-error':
return __('Manual sync following an error in synonyms settings.', 'elasticpress');
case 'manual':
return __('Manual sync from Sync Settings.', 'elasticpress');
case 'upgrade':
Expand Down
6 changes: 6 additions & 0 deletions assets/js/sync-ui/components/progress.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ export default () => {
'Started manually from the Sync page at <time>%s</time>.',
'elasticpress',
);
case 'synonyms-error':
/* translators: %1$s Sync start date and time. */
return __(
'Started manually from an error on the Synonyms Settings page at <time>%s</time>.',
'elasticpress',
);
case 'upgrade':
/* translators: %1$s Sync start date and time. */
return __(
Expand Down
169 changes: 169 additions & 0 deletions assets/js/synonyms/apps/synonyms-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/**
* WordPress dependencies.
*/
import { Button, Panel, PanelBody, PanelHeader, TabPanel } from '@wordpress/components';
import { WPElement } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies.
*/
import { useSettingsScreen } from '../../settings-screen';
import { useSynonymsSettings } from '../provider';
import GroupTab from '../components/common/group-tab';
import SolrEditor from '../components/editors/solr-editor';
import Hyponyms from '../components/groups/hyponyms';
import Replacements from '../components/groups/replacements';
import Synonyms from '../components/groups/synonyms';

/**
* Synonyms settings app.
*
* @returns {WPElement} App element.
*/
export default () => {
const { ActionSlot, createNotice } = useSettingsScreen();
const { isBusy, hyponyms, isSolr, replacements, save, synonyms, switchEditor, syncUrl } =
useSynonymsSettings();

/**
* Handle clicking the editor switch button.
*
* @returns {void}
*/
const onClick = () => {
switchEditor();
};

/**
* Submit event.
*
* @param {Event} event Submit event.
*/
const onSubmit = async (event) => {
event.preventDefault();

try {
await save();
createNotice('success', __('Synonym settings saved.', 'elasticpress'));
} catch (e) {
if (e.code === 'error-update-index') {
createNotice(
'error',
__(
'Could not update index with synonyms. Make sure your data is synced.',
'elasticpress',
),
{
actions: [
{
url: syncUrl,
label: __('Sync', 'elasticpress'),
},
],
},
);
} else {
createNotice(
'error',
__('Something went wrong. Please try again.', 'elasticpress'),
);
}
}
};

/**
* Tabs.
*
* @type {Array}
*/
const tabs = [
{
name: 'synonyms',
title: (
<GroupTab isValid={!synonyms.some((s) => !s.valid)}>
{sprintf(__('Synonyms (%d)', 'elasticpress'), synonyms.length)}
</GroupTab>
),
},
{
name: 'hyponyms',
title: (
<GroupTab isValid={!hyponyms.some((s) => !s.valid)}>
{sprintf(__('Hyponyms (%d)', 'elasticpress'), hyponyms.length)}
</GroupTab>
),
},
{
name: 'replacements',
title: (
<GroupTab isValid={!replacements.some((s) => !s.valid)}>
{sprintf(__('Replacements (%d)', 'elasticpress'), replacements.length)}
</GroupTab>
),
},
];

return (
<>
<ActionSlot>
<Button onClick={onClick} size="small" type="button" variant="secondary">
{isSolr
? __('Switch to visual editor', 'elasticpress')
: __('Switch to advanced text editor', 'elasticpress')}
</Button>
</ActionSlot>
<p>
{__(
'Synonym rules enable a more flexible search experience that returns relevant results even without an exact match. Rules can be defined as synonyms, for terms with similar meanings; hyponyms, for terms with a hierarchical relationship; or replacements, for corrections and substitutions.',
'elasticpress',
)}
</p>
{!isSolr ? (
<Panel className="ep-synonyms-panel">
<TabPanel tabs={tabs}>
{({ name }) => (
<PanelBody>
{() => {
switch (name) {
case 'hyponyms':
return <Hyponyms />;
case 'replacements':
return <Replacements />;
case 'synonyms':
default:
return <Synonyms />;
}
}}
</PanelBody>
)}
</TabPanel>
</Panel>
) : (
<Panel className="ep-synonyms-panel">
<PanelHeader>
<h2>{__('Advanced Synonyms Editor', 'elasticpress')}</h2>
</PanelHeader>
<PanelBody>
<p>
{__(
'ElasticPress uses the Solr format to define your synonym rules for Elasticsearch. Advanced users can use the field below to edit the synonym rules in this format directly. This can also be used to import a large dictionary of synonyms, or to export your synonyms for use on another site.',
'elasticpress',
)}
</p>
<SolrEditor />
</PanelBody>
</Panel>
)}
<Button
disabled={isBusy}
isBusy={isBusy}
onClick={onSubmit}
type="button"
variant="primary"
>
{__('Save changes', 'elasticpress')}
</Button>
</>
);
};
Loading

0 comments on commit 2dadd92

Please sign in to comment.