Skip to content

Commit

Permalink
Merge branch 'develop' into feature/vector-embeddings
Browse files Browse the repository at this point in the history
  • Loading branch information
felipeelia authored Jan 30, 2025
2 parents ca50fe4 + f61c5d8 commit 58c9c5c
Show file tree
Hide file tree
Showing 27 changed files with 2,204 additions and 14,961 deletions.
5 changes: 5 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"presets": [
"@10up/babel-preset-default"
]
}
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/.nvmrc export-ignore
/.stylelintignore export-ignore
/.stylelintrc export-ignore
/.wp-env.json export-ignore
/babel.config.js export-ignore
/CHANGELOG.md export-ignore
/CODE_OF_CONDUCT.md export-ignore
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/cypress-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,14 @@ jobs:
${{ github.workspace }}/tests/cypress/videos/
${{ github.workspace }}/tests/cypress/logs/
- name: Delete Elasticsearch search templates
if: always()
run: |
./bin/wp-env-cli tests-wordpress "wp --allow-root plugin activate elasticpress elasticpress-labs"
./bin/wp-env-cli tests-wordpress "wp --allow-root elasticpress-tests delete-all-search-templates"
- name: Delete Elasticsearch indices
if: always()
run: |
./bin/wp-env-cli tests-wordpress "wp --allow-root plugin activate elasticpress elasticpress-labs"
./bin/wp-env-cli tests-wordpress "wp --allow-root elasticpress-tests delete-all-indices"
./bin/wp-env-cli tests-wordpress "wp --allow-root elasticpress-tests delete-all-indices"
1 change: 1 addition & 0 deletions .wp-env.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"mappings": {
"wp-content/plugins/elasticpress-labs": ".",
".htaccess": "./tests/cypress/wordpress-files/.htaccess",
"wp-content/mu-plugins/delete-all-templates.php": "./tests/cypress/wordpress-files/test-mu-plugins/delete-all-templates.php",
"wp-content/mu-plugins/unique-index-name.php": "./tests/cypress/wordpress-files/test-mu-plugins/unique-index-name.php"
}
}
Expand Down
73 changes: 73 additions & 0 deletions assets/js/search-templates/apps/search-templates-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* WordPress Dependencies.
*/
import { createInterpolateElement, WPElement } from '@wordpress/element';
import { Panel, Spinner } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies.
*/
import { useSearchTemplate } from '../provider';
import TemplateRow from '../components/template-row';
import NewTemplateRow from '../components/new-template-row';
import { endpointExample, searchApiDocUrl } from '../config';

/**
* Search Templates app.
*
* @returns {WPElement} App element.
*/
export default () => {
const { isLoading, templates } = useSearchTemplate();

return (
<>
<p>
{createInterpolateElement(
__(
'Search templates are Elasticsearch queries stored in ElasticPress.io servers used by the <a>Search API</a>. Please note that all the API fields are still available for custom search templates. Your templates do not to differ in post types, offset, pagination arguments, or even filters, as for those you can still use query parameters. The templates can be used for searching in different fields or applying different scores, for instance.',
'elasticpress-labs',
),
{ a: <a href={searchApiDocUrl} /> }, // eslint-disable-line jsx-a11y/anchor-has-content, jsx-a11y/control-has-associated-label
)}
</p>
<p>
{createInterpolateElement(
sprintf(
__(
'Once you have a search template saved, you can start sending requests to your endpoint URL below. Your template needs to have <code>{{ep_placeholder}}</code> in all places where the search term needs to be used.',
'elasticpress-labs',
),
endpointExample,
),
{ code: <code /> },
)}
</p>
<p>
{createInterpolateElement(
sprintf(
__('<strong>Endpoint URL:</strong> <code>%s</code>', 'elasticpress-labs'),
endpointExample,
),
{ strong: <strong />, code: <code /> },
)}
</p>
<Panel className="ep-search-template-panel">
{isLoading ? (
<div style={{ padding: '20px', textAlign: 'center' }}>
{__('Loading...', 'elasticpress-labs')}
<Spinner />
</div>
) : (
<>
{Object.keys(templates).map((templateName) => (
<TemplateRow key={templateName} templateName={templateName} />
))}
<NewTemplateRow />
</>
)}
</Panel>
</>
);
};
89 changes: 89 additions & 0 deletions assets/js/search-templates/components/new-template-row.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* WordPress Dependencies.
*/
import { Button, Flex, Notice, PanelBody, PanelRow, TextControl } from '@wordpress/components';
import { useState, WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies.
*/
import { useSearchTemplate, useSearchTemplateDispatch } from '../provider';
import { useSettingsScreen } from '../../settings-screen';
import TemplateField from './template-field';

/**
* New Template Row component.
*
* @returns {WPElement}
*/
export default () => {
const [name, setName] = useState('');
const [template, setTemplate] = useState('');
const [disabled, setDisabled] = useState(false);

const { templates } = useSearchTemplate();
const { saveTemplate } = useSearchTemplateDispatch();
const { createNotice } = useSettingsScreen();

const onAddNewTemplate = () => {
saveTemplate(name, template)
.then(() => {
setName('');
setTemplate('');
createNotice('success', __('Template saved.', 'elasticpress-labs'));
})
.catch((error) => {
createNotice(
'error',
error.message ||
__('Could not save the template. Please try again.', 'elasticpress-labs'),
);
// eslint-disable-next-line no-console
console.error(__('ElasticPress Labs Error: ', 'elasticpress-labs'), error);
});
};

const onChangeName = (newName) => {
setName(newName);
setDisabled(Object.keys(templates).includes(newName));
};

return (
<PanelBody title={__('Add New Template', 'elasticpress-labs')} initialOpen>
<PanelRow>
<Flex direction="column" style={{ width: '100%' }}>
{name && disabled && (
<Notice status="error" isDismissible={false}>
{__(
'This name is already in use. You can change the existing template instead.',
'elasticpress-labs',
)}
</Notice>
)}
<TextControl
label={__('Name', 'elasticpress-labs')}
help={__(
'Template names are not editable. Double-check your template name before saving it.',
'elasticpress-labs',
)}
value={name}
onChange={onChangeName}
/>
<TemplateField value={template} onChange={setTemplate} />
<Flex justify="flex-start">
<Button
disabled={disabled}
isBusy={false}
onClick={onAddNewTemplate}
type="button"
variant="primary"
>
{__('Save Template', 'elasticpress-labs')}
</Button>
</Flex>
</Flex>
</PanelRow>
</PanelBody>
);
};
80 changes: 80 additions & 0 deletions assets/js/search-templates/components/template-field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* WordPress Dependencies.
*/
import { BaseControl, Button, Flex, Notice } from '@wordpress/components';
import { createInterpolateElement, WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies.
*/
import { defaultTemplate } from '../config';

/**
* Template Field component.
*
* @param {object} props Component props.
* @param {string} props.value The search template as a string.
* @param {Function} props.onChange Function to be executed when the value changes.
* @param {boolean} props.disabled If the field should be enabled or not.
* @returns {WPElement}
*/
export default ({ value, onChange, disabled }) => {
const isValueValidJson = () => {
if (!value) {
return true;
}

try {
return JSON.parse(value) && !!value;
} catch (e) {
return false;
}
};

return (
<BaseControl
help={createInterpolateElement(
__(
'Make sure your template is a valid JSON object and has <code>{{ep_placeholder}}</code>, so it can be replaced by the actual search term.',
'elasticpress-labs',
),
{ code: <code /> },
)}
>
{isValueValidJson() || (
<Notice status="error" isDismissible={false}>
{__('This does not seem to be a valid JSON object.', 'elasticpress-labs')}
</Notice>
)}
<Flex style={{ marginBottom: '10px' }}>
<BaseControl.VisualLabel>
{__('Template', 'elasticpress-labs')}
</BaseControl.VisualLabel>
{defaultTemplate && (
<Button
disabled={false}
isBusy={false}
size="small"
onClick={() => {
onChange(JSON.stringify(defaultTemplate, null, '\t'));
}}
type="button"
variant="secondary"
>
{__('Import default template', 'elasticpress-labs')}
</Button>
)}
</Flex>
<textarea
value={value}
onChange={(e) => onChange(e.target.value)}
rows={10}
disabled={disabled}
style={{
width: '100%',
}}
/>
</BaseControl>
);
};
Loading

0 comments on commit 58c9c5c

Please sign in to comment.