├── dist ├── css │ ├── facets-admin-styles.min.css │ ├── highlighting-styles.min.css │ ├── comments-styles.min.asset.php │ ├── facets-styles.min.asset.php │ ├── ordering-styles.min.asset.php │ ├── sync-styles.min.asset.php │ ├── synonyms-styles.min.asset.php │ ├── autosuggest-styles.min.asset.php │ ├── dashboard-styles.min.asset.php │ ├── facets-admin-styles.min.asset.php │ ├── highlighting-styles.min.asset.php │ ├── instant-results-styles.min.asset.php │ ├── related-posts-block-styles.min.asset.php │ ├── related-posts-block-styles.min.css │ ├── comments-styles.min.css │ ├── autosuggest-styles.min.css │ ├── facets-styles.min.css │ ├── ordering-styles.min.css │ └── synonyms-styles.min.css └── js │ ├── facets-script.min.asset.php │ ├── autosuggest-script.min.asset.php │ ├── comments-script.min.asset.php │ ├── stats-script.min.asset.php │ ├── dashboard-script.min.asset.php │ ├── weighting-script.min.asset.php │ ├── settings-script.min.asset.php │ ├── notice-script.min.asset.php │ ├── synonyms-script.min.asset.php │ ├── ordering-script.min.asset.php │ ├── instant-results-admin-script.min.asset.php │ ├── instant-results-script.min.asset.php │ ├── sites-admin-script.min.asset.php │ ├── facets-block-script.min.asset.php │ ├── sync-script.min.asset.php │ ├── related-posts-block-script.min.asset.php │ ├── facets-script.min.js │ ├── notice-script.min.js │ ├── weighting-script.min.js │ ├── settings-script.min.js │ ├── instant-results-admin-script.min.js │ ├── sites-admin-script.min.js │ ├── related-posts-block-script.min.js │ ├── facets-block-script.min.js │ └── comments-script.min.js ├── assets ├── css │ ├── facets-admin.css │ ├── highlighting.css │ ├── instant-results │ │ ├── input.css │ │ ├── tokens.css │ │ ├── sidebar-toggle.css │ │ ├── checkbox.css │ │ ├── toolbar.css │ │ ├── sidebar.css │ │ ├── options-list.css │ │ ├── pagination.css │ │ ├── sort.css │ │ ├── panel.css │ │ ├── results.css │ │ ├── page.css │ │ ├── range-slider.css │ │ ├── modal.css │ │ ├── utilities.css │ │ └── result.css │ ├── sync │ │ ├── heading.css │ │ ├── warning.css │ │ ├── controls.css │ │ ├── button.css │ │ ├── status.css │ │ ├── messages.css │ │ ├── panel.css │ │ ├── progress-bar.css │ │ └── progress.css │ ├── related-posts-block.css │ ├── comments.css │ ├── sync.css │ ├── autosuggest.css │ ├── instant-results.css │ ├── facets.css │ ├── ordering.css │ └── synonyms.css └── js │ ├── instant-results │ ├── admin │ │ ├── config.js │ │ ├── index.js │ │ └── components │ │ │ └── facet-selector.js │ ├── context.js │ ├── components │ │ ├── common │ │ │ ├── image.js │ │ │ ├── small-button.js │ │ │ ├── range-slider.js │ │ │ ├── star-rating.js │ │ │ ├── checkbox.js │ │ │ ├── panel.js │ │ │ └── modal.js │ │ ├── layout │ │ │ ├── toolbar.js │ │ │ ├── sidebar.js │ │ │ └── results.js │ │ ├── tools │ │ │ ├── sidebar-toggle.js │ │ │ ├── active-constraints.js │ │ │ ├── clear-constraints.js │ │ │ └── sort.js │ │ ├── facets │ │ │ ├── facet.js │ │ │ ├── search-term-facet.js │ │ │ └── post-type-facet.js │ │ ├── layout.js │ │ └── results │ │ │ ├── pagination.js │ │ │ └── result.js │ ├── config.js │ ├── hooks.js │ ├── reducer.js │ ├── utilities.js │ └── functions.js │ ├── blocks │ ├── facets │ │ ├── index.js │ │ ├── block.json │ │ └── edit.js │ └── related-posts │ │ ├── block.js │ │ └── Edit.js │ ├── ordering │ └── index.js │ ├── sync │ ├── components │ │ ├── icons │ │ │ ├── play.js │ │ │ ├── pause.js │ │ │ ├── stop.js │ │ │ ├── thumbs-up.js │ │ │ ├── thumbs-down.js │ │ │ └── sync.js │ │ ├── common │ │ │ ├── date-time.js │ │ │ ├── message-log.js │ │ │ └── progress-bar.js │ │ └── sync │ │ │ ├── status.js │ │ │ ├── log.js │ │ │ ├── progress.js │ │ │ └── controls.js │ ├── config.js │ ├── utilities.js │ └── hooks.js │ ├── synonyms │ ├── index.js │ ├── context.js │ ├── components │ │ ├── editors │ │ │ ├── SolrEditor.js │ │ │ ├── SetsEditor.js │ │ │ ├── AlternativeEditor.js │ │ │ └── AlternativesEditor.js │ │ ├── shared │ │ │ └── LinkedMultiInput.js │ │ └── SynonymsEditor.js │ ├── utils.js │ └── reducers │ │ └── editorReducer.js │ ├── facets.js │ ├── notice.js │ ├── weighting.js │ ├── sites-admin.js │ ├── stats.js │ └── settings.js ├── images ├── setup-screenshot.png ├── sync-in-progress.png ├── features-screenshot.png ├── warning.svg ├── logo-icon.svg └── logo.svg └── includes ├── partials ├── sync-page.php ├── header.php ├── dashboard-page.php └── stats-page.php ├── health-check.php └── classes ├── FeatureRequirementsStatus.php ├── Indexables.php ├── HealthCheck.php ├── HealthCheck └── HealthCheckElasticsearch.php ├── Feature ├── Users │ └── Users.php ├── Terms │ └── Terms.php └── RelatedPosts │ └── Widget.php ├── Indexable └── User │ └── SyncManager.php └── Installer.php /dist/css/facets-admin-styles.min.css: -------------------------------------------------------------------------------- 1 | .widget-ep-facet label{margin-right:5px} 2 | -------------------------------------------------------------------------------- /assets/css/facets-admin.css: -------------------------------------------------------------------------------- 1 | .widget-ep-facet label { 2 | margin-right: 5px; 3 | } 4 | -------------------------------------------------------------------------------- /images/setup-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/ElasticPress/HEAD/images/setup-screenshot.png -------------------------------------------------------------------------------- /images/sync-in-progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/ElasticPress/HEAD/images/sync-in-progress.png -------------------------------------------------------------------------------- /dist/css/highlighting-styles.min.css: -------------------------------------------------------------------------------- 1 | .ep-highlight{background-color:transparent;font-style:italic;font-weight:700} 2 | -------------------------------------------------------------------------------- /images/features-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/ElasticPress/HEAD/images/features-screenshot.png -------------------------------------------------------------------------------- /dist/css/comments-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => 'd5cf29bd60b0dd4480724d7b606e458f'); -------------------------------------------------------------------------------- /dist/css/facets-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => 'be774ee7a4f194dfe65a980bdb745f6a'); -------------------------------------------------------------------------------- /dist/css/ordering-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '1310e7d723dab4632cfce851ad418485'); -------------------------------------------------------------------------------- /dist/css/sync-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '5f82e66765bbe534473746cd12df6189'); -------------------------------------------------------------------------------- /dist/css/synonyms-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => 'e1b6c3a9b9ef4fa92b23571f6661577b'); -------------------------------------------------------------------------------- /assets/css/highlighting.css: -------------------------------------------------------------------------------- 1 | .ep-highlight { 2 | background-color: transparent; 3 | font-style: italic; 4 | font-weight: 700; 5 | } 6 | -------------------------------------------------------------------------------- /assets/css/instant-results/input.css: -------------------------------------------------------------------------------- 1 | .ep-search-input { 2 | font-size: 1.25em; 3 | margin: 0 !important; 4 | width: 100%; 5 | } 6 | -------------------------------------------------------------------------------- /assets/css/instant-results/tokens.css: -------------------------------------------------------------------------------- 1 | .ep-search-tokens { 2 | 3 | @nest .ep-search-toolbar & { 4 | display: contents; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /dist/css/autosuggest-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '26e3c1cd915b73e742ab41d02cd86563'); -------------------------------------------------------------------------------- /dist/css/dashboard-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '71469307d99d88ac231f099cc82fa522'); -------------------------------------------------------------------------------- /dist/css/facets-admin-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => 'f8e36dd4c8462c8408ca6f064bb7d277'); -------------------------------------------------------------------------------- /dist/css/highlighting-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '48ac6df2f0406f2e2d5d4ea06f5759b5'); -------------------------------------------------------------------------------- /dist/css/instant-results-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '9e7642cfd2537aa60b4d59e8a75cbb59'); -------------------------------------------------------------------------------- /dist/js/facets-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('wp-polyfill'), 'version' => '0ed518d455727a8be493af1cdee55711'); -------------------------------------------------------------------------------- /dist/css/related-posts-block-styles.min.asset.php: -------------------------------------------------------------------------------- 1 | array(), 'version' => '57ed3b8acc523fe9b9e9a53dae101978'); -------------------------------------------------------------------------------- /dist/js/autosuggest-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('wp-polyfill'), 'version' => '5c609d7ba064036a58c72be668e0515d'); -------------------------------------------------------------------------------- /dist/js/comments-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('wp-polyfill'), 'version' => '1e0e945692ffaa2ddd6377c7ff11fea6'); -------------------------------------------------------------------------------- /dist/js/stats-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('moment', 'wp-polyfill'), 'version' => '8329a3a1a2860cfdaa11bdc69042b7a0'); -------------------------------------------------------------------------------- /dist/js/dashboard-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('wp-i18n', 'wp-polyfill'), 'version' => '0fe1d3b8e3b503af840f3315a5007b5d'); -------------------------------------------------------------------------------- /dist/js/weighting-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('wp-dom-ready', 'wp-polyfill'), 'version' => 'cd98315de2a5b6514fa1749bc4e954e0'); -------------------------------------------------------------------------------- /assets/js/instant-results/admin/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Window dependencies. 3 | */ 4 | const { facets } = window.epInstantResultsAdmin; 5 | 6 | export { facets }; 7 | -------------------------------------------------------------------------------- /assets/css/instant-results/sidebar-toggle.css: -------------------------------------------------------------------------------- 1 | .ep-search-sidebar-toggle { 2 | width: 100%; 3 | 4 | @media ( min-width: 768px ) { 5 | display: none; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /dist/js/settings-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('wp-dom-ready', 'wp-i18n', 'wp-polyfill'), 'version' => 'f21347b966fa44702392dbc013c4a77f'); -------------------------------------------------------------------------------- /assets/css/instant-results/checkbox.css: -------------------------------------------------------------------------------- 1 | .ep-search-checkbox__count::before { 2 | content: "("; 3 | } 4 | 5 | .ep-search-checkbox__count::after { 6 | content: ")"; 7 | } 8 | -------------------------------------------------------------------------------- /dist/js/notice-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('wp-api-fetch', 'wp-dom-ready', 'wp-polyfill'), 'version' => 'c5e60b5e270f694cfbac47b0f56da375'); -------------------------------------------------------------------------------- /assets/js/instant-results/context.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal dependencies. 3 | */ 4 | import { createContext } from '@wordpress/element'; 5 | 6 | export default createContext(); 7 | -------------------------------------------------------------------------------- /dist/js/synonyms-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'wp-components', 'wp-element', 'wp-polyfill'), 'version' => '6095864ad1b2d9570d7e36bb602234f0'); -------------------------------------------------------------------------------- /dist/js/ordering-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'react-dom', 'wp-api-fetch', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '7b10fc96fdd0a88cbfedbc154a80b1c2'); -------------------------------------------------------------------------------- /dist/js/instant-results-admin-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'wp-components', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => 'f44a3bc2ae3235e2bd24c5160052fffc'); -------------------------------------------------------------------------------- /dist/js/instant-results-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'react-dom', 'wp-element', 'wp-i18n', 'wp-polyfill', 'wp-primitives'), 'version' => '2204b560c2a26143c2bdb30213f98a3b'); -------------------------------------------------------------------------------- /images/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/css/sync/heading.css: -------------------------------------------------------------------------------- 1 | .ep-sync-heading { 2 | 3 | @nest .wrap & { 4 | font-weight: 400; 5 | margin: 0.5rem 0 0.75rem; 6 | padding: 0; 7 | 8 | &h2 { 9 | color: inherit; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /dist/js/sites-admin-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'wp-api-fetch', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '30cf86d5c387e97cc70e8b0f16390e0c'); -------------------------------------------------------------------------------- /assets/js/blocks/facets/index.js: -------------------------------------------------------------------------------- 1 | import edit from './edit'; 2 | import block from './block.json'; 3 | 4 | const { registerBlockType } = wp.blocks; 5 | 6 | registerBlockType(block, { 7 | edit, 8 | save: () => {}, 9 | }); 10 | -------------------------------------------------------------------------------- /dist/js/facets-block-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-components', 'wp-element', 'wp-i18n', 'wp-polyfill'), 'version' => '3b1c7b5d6ccc4bcd15bd0ae2816b1138'); -------------------------------------------------------------------------------- /dist/js/sync-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'wp-api-fetch', 'wp-components', 'wp-date', 'wp-element', 'wp-i18n', 'wp-polyfill', 'wp-primitives'), 'version' => '2013fd50cb46aae737b144d70c78f608'); -------------------------------------------------------------------------------- /assets/css/sync/warning.css: -------------------------------------------------------------------------------- 1 | .ep-sync-warning { 2 | display: grid; 3 | grid-gap: 0.5rem; 4 | grid-template-columns: min-content auto; 5 | 6 | & svg { 7 | fill: var(--ep-sync-color-warning); 8 | margin-top: -3px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /dist/js/related-posts-block-script.min.asset.php: -------------------------------------------------------------------------------- 1 | array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-polyfill', 'wp-url'), 'version' => '1bb8cd8c4ce338de53fdcd9dfa0a020c'); -------------------------------------------------------------------------------- /assets/css/instant-results/toolbar.css: -------------------------------------------------------------------------------- 1 | .ep-search-toolbar { 2 | align-items: start; 3 | display: flex; 4 | flex-wrap: wrap; 5 | gap: 0.25em; 6 | margin: 1em 0; 7 | 8 | @media ( min-width: 768px ) { 9 | align-items: center; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /dist/css/related-posts-block-styles.min.css: -------------------------------------------------------------------------------- 1 | .editor-styles-wrapper .wp-block-elasticpress-related-posts ul,.wp-block-elasticpress-related-posts ul{list-style-type:none;padding:0}.editor-styles-wrapper .wp-block-elasticpress-related-posts ul li a>div{display:inline} 2 | -------------------------------------------------------------------------------- /dist/css/comments-styles.min.css: -------------------------------------------------------------------------------- 1 | .ep-widget-search-comments-results{list-style-type:none;margin-left:0}.ep-widget-search-comments-result-item,.ep-widget-search-comments-result-item-not-found{margin-left:0}.ep-widget-search-comments-result-item.selected a{border:2px dotted #171923} 2 | -------------------------------------------------------------------------------- /assets/js/ordering/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { render } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependencies. 8 | */ 9 | import { Pointers } from './pointers'; 10 | 11 | render(, document.getElementById('ordering-app')); 12 | -------------------------------------------------------------------------------- /assets/css/related-posts-block.css: -------------------------------------------------------------------------------- 1 | .editor-styles-wrapper .wp-block-elasticpress-related-posts ul, 2 | .wp-block-elasticpress-related-posts ul { 3 | list-style-type: none; 4 | padding: 0; 5 | } 6 | 7 | .editor-styles-wrapper .wp-block-elasticpress-related-posts ul li a > div { 8 | display: inline; 9 | } 10 | -------------------------------------------------------------------------------- /assets/css/instant-results/sidebar.css: -------------------------------------------------------------------------------- 1 | .ep-search-sidebar { 2 | display: none; 3 | margin-bottom: 2em; 4 | 5 | &.is-open { 6 | display: block; 7 | } 8 | 9 | @media ( min-width: 768px ) { 10 | display: block; 11 | max-height: calc(100% - 1em); 12 | min-width: 25%; 13 | overflow-y: auto; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /assets/css/instant-results/options-list.css: -------------------------------------------------------------------------------- 1 | .ep-search-options-list { 2 | list-style: none; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | .ep-search-options-list__item { 8 | margin: 0.5em 0; 9 | 10 | &::before { 11 | content: none; 12 | } 13 | } 14 | 15 | .ep-search-options-list__sub-menu { 16 | padding-left: 1em; 17 | } 18 | -------------------------------------------------------------------------------- /assets/css/sync/controls.css: -------------------------------------------------------------------------------- 1 | .ep-sync-controls { 2 | display: grid; 3 | grid-gap: 1em; 4 | grid-template-columns: 1fr 1fr; 5 | margin: 0 auto; 6 | max-width: 16rem; 7 | } 8 | 9 | .ep-sync-controls__sync { 10 | grid-column: 1 / -1; 11 | } 12 | 13 | .ep-sync-controls__learn-more { 14 | grid-column: 1 / -1; 15 | text-align: center; 16 | } 17 | -------------------------------------------------------------------------------- /includes/partials/sync-page.php: -------------------------------------------------------------------------------- 1 | 15 | 16 |
17 | -------------------------------------------------------------------------------- /assets/css/comments.css: -------------------------------------------------------------------------------- 1 | .ep-widget-search-comments-results { 2 | list-style-type: none; 3 | margin-left: 0; 4 | } 5 | 6 | .ep-widget-search-comments-result-item, 7 | .ep-widget-search-comments-result-item-not-found { 8 | margin-left: 0; 9 | } 10 | 11 | .ep-widget-search-comments-result-item.selected a { 12 | border: 2px dotted #171923; 13 | } 14 | -------------------------------------------------------------------------------- /assets/js/sync/components/icons/play.js: -------------------------------------------------------------------------------- 1 | import { SVG, Path } from '@wordpress/primitives'; 2 | 3 | export default () => { 4 | return ( 5 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /assets/js/sync/components/icons/pause.js: -------------------------------------------------------------------------------- 1 | import { SVG, Path } from '@wordpress/primitives'; 2 | 3 | export default () => { 4 | return ( 5 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /assets/js/sync/components/icons/stop.js: -------------------------------------------------------------------------------- 1 | import { SVG, Path } from '@wordpress/primitives'; 2 | 3 | export default () => { 4 | return ( 5 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /assets/css/instant-results/pagination.css: -------------------------------------------------------------------------------- 1 | .ep-search-pagination { 2 | align-items: center; 3 | display: grid; 4 | grid-template-columns: 1fr 1fr 1fr; 5 | margin-top: auto; 6 | text-align: center; 7 | 8 | @nest .rtl & { 9 | direction: rtl; 10 | } 11 | } 12 | 13 | .ep-search-pagination__next { 14 | justify-self: end; 15 | } 16 | 17 | .ep-search-pagination__previous { 18 | justify-self: start; 19 | } 20 | -------------------------------------------------------------------------------- /assets/js/sync/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Window dependencies. 3 | */ 4 | const { 5 | auto_start_index: autoIndex, 6 | ajax_url: ajaxUrl, 7 | index_meta: indexMeta = null, 8 | is_epio: isEpio, 9 | ep_last_sync_date: lastSyncDateTime = null, 10 | ep_last_sync_failed: lastSyncFailed = false, 11 | nonce, 12 | } = window.epDash; 13 | 14 | export { autoIndex, ajaxUrl, indexMeta, isEpio, lastSyncDateTime, lastSyncFailed, nonce }; 15 | -------------------------------------------------------------------------------- /includes/health-check.php: -------------------------------------------------------------------------------- 1 | register_test(); 21 | } 22 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/common/image.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Image component. 8 | * 9 | * @param {Option} props Component props. 10 | * 11 | * @returns {WPElement} Component element. 12 | */ 13 | export default ({ alt, height, ID, src, width, ...props }) => { 14 | return {alt}; 15 | }; 16 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/layout/toolbar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Search field component. 8 | * 9 | * @param {object} props Props. 10 | * @param {WPElement} props.children Children. 11 | * @returns {WPElement} Element. 12 | */ 13 | export default ({ children }) => { 14 | return
{children}
; 15 | }; 16 | -------------------------------------------------------------------------------- /assets/css/instant-results/sort.css: -------------------------------------------------------------------------------- 1 | .ep-search-sort { 2 | flex-shrink: 0; 3 | gap: 0.5em; 4 | margin: 0; 5 | 6 | @nest .ep-search-results & { 7 | display: none; 8 | 9 | @media ( min-width: 768px ) { 10 | align-items: center; 11 | display: flex; 12 | } 13 | } 14 | 15 | @nest .ep-search-sidebar & { 16 | display: flex; 17 | flex-direction: column; 18 | margin-bottom: 1em; 19 | 20 | @media ( min-width: 768px ) { 21 | display: none; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /assets/css/sync/button.css: -------------------------------------------------------------------------------- 1 | .ep-sync-button { 2 | 3 | &.components-button.has-icon.has-text { 4 | height: 4rem; 5 | justify-content: center; 6 | width: 100%; 7 | 8 | & svg { 9 | height: 2em; 10 | margin: 0; 11 | width: 2em; 12 | } 13 | } 14 | } 15 | 16 | .ep-sync-button--sync { 17 | font-size: 1.5em; 18 | font-weight: 700; 19 | } 20 | 21 | .ep-sync-button--pause, 22 | .ep-sync-button--resume, 23 | .ep-sync-button--stop { 24 | flex-direction: column; 25 | } 26 | -------------------------------------------------------------------------------- /assets/css/sync/status.css: -------------------------------------------------------------------------------- 1 | .ep-sync-status { 2 | align-items: center; 3 | display: grid; 4 | grid-gap: 0.5rem; 5 | grid-template-columns: min-content auto; 6 | 7 | & svg { 8 | fill: var(--ep-sync-color-error); 9 | } 10 | } 11 | 12 | .ep-sync-status--success { 13 | 14 | & svg { 15 | fill: var(--ep-sync-color-success); 16 | } 17 | } 18 | 19 | .ep-sync-status__time { 20 | background-color: var(--ep-sync-color-light-grey); 21 | border-radius: 2px; 22 | padding: 0.25em 0.5em; 23 | } 24 | -------------------------------------------------------------------------------- /images/logo-icon.svg: -------------------------------------------------------------------------------- 1 | logo -------------------------------------------------------------------------------- /assets/css/instant-results/panel.css: -------------------------------------------------------------------------------- 1 | .ep-search-panel { 2 | border: 1px solid var(--ep-search-border-color); 3 | margin: 0; 4 | padding: 0; 5 | 6 | @nest .ep-search-panel + & { 7 | border-top-width: 0; 8 | } 9 | } 10 | 11 | .ep-search-panel__heading { 12 | font-size: inherit; 13 | margin: 0; 14 | } 15 | 16 | .ep-search-panel__button { 17 | padding: 1em !important; 18 | width: 100% !important; 19 | } 20 | 21 | .ep-search-panel__content { 22 | padding: 0 1em 1em 1em; 23 | 24 | &[aria-hidden="true"] { 25 | display: none; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /assets/css/sync.css: -------------------------------------------------------------------------------- 1 | @import "sync/button.css"; 2 | @import "sync/controls.css"; 3 | @import "sync/heading.css"; 4 | @import "sync/messages.css"; 5 | @import "sync/panel.css"; 6 | @import "sync/progress.css"; 7 | @import "sync/progress-bar.css"; 8 | @import "sync/status.css"; 9 | @import "sync/warning.css"; 10 | 11 | :root { 12 | --ep-sync-color-black: #1a1e24; 13 | --ep-sync-color-error: #b52727; 14 | --ep-sync-color-light-grey: #f0f0f0; 15 | --ep-sync-color-success: #46b450; 16 | --ep-sync-color-warning: #ffb359; 17 | --ep-sync-color-white: #fff; 18 | } 19 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/common/small-button.js: -------------------------------------------------------------------------------- 1 | import { WPElement } from '@wordpress/element'; 2 | 3 | /** 4 | * Small button component. 5 | * 6 | * @param {object} props Props. 7 | * @param {WPElement} props.children Children. 8 | * @param {string} props.className Class attribute. 9 | * @returns {WPElement} Element. 10 | */ 11 | export default ({ children, className, ...props }) => { 12 | return ( 13 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /assets/js/sync/components/common/date-time.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { dateI18n } from '@wordpress/date'; 5 | import { WPElement } from '@wordpress/element'; 6 | 7 | /** 8 | * Log component. 9 | * 10 | * @param {object} props Component props. 11 | * @param {string} props.dateTime Date and time. 12 | * @returns {WPElement} Component. 13 | */ 14 | export default ({ dateTime, ...props }) => { 15 | return ( 16 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /assets/js/sync/components/icons/thumbs-up.js: -------------------------------------------------------------------------------- 1 | import { SVG, Path } from '@wordpress/primitives'; 2 | 3 | export default () => { 4 | return ( 5 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /assets/js/sync/components/icons/thumbs-down.js: -------------------------------------------------------------------------------- 1 | import { SVG, Path } from '@wordpress/primitives'; 2 | 3 | export default () => { 4 | return ( 5 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /assets/js/synonyms/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { render } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependencies. 8 | */ 9 | import { AppContext } from './context'; 10 | import SynonymsEditor from './components/SynonymsEditor'; 11 | 12 | const SELECTOR = '#synonym-root'; 13 | 14 | /** 15 | * Get Root. 16 | * 17 | * @returns {Element|false} Root element 18 | */ 19 | const getRoot = () => document.querySelector(SELECTOR) || false; 20 | 21 | render( 22 | 23 | 24 | , 25 | getRoot(), 26 | ); 27 | -------------------------------------------------------------------------------- /assets/css/sync/messages.css: -------------------------------------------------------------------------------- 1 | .ep-sync-messages { 2 | align-content: start; 3 | background: var(--ep-sync-color-black); 4 | color: var(--ep-sync-color-white); 5 | display: grid; 6 | font-family: monospace; 7 | grid-auto-flow: column; 8 | grid-template-columns: min-content auto; 9 | height: 21em; 10 | line-height: 2; 11 | overflow-y: auto; 12 | white-space: pre-wrap; 13 | } 14 | 15 | .ep-sync-messages__message { 16 | grid-column: 2; 17 | } 18 | 19 | .ep-sync-messages__line-number { 20 | box-sizing: content-box; 21 | min-width: 3ch; 22 | opacity: 0.5; 23 | padding: 0 0.5em; 24 | text-align: right; 25 | } 26 | -------------------------------------------------------------------------------- /assets/css/instant-results/results.css: -------------------------------------------------------------------------------- 1 | .ep-search-results { 2 | display: grid; 3 | grid-gap: 2em; 4 | grid-template-columns: 100%; 5 | grid-template-rows: max-content; 6 | padding: 0 0 1em 0; 7 | width: 100%; 8 | 9 | @media ( min-width: 768px ) { 10 | height: 100%; 11 | overflow-y: auto; 12 | padding: 0 1em 1em 1em; 13 | } 14 | } 15 | 16 | .ep-search-results__header { 17 | align-items: center; 18 | display: flex; 19 | gap: 1em; 20 | justify-content: space-between; 21 | } 22 | 23 | .ep-search-results__title { 24 | font-size: 1.25em; 25 | margin: 0 !important; 26 | 27 | @media ( min-width: 768px ) { 28 | font-size: 1.5em; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dist/js/facets-script.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";const e=(e,t)=>{let r=null;return function(...c){const s=this;window.clearTimeout(r),r=window.setTimeout((()=>{e.apply(s,c)}),t)}};document.querySelectorAll(".widget_ep-facet, .wp-block-elasticpress-facet").forEach((t=>{if(!t.querySelector(".facet-search"))return;const r=t.querySelector(".terms");t.querySelector(".facet-search").addEventListener("keyup",e((e=>{13!==e.keyCode&&((e,t)=>{const{target:r}=e,c=r.value.toLowerCase();t.querySelectorAll(".term").forEach((e=>{const t=e.getAttribute("data-term-slug");e.getAttribute("data-term-name").includes(c)||t.includes(c)?e.classList.remove("hide"):e.classList.add("hide")}))})(e,r)}),200))}))}(); -------------------------------------------------------------------------------- /assets/css/sync/panel.css: -------------------------------------------------------------------------------- 1 | .ep-sync-panel { 2 | margin-bottom: 2rem; 3 | max-width: 1200px; 4 | } 5 | 6 | .ep-sync-panel__body { 7 | display: grid; 8 | grid-column-gap: 2rem; 9 | grid-row-gap: 1rem; 10 | grid-template-columns: auto 16rem; 11 | 12 | &.is-opened { 13 | padding: 2rem 2rem 1rem 2rem; 14 | } 15 | 16 | & p, 17 | & .components-toggle-control, 18 | & .components-tab-panel__tab-content { 19 | margin-bottom: 1rem; 20 | margin-top: 0; 21 | } 22 | 23 | @media (max-width: 960px) { 24 | grid-template-columns: 100%; 25 | } 26 | } 27 | 28 | .ep-sync-panel__row { 29 | grid-column: 1 / -1; 30 | } 31 | 32 | .ep-sync-panel__introduction { 33 | font-size: 18px; 34 | } 35 | -------------------------------------------------------------------------------- /assets/css/sync/progress-bar.css: -------------------------------------------------------------------------------- 1 | .ep-sync-progress-bar { 2 | background: var(--ep-sync-color-light-grey); 3 | display: flex; 4 | overflow: hidden; 5 | text-align: center; 6 | } 7 | 8 | .ep-sync-progress-bar, 9 | .ep-sync-progress-bar__progress { 10 | border-radius: 0.875em; 11 | } 12 | 13 | .ep-sync-progress-bar__progress { 14 | background: var(--wp-admin-theme-color); 15 | color: var(--ep-sync-color-white); 16 | padding: 0 0.875em; 17 | transition: all 500ms ease-in-out; 18 | white-space: nowrap; 19 | 20 | @nest .ep-sync-progress-bar--complete & { 21 | background: var(--ep-sync-color-success); 22 | } 23 | 24 | @nest .ep-sync-progress-bar--paused & { 25 | opacity: 0.5; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/layout/sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { useContext, WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependencies. 8 | */ 9 | import Context from '../../context'; 10 | 11 | /** 12 | * Search field component. 13 | * 14 | * @param {object} props Props. 15 | * @param {WPElement} props.children Children. 16 | * @returns {WPElement} Element. 17 | */ 18 | export default ({ children }) => { 19 | const { 20 | state: { isSidebarOpen }, 21 | } = useContext(Context); 22 | 23 | return ( 24 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /assets/js/instant-results/admin/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { render } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependences. 8 | */ 9 | import FacetSelector from './components/facet-selector'; 10 | 11 | document.addEventListener('DOMContentLoaded', () => { 12 | const input = document.getElementById('feature_instant_results_facets'); 13 | 14 | const { 15 | className, 16 | dataset: { fieldName }, 17 | id, 18 | name, 19 | value, 20 | } = input; 21 | 22 | render( 23 | , 30 | input.parentElement, 31 | ); 32 | }); 33 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/common/range-slider.js: -------------------------------------------------------------------------------- 1 | /** 2 | * External dependencies. 3 | */ 4 | import ReactSlider from 'react-slider'; 5 | 6 | /** 7 | * WordPress dependencies. 8 | */ 9 | import { WPElement } from '@wordpress/element'; 10 | 11 | /** 12 | * Range slider component. 13 | * 14 | * @param {object} props Props. 15 | * @returns {WPElement} Element. 16 | */ 17 | export default ({ ...props }) => { 18 | return ( 19 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /assets/css/instant-results/page.css: -------------------------------------------------------------------------------- 1 | .ep-search-page { 2 | display: flex; 3 | flex-direction: column; 4 | flex-grow: 2; 5 | margin: 0; 6 | overflow-y: auto; 7 | transition: opacity 300ms ease-out; 8 | width: 100%; 9 | 10 | @media ( min-width: 768px ) { 11 | overflow: hidden; 12 | } 13 | 14 | & *, 15 | & *::before, 16 | & *::after { 17 | box-sizing: border-box; 18 | } 19 | 20 | &.is-loading { 21 | opacity: 0.5; 22 | } 23 | } 24 | 25 | .ep-search-page__header, 26 | .ep-search-page__tools, 27 | .ep-search-page__body { 28 | padding: 0 1em; 29 | } 30 | 31 | .ep-search-page__body { 32 | 33 | @media ( min-width: 768px ) { 34 | align-items: flex-start; 35 | display: flex; 36 | flex-grow: 2; 37 | overflow: hidden; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dist/js/notice-script.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var n={n:function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},d:function(e,t){for(var o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},o:function(n,e){return Object.prototype.hasOwnProperty.call(n,e)}},e=window.wp.apiFetch,t=n.n(e),o=window.wp.domReady,r=n.n(o);const{epAdmin:c,ajaxurl:i}=window;r()((()=>{const n=document.querySelectorAll(".notice[data-ep-notice]"),e=n=>{if(!n.target.classList.contains("notice-dismiss"))return;const e=new FormData;e.append("action","ep_notice_dismiss"),e.append("notice",n.currentTarget.dataset.epNotice),e.append("nonce",c.nonce),t()({method:"POST",url:i,body:e})};for(const t of n)t.addEventListener("click",e)}))}(); -------------------------------------------------------------------------------- /assets/js/blocks/facets/block.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schemas.wp.org/trunk/block.json", 3 | "apiVersion": 2, 4 | "title": "Facet (ElasticPress)", 5 | "textdomain": "elasticpress", 6 | "name": "elasticpress/facet", 7 | "icon": "feedback", 8 | "category": "widgets", 9 | "attributes": { 10 | "facet": { 11 | "type": "string", 12 | "default": "" 13 | }, 14 | "orderby": { 15 | "type" : "string", 16 | "default": "count", 17 | "enum" : [ "count", "name" ] 18 | }, 19 | "order": { 20 | "type": "string", 21 | "default": "desc", 22 | "enum": [ "desc", "asc" ] 23 | } 24 | }, 25 | "supports": { 26 | "html": false 27 | }, 28 | "editorScript": "file:/../../../../dist/js/facets-block-script.min.js", 29 | "style": "file:/../../../../dist/css/facets-styles.min.css" 30 | } -------------------------------------------------------------------------------- /dist/css/autosuggest-styles.min.css: -------------------------------------------------------------------------------- 1 | .ep-autosuggest-container{position:relative}.ep-autosuggest-container .ep-autosuggest{background:#fff;border:1px solid #ccc;-webkit-box-shadow:0 2px 4px rgba(0,0,0,.2);box-shadow:0 2px 4px rgba(0,0,0,.2);display:none;position:absolute;width:100%;z-index:200}.ep-autosuggest-container .ep-autosuggest>ul{list-style:none;margin:0!important}.ep-autosuggest-container .ep-autosuggest>ul>li{font-family:sans-serif}.ep-autosuggest-container .ep-autosuggest>ul>li>a.autosuggest-link{color:#000;cursor:pointer;display:block;padding:2px 10px}.ep-autosuggest-container .ep-autosuggest>ul>li>a.autosuggest-link:active,.ep-autosuggest-container .ep-autosuggest>ul>li>a.autosuggest-link:hover{background-color:#eee;text-decoration:none}.ep-autosuggest-container .selected{background-color:#eee;text-decoration:none} 2 | -------------------------------------------------------------------------------- /assets/css/autosuggest.css: -------------------------------------------------------------------------------- 1 | .ep-autosuggest-container { 2 | position: relative; 3 | 4 | & .ep-autosuggest { 5 | background: #fff; 6 | border: 1px solid #ccc; 7 | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); 8 | display: none; 9 | position: absolute; 10 | 11 | width: 100%; 12 | z-index: 200; 13 | 14 | & > ul { 15 | list-style: none; 16 | margin: 0 !important; 17 | 18 | & > li { 19 | font-family: sans-serif; 20 | 21 | & > a.autosuggest-link { 22 | color: #000; 23 | cursor: pointer; 24 | display: block; 25 | padding: 2px 10px; 26 | 27 | &:hover, 28 | &:active { 29 | background-color: #eee; 30 | text-decoration: none; 31 | } 32 | } 33 | } 34 | } 35 | } 36 | 37 | & .selected { 38 | background-color: #eee; 39 | text-decoration: none; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/common/star-rating.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { __, sprintf } from '@wordpress/i18n'; 5 | import { WPElement } from '@wordpress/element'; 6 | 7 | /** 8 | * Star rating component. 9 | * 10 | * @param {Option} props Component props. 11 | * @param {string} props.rating Rating. 12 | * 13 | * @returns {WPElement} Component element. 14 | */ 15 | export default ({ rating }) => { 16 | const label = sprintf( 17 | /* translators: %1$f Rating. %2$d Max rating. */ 18 | __('Rated %1$f out of %2$d', 'elasticpress'), 19 | rating, 20 | 5, 21 | ); 22 | 23 | return ( 24 |
25 |
26 | {label} 27 |
28 |
29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /assets/js/synonyms/context.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { createContext, useReducer, WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependencies. 8 | */ 9 | import { editorReducer, initialState } from './reducers/editorReducer'; 10 | 11 | const State = createContext(); 12 | const Dispatch = createContext(); 13 | 14 | /** 15 | * App Context. 16 | * 17 | * @param {object} props Props. 18 | * @returns {WPElement} AppContext component 19 | */ 20 | const AppContext = (props) => { 21 | const { children } = props; 22 | const [state, dispatch] = useReducer(editorReducer, initialState); 23 | 24 | return ( 25 | 26 | {children} 27 | 28 | ); 29 | }; 30 | 31 | export { AppContext, State, Dispatch }; 32 | -------------------------------------------------------------------------------- /dist/js/weighting-script.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var e={n:function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,{a:n}),n},d:function(t,n){for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t=window.wp.domReady;e.n(t)()((()=>{const e=e=>{e.labels[0].querySelector(".weighting-value").textContent=e.disabled?"0":e.value},t=t=>{e(t.currentTarget)},n=t=>{const n=t.currentTarget.closest("fieldset").querySelector('input[type="range"]');n.disabled=!t.currentTarget.checked,e(n)},r=document.querySelectorAll(".weighting-settings input[type=range]");for(const e of r)e.addEventListener("input",t);const o=document.querySelectorAll(".weighting-settings .searchable input[type=checkbox]");for(const e of o)e.addEventListener("change",n)}))}(); -------------------------------------------------------------------------------- /assets/js/instant-results/components/common/checkbox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Checkbox component. 8 | * 9 | * @param {Option} props Component props. 10 | * @param {string} props.count Checkbox count. 11 | * @param {string} props.id Checkbox ID. 12 | * @param {string} props.label Checkbox label. 13 | * 14 | * @returns {WPElement} Component element. 15 | */ 16 | export default ({ count, id, label, ...props }) => { 17 | return ( 18 |
19 | {' '} 20 | 23 |
24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /assets/js/sync/components/common/message-log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Log component. 8 | * 9 | * @param {object} props Component props. 10 | * @param {object[]} props.messages Log messages. 11 | * @returns {WPElement} Component. 12 | */ 13 | export default ({ messages }) => { 14 | return ( 15 |
16 | {messages.map((m, i) => ( 17 |
22 | {i + 1} 23 |
24 | ))} 25 | {messages.map((m) => ( 26 |
30 | {m.message} 31 |
32 | ))} 33 |
34 | ); 35 | }; 36 | -------------------------------------------------------------------------------- /assets/js/sync/components/common/progress-bar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Progress bar component. 8 | * 9 | * @param {object} props Component props. 10 | * @param {number} props.current Current value. 11 | * @param {number} props.total Current total. 12 | * @param {boolean} props.isComplete If operation is complete. 13 | * @returns {WPElement} Component. 14 | */ 15 | export default ({ isComplete, current, total }) => { 16 | const now = Math.floor((current / total) * 100); 17 | 18 | return ( 19 |
26 |
{`${now}%`}
30 |
31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /assets/css/instant-results/range-slider.css: -------------------------------------------------------------------------------- 1 | .ep-search-range-slider { 2 | align-items: center; 3 | display: flex; 4 | margin: 0.5em 0; 5 | min-height: var(--ep-search-range-thumb-size); 6 | } 7 | 8 | .ep-search-range-slider__track { 9 | background: var(--ep-search-alternate-background-color); 10 | border-radius: calc(var(--ep-search-range-track-size) / 2); 11 | height: var(--ep-search-range-track-size); 12 | } 13 | 14 | .ep-search-range-slider__track-1 { 15 | background-color: currentColor; 16 | } 17 | 18 | .ep-search-range-slider__thumb { 19 | background-color: currentColor; 20 | border-radius: calc(var(--ep-search-range-thumb-size) / 2); 21 | box-shadow: 22 | inset 0 0 0 calc(var(--ep-search-range-thumb-size) / 10) currentColor, 23 | inset 0 0 0 calc((var(--ep-search-range-thumb-size) - var(--ep-search-range-track-size)) / 2) var(--ep-search-background-color); 24 | height: var(--ep-search-range-thumb-size); 25 | width: var(--ep-search-range-thumb-size); 26 | } 27 | -------------------------------------------------------------------------------- /assets/js/blocks/related-posts/block.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { registerBlockType } from '@wordpress/blocks'; 5 | import { __ } from '@wordpress/i18n'; 6 | 7 | /** 8 | * Internal dependencies. 9 | */ 10 | import Edit from './Edit'; 11 | 12 | registerBlockType('elasticpress/related-posts', { 13 | title: __('Related Posts (ElasticPress)', 'elasticpress'), 14 | supports: { 15 | align: true, 16 | }, 17 | category: 'widgets', 18 | attributes: { 19 | alignment: { 20 | type: 'string', 21 | default: 'none', 22 | }, 23 | number: { 24 | type: 'number', 25 | default: 5, 26 | }, 27 | }, 28 | usesContext: ['postId'], 29 | 30 | /** 31 | * Handle edit 32 | * 33 | * @param {object} props Component properties 34 | * @returns {object} 35 | */ 36 | edit(props) { 37 | return ; 38 | }, 39 | 40 | /** 41 | * Handle save 42 | * 43 | * @returns {void} 44 | */ 45 | save() { 46 | return null; 47 | }, 48 | }); 49 | -------------------------------------------------------------------------------- /assets/css/sync/progress.css: -------------------------------------------------------------------------------- 1 | @keyframes epSyncRotation { 2 | 3 | from { 4 | transform: rotate(0deg); 5 | } 6 | 7 | to { 8 | transform: rotate(359deg); 9 | } 10 | } 11 | 12 | .ep-sync-progress { 13 | align-items: center; 14 | display: grid; 15 | grid-row-gap: 1rem; 16 | grid-template-columns: min-content minmax(max-content, 1fr) 3fr; 17 | margin-bottom: 1rem; 18 | 19 | @media (max-width: 960px) { 20 | grid-template-columns: min-content auto; 21 | } 22 | 23 | & svg { 24 | animation: epSyncRotation 1500ms infinite linear; 25 | animation-play-state: paused; 26 | height: 36px; 27 | margin-right: 12px; 28 | width: 36px; 29 | } 30 | } 31 | 32 | .ep-sync-progress--syncing { 33 | 34 | & svg { 35 | animation-play-state: running; 36 | } 37 | } 38 | 39 | .ep-sync-progress__details { 40 | 41 | & strong { 42 | display: block; 43 | font-size: 14px; 44 | } 45 | } 46 | 47 | .ep-sync-progress__progress-bar { 48 | 49 | @media (max-width: 960px) { 50 | grid-column: 1 / -1; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /assets/css/instant-results.css: -------------------------------------------------------------------------------- 1 | @import "instant-results/utilities.css"; 2 | @import "instant-results/checkbox.css"; 3 | @import "instant-results/input.css"; 4 | @import "instant-results/modal.css"; 5 | @import "instant-results/options-list.css"; 6 | @import "instant-results/page.css"; 7 | @import "instant-results/panel.css"; 8 | @import "instant-results/pagination.css"; 9 | @import "instant-results/range-slider.css"; 10 | @import "instant-results/result.css"; 11 | @import "instant-results/results.css"; 12 | @import "instant-results/sidebar.css"; 13 | @import "instant-results/sidebar-toggle.css"; 14 | @import "instant-results/sort.css"; 15 | @import "instant-results/tokens.css"; 16 | @import "instant-results/toolbar.css"; 17 | 18 | :root { 19 | --ep-search-background-color: #fff; 20 | --ep-search-alternate-background-color: #efefef; 21 | --ep-search-border-color: #dfdfdf; 22 | --ep-search-range-thumb-size: 1.625em; 23 | --ep-search-range-track-size: 0.75em; 24 | 25 | @media ( min-width: 768px ) { 26 | --ep-search-range-thumb-size: 1.25em; 27 | --ep-search-range-track-size: 0.5em; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/tools/sidebar-toggle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress deendencies. 3 | */ 4 | import { useContext, WPElement } from '@wordpress/element'; 5 | import { chevronDown, chevronUp, Icon } from '@wordpress/icons'; 6 | import { __ } from '@wordpress/i18n'; 7 | 8 | /** 9 | * Internal deendencies. 10 | */ 11 | import Context from '../../context'; 12 | 13 | /** 14 | * Open sidebar component. 15 | * 16 | * @returns {WPElement} Element. 17 | */ 18 | export default () => { 19 | const { 20 | state: { isSidebarOpen }, 21 | dispatch, 22 | } = useContext(Context); 23 | 24 | /** 25 | * Handle click. 26 | */ 27 | const onClick = () => { 28 | dispatch({ type: 'TOGGLE_SIDEBAR' }); 29 | }; 30 | 31 | return ( 32 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /assets/js/sync/components/icons/sync.js: -------------------------------------------------------------------------------- 1 | import { SVG, Path } from '@wordpress/primitives'; 2 | 3 | export default () => { 4 | return ( 5 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /includes/classes/FeatureRequirementsStatus.php: -------------------------------------------------------------------------------- 1 | code = $code; 29 | 30 | $this->message = $message; 31 | } 32 | 33 | /** 34 | * Returns the status of a feature 35 | * 36 | * 0 is no issues 37 | * 1 is usable but there are warnngs 38 | * 2 is not usable 39 | * 40 | * @var int 41 | * @since 2.2 42 | */ 43 | public $code; 44 | 45 | /** 46 | * Optional message to describe status code 47 | * 48 | * @var string|array 49 | * @since 2.2 50 | */ 51 | public $message; 52 | } 53 | -------------------------------------------------------------------------------- /assets/css/instant-results/modal.css: -------------------------------------------------------------------------------- 1 | .has-ep-search-modal { 2 | overflow: hidden; 3 | } 4 | 5 | .ep-search-modal { 6 | --ep-search-modal-focus-within: 0; 7 | background-color: rgba(43, 46, 56, 0.9); 8 | bottom: 0; 9 | display: flex; 10 | left: 0; 11 | position: fixed; 12 | right: 0; 13 | top: 0; 14 | z-index: 9999; 15 | 16 | @nest .rtl & { 17 | direction: rtl; 18 | text-align: right; 19 | } 20 | 21 | @nest .admin-bar & { 22 | top: 32px; 23 | 24 | @media ( max-width: 782px ) { 25 | top: 46px; 26 | } 27 | } 28 | 29 | &[aria-hidden="true"] { 30 | display: none; 31 | } 32 | 33 | &:focus-within { 34 | --ep-search-modal-focus-within: 1; 35 | } 36 | } 37 | 38 | .ep-search-modal__content { 39 | background-color: var(--ep-search-background-color); 40 | bottom: 0; 41 | display: flex; 42 | flex-direction: column; 43 | left: 0; 44 | position: absolute; 45 | right: 0; 46 | top: 0; 47 | 48 | @media ( min-width: 768px ) { 49 | bottom: 1em; 50 | margin: 0 auto; 51 | max-width: calc(100% - 2em); 52 | top: 1em; 53 | width: 80em; 54 | } 55 | } 56 | 57 | .ep-search-modal__close { 58 | align-self: flex-end; 59 | padding: 1em !important; 60 | } 61 | -------------------------------------------------------------------------------- /assets/css/instant-results/utilities.css: -------------------------------------------------------------------------------- 1 | .ep-search-reset-button { 2 | font: inherit !important; 3 | height: auto !important; 4 | letter-spacing: inherit !important; 5 | line-height: 1 !important; 6 | margin: 0 !important; 7 | padding: 0 !important; 8 | text-align: inherit !important; 9 | text-transform: inherit !important; 10 | width: auto !important; 11 | 12 | &, 13 | &:focus, 14 | &:hover { 15 | background: transparent !important; 16 | border: none !important; 17 | box-shadow: none !important; 18 | color: inherit !important; 19 | cursor: default !important; 20 | } 21 | 22 | &:focus { 23 | outline: medium auto Highlight !important; 24 | outline: medium auto -webkit-focus-ring-color !important; 25 | outline-offset: 0 !important; 26 | } 27 | } 28 | 29 | .ep-search-small-button { 30 | font-size: 0.875em !important; 31 | height: auto !important; 32 | line-height: 1 !important; 33 | padding: 0.5em !important; 34 | } 35 | 36 | .ep-search-icon-button { 37 | align-items: center; 38 | display: flex; 39 | justify-content: space-between; 40 | 41 | & svg { 42 | fill: currentColor; 43 | flex-shrink: 0; 44 | height: 1em; 45 | width: 1em; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /dist/js/settings-script.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var e={n:function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,{a:n}),n},d:function(t,n){for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t=window.wp.domReady,n=e.n(t),r=window.wp.i18n;n()((()=>{const e=document.querySelectorAll(".ep-credentials-tab"),t=document.getElementById("ep_host"),n=t.labels[0],s=t.nextElementSibling,a=document.getElementsByClassName("ep-additional-fields");let o=document.querySelector(".nav-tab-active");const i=()=>o&&"epio"in o.dataset;let c=i()?t.value:"",l=i()?"":t.value;const u=e=>{i()?c=e.currentTarget.value:l=e.currentTarget.value},d=u=>{o=u.currentTarget;for(const t of e)t.classList.toggle("nav-tab-active",t===o);for(const e of a)e.classList.toggle("hidden",!i());n.innerText=i()?(0,r.__)("ElasticPress.io Host URL","elasticpress"):(0,r.__)("Elasticsearch Host URL","elasticpress"),t.disabled||(t.value=i()?c:l,s.innerText=i()?(0,r.__)("Plug in your ElasticPress.io server here!","elasticpress"):(0,r.__)("Plug in your Elasticsearch server here!","elasticpress"))};t&&t.addEventListener("input",u);for(const t of e)t.addEventListener("click",d)}))}(); -------------------------------------------------------------------------------- /assets/js/sync/components/sync/status.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { Icon } from '@wordpress/components'; 5 | import { dateI18n } from '@wordpress/date'; 6 | import { WPElement } from '@wordpress/element'; 7 | import { __ } from '@wordpress/i18n'; 8 | 9 | /** 10 | * Internal dependencies. 11 | */ 12 | import DateTime from '../common/date-time'; 13 | import thumbsDown from '../icons/thumbs-down'; 14 | import thumbsUp from '../icons/thumbs-up'; 15 | 16 | /** 17 | * Sync button component. 18 | * 19 | * @param {object} props Component props. 20 | * @param {string} props.dateTime Sync date and time. 21 | * @param {boolean} props.isSuccess If sync was a success. 22 | * @returns {WPElement} Component. 23 | */ 24 | export default ({ dateTime, isSuccess }) => { 25 | return ( 26 |

31 | 32 | 33 | {isSuccess 34 | ? __('Sync success on', 'elasticpress') 35 | : __('Sync unsuccessful on', 'elasticpress')}{' '} 36 | 37 | 38 |

39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/common/panel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { useState, WPElement } from '@wordpress/element'; 5 | import { chevronDown, chevronUp, Icon } from '@wordpress/icons'; 6 | 7 | /** 8 | * Facet wrapper component. 9 | * 10 | * @param {object} props Component props. 11 | * @param {WPElement} props.children Component children. 12 | * @param {boolean} props.defaultIsOpen Whether the panel is open by default. 13 | * @param {string} props.label Facet label. 14 | * @returns {WPElement} Component element. 15 | */ 16 | export default ({ children, defaultIsOpen, label }) => { 17 | const [isOpen, setIsOpen] = useState(defaultIsOpen); 18 | 19 | /** 20 | * Handle click event on the header. 21 | */ 22 | const onClick = () => { 23 | setIsOpen(!isOpen); 24 | }; 25 | 26 | return ( 27 |
28 |

29 | 38 |

39 |
40 | {children(isOpen)} 41 |
42 |
43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/tools/active-constraints.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { createPortal, createRef, WPElement } from '@wordpress/element'; 5 | import { closeSmall, Icon } from '@wordpress/icons'; 6 | import { __, sprintf } from '@wordpress/i18n'; 7 | 8 | /** 9 | * Internal dependencies. 10 | */ 11 | import SmallButton from '../common/small-button'; 12 | 13 | /** 14 | * Create ref for portal. 15 | */ 16 | const ref = createRef(); 17 | 18 | /** 19 | * Active filter component. 20 | * 21 | * @param {object} props Props. 22 | * @param {string} props.label Constraint label. 23 | * @param {Function} props.onClick Click handler. 24 | * @returns {WPElement} Element. 25 | */ 26 | export const ActiveContraint = ({ label, onClick }) => { 27 | if (!ref.current) { 28 | return null; 29 | } 30 | 31 | return createPortal( 32 | 41 | 42 | {label} 43 | , 44 | ref.current, 45 | ); 46 | }; 47 | 48 | /** 49 | * Active constraints component. 50 | * 51 | * @returns {WPElement} Element. 52 | */ 53 | export default () => { 54 | return
; 55 | }; 56 | -------------------------------------------------------------------------------- /assets/js/facets.js: -------------------------------------------------------------------------------- 1 | import { debounce } from './utils/helpers'; 2 | 3 | /** 4 | * Filters the facets to match the input search term when 5 | * the number of terms exceeds the threshold determined 6 | * by the ep_facet_search_threshold filter 7 | * 8 | * @param {event} event - keyup 9 | * @param {Node} facetTerms - terms node 10 | */ 11 | const handleFacetSearch = (event, facetTerms) => { 12 | const { target } = event; 13 | const searchTerm = target.value.toLowerCase(); 14 | const terms = facetTerms.querySelectorAll('.term'); 15 | 16 | terms.forEach((term) => { 17 | const slug = term.getAttribute('data-term-slug'); 18 | const name = term.getAttribute('data-term-name'); 19 | 20 | if (name.includes(searchTerm) || slug.includes(searchTerm)) { 21 | term.classList.remove('hide'); 22 | } else { 23 | term.classList.add('hide'); 24 | } 25 | }); 26 | }; 27 | 28 | /** 29 | * Filter facet choices to match the search field term 30 | */ 31 | const facets = document.querySelectorAll('.widget_ep-facet, .wp-block-elasticpress-facet'); 32 | 33 | facets.forEach((facet) => { 34 | const facetSearchInput = facet.querySelector('.facet-search'); 35 | 36 | if (!facetSearchInput) { 37 | return; 38 | } 39 | 40 | const facetTerms = facet.querySelector('.terms'); 41 | 42 | facet.querySelector('.facet-search').addEventListener( 43 | 'keyup', 44 | debounce((event) => { 45 | if (event.keyCode === 13) { 46 | return; 47 | } 48 | 49 | handleFacetSearch(event, facetTerms); 50 | }, 200), 51 | ); 52 | }); 53 | -------------------------------------------------------------------------------- /assets/js/notice.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import apiFetch from '@wordpress/api-fetch'; 5 | import domReady from '@wordpress/dom-ready'; 6 | 7 | /** 8 | * Window dependencies. 9 | */ 10 | const { epAdmin, ajaxurl } = window; 11 | 12 | /** 13 | * Initialize. 14 | * 15 | * @returns {void} 16 | */ 17 | const init = () => { 18 | const notices = document.querySelectorAll('.notice[data-ep-notice]'); 19 | 20 | /** 21 | * Handle clicking in an ElasticPress notice. 22 | * 23 | * If the click target is the dismiss button send an AJAX request to remember 24 | * the dismissal. 25 | * 26 | * @param {Event} event Click event. 27 | * @returns {void} 28 | */ 29 | const onClick = (event) => { 30 | /** 31 | * Only proceed if we're clicking dismiss. 32 | */ 33 | if (!event.target.classList.contains('notice-dismiss')) { 34 | return; 35 | } 36 | 37 | /** 38 | * Handler is admin-ajax.php, so the body needs to be form data. 39 | */ 40 | const formData = new FormData(); 41 | 42 | formData.append('action', 'ep_notice_dismiss'); 43 | formData.append('notice', event.currentTarget.dataset.epNotice); 44 | formData.append('nonce', epAdmin.nonce); 45 | 46 | apiFetch({ 47 | method: 'POST', 48 | url: ajaxurl, 49 | body: formData, 50 | }); 51 | }; 52 | 53 | /** 54 | * Bind click events to notices. 55 | */ 56 | for (const notice of notices) { 57 | notice.addEventListener('click', onClick); 58 | } 59 | }; 60 | 61 | /** 62 | * Initialize. 63 | */ 64 | domReady(init); 65 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/facets/facet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependencies. 8 | */ 9 | import PostTypeFacet from './post-type-facet'; 10 | import PriceRangeFacet from './price-range-facet'; 11 | import TaxonomyTermsFacet from './taxonomy-terms-facet'; 12 | 13 | /** 14 | * Facet component. 15 | * 16 | * @param {object} props Props. 17 | * @param {number} props.index Facet index. 18 | * @param {string} props.name Facet name. 19 | * @param {string} props.label Facet label. 20 | * @param {string} props.postTypes Facet post types. 21 | * @param {'post_type'|'price_range'|'taxonomy'} props.type Facet type. 22 | * @returns {WPElement} Component element. 23 | */ 24 | export default ({ index, label, name, postTypes, type }) => { 25 | const defaultIsOpen = index < 2; 26 | 27 | switch (type) { 28 | case 'post_type': 29 | return ; 30 | case 'price_range': 31 | return ; 32 | case 'taxonomy': 33 | return ( 34 | 40 | ); 41 | default: 42 | return null; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /assets/js/instant-results/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { __ } from '@wordpress/i18n'; 5 | 6 | /** 7 | * Window dependencies. 8 | */ 9 | const { 10 | apiEndpoint, 11 | apiHost, 12 | argsSchema, 13 | currencyCode, 14 | facets, 15 | isWooCommerce, 16 | locale, 17 | matchType, 18 | paramPrefix, 19 | postTypeLabels, 20 | taxonomyLabels, 21 | } = window.epInstantResults; 22 | 23 | /** 24 | * Sorting options configuration. 25 | */ 26 | const sortOptions = { 27 | relevance_desc: { 28 | name: __('Most relevant', 'elasticpress'), 29 | orderby: 'relevance', 30 | order: 'desc', 31 | currencyCode, 32 | }, 33 | date_desc: { 34 | name: __('Date, newest to oldest', 'elasticpress'), 35 | orderby: 'date', 36 | order: 'desc', 37 | }, 38 | date_asc: { 39 | name: __('Date, oldest to newest', 'elasticpress'), 40 | orderby: 'date', 41 | order: 'asc', 42 | }, 43 | }; 44 | 45 | /** 46 | * Sort by price is only available for WooCommerce. 47 | */ 48 | if (isWooCommerce) { 49 | sortOptions.price_desc = { 50 | name: __('Price, highest to lowest', 'elasticpress'), 51 | orderby: 'price', 52 | order: 'desc', 53 | }; 54 | 55 | sortOptions.price_asc = { 56 | name: __('Price, lowest to highest', 'elasticpress'), 57 | orderby: 'price', 58 | order: 'asc', 59 | }; 60 | } 61 | 62 | export { 63 | apiEndpoint, 64 | apiHost, 65 | argsSchema, 66 | currencyCode, 67 | facets, 68 | isWooCommerce, 69 | locale, 70 | matchType, 71 | paramPrefix, 72 | postTypeLabels, 73 | sortOptions, 74 | taxonomyLabels, 75 | }; 76 | -------------------------------------------------------------------------------- /assets/js/weighting.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import domReady from '@wordpress/dom-ready'; 5 | 6 | /** 7 | * Initialize. 8 | * 9 | * @returns {void} 10 | */ 11 | const init = () => { 12 | /** 13 | * Update the value in the range input label. 14 | * 15 | * @param {Element} el Range input element. 16 | */ 17 | const updateSliderValue = (el) => { 18 | el.labels[0].querySelector('.weighting-value').textContent = el.disabled ? '0' : el.value; 19 | }; 20 | 21 | /** 22 | * Handle range slider input. 23 | * 24 | * @param {Event} event Input event. 25 | */ 26 | const onSliderInput = (event) => { 27 | updateSliderValue(event.currentTarget); 28 | }; 29 | 30 | /** 31 | * Handle checkbox change. 32 | * 33 | * @param {Event} event Change event. 34 | */ 35 | const onCheckboxChange = (event) => { 36 | const el = event.currentTarget.closest('fieldset').querySelector('input[type="range"]'); 37 | 38 | el.disabled = !event.currentTarget.checked; 39 | 40 | updateSliderValue(el); 41 | }; 42 | 43 | /** 44 | * Bind events. 45 | */ 46 | const sliders = document.querySelectorAll('.weighting-settings input[type=range]'); 47 | 48 | for (const slider of sliders) { 49 | slider.addEventListener('input', onSliderInput); 50 | } 51 | 52 | const checkboxes = document.querySelectorAll( 53 | '.weighting-settings .searchable input[type=checkbox]', 54 | ); 55 | 56 | for (const checkbox of checkboxes) { 57 | checkbox.addEventListener('change', onCheckboxChange); 58 | } 59 | }; 60 | 61 | /** 62 | * Initialize. 63 | */ 64 | domReady(init); 65 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/tools/clear-constraints.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { useContext, useMemo, WPElement } from '@wordpress/element'; 5 | import { __ } from '@wordpress/i18n'; 6 | 7 | /** 8 | * Internal dependencies. 9 | */ 10 | import { facets } from '../../config'; 11 | import Context from '../../context'; 12 | import SmallButton from '../common/small-button'; 13 | 14 | /** 15 | * Active constraints component. 16 | * 17 | * @returns {WPElement} Element. 18 | */ 19 | export default () => { 20 | const { 21 | state: { args }, 22 | dispatch, 23 | } = useContext(Context); 24 | 25 | /** 26 | * Return whether there are active filters. 27 | * 28 | * Only filters that are available as facets are checked, as these are the 29 | * only filters that will be cleared. This is to support applying filters 30 | * that cannot be modified by the user. 31 | * 32 | * @returns {boolean} Whether there are active filters. 33 | */ 34 | const hasFilters = useMemo(() => { 35 | return facets.some(({ name, type }) => { 36 | switch (type) { 37 | case 'post_type': 38 | case 'taxonomy': 39 | return args[name]?.length > 0; 40 | case 'price_range': 41 | return args.max_price || args.min_price; 42 | default: 43 | return args[name]; 44 | } 45 | }); 46 | }, [args]); 47 | 48 | /** 49 | * Handle clicking button. 50 | * 51 | * @returns {void} 52 | */ 53 | const onClick = () => { 54 | dispatch({ type: 'CLEAR_FACETS' }); 55 | }; 56 | 57 | return ( 58 | hasFilters && ( 59 | {__('Clear filters', 'elasticpress')} 60 | ) 61 | ); 62 | }; 63 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/layout.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { useContext, WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependencies. 8 | */ 9 | import { facets } from '../config'; 10 | import Context from '../context'; 11 | import Facet from './facets/facet'; 12 | import SearchTermFacet from './facets/search-term-facet'; 13 | import Results from './layout/results'; 14 | import Sidebar from './layout/sidebar'; 15 | import Toolbar from './layout/toolbar'; 16 | import ActiveConstraints from './tools/active-constraints'; 17 | import ClearConstraints from './tools/clear-constraints'; 18 | import SidebarToggle from './tools/sidebar-toggle'; 19 | import Sort from './tools/sort'; 20 | 21 | /** 22 | * Search dialog. 23 | * 24 | * @returns {WPElement} Component element. 25 | */ 26 | export default () => { 27 | const { 28 | state: { isLoading }, 29 | } = useContext(Context); 30 | 31 | return ( 32 |
33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 43 |
44 | 45 | 46 | {facets.map(({ label, name, postTypes, type }, index) => ( 47 | 55 | ))} 56 | 57 | 58 | 59 |
60 |
61 | ); 62 | }; 63 | -------------------------------------------------------------------------------- /assets/js/instant-results/components/tools/sort.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress deendencies. 3 | */ 4 | import { useContext, useMemo, WPElement } from '@wordpress/element'; 5 | import { __ } from '@wordpress/i18n'; 6 | 7 | /** 8 | * Internal deendencies. 9 | */ 10 | import { sortOptions } from '../../config'; 11 | import Context from '../../context'; 12 | 13 | /** 14 | * Search results component. 15 | * 16 | * @returns {WPElement} Component element. 17 | */ 18 | export default () => { 19 | const { 20 | state: { 21 | args: { orderby, order }, 22 | }, 23 | dispatch, 24 | } = useContext(Context); 25 | 26 | /** 27 | * The key for the current sorting option. 28 | */ 29 | const currentOption = useMemo(() => { 30 | return Object.keys(sortOptions).find((key) => { 31 | return sortOptions[key].orderby === orderby && sortOptions[key].order === order; 32 | }); 33 | }, [orderby, order]); 34 | 35 | /** 36 | * Handle sorting option change. 37 | * 38 | * @param {Event} event Change event. 39 | */ 40 | const onChange = (event) => { 41 | const { orderby, order } = sortOptions[event.target.value]; 42 | 43 | dispatch({ type: 'APPLY_ARGS', payload: { orderby, order } }); 44 | }; 45 | 46 | return ( 47 | 62 | ); 63 | }; 64 | -------------------------------------------------------------------------------- /assets/js/sync/utilities.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Clear sync parameter from the URL. 3 | * 4 | * @returns {void} 5 | */ 6 | export const clearSyncParam = () => { 7 | window.history.replaceState( 8 | {}, 9 | document.title, 10 | document.location.pathname + document.location.search.replace(/&do_sync/, ''), 11 | ); 12 | }; 13 | 14 | /** 15 | * Get the total number of items from index meta. 16 | * 17 | * @param {object} indexMeta Index meta. 18 | * @returns {number} Number of items. 19 | */ 20 | export const getItemsTotalFromIndexMeta = (indexMeta) => { 21 | let itemsTotal = 0; 22 | 23 | if (indexMeta.current_sync_item) { 24 | itemsTotal += indexMeta.current_sync_item.found_items; 25 | } 26 | 27 | itemsTotal = indexMeta.sync_stack.reduce( 28 | (itemsTotal, sync) => itemsTotal + sync.found_items, 29 | itemsTotal, 30 | ); 31 | 32 | itemsTotal += indexMeta.totals.failed; 33 | itemsTotal += indexMeta.totals.skipped; 34 | itemsTotal += indexMeta.totals.synced; 35 | 36 | return itemsTotal; 37 | }; 38 | 39 | /** 40 | * Get the number of processed items from index meta. 41 | * 42 | * @param {object} indexMeta Index meta. 43 | * @returns {number} Number of processed items. 44 | */ 45 | export const getItemsProcessedFromIndexMeta = (indexMeta) => { 46 | let itemsProcessed = 0; 47 | 48 | if (indexMeta.current_sync_item) { 49 | itemsProcessed += indexMeta.current_sync_item.failed; 50 | itemsProcessed += indexMeta.current_sync_item.skipped; 51 | itemsProcessed += indexMeta.current_sync_item.synced; 52 | } 53 | 54 | itemsProcessed += indexMeta.totals.failed; 55 | itemsProcessed += indexMeta.totals.skipped; 56 | itemsProcessed += indexMeta.totals.synced; 57 | 58 | return itemsProcessed; 59 | }; 60 | -------------------------------------------------------------------------------- /assets/css/facets.css: -------------------------------------------------------------------------------- 1 | .widget_ep-facet, 2 | .wp-block-elasticpress-facet { 3 | 4 | & input[type="search"] { 5 | margin-bottom: 1rem; 6 | } 7 | 8 | & .searchable .inner { 9 | max-height: 20em; 10 | overflow: scroll; 11 | } 12 | 13 | & .term.hide { 14 | display: none; 15 | } 16 | 17 | & .empty-term { 18 | opacity: 0.5; 19 | position: relative; 20 | } 21 | 22 | & .empty-term::after { 23 | bottom: 0; 24 | content: " "; 25 | display: block; 26 | left: 0; 27 | position: absolute; 28 | right: 0; 29 | top: 0; 30 | width: 100%; 31 | z-index: 2; 32 | } 33 | 34 | & .level-1 { 35 | padding-left: 20px; 36 | } 37 | 38 | & .level-2 { 39 | padding-left: 40px; 40 | } 41 | 42 | & .level-3 { 43 | padding-left: 60px; 44 | } 45 | 46 | & .level-4 { 47 | padding-left: 80px; 48 | } 49 | 50 | & .level-5 { 51 | padding-left: 100px; 52 | } 53 | 54 | & input[disabled] { 55 | cursor: pointer; 56 | opacity: 1; 57 | } 58 | 59 | & .term a { 60 | align-items: center; 61 | display: flex; 62 | position: relative; 63 | } 64 | 65 | & .term a:hover .ep-checkbox { 66 | background-color: #ccc; 67 | } 68 | } 69 | 70 | .ep-checkbox { 71 | align-items: center; 72 | background-color: #eee; 73 | display: flex; 74 | flex-shrink: 0; 75 | height: 1em; 76 | justify-content: center; 77 | margin-right: 0.25em; 78 | width: 1em; 79 | } 80 | 81 | .ep-checkbox::after { 82 | border: solid #fff; 83 | border-width: 0 0.125em 0.125em 0; 84 | content: ""; 85 | display: none; 86 | height: 0.5em; 87 | transform: rotate(45deg); 88 | width: 0.25em; 89 | } 90 | 91 | .ep-checkbox.checked { 92 | background-color: #5e5e5e; 93 | } 94 | 95 | .ep-checkbox.checked::after { 96 | display: block; 97 | } 98 | -------------------------------------------------------------------------------- /assets/js/synonyms/components/editors/SolrEditor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * WordPress dependencies. 3 | */ 4 | import { useContext, WPElement } from '@wordpress/element'; 5 | 6 | /** 7 | * Internal dependencies. 8 | */ 9 | import { State, Dispatch } from '../../context'; 10 | 11 | /** 12 | * Synonym Inspector 13 | * 14 | * @returns {WPElement} SolrEditor Component 15 | */ 16 | const SolrEditor = () => { 17 | const state = useContext(State); 18 | const dispatch = useContext(Dispatch); 19 | const { alternatives, isSolrEditable, isSolrVisible, sets, solr } = state; 20 | const { 21 | synonymsTextareaInputName, 22 | solrInputHeading, 23 | solrAlternativesErrorMessage, 24 | solrSetsErrorMessage, 25 | } = window.epSynonyms.i18n; 26 | 27 | return ( 28 |
29 |
30 |

31 | {solrInputHeading} 32 |

33 |
34 |