From 6533af8757f4cfe54a2adeec05706445b400c610 Mon Sep 17 00:00:00 2001
From: mehidi258
Date: Tue, 8 Feb 2022 22:48:27 +0600
Subject: [PATCH 01/63] Add weghting screen page in react
---
assets/css/dashboard.css | 109 ++++++++-
assets/js/weighting/components/field-group.js | 181 ++++++++++++++
assets/js/weighting/components/field-item.js | 102 ++++++++
assets/js/weighting/components/meta-Item.js | 72 ++++++
.../js/weighting/components/undo-changes.js | 20 ++
assets/js/weighting/dummyData.js | 224 ++++++++++++++++++
assets/js/weighting/index.js | 214 +++++++++++++++++
assets/js/weighting/utils.js | 7 +
includes/classes/Feature/Search/Weighting.php | 92 +++----
package-lock.json | 45 ++--
package.json | 3 +-
11 files changed, 982 insertions(+), 87 deletions(-)
create mode 100644 assets/js/weighting/components/field-group.js
create mode 100644 assets/js/weighting/components/field-item.js
create mode 100644 assets/js/weighting/components/meta-Item.js
create mode 100644 assets/js/weighting/components/undo-changes.js
create mode 100644 assets/js/weighting/dummyData.js
create mode 100644 assets/js/weighting/index.js
create mode 100644 assets/js/weighting/utils.js
diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css
index 19f2d6bbb3..72f24ca62d 100644
--- a/assets/css/dashboard.css
+++ b/assets/css/dashboard.css
@@ -658,18 +658,97 @@ h2.ep-list-features {
* Weighting
*/
-.weighting-settings .postbox {
+.weighting-settings {
box-sizing: border-box;
max-width: 650px;
- & * {
- box-sizing: border-box;
+ & .postbox {
+
+ & .components-range-control__number {
+ display: none;
+ }
+
+ & .postbox__header {
+ align-items: center;
+ border-bottom: 1px solid #c3c4c7;
+ display: flex;
+ }
+
+ & .undo-changes {
+ background-color: transparent;
+ border: 0;
+ color: #1e8cbe;
+ cursor: pointer;
+ margin-left: auto;
+ padding: 0 10px;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
+ & * {
+ box-sizing: border-box;
+ }
+ }
+
+ & .add-meta-key-wrap {
+ align-items: center;
+ display: flex;
+
+ & legend {
+ top: 0;
+ }
+ }
+
+ & .add-meta-key {
+ width: 300px;
+ }
+
+ & .submit__button {
+ align-items: center;
+ background: #fff;
+ bottom: 0;
+ display: flex;
+ padding: 10px;
+ position: sticky;
+
+ & button {
+ margin-right: 10px;
+ }
+ }
+
+}
+
+.components-range-control__wrapper {
+ min-width: 100px;
+
+ & span:last-child {
+ background-color: #1e8cbe;
+ pointer-events: none;
}
}
+div.components-base-control__field {
+ align-items: center;
+ display: flex;
+ height: 20px;
+ margin: 0;
+
+ & .components-base-control__label {
+ margin: 0;
+ }
+}
+
+.field-item .components-base-control__help {
+ margin-top: -10px;
+ padding: 0;
+}
+
.weighting-settings .postbox h2.hndle {
color: #444;
cursor: inherit;
+ width: 110px;
}
.weighting-settings fieldset {
@@ -702,9 +781,26 @@ h2.ep-list-features {
background: #f9f9f9;
}
-.weighting-settings .searchable {
+.field-item {
+ align-items: center;
+ display: flex;
+}
+
+.remove-meta-item {
+ cursor: pointer;
+
+ & path {
+ fill: #d84440;
+ }
+}
+
+.field-item p {
display: inline-block;
- width: 120px;
+ padding: 0 10px;
+
+ & a {
+ text-decoration: none;
+ }
}
.weighting-settings .weighting {
@@ -713,7 +809,6 @@ h2.ep-list-features {
}
.weighting-settings .weighting label {
- margin-right: 10px;
min-width: 80px;
}
@@ -724,7 +819,7 @@ h2.ep-list-features {
height: 1em;
margin: 0;
vertical-align: middle;
- width: 200px;
+ width: 120px;
}
.weighting-settings input[type="range"]:focus {
diff --git a/assets/js/weighting/components/field-group.js b/assets/js/weighting/components/field-group.js
new file mode 100644
index 0000000000..57777abce8
--- /dev/null
+++ b/assets/js/weighting/components/field-group.js
@@ -0,0 +1,181 @@
+/**
+ * Wordpress Dependecies.
+ */
+import { useState } from '@wordpress/element';
+import AsyncSelect from 'react-select/async';
+import { __ } from '@wordpress/i18n';
+import PropTypes from 'prop-types';
+
+/**
+ * Internal Dependencies.
+ */
+import FieldItem from './field-item';
+import MetaItem from './meta-Item';
+import { sortListByOrder } from '../utils';
+
+const FieldGroup = ({
+ postType,
+ onChangeHandler,
+ getCurrentFormData,
+ formData,
+ setFormData,
+ undoHandler,
+ savedData,
+}) => {
+ const [selectedValue, setSelectedValue] = useState(null);
+
+ // handle selection
+ const handleChange = (value) => {
+ let currentFormData = getCurrentFormData(postType.name);
+ if (currentFormData.metas.findIndex((metaItem) => metaItem.name === value.name) === -1) {
+ currentFormData = {
+ ...currentFormData,
+ metas: [...currentFormData.metas, value],
+ };
+ }
+ const excludedFormData = formData.filter((item) => item.name !== postType.name);
+ const newFormData = [...excludedFormData, currentFormData];
+ setFormData(sortListByOrder(newFormData));
+ setSelectedValue(value);
+ };
+
+ // load options using API call
+ const loadOptions = (inputValue) => {
+ return fetch(
+ `https://jsonplaceholder.typicode.com/posts?search=${inputValue}$post_type=${postType.name}`,
+ )
+ .then((res) => res.json())
+ .then((result) => {
+ const newResult = [];
+ result.forEach((item) => {
+ newResult.push({
+ name: item.title,
+ searchable: false,
+ weight: 10,
+ });
+ });
+ return newResult;
+ });
+ };
+
+ const removeMetaItem = (metaName) => {
+ const newCurrentFormData = {
+ ...getCurrentFormData(postType.name),
+ metas: getCurrentFormData(postType.name).metas.filter((item) => item.name !== metaName),
+ };
+
+ const excludedFormData = formData.filter((item) => item.name !== postType.name);
+ const newFormData = [...excludedFormData, newCurrentFormData];
+ setFormData(sortListByOrder(newFormData));
+ };
+
+ const currentOriginalData = savedData.find((item) => item.name === postType.name);
+
+ return (
+ <>
+
+
{__('Attributes', 'elasticpress')}
+
+ {postType.attributes.map((attribute, index) => {
+ const fieldType = 'attributes';
+ const isAttributeChanged =
+ JSON.stringify(attribute) !==
+ JSON.stringify(currentOriginalData[fieldType][index]);
+ return (
+
+ );
+ })}
+
+
+
+
{__('Taxonomies', 'elasticpress')}
+
+ {postType.taxonomies.map((taxonomy, index) => {
+ const fieldType = 'taxonomies';
+ const isAttributeChanged =
+ JSON.stringify(taxonomy) !==
+ JSON.stringify(currentOriginalData[fieldType][index]);
+
+ return (
+
+ );
+ })}
+
+
+
+
{__('Meta to be indexed', 'elasticpress')}
+
+ {getCurrentFormData(postType.name) &&
+ getCurrentFormData(postType.name).metas &&
+ getCurrentFormData(postType.name).metas.map((meta, index) => {
+ const fieldType = 'metas';
+ const isAttributeChanged =
+ JSON.stringify(meta) !==
+ JSON.stringify(currentOriginalData[fieldType][index]);
+ return (
+
+ );
+ })}
+
+ {__('Add Meta Key:', 'elasticpress')}
+
+
e.name}
+ getOptionValue={(e) => e.name}
+ loadOptions={loadOptions}
+ // onInputChange={handleInputChange}
+ onChange={handleChange}
+ />
+
+
+
+
+ >
+ );
+};
+
+FieldGroup.propTypes = {
+ postType: PropTypes.object.isRequired,
+ onChangeHandler: PropTypes.func.isRequired,
+ getCurrentFormData: PropTypes.func.isRequired,
+ formData: PropTypes.array.isRequired,
+ setFormData: PropTypes.func.isRequired,
+ undoHandler: PropTypes.func.isRequired,
+ savedData: PropTypes.array.isRequired,
+};
+
+export default FieldGroup;
diff --git a/assets/js/weighting/components/field-item.js b/assets/js/weighting/components/field-item.js
new file mode 100644
index 0000000000..4e5c8baf45
--- /dev/null
+++ b/assets/js/weighting/components/field-item.js
@@ -0,0 +1,102 @@
+/**
+ * Wordpress Dependencies.
+ */
+import { RangeControl } from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
+import PropTypes from 'prop-types';
+
+/**
+ * Internal Dependecies.
+ */
+import UndoChanges from './undo-changes';
+
+const FieldItem = (props) => {
+ const {
+ postType,
+ attribute,
+ fieldType,
+ onChangeHandler,
+ getCurrentFormData,
+ currentIndex,
+ undoHandler,
+ isAttributeChanged,
+ } = props;
+
+ return (
+
+ {attribute.label}
+
+
+
+
+ onChangeHandler(event, postType.name, fieldType, attribute.name)
+ }
+ checked={
+ getCurrentFormData(postType.name)[fieldType][currentIndex].indexable
+ }
+ />
+ {__('Index', 'elsaticpress')}
+
+
+
+ {getCurrentFormData(postType.name)[fieldType][currentIndex].indexable && (
+
+
+
+ onChangeHandler(event, postType.name, fieldType, attribute.name)
+ }
+ checked={
+ getCurrentFormData(postType.name)[fieldType][currentIndex]
+ .searchable
+ }
+ />
+ {__('Searchable', 'elsaticpress')}
+
+
+ )}
+
+ {getCurrentFormData(postType.name)[fieldType][currentIndex].searchable &&
+ getCurrentFormData(postType.name)[fieldType][currentIndex].indexable && (
+
+
+ onChangeHandler(value, postType.name, fieldType, attribute.name)
+ }
+ min={1}
+ max={100}
+ />
+
+ )}
+
+ {isAttributeChanged && }
+
+ );
+};
+
+FieldItem.propTypes = {
+ postType: PropTypes.object.isRequired,
+ attribute: PropTypes.object.isRequired,
+ fieldType: PropTypes.string.isRequired,
+ onChangeHandler: PropTypes.func.isRequired,
+ getCurrentFormData: PropTypes.func.isRequired,
+ currentIndex: PropTypes.number.isRequired,
+ undoHandler: PropTypes.func.isRequired,
+ isAttributeChanged: PropTypes.bool.isRequired,
+};
+
+export default FieldItem;
diff --git a/assets/js/weighting/components/meta-Item.js b/assets/js/weighting/components/meta-Item.js
new file mode 100644
index 0000000000..877dae5a00
--- /dev/null
+++ b/assets/js/weighting/components/meta-Item.js
@@ -0,0 +1,72 @@
+/**
+ * WordPress dependencies.
+ */
+import { RangeControl } from '@wordpress/components';
+import { closeSmall, Icon } from '@wordpress/icons';
+import { __ } from '@wordpress/i18n';
+import PropTypes from 'prop-types';
+
+const MetaItem = ({
+ postType,
+ attribute,
+ fieldType,
+ onChangeHandler,
+ getCurrentFormData,
+ currentIndex,
+ removeMetaItem,
+}) => {
+ return (
+
+
+ removeMetaItem(attribute.name)} icon={closeSmall} />
+
+ {attribute.name}
+
+
+
+
+ onChangeHandler(event, postType.name, fieldType, attribute.name)
+ }
+ checked={
+ getCurrentFormData(postType.name)[fieldType][currentIndex].searchable
+ }
+ />
+ {__('Searchable', 'elasticpress')}
+
+
+
+ {getCurrentFormData(postType.name)[fieldType][currentIndex].searchable && (
+
+
+ onChangeHandler(value, postType.name, fieldType, attribute.name)
+ }
+ min={1}
+ max={100}
+ />
+
+ )}
+
+ );
+};
+
+MetaItem.propTypes = {
+ postType: PropTypes.object.isRequired,
+ attribute: PropTypes.object.isRequired,
+ fieldType: PropTypes.string.isRequired,
+ onChangeHandler: PropTypes.func.isRequired,
+ getCurrentFormData: PropTypes.func.isRequired,
+ currentIndex: PropTypes.number.isRequired,
+ removeMetaItem: PropTypes.func.isRequired,
+};
+
+export default MetaItem;
diff --git a/assets/js/weighting/components/undo-changes.js b/assets/js/weighting/components/undo-changes.js
new file mode 100644
index 0000000000..689d88147a
--- /dev/null
+++ b/assets/js/weighting/components/undo-changes.js
@@ -0,0 +1,20 @@
+/**
+ * Wordpress Dependencies.
+ */
+import { __ } from '@wordpress/i18n';
+import PropTypes from 'prop-types';
+
+const UndoChanges = ({ undoHandler, undoProps }) => {
+ return (
+ undoHandler(undoProps)}>
+ {__('Undo changes', 'elasticpress')}
+
+ );
+};
+
+UndoChanges.propTypes = {
+ undoHandler: PropTypes.func.isRequired,
+ undoProps: PropTypes.object.isRequired,
+};
+
+export default UndoChanges;
diff --git a/assets/js/weighting/dummyData.js b/assets/js/weighting/dummyData.js
new file mode 100644
index 0000000000..98e5482731
--- /dev/null
+++ b/assets/js/weighting/dummyData.js
@@ -0,0 +1,224 @@
+export const dummyData = [
+ {
+ label: 'Posts',
+ name: 'post',
+ indexable: true,
+ order: 0,
+
+ attributes: [
+ {
+ label: 'Title',
+ name: 'post_title',
+ indexable: true,
+ searchable: true,
+ weight: 40,
+ },
+ {
+ label: 'Content',
+ name: 'post_content',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Excerpt',
+ name: 'post_excerpt',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Author',
+ name: 'post_author',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ ],
+
+ taxonomies: [
+ {
+ label: 'Categories',
+ name: 'post_categories',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Tags',
+ name: 'post_tags',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Formats',
+ name: 'post_formats',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ ],
+
+ metas: [
+ // {
+ // name: 'example_key',
+ // searchable: false,
+ // weight: 10,
+ // },
+ // {
+ // name: 'another_key',
+ // searchable: false,
+ // weight: 10,
+ // },
+ // {
+ // name: 'one_more_key',
+ // searchable: false,
+ // weight: 10,
+ // },
+ ],
+ },
+ {
+ label: 'Pages',
+ name: 'page',
+ indexable: true,
+ order: 1,
+
+ attributes: [
+ {
+ label: 'Title',
+ name: 'post_title',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Content',
+ name: 'post_content',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Excerpt',
+ name: 'post_excerpt',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Author',
+ name: 'post_author',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ ],
+
+ taxonomies: [
+ {
+ label: 'Categories',
+ name: 'post_categories',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Tags',
+ name: 'post_tags',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Formats',
+ name: 'post_formats',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ ],
+
+ metas: [],
+ },
+ {
+ label: 'Product',
+ name: 'product',
+ indexable: true,
+ order: 2,
+
+ attributes: [
+ {
+ label: 'Title',
+ name: 'post_title',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Content',
+ name: 'post_content',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Excerpt',
+ name: 'post_excerpt',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Author',
+ name: 'post_author',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ ],
+
+ taxonomies: [
+ {
+ label: 'Categories',
+ name: 'post_categories',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Tags',
+ name: 'post_tags',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ {
+ label: 'Formats',
+ name: 'post_formats',
+ indexable: false,
+ searchable: false,
+ weight: 1,
+ },
+ ],
+ metas: [],
+ },
+];
+
+export const dummyMetaKeys = [
+ {
+ name: 'example_key',
+ searchable: false,
+ weight: 10,
+ },
+ {
+ name: 'another_key',
+ searchable: false,
+ weight: 10,
+ },
+ {
+ name: 'one_more_key',
+ searchable: false,
+ weight: 10,
+ },
+];
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
new file mode 100644
index 0000000000..9c4d94daef
--- /dev/null
+++ b/assets/js/weighting/index.js
@@ -0,0 +1,214 @@
+/**
+ * WordPress dependencies.
+ */
+import { render, WPElement, useState, useEffect } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal Dependencies.
+ */
+import FieldGroup from './components/field-group';
+import { dummyData } from './dummyData';
+import { sortListByOrder } from './utils';
+
+/**
+ * component.
+ *
+ * @return {WPElement} Element.
+ */
+const App = () => {
+ const [formData, setFormData] = useState([]);
+ const [savedData, setSavedData] = useState([]);
+ const [isSaving, setIsSaving] = useState(false);
+
+ const hasChanges = JSON.stringify(savedData) !== JSON.stringify(formData);
+
+ /**
+ * Fetch api response on component mount and set instead of dummy data.
+ */
+ useEffect(() => {
+ setTimeout(() => {
+ setSavedData(dummyData);
+ setFormData(dummyData);
+ }, 200);
+ }, []);
+
+ /**
+ * Get currently editing form type
+ *
+ * @param {string} postType type of the wp post.
+ * @return {Object} currently editing form.
+ */
+ const getCurrentFormData = (postType) => formData.find((item) => item.name === postType);
+
+ /**
+ * Get currently editing form type
+ *
+ * @param {string} postType type of the wp post.
+ * @return {Object} currently editing form.
+ */
+ const getSavedFormData = (postType) => savedData.find((item) => item.name === postType);
+
+ const undoHandler = (props) => {
+ const { currentIndex, fieldType, postType, attribute } = props;
+ let currentFormData = getCurrentFormData(postType.name);
+ const savedFormData = getSavedFormData(postType.name);
+
+ currentFormData = {
+ ...currentFormData,
+ [fieldType]: currentFormData[fieldType].map((item) => {
+ let newItem = item;
+ if (item.name === attribute.name) {
+ newItem = savedFormData[fieldType][currentIndex];
+ }
+ return newItem;
+ }),
+ };
+
+ const excludeOldCurrentFormData = formData.filter((item) => item.name !== postType.name);
+
+ const newFormData = [...excludeOldCurrentFormData, currentFormData];
+
+ setFormData(sortListByOrder(newFormData));
+ };
+
+ /**
+ * Handle input changes.
+ *
+ * @param {Object} event react synthetic event
+ * @param {string} postType wp post type
+ * @param {string} type type of the field
+ * @param {string} attributeName field attribute name
+ */
+ const onChangeHandler = (event, postType, type, attributeName) => {
+ let currentFormData = getCurrentFormData(postType);
+
+ if (type === 'root') {
+ currentFormData = { ...currentFormData, indexable: !currentFormData.indexable };
+ } else {
+ currentFormData = {
+ ...currentFormData,
+ [type]: currentFormData[type].map((item) => {
+ let newItem = item;
+ if (typeof event === 'number' && item.name === attributeName) {
+ newItem = { ...newItem, weight: event };
+ } else if (item.name === attributeName) {
+ newItem = { ...newItem, [event.target.name]: !newItem[event.target.name] };
+ }
+ return newItem;
+ }),
+ };
+ }
+
+ const excludeOldCurrentFormData = formData.filter((item) => item.name !== postType);
+
+ const newFormData = [...excludeOldCurrentFormData, currentFormData];
+
+ setFormData(sortListByOrder(newFormData));
+ };
+
+ /**
+ * Reset all changes of the form.
+ */
+ const resetAllChanges = () => {
+ setFormData(sortListByOrder(dummyData));
+ };
+
+ /**
+ * Handle for submission.
+ *
+ * @param {Object} event react synthetic event.
+ */
+ const handleSubmit = (event) => {
+ event.preventDefault();
+ setIsSaving(true);
+
+ // do api request to save formData
+ setTimeout(() => {
+ console.log({ formData });
+ }, 500);
+
+ setIsSaving(false);
+ };
+
+ return (
+
+ );
+};
+
+render( , document.getElementById('ep-weighting-screen'));
diff --git a/assets/js/weighting/utils.js b/assets/js/weighting/utils.js
new file mode 100644
index 0000000000..7b0847f5b3
--- /dev/null
+++ b/assets/js/weighting/utils.js
@@ -0,0 +1,7 @@
+/**
+ * Sort list by order.
+ *
+ * @param {Array} list items to bo sorted.
+ * @return {Array} sorted list by it's order.
+ */
+export const sortListByOrder = (list = []) => list.sort((a, b) => a.order - b.order);
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 95902a8ea4..9b15194ec9 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -40,6 +40,32 @@ public function setup() {
add_filter( 'ep_query_weighting_fields', [ $this, 'adjust_weight_for_cross_fields' ], 10, 5 );
}
+ /**
+ * Returns unique list of meta keys
+ *
+ * @param string $post_type Post type
+ *
+ * @return array
+ */
+ public function get_meta_keys_for_post_type( $post_type ) {
+
+
+ $meta_keys = array();
+ $posts = get_posts( array( 'post_type' => $post_type, 'limit' => -1 ) );
+
+
+ foreach ( $posts as $post ) {
+ $post_meta_keys = get_post_custom_keys( $post->ID );
+ var_dump($post_meta_keys);
+ $meta_keys = array_merge( $meta_keys, $post_meta_keys );
+ }
+
+ // Use array_unique to remove duplicate meta_keys that we received from all posts
+ // Use array_values to reset the index of the array
+ return array_values( array_unique( $meta_keys ) );
+
+ }
+
/**
* Returns a grouping of all the fields that support weighting for the post type
*
@@ -211,58 +237,7 @@ public function add_weighting_submenu_page() {
public function render_settings_page() {
include EP_PATH . '/includes/partials/header.php'; ?>
-
+
+
+ id="" name="weighting[][][enabled]">
+ ">
+
+
- id="" name="weighting[][][enabled]">
- ">
+ id="" name="weighting[][][enabled]">
+ ">
@@ -326,6 +306,8 @@ public function render_settings_section( $post_type, $field, $current_values ) {
" name="weighting[][][weight]" >
+
+
Date: Wed, 9 Feb 2022 22:06:02 +0600
Subject: [PATCH 02/63] Fix weghting screen
---
assets/css/dashboard.css | 8 ++++++--
assets/js/weighting/index.js | 37 +++++++++++++++++++++++++++++++++---
package-lock.json | 19 ++++++++----------
package.json | 1 +
4 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css
index 72f24ca62d..1ac874893a 100644
--- a/assets/css/dashboard.css
+++ b/assets/css/dashboard.css
@@ -713,8 +713,12 @@ h2.ep-list-features {
padding: 10px;
position: sticky;
- & button {
- margin-right: 10px;
+ & .note {
+ margin-left: 10px;
+ }
+
+ & .reset-all-changes-button {
+ margin-left: auto;
}
}
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index 9c4d94daef..57c1940568 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -114,6 +114,28 @@ const App = () => {
setFormData(sortListByOrder(dummyData));
};
+ /**
+ * Reset current form changes.
+ *
+ * @param {string} postType name of the post type.
+ */
+ const resetCurrentFormChanges = (postType) => {
+ const savedFormData = getSavedFormData(postType);
+ const excludeOldCurrentFormData = formData.filter((item) => item.name !== postType);
+
+ const newFormData = [...excludeOldCurrentFormData, savedFormData];
+
+ setFormData(sortListByOrder(newFormData));
+ };
+
+ /**
+ * Check if current has changes.
+ *
+ * @param {string} postType name of the post type.
+ */
+ const hasCurrentFormChanges = (postType) =>
+ JSON.stringify(getCurrentFormData(postType)) !== JSON.stringify(getSavedFormData(postType));
+
/**
* Handle for submission.
*
@@ -166,11 +188,11 @@ const App = () => {
- {hasChanges && (
+ {hasCurrentFormChanges(postType.name) && (
resetCurrentFormChanges(postType.name)}
>
{__('Undo all changes', 'elasticpress')}
@@ -201,11 +223,20 @@ const App = () => {
{isSaving ? __('Saving…', 'elasticpress') : __('Save changes', 'elasticpress')}
-
+
{hasChanges
? __('Please re-sync your data after saving.', 'elasticpress')
: __('You have nothing to save.', 'elasticpress')}
+
+
+ {__('Reset all changes', 'elasticpress')}
+
);
diff --git a/package-lock.json b/package-lock.json
index 42388a7cf2..66ae5bb6a4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17087,22 +17087,19 @@
}
},
"prop-types": {
- "version": "15.7.2",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
- "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"requires": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
- "react-is": "^16.8.1"
+ "react-is": "^16.13.1"
},
"dependencies": {
- "loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "requires": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- }
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}
}
},
diff --git a/package.json b/package.json
index 2dcb7ef8e0..2e9bb1cd8e 100644
--- a/package.json
+++ b/package.json
@@ -75,6 +75,7 @@
"focus-trap-react": "^8.8.2",
"jquery": "^3.6.0",
"promise-polyfill": "^8.2.1",
+ "prop-types": "^15.8.1",
"react": "^16.14.0",
"react-beautiful-dnd": "^11.0.5",
"react-dom": "^16.14.0",
From d865cf059f4d62c9937f4c92592a2d9e12c7674d Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 4 Oct 2022 12:37:51 +1100
Subject: [PATCH 03/63] Refactor with core components.
---
assets/css/dashboard.css | 292 ---------
assets/css/weighting.css | 57 ++
.../components/common/undo-button.js | 16 +
.../components/common/weight-control.js | 16 +
assets/js/weighting/components/field-group.js | 181 -----
assets/js/weighting/components/field-item.js | 102 ---
assets/js/weighting/components/meta-Item.js | 72 --
assets/js/weighting/components/post-type.js | 110 ++++
.../components/post-type/properties.js | 54 ++
.../components/post-type/property.js | 107 +++
assets/js/weighting/components/save.js | 31 +
.../js/weighting/components/undo-changes.js | 20 -
assets/js/weighting/dummyData.js | 6 +-
assets/js/weighting/index.js | 226 ++-----
assets/js/weighting/utils.js | 7 -
includes/dashboard.php | 8 +
package-lock.json | 616 ++++++++++++------
package.json | 7 +-
18 files changed, 853 insertions(+), 1075 deletions(-)
create mode 100644 assets/css/weighting.css
create mode 100644 assets/js/weighting/components/common/undo-button.js
create mode 100644 assets/js/weighting/components/common/weight-control.js
delete mode 100644 assets/js/weighting/components/field-group.js
delete mode 100644 assets/js/weighting/components/field-item.js
delete mode 100644 assets/js/weighting/components/meta-Item.js
create mode 100644 assets/js/weighting/components/post-type.js
create mode 100644 assets/js/weighting/components/post-type/properties.js
create mode 100644 assets/js/weighting/components/post-type/property.js
create mode 100644 assets/js/weighting/components/save.js
delete mode 100644 assets/js/weighting/components/undo-changes.js
delete mode 100644 assets/js/weighting/utils.js
diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css
index 02310c9f49..0d8749570d 100644
--- a/assets/css/dashboard.css
+++ b/assets/css/dashboard.css
@@ -689,298 +689,6 @@ h2.ep-list-features {
color: #d84440;
}
-/**
- * Weighting
- */
-
-.weighting-settings {
- box-sizing: border-box;
- max-width: 650px;
-
- & .postbox {
-
- & .components-range-control__number {
- display: none;
- }
-
- & .postbox__header {
- align-items: center;
- border-bottom: 1px solid #c3c4c7;
- display: flex;
- }
-
- & .undo-changes {
- background-color: transparent;
- border: 0;
- color: #1e8cbe;
- cursor: pointer;
- margin-left: auto;
- padding: 0 10px;
-
- &:hover {
- text-decoration: underline;
- }
- }
-
- & * {
- box-sizing: border-box;
- }
- }
-
- & .add-meta-key-wrap {
- align-items: center;
- display: flex;
-
- & legend {
- top: 0;
- }
- }
-
- & .add-meta-key {
- width: 300px;
- }
-
- & .submit__button {
- align-items: center;
- background: #fff;
- bottom: 0;
- display: flex;
- padding: 10px;
- position: sticky;
-
- & .note {
- margin-left: 10px;
- }
-
- & .reset-all-changes-button {
- margin-left: auto;
- }
- }
-
-}
-
-.components-range-control__wrapper {
- min-width: 100px;
-
- & span:last-child {
- background-color: #1e8cbe;
- pointer-events: none;
- }
-}
-
-div.components-base-control__field {
- align-items: center;
- display: flex;
- height: 20px;
- margin: 0;
-
- & .components-base-control__label {
- margin: 0;
- }
-}
-
-.field-item .components-base-control__help {
- margin-top: -10px;
- padding: 0;
-}
-
-.weighting-settings .postbox h2.hndle {
- color: #444;
- cursor: inherit;
- width: 110px;
-}
-
-.weighting-settings fieldset {
- padding: 10px;
-}
-
-.weighting-settings fieldset legend {
- float: left; /* legend cannot use display */
- position: relative;
- top: 5px;
- width: 100px;
-}
-
-.weighting-settings fieldset p {
- display: inline-block;
- float: left;
- margin: 0;
-}
-
-.weighting-settings .field-group {
- margin: 10px 0 0;
-}
-
-.weighting-settings .field-group h3 {
- font-size: 1em;
- margin: 10px;
-}
-
-.weighting-settings .fields > fieldset:nth-of-type(odd) {
- background: #f9f9f9;
-}
-
-.field-item {
- align-items: center;
- display: flex;
-}
-
-.remove-meta-item {
- cursor: pointer;
-
- & path {
- fill: #d84440;
- }
-}
-
-.field-item p {
- display: inline-block;
- padding: 0 10px;
-
- & a {
- text-decoration: none;
- }
-}
-
-.weighting-settings .weighting {
- align-items: center;
- display: flex;
-}
-
-.weighting-settings .weighting label {
- min-width: 80px;
-}
-
-.weighting-settings input[type="range"] {
- -webkit-appearance: none;
- background: transparent;
- display: inline-block;
- height: 1em;
- margin: 0;
- vertical-align: middle;
- width: 120px;
-}
-
-.weighting-settings input[type="range"]:focus {
- outline: none;
-}
-
-.weighting-settings input[type="range"]:disabled {
- opacity: 0.5;
- pointer-events: none;
-}
-
-.weighting-settings input[type="range"]::-webkit-slider-runnable-track {
- background: #ddd;
- border: 0 solid #000;
- border-radius: 1px;
- box-shadow: 0 0 0 #000;
- cursor: pointer;
- height: 3px;
- width: 100%;
-}
-
-.weighting-settings input[type="range"]::-webkit-slider-thumb {
- -webkit-appearance: none;
- background: #1e8cbe;
- border: 1px solid #1e8cbe;
- border-radius: 25px;
- box-shadow: 0 0 0 #000;
- cursor: pointer;
- height: 14px;
- margin-top: -6px;
- width: 14px;
-}
-
-.weighting-settings input[type="range"]:focus::-webkit-slider-runnable-track {
- background: #ddd;
-}
-
-.weighting-settings input[type="range"]:focus::-webkit-slider-thumb {
- background: #fff !important;
-}
-
-.weighting-settings input[type="range"]::-moz-range-track {
- background: #1e8cbe;
- border: 0 solid #000;
- border-radius: 1px;
- box-shadow: 0 0 0 #000;
- cursor: pointer;
- height: 3px;
- width: 100%;
-}
-
-.weighting-settings input[type="range"]::-moz-range-thumb {
- background: #1e8cbe;
- border: 1px solid #1e8cbe;
- border-radius: 25px;
- box-shadow: 0 0 0 #000;
- cursor: pointer;
- height: 14px;
- width: 14px;
-}
-
-.weighting-settings input[type="range"]::-ms-track {
- background: transparent;
- border-color: transparent;
- color: transparent;
- cursor: pointer;
- height: 3px;
- width: 100%;
-}
-
-.weighting-settings input[type="range"]::-ms-fill-lower {
- background: #1e8cbe;
- border: 0 solid #000;
- border-radius: 2px;
- box-shadow: 0 0 0 #000;
-}
-
-.weighting-settings input[type="range"]::-ms-fill-upper {
- background: #1e8cbe;
- border: 0 solid #000;
- border-radius: 2px;
- box-shadow: 0 0 0 #000;
-}
-
-.weighting-settings input[type="range"]::-ms-thumb {
- background: #a1d0ff;
- border: 1px solid #1e8cbe;
- border-radius: 25px;
- box-shadow: 0 0 0 #000;
- cursor: pointer;
- height: 14px;
- margin-top: 1px;
- width: 14px;
-}
-
-.weighting-settings input[type="range"]:focus::-ms-fill-lower {
- background: #1e8cbe;
-}
-
-.weighting-settings input[type="range"]:focus::-ms-fill-upper {
- background: #1e8cbe;
-}
-
-.ep-feature-search .wp-color-result.button {
- margin-bottom: 10px;
-}
-
-
-.ep-feature.ep-feature-search .settings .wp-picker-input-wrap > label {
- margin-right: 10px;
- margin-top: 0;
-}
-
-.ep-feature.ep-feature-search .settings.wp-picker-input-wrap label {
- align-items: center;
- display: flex;
-}
-
-.ep-feature.ep-feature-search .settings .wp-picker-open + .wp-picker-input-wrap {
- display: flex;
-}
-
/**
* Animations
*/
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
new file mode 100644
index 0000000000..efff47d69e
--- /dev/null
+++ b/assets/css/weighting.css
@@ -0,0 +1,57 @@
+#ep-weighting-screen {
+
+ & .components-panel {
+ margin-bottom: 2rem;
+ max-width: 800px;
+ }
+}
+
+.ep-weighting-property {
+ align-items: center;
+ display: grid;
+ grid-gap: 1em;
+ grid-template-columns: min(20%, 30ch) max-content max-content auto max-content;
+ width: 100%;
+
+ & .components-base-control__field {
+ margin-bottom: 0;
+ }
+
+ & .components-range-control {
+
+ & .components-base-control__field {
+ align-items: center;
+ display: flex;
+ }
+
+ & .components-base-control__label {
+ margin-bottom: 0;
+ }
+ }
+}
+
+.ep-weighting-property fieldset {
+ display: contents;
+}
+
+.ep-weighting-property__name {
+
+ & h2 {
+ color: inherit;
+ font-size: 15px;
+ margin: 0;
+ }
+}
+
+.ep-weighting-property__undo {
+ grid-column-start: 5;
+ justify-self: end;
+}
+
+
+.ep-weighting-undo {
+
+ &[disabled] {
+ visibility: hidden;
+ }
+}
diff --git a/assets/js/weighting/components/common/undo-button.js b/assets/js/weighting/components/common/undo-button.js
new file mode 100644
index 0000000000..04513b813b
--- /dev/null
+++ b/assets/js/weighting/components/common/undo-button.js
@@ -0,0 +1,16 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
+import { undo } from '@wordpress/icons';
+
+/**
+ * Undo button component.
+ *
+ * @param {object} props Component props.
+ * @returns {WPElement} Component element.
+ */
+export default (props) => {
+ return ;
+};
diff --git a/assets/js/weighting/components/common/weight-control.js b/assets/js/weighting/components/common/weight-control.js
new file mode 100644
index 0000000000..3a02dd8f9b
--- /dev/null
+++ b/assets/js/weighting/components/common/weight-control.js
@@ -0,0 +1,16 @@
+/**
+ * WordPress dependencies.
+ */
+import { RangeControl } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Weight control component.
+ *
+ * @param {object} props Component props.
+ * @returns {WPElement} Component element.
+ */
+export default (props) => {
+ return ;
+};
diff --git a/assets/js/weighting/components/field-group.js b/assets/js/weighting/components/field-group.js
deleted file mode 100644
index 57777abce8..0000000000
--- a/assets/js/weighting/components/field-group.js
+++ /dev/null
@@ -1,181 +0,0 @@
-/**
- * Wordpress Dependecies.
- */
-import { useState } from '@wordpress/element';
-import AsyncSelect from 'react-select/async';
-import { __ } from '@wordpress/i18n';
-import PropTypes from 'prop-types';
-
-/**
- * Internal Dependencies.
- */
-import FieldItem from './field-item';
-import MetaItem from './meta-Item';
-import { sortListByOrder } from '../utils';
-
-const FieldGroup = ({
- postType,
- onChangeHandler,
- getCurrentFormData,
- formData,
- setFormData,
- undoHandler,
- savedData,
-}) => {
- const [selectedValue, setSelectedValue] = useState(null);
-
- // handle selection
- const handleChange = (value) => {
- let currentFormData = getCurrentFormData(postType.name);
- if (currentFormData.metas.findIndex((metaItem) => metaItem.name === value.name) === -1) {
- currentFormData = {
- ...currentFormData,
- metas: [...currentFormData.metas, value],
- };
- }
- const excludedFormData = formData.filter((item) => item.name !== postType.name);
- const newFormData = [...excludedFormData, currentFormData];
- setFormData(sortListByOrder(newFormData));
- setSelectedValue(value);
- };
-
- // load options using API call
- const loadOptions = (inputValue) => {
- return fetch(
- `https://jsonplaceholder.typicode.com/posts?search=${inputValue}$post_type=${postType.name}`,
- )
- .then((res) => res.json())
- .then((result) => {
- const newResult = [];
- result.forEach((item) => {
- newResult.push({
- name: item.title,
- searchable: false,
- weight: 10,
- });
- });
- return newResult;
- });
- };
-
- const removeMetaItem = (metaName) => {
- const newCurrentFormData = {
- ...getCurrentFormData(postType.name),
- metas: getCurrentFormData(postType.name).metas.filter((item) => item.name !== metaName),
- };
-
- const excludedFormData = formData.filter((item) => item.name !== postType.name);
- const newFormData = [...excludedFormData, newCurrentFormData];
- setFormData(sortListByOrder(newFormData));
- };
-
- const currentOriginalData = savedData.find((item) => item.name === postType.name);
-
- return (
- <>
-
-
{__('Attributes', 'elasticpress')}
-
- {postType.attributes.map((attribute, index) => {
- const fieldType = 'attributes';
- const isAttributeChanged =
- JSON.stringify(attribute) !==
- JSON.stringify(currentOriginalData[fieldType][index]);
- return (
-
- );
- })}
-
-
-
-
{__('Taxonomies', 'elasticpress')}
-
- {postType.taxonomies.map((taxonomy, index) => {
- const fieldType = 'taxonomies';
- const isAttributeChanged =
- JSON.stringify(taxonomy) !==
- JSON.stringify(currentOriginalData[fieldType][index]);
-
- return (
-
- );
- })}
-
-
-
-
{__('Meta to be indexed', 'elasticpress')}
-
- {getCurrentFormData(postType.name) &&
- getCurrentFormData(postType.name).metas &&
- getCurrentFormData(postType.name).metas.map((meta, index) => {
- const fieldType = 'metas';
- const isAttributeChanged =
- JSON.stringify(meta) !==
- JSON.stringify(currentOriginalData[fieldType][index]);
- return (
-
- );
- })}
-
- {__('Add Meta Key:', 'elasticpress')}
-
-
e.name}
- getOptionValue={(e) => e.name}
- loadOptions={loadOptions}
- // onInputChange={handleInputChange}
- onChange={handleChange}
- />
-
-
-
-
- >
- );
-};
-
-FieldGroup.propTypes = {
- postType: PropTypes.object.isRequired,
- onChangeHandler: PropTypes.func.isRequired,
- getCurrentFormData: PropTypes.func.isRequired,
- formData: PropTypes.array.isRequired,
- setFormData: PropTypes.func.isRequired,
- undoHandler: PropTypes.func.isRequired,
- savedData: PropTypes.array.isRequired,
-};
-
-export default FieldGroup;
diff --git a/assets/js/weighting/components/field-item.js b/assets/js/weighting/components/field-item.js
deleted file mode 100644
index 4e5c8baf45..0000000000
--- a/assets/js/weighting/components/field-item.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Wordpress Dependencies.
- */
-import { RangeControl } from '@wordpress/components';
-import { __ } from '@wordpress/i18n';
-import PropTypes from 'prop-types';
-
-/**
- * Internal Dependecies.
- */
-import UndoChanges from './undo-changes';
-
-const FieldItem = (props) => {
- const {
- postType,
- attribute,
- fieldType,
- onChangeHandler,
- getCurrentFormData,
- currentIndex,
- undoHandler,
- isAttributeChanged,
- } = props;
-
- return (
-
- {attribute.label}
-
-
-
-
- onChangeHandler(event, postType.name, fieldType, attribute.name)
- }
- checked={
- getCurrentFormData(postType.name)[fieldType][currentIndex].indexable
- }
- />
- {__('Index', 'elsaticpress')}
-
-
-
- {getCurrentFormData(postType.name)[fieldType][currentIndex].indexable && (
-
-
-
- onChangeHandler(event, postType.name, fieldType, attribute.name)
- }
- checked={
- getCurrentFormData(postType.name)[fieldType][currentIndex]
- .searchable
- }
- />
- {__('Searchable', 'elsaticpress')}
-
-
- )}
-
- {getCurrentFormData(postType.name)[fieldType][currentIndex].searchable &&
- getCurrentFormData(postType.name)[fieldType][currentIndex].indexable && (
-
-
- onChangeHandler(value, postType.name, fieldType, attribute.name)
- }
- min={1}
- max={100}
- />
-
- )}
-
- {isAttributeChanged && }
-
- );
-};
-
-FieldItem.propTypes = {
- postType: PropTypes.object.isRequired,
- attribute: PropTypes.object.isRequired,
- fieldType: PropTypes.string.isRequired,
- onChangeHandler: PropTypes.func.isRequired,
- getCurrentFormData: PropTypes.func.isRequired,
- currentIndex: PropTypes.number.isRequired,
- undoHandler: PropTypes.func.isRequired,
- isAttributeChanged: PropTypes.bool.isRequired,
-};
-
-export default FieldItem;
diff --git a/assets/js/weighting/components/meta-Item.js b/assets/js/weighting/components/meta-Item.js
deleted file mode 100644
index 877dae5a00..0000000000
--- a/assets/js/weighting/components/meta-Item.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { RangeControl } from '@wordpress/components';
-import { closeSmall, Icon } from '@wordpress/icons';
-import { __ } from '@wordpress/i18n';
-import PropTypes from 'prop-types';
-
-const MetaItem = ({
- postType,
- attribute,
- fieldType,
- onChangeHandler,
- getCurrentFormData,
- currentIndex,
- removeMetaItem,
-}) => {
- return (
-
-
- removeMetaItem(attribute.name)} icon={closeSmall} />
-
- {attribute.name}
-
-
-
-
- onChangeHandler(event, postType.name, fieldType, attribute.name)
- }
- checked={
- getCurrentFormData(postType.name)[fieldType][currentIndex].searchable
- }
- />
- {__('Searchable', 'elasticpress')}
-
-
-
- {getCurrentFormData(postType.name)[fieldType][currentIndex].searchable && (
-
-
- onChangeHandler(value, postType.name, fieldType, attribute.name)
- }
- min={1}
- max={100}
- />
-
- )}
-
- );
-};
-
-MetaItem.propTypes = {
- postType: PropTypes.object.isRequired,
- attribute: PropTypes.object.isRequired,
- fieldType: PropTypes.string.isRequired,
- onChangeHandler: PropTypes.func.isRequired,
- getCurrentFormData: PropTypes.func.isRequired,
- currentIndex: PropTypes.number.isRequired,
- removeMetaItem: PropTypes.func.isRequired,
-};
-
-export default MetaItem;
diff --git a/assets/js/weighting/components/post-type.js b/assets/js/weighting/components/post-type.js
new file mode 100644
index 0000000000..bb06b751e7
--- /dev/null
+++ b/assets/js/weighting/components/post-type.js
@@ -0,0 +1,110 @@
+/**
+ * WordPress dependencies.
+ */
+import { CheckboxControl, Panel, PanelHeader } from '@wordpress/components';
+import { useMemo, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { isEqual } from 'lodash';
+
+/**
+ * Internal dependencies.
+ */
+import Properties from './post-type/properties';
+import UndoButton from './common/undo-button';
+
+/**
+ * Post type weighting settings component.
+ *
+ * @param {object} props Components props.
+ * @param {string} props.label Post type label.
+ * @param {Function} props.onChange Data change handler.
+ * @param {object} props.originalValue Saved post type settings.
+ * @param {object} props.value Current post type settings.
+ * @returns {WPElement} Component element.
+ */
+export default ({ label, onChange, originalValue, value }) => {
+ const isChanged = useMemo(() => !isEqual(originalValue, value), [originalValue, value]);
+
+ /**
+ * Handle a change to post type indexing.
+ *
+ * @param {boolean} indexable Is post type indexable.
+ * @returns {void}
+ */
+ const onChangeIndexable = (indexable) => {
+ onChange({ ...value, indexable });
+ };
+
+ /**
+ * Handle a change to the post type's attribute setttings.
+ *
+ * @param {Array} attributes Attribute settings.
+ * @returns {void}
+ */
+ const onChangeAttributes = (attributes) => {
+ onChange({ ...value, attributes });
+ };
+
+ /**
+ * Handle a change to the post type's taxonomy setttings.
+ *
+ * @param {Array} taxonomies Taxonomy settings.
+ * @returns {void}
+ */
+ const onChangeTaxonomies = (taxonomies) => {
+ onChange({ ...value, taxonomies });
+ };
+
+ /**
+ * Handle resetting settings for the post type.
+ *
+ * @returns {void}
+ */
+ const onReset = () => {
+ onChange({ ...originalValue });
+ };
+
+ return (
+
+
+
+
+
{label}
+
+
+
+
+
+ {isChanged ? (
+
+ ) : null}
+
+
+
+ {value.indexable ? (
+ <>
+
+
+ >
+ ) : null}
+
+ );
+};
diff --git a/assets/js/weighting/components/post-type/properties.js b/assets/js/weighting/components/post-type/properties.js
new file mode 100644
index 0000000000..dc0b75aac1
--- /dev/null
+++ b/assets/js/weighting/components/post-type/properties.js
@@ -0,0 +1,54 @@
+/**
+ * WordPress dependencies.
+ */
+import { PanelBody, PanelRow } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
+
+/**
+ * Internal dependencies.
+ */
+import Property from './property';
+
+/**
+ * Post type propertes component.
+ *
+ * @param {object} props Component props.
+ * @param {string} props.label Properties label.
+ * @param {Function} props.onChange Change handler.
+ * @param {object[]} props.originalValue Saved property values.
+ * @param {object[]} props.value Current property values.
+ * @returns {WPElement} Component element.
+ */
+export default ({ label, onChange, originalValue, value }) => {
+ /**
+ * Handle changes to a property.
+ *
+ * @param {object} property New property data.
+ * @param {number} index Index of the changed property.
+ * @returns {void}
+ */
+ const onChangeProperty = (property, index) => {
+ const newValue = [...value];
+
+ newValue[index] = { ...value[index], ...property };
+
+ onChange(newValue);
+ };
+
+ return (
+
+ {value.map((value, index) => (
+
+ {
+ onChangeProperty(value, index);
+ }}
+ />
+
+ ))}
+
+ );
+};
diff --git a/assets/js/weighting/components/post-type/property.js b/assets/js/weighting/components/post-type/property.js
new file mode 100644
index 0000000000..b4715610fa
--- /dev/null
+++ b/assets/js/weighting/components/post-type/property.js
@@ -0,0 +1,107 @@
+/**
+ * Wordpress Dependencies.
+ */
+import { CheckboxControl } from '@wordpress/components';
+import { useMemo, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { isEqual } from 'lodash';
+
+/**
+ * Internal dependencies.
+ */
+import UndoButton from '../common/undo-button';
+import WeightControl from '../common/weight-control';
+
+/**
+ * Property settings component.
+ *
+ * @param {object} props Component props.
+ * @param {string} props.label Property label.
+ * @param {Function} props.onChange Change handler.
+ * @param {object} props.originalValue Original value.
+ * @param {object} props.value Values.
+ * @returns {WPElement} Component element.
+ */
+export default ({ label, onChange, originalValue, value }) => {
+ const { indexable, searchable, weight } = value;
+
+ /**
+ * Is the current value different to the original.
+ */
+ const isChanged = useMemo(() => !isEqual(originalValue, value), [originalValue, value]);
+
+ /**
+ * Handle change of indexable.
+ *
+ * @param {boolean} indexable New indexable value.
+ * @returns {void}
+ */
+ const onChangeIndex = (indexable) => {
+ onChange({ ...value, indexable, searchable: false });
+ };
+
+ /**
+ * Handle change of searchable.
+ *
+ * @param {boolean} searchable New searchable value.
+ * @returns {void}
+ */
+ const onChangeSearchable = (searchable) => {
+ onChange({ ...value, indexable: true, searchable });
+ };
+
+ /**
+ * Handle change of weighting.
+ *
+ * @param {number} weight New weight value.
+ * @returns {void}
+ */
+ const onChangeWeight = (weight) => {
+ onChange({ ...value, weight });
+ };
+
+ /**
+ * Handle clicking undo.
+ *
+ * @returns {void}
+ */
+ const onUndo = () => {
+ onChange({ ...originalValue });
+ };
+
+ return (
+
+
+ {label}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/assets/js/weighting/components/save.js b/assets/js/weighting/components/save.js
new file mode 100644
index 0000000000..65cf401154
--- /dev/null
+++ b/assets/js/weighting/components/save.js
@@ -0,0 +1,31 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button, Panel, PanelBody, PanelRow } from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
+import { undo } from '@wordpress/icons';
+
+export default ({ isBusy, isChanged, onReset }) => {
+ return (
+
+
+
+
+
+ {__('Save Changes', 'elasticpress')}
+
+
+
+ {__('Undo All Changes', 'elasticpress')}
+
+
+
+
+ );
+};
diff --git a/assets/js/weighting/components/undo-changes.js b/assets/js/weighting/components/undo-changes.js
deleted file mode 100644
index 689d88147a..0000000000
--- a/assets/js/weighting/components/undo-changes.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Wordpress Dependencies.
- */
-import { __ } from '@wordpress/i18n';
-import PropTypes from 'prop-types';
-
-const UndoChanges = ({ undoHandler, undoProps }) => {
- return (
- undoHandler(undoProps)}>
- {__('Undo changes', 'elasticpress')}
-
- );
-};
-
-UndoChanges.propTypes = {
- undoHandler: PropTypes.func.isRequired,
- undoProps: PropTypes.object.isRequired,
-};
-
-export default UndoChanges;
diff --git a/assets/js/weighting/dummyData.js b/assets/js/weighting/dummyData.js
index 98e5482731..19c44464b6 100644
--- a/assets/js/weighting/dummyData.js
+++ b/assets/js/weighting/dummyData.js
@@ -60,7 +60,7 @@ export const dummyData = [
},
],
- metas: [
+ meta: [
// {
// name: 'example_key',
// searchable: false,
@@ -139,7 +139,7 @@ export const dummyData = [
},
],
- metas: [],
+ meta: [],
},
{
label: 'Product',
@@ -201,7 +201,7 @@ export const dummyData = [
weight: 1,
},
],
- metas: [],
+ meta: [],
},
];
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index 57c1940568..29d5dab8a6 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -1,160 +1,70 @@
/**
* WordPress dependencies.
*/
-import { render, WPElement, useState, useEffect } from '@wordpress/element';
+import { render, WPElement, useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
+import { cloneDeep, isEqual } from 'lodash';
/**
* Internal Dependencies.
*/
-import FieldGroup from './components/field-group';
import { dummyData } from './dummyData';
-import { sortListByOrder } from './utils';
+import PostType from './components/post-type';
+import Save from './components/save';
/**
* component.
*
- * @return {WPElement} Element.
+ * @returns {WPElement} Element.
*/
const App = () => {
- const [formData, setFormData] = useState([]);
- const [savedData, setSavedData] = useState([]);
- const [isSaving, setIsSaving] = useState(false);
-
- const hasChanges = JSON.stringify(savedData) !== JSON.stringify(formData);
+ const [data, setData] = useState(cloneDeep(dummyData));
+ const [savedData, setSavedData] = useState(cloneDeep(dummyData));
+ const [isBusy, setIsBusy] = useState(false);
/**
- * Fetch api response on component mount and set instead of dummy data.
- */
- useEffect(() => {
- setTimeout(() => {
- setSavedData(dummyData);
- setFormData(dummyData);
- }, 200);
- }, []);
-
- /**
- * Get currently editing form type
- *
- * @param {string} postType type of the wp post.
- * @return {Object} currently editing form.
+ * Is the current data different to the saved data.
*/
- const getCurrentFormData = (postType) => formData.find((item) => item.name === postType);
+ const isChanged = useMemo(() => !isEqual(data, savedData), [data, savedData]);
/**
- * Get currently editing form type
+ * Handle data change.
*
- * @param {string} postType type of the wp post.
- * @return {Object} currently editing form.
+ * @param {Array} value Updated data.
+ * @returns {void}
*/
- const getSavedFormData = (postType) => savedData.find((item) => item.name === postType);
-
- const undoHandler = (props) => {
- const { currentIndex, fieldType, postType, attribute } = props;
- let currentFormData = getCurrentFormData(postType.name);
- const savedFormData = getSavedFormData(postType.name);
-
- currentFormData = {
- ...currentFormData,
- [fieldType]: currentFormData[fieldType].map((item) => {
- let newItem = item;
- if (item.name === attribute.name) {
- newItem = savedFormData[fieldType][currentIndex];
- }
- return newItem;
- }),
- };
-
- const excludeOldCurrentFormData = formData.filter((item) => item.name !== postType.name);
-
- const newFormData = [...excludeOldCurrentFormData, currentFormData];
-
- setFormData(sortListByOrder(newFormData));
- };
-
- /**
- * Handle input changes.
- *
- * @param {Object} event react synthetic event
- * @param {string} postType wp post type
- * @param {string} type type of the field
- * @param {string} attributeName field attribute name
- */
- const onChangeHandler = (event, postType, type, attributeName) => {
- let currentFormData = getCurrentFormData(postType);
-
- if (type === 'root') {
- currentFormData = { ...currentFormData, indexable: !currentFormData.indexable };
- } else {
- currentFormData = {
- ...currentFormData,
- [type]: currentFormData[type].map((item) => {
- let newItem = item;
- if (typeof event === 'number' && item.name === attributeName) {
- newItem = { ...newItem, weight: event };
- } else if (item.name === attributeName) {
- newItem = { ...newItem, [event.target.name]: !newItem[event.target.name] };
- }
- return newItem;
- }),
- };
- }
-
- const excludeOldCurrentFormData = formData.filter((item) => item.name !== postType);
-
- const newFormData = [...excludeOldCurrentFormData, currentFormData];
-
- setFormData(sortListByOrder(newFormData));
+ const onChange = (value) => {
+ setData(value);
};
/**
- * Reset all changes of the form.
- */
- const resetAllChanges = () => {
- setFormData(sortListByOrder(dummyData));
- };
-
- /**
- * Reset current form changes.
+ * Handle for submission.
*
- * @param {string} postType name of the post type.
+ * @param {Event} event Submit event.
+ * @returns {void}
*/
- const resetCurrentFormChanges = (postType) => {
- const savedFormData = getSavedFormData(postType);
- const excludeOldCurrentFormData = formData.filter((item) => item.name !== postType);
+ const onSubmit = (event) => {
+ event.preventDefault();
- const newFormData = [...excludeOldCurrentFormData, savedFormData];
+ const savedData = cloneDeep(data);
- setFormData(sortListByOrder(newFormData));
+ setIsBusy(true);
+ setSavedData(savedData);
};
/**
- * Check if current has changes.
- *
- * @param {string} postType name of the post type.
- */
- const hasCurrentFormChanges = (postType) =>
- JSON.stringify(getCurrentFormData(postType)) !== JSON.stringify(getSavedFormData(postType));
-
- /**
- * Handle for submission.
+ * Handle resetting all settings.
*
- * @param {Object} event react synthetic event.
+ * @returns {void}
*/
- const handleSubmit = (event) => {
- event.preventDefault();
- setIsSaving(true);
+ const onUndo = () => {
+ const data = cloneDeep(savedData);
- // do api request to save formData
- setTimeout(() => {
- console.log({ formData });
- }, 500);
-
- setIsSaving(false);
+ setData(data);
};
return (
-
);
};
diff --git a/assets/js/weighting/utils.js b/assets/js/weighting/utils.js
deleted file mode 100644
index 7b0847f5b3..0000000000
--- a/assets/js/weighting/utils.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Sort list by order.
- *
- * @param {Array} list items to bo sorted.
- * @return {Array} sorted list by it's order.
- */
-export const sortListByOrder = (list = []) => list.sort((a, b) => a.order - b.order);
diff --git a/includes/dashboard.php b/includes/dashboard.php
index 7d1a14d851..cf1a4b2089 100644
--- a/includes/dashboard.php
+++ b/includes/dashboard.php
@@ -491,6 +491,14 @@ function action_admin_enqueue_dashboard_scripts() {
}
if ( in_array( Screen::factory()->get_current_screen(), [ 'weighting', 'install' ], true ) ) {
+ wp_enqueue_style( 'wp-edit-post' );
+ wp_enqueue_style(
+ 'ep_weighting_styles',
+ EP_URL . 'dist/css/weighting-styles.min.css',
+ Utils\get_asset_info( 'weighting-styles', 'dependencies' ),
+ Utils\get_asset_info( 'weighting-styles', 'version' )
+ );
+
wp_enqueue_script(
'ep_weighting_script',
EP_URL . 'dist/js/weighting-script.min.js',
diff --git a/package-lock.json b/package-lock.json
index 5dce9906eb..60b033c52c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,11 +13,9 @@
"@wordpress/icons": "^6.1.1",
"chart.js": "^2.9.4",
"focus-trap-react": "^8.8.2",
- "jquery": "^3.6.0",
- "promise-polyfill": "^8.2.1",
"prop-types": "^15.8.1",
- "react": "^16.14.0",
"react-beautiful-dnd": "^11.0.5",
+ "react-select": "^5.4.0",
"react-slider": "^1.3.1",
"uuid": "^8.3.2"
},
@@ -29,6 +27,7 @@
"cypress-file-upload": "^5.0.8",
"eslint-plugin-cypress": "^2.12.1",
"jsdoc": "^3.6.10",
+ "lodash": "^4.17.21",
"postcss-preset-env": "^7.0.1",
"terser-webpack-plugin": "^5.3.0",
"wp-hookdoc": "^0.2.0"
@@ -149,7 +148,6 @@
},
"node_modules/@ampproject/remapping": {
"version": "2.1.2",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.0"
@@ -160,7 +158,6 @@
},
"node_modules/@babel/code-frame": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/highlight": "^7.16.7"
@@ -171,7 +168,6 @@
},
"node_modules/@babel/compat-data": {
"version": "7.17.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -179,7 +175,6 @@
},
"node_modules/@babel/core": {
"version": "7.17.5",
- "dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.1.0",
@@ -225,7 +220,6 @@
},
"node_modules/@babel/generator": {
"version": "7.17.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.17.0",
@@ -261,7 +255,6 @@
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.16.4",
@@ -331,7 +324,6 @@
},
"node_modules/@babel/helper-environment-visitor": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -353,7 +345,6 @@
},
"node_modules/@babel/helper-function-name": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-get-function-arity": "^7.16.7",
@@ -366,7 +357,6 @@
},
"node_modules/@babel/helper-get-function-arity": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -377,7 +367,6 @@
},
"node_modules/@babel/helper-hoist-variables": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -399,7 +388,6 @@
},
"node_modules/@babel/helper-module-imports": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -410,7 +398,6 @@
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.17.6",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-environment-visitor": "^7.16.7",
@@ -438,9 +425,9 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.16.7",
- "dev": true,
- "license": "MIT",
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
+ "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==",
"engines": {
"node": ">=6.9.0"
}
@@ -475,7 +462,6 @@
},
"node_modules/@babel/helper-simple-access": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -497,7 +483,6 @@
},
"node_modules/@babel/helper-split-export-declaration": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -508,7 +493,6 @@
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -516,7 +500,6 @@
},
"node_modules/@babel/helper-validator-option": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -538,7 +521,6 @@
},
"node_modules/@babel/helpers": {
"version": "7.17.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.16.7",
@@ -551,7 +533,6 @@
},
"node_modules/@babel/highlight": {
"version": "7.16.10",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.16.7",
@@ -564,7 +545,6 @@
},
"node_modules/@babel/parser": {
"version": "7.17.3",
- "dev": true,
"license": "MIT",
"bin": {
"parser": "bin/babel-parser.js"
@@ -928,11 +908,11 @@
}
},
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.16.7",
- "dev": true,
- "license": "MIT",
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.16.7"
+ "@babel/helper-plugin-utils": "^7.18.6"
},
"engines": {
"node": ">=6.9.0"
@@ -1788,8 +1768,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.17.2",
- "license": "MIT",
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
+ "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
@@ -1827,7 +1808,6 @@
},
"node_modules/@babel/template": {
"version": "7.16.7",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.16.7",
@@ -1840,7 +1820,6 @@
},
"node_modules/@babel/traverse": {
"version": "7.17.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.16.7",
@@ -1860,7 +1839,6 @@
},
"node_modules/@babel/types": {
"version": "7.17.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.16.7",
@@ -2035,6 +2013,117 @@
"ms": "^2.1.1"
}
},
+ "node_modules/@emotion/babel-plugin": {
+ "version": "11.10.2",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz",
+ "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/plugin-syntax-jsx": "^7.17.12",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/serialize": "^1.1.0",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.0.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@emotion/cache": {
+ "version": "11.10.3",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz",
+ "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/sheet": "^1.2.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "stylis": "4.0.13"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
+ "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
+ },
+ "node_modules/@emotion/react": {
+ "version": "11.10.4",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz",
+ "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.10.0",
+ "@emotion/cache": "^11.10.0",
+ "@emotion/serialize": "^1.1.0",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "hoist-non-react-statics": "^3.3.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@emotion/serialize": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz",
+ "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==",
+ "dependencies": {
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/unitless": "^0.8.0",
+ "@emotion/utils": "^1.2.0",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@emotion/sheet": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz",
+ "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w=="
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
+ "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
+ },
+ "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
+ "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@emotion/utils": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
+ "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
+ },
+ "node_modules/@emotion/weak-memoize": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
+ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
+ },
"node_modules/@es-joy/jsdoccomment": {
"version": "0.20.1",
"dev": true,
@@ -2777,7 +2866,6 @@
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.0.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -2804,14 +2892,12 @@
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.11",
- "dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
- "dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -3517,7 +3603,6 @@
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/prettier": {
@@ -3565,6 +3650,14 @@
"redux": "^4.0.0"
}
},
+ "node_modules/@types/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
@@ -4537,7 +4630,6 @@
},
"node_modules/ansi-styles": {
"version": "3.2.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^1.9.0"
@@ -4960,6 +5052,20 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
+ "node_modules/babel-plugin-macros": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ }
+ },
"node_modules/babel-plugin-polyfill-corejs2": {
"version": "0.3.1",
"dev": true,
@@ -5218,7 +5324,6 @@
},
"node_modules/browserslist": {
"version": "4.19.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"caniuse-lite": "^1.0.30001312",
@@ -5344,7 +5449,6 @@
},
"node_modules/callsites": {
"version": "3.1.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5417,7 +5521,6 @@
"version": "1.0.30001375",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
"integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
- "dev": true,
"funding": [
{
"type": "opencollective",
@@ -5447,7 +5550,6 @@
},
"node_modules/chalk": {
"version": "2.4.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^3.2.1",
@@ -5460,7 +5562,6 @@
},
"node_modules/chalk/node_modules/escape-string-regexp": {
"version": "1.0.5",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
@@ -5948,7 +6049,6 @@
},
"node_modules/convert-source-map": {
"version": "1.8.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.1"
@@ -6132,7 +6232,6 @@
},
"node_modules/cosmiconfig": {
"version": "7.0.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/parse-json": "^4.0.0",
@@ -6678,7 +6777,6 @@
},
"node_modules/debug": {
"version": "4.3.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
@@ -6997,6 +7095,15 @@
"utila": "~0.4"
}
},
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
"node_modules/dom-serializer": {
"version": "1.3.2",
"dev": true,
@@ -7105,7 +7212,6 @@
},
"node_modules/electron-to-chromium": {
"version": "1.4.75",
- "dev": true,
"license": "ISC"
},
"node_modules/emittery": {
@@ -7191,7 +7297,6 @@
},
"node_modules/error-ex": {
"version": "1.3.2",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
@@ -7261,7 +7366,6 @@
},
"node_modules/escalade": {
"version": "3.1.1",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -7274,7 +7378,6 @@
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -8571,6 +8674,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+ },
"node_modules/find-up": {
"version": "5.0.0",
"dev": true,
@@ -8716,7 +8824,6 @@
},
"node_modules/function-bind": {
"version": "1.1.1",
- "dev": true,
"license": "MIT"
},
"node_modules/functional-red-black-tree": {
@@ -8726,7 +8833,6 @@
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -8908,7 +9014,6 @@
},
"node_modules/globals": {
"version": "11.12.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -9011,7 +9116,6 @@
},
"node_modules/has": {
"version": "1.0.3",
- "dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.1"
@@ -9030,7 +9134,6 @@
},
"node_modules/has-flag": {
"version": "3.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -9476,7 +9579,6 @@
},
"node_modules/import-fresh": {
"version": "3.3.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -9491,7 +9593,6 @@
},
"node_modules/import-fresh/node_modules/resolve-from": {
"version": "4.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -9708,7 +9809,6 @@
},
"node_modules/is-arrayish": {
"version": "0.2.1",
- "dev": true,
"license": "MIT"
},
"node_modules/is-bigint": {
@@ -9794,7 +9894,6 @@
},
"node_modules/is-core-module": {
"version": "2.8.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"has": "^1.0.3"
@@ -11955,11 +12054,6 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
- "node_modules/jquery": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
- "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw=="
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"license": "MIT"
@@ -12126,7 +12220,6 @@
},
"node_modules/jsesc": {
"version": "2.5.2",
- "dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -12148,7 +12241,6 @@
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
- "dev": true,
"license": "MIT"
},
"node_modules/json-schema": {
@@ -12178,7 +12270,6 @@
},
"node_modules/json5": {
"version": "2.2.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"minimist": "^1.2.5"
@@ -12325,7 +12416,6 @@
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
- "dev": true,
"license": "MIT"
},
"node_modules/linkify-it": {
@@ -12407,7 +12497,8 @@
},
"node_modules/lodash": {
"version": "4.17.21",
- "license": "MIT"
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
@@ -13069,8 +13160,7 @@
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
- "dev": true
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"node_modules/minimist-options": {
"version": "4.1.0",
@@ -13114,7 +13204,6 @@
},
"node_modules/ms": {
"version": "2.1.2",
- "dev": true,
"license": "MIT"
},
"node_modules/multicast-dns": {
@@ -13193,7 +13282,6 @@
},
"node_modules/node-releases": {
"version": "2.0.2",
- "dev": true,
"license": "MIT"
},
"node_modules/normalize-package-data": {
@@ -13724,7 +13812,6 @@
},
"node_modules/parent-module": {
"version": "1.0.1",
- "dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
@@ -13752,7 +13839,6 @@
},
"node_modules/parse-json": {
"version": "5.2.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
@@ -13815,7 +13901,6 @@
},
"node_modules/path-parse": {
"version": "1.0.7",
- "dev": true,
"license": "MIT"
},
"node_modules/path-to-regexp": {
@@ -13825,7 +13910,6 @@
},
"node_modules/path-type": {
"version": "4.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -13843,7 +13927,6 @@
},
"node_modules/picocolors": {
"version": "1.0.0",
- "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
@@ -15383,11 +15466,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/promise-polyfill": {
- "version": "8.2.3",
- "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.3.tgz",
- "integrity": "sha512-Og0+jCRQetV84U8wVjMNccfGCnMQ9mGs9Hv78QFe+pSDD3gWTpz0y+1QCuxy5d/vBFuZ3iwP2eycAkvqIMPmWg=="
- },
"node_modules/prompts": {
"version": "2.4.2",
"dev": true,
@@ -15551,6 +15629,7 @@
"node_modules/react": {
"version": "16.14.0",
"license": "MIT",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
@@ -15626,6 +15705,24 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-select": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.4.0.tgz",
+ "integrity": "sha512-CjE9RFLUvChd5SdlfG4vqxZd55AZJRrLrHzkQyTYeHlpOztqcgnyftYAolJ0SGsBev6zAs6qFrjm6KU3eo2hzg==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.0",
+ "@emotion/cache": "^11.4.0",
+ "@emotion/react": "^11.8.1",
+ "@types/react-transition-group": "^4.4.0",
+ "memoize-one": "^5.0.0",
+ "prop-types": "^15.6.0",
+ "react-transition-group": "^4.3.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-slider": {
"version": "1.3.1",
"license": "MIT",
@@ -15634,6 +15731,21 @@
"react": "^16 || ^17"
}
},
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
"node_modules/read-cache": {
"version": "1.0.0",
"dev": true,
@@ -15994,7 +16106,6 @@
},
"node_modules/resolve": {
"version": "1.22.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.8.1",
@@ -16157,7 +16268,6 @@
},
"node_modules/safe-buffer": {
"version": "5.1.2",
- "dev": true,
"license": "MIT"
},
"node_modules/safer-buffer": {
@@ -16273,7 +16383,6 @@
},
"node_modules/semver": {
"version": "6.3.0",
- "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -16537,7 +16646,6 @@
},
"node_modules/source-map": {
"version": "0.5.7",
- "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -17219,6 +17327,11 @@
"node": ">=8"
}
},
+ "node_modules/stylis": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
+ "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag=="
+ },
"node_modules/sugarss": {
"version": "3.0.3",
"dev": true,
@@ -17236,7 +17349,6 @@
},
"node_modules/supports-color": {
"version": "5.5.0",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^3.0.0"
@@ -17278,7 +17390,6 @@
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -17587,7 +17698,6 @@
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -18841,7 +18951,6 @@
},
"node_modules/yaml": {
"version": "1.10.2",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">= 6"
@@ -18980,25 +19089,21 @@
},
"@ampproject/remapping": {
"version": "2.1.2",
- "dev": true,
"requires": {
"@jridgewell/trace-mapping": "^0.3.0"
}
},
"@babel/code-frame": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/highlight": "^7.16.7"
}
},
"@babel/compat-data": {
- "version": "7.17.0",
- "dev": true
+ "version": "7.17.0"
},
"@babel/core": {
"version": "7.17.5",
- "dev": true,
"requires": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.16.7",
@@ -19028,7 +19133,6 @@
},
"@babel/generator": {
"version": "7.17.3",
- "dev": true,
"requires": {
"@babel/types": "^7.17.0",
"jsesc": "^2.5.1",
@@ -19052,7 +19156,6 @@
},
"@babel/helper-compilation-targets": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/compat-data": "^7.16.4",
"@babel/helper-validator-option": "^7.16.7",
@@ -19097,7 +19200,6 @@
},
"@babel/helper-environment-visitor": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
@@ -19111,7 +19213,6 @@
},
"@babel/helper-function-name": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.16.7",
"@babel/template": "^7.16.7",
@@ -19120,14 +19221,12 @@
},
"@babel/helper-get-function-arity": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
},
"@babel/helper-hoist-variables": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
@@ -19141,14 +19240,12 @@
},
"@babel/helper-module-imports": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
},
"@babel/helper-module-transforms": {
"version": "7.17.6",
- "dev": true,
"requires": {
"@babel/helper-environment-visitor": "^7.16.7",
"@babel/helper-module-imports": "^7.16.7",
@@ -19168,8 +19265,9 @@
}
},
"@babel/helper-plugin-utils": {
- "version": "7.16.7",
- "dev": true
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
+ "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw=="
},
"@babel/helper-remap-async-to-generator": {
"version": "7.16.8",
@@ -19193,7 +19291,6 @@
},
"@babel/helper-simple-access": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
@@ -19207,18 +19304,15 @@
},
"@babel/helper-split-export-declaration": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.16.7",
- "dev": true
+ "version": "7.16.7"
},
"@babel/helper-validator-option": {
- "version": "7.16.7",
- "dev": true
+ "version": "7.16.7"
},
"@babel/helper-wrap-function": {
"version": "7.16.8",
@@ -19232,7 +19326,6 @@
},
"@babel/helpers": {
"version": "7.17.2",
- "dev": true,
"requires": {
"@babel/template": "^7.16.7",
"@babel/traverse": "^7.17.0",
@@ -19241,7 +19334,6 @@
},
"@babel/highlight": {
"version": "7.16.10",
- "dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.16.7",
"chalk": "^2.0.0",
@@ -19249,8 +19341,7 @@
}
},
"@babel/parser": {
- "version": "7.17.3",
- "dev": true
+ "version": "7.17.3"
},
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
"version": "7.16.7",
@@ -19453,10 +19544,11 @@
}
},
"@babel/plugin-syntax-jsx": {
- "version": "7.16.7",
- "dev": true,
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
"requires": {
- "@babel/helper-plugin-utils": "^7.16.7"
+ "@babel/helper-plugin-utils": "^7.18.6"
}
},
"@babel/plugin-syntax-logical-assignment-operators": {
@@ -19960,7 +20052,9 @@
}
},
"@babel/runtime": {
- "version": "7.17.2",
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
+ "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@@ -19987,7 +20081,6 @@
},
"@babel/template": {
"version": "7.16.7",
- "dev": true,
"requires": {
"@babel/code-frame": "^7.16.7",
"@babel/parser": "^7.16.7",
@@ -19996,7 +20089,6 @@
},
"@babel/traverse": {
"version": "7.17.3",
- "dev": true,
"requires": {
"@babel/code-frame": "^7.16.7",
"@babel/generator": "^7.17.3",
@@ -20012,7 +20104,6 @@
},
"@babel/types": {
"version": "7.17.0",
- "dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.16.7",
"to-fast-properties": "^2.0.0"
@@ -20122,6 +20213,100 @@
}
}
},
+ "@emotion/babel-plugin": {
+ "version": "11.10.2",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz",
+ "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==",
+ "requires": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/plugin-syntax-jsx": "^7.17.12",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/serialize": "^1.1.0",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.0.13"
+ }
+ },
+ "@emotion/cache": {
+ "version": "11.10.3",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz",
+ "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==",
+ "requires": {
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/sheet": "^1.2.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "stylis": "4.0.13"
+ }
+ },
+ "@emotion/hash": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
+ "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
+ },
+ "@emotion/memoize": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
+ "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
+ },
+ "@emotion/react": {
+ "version": "11.10.4",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz",
+ "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==",
+ "requires": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.10.0",
+ "@emotion/cache": "^11.10.0",
+ "@emotion/serialize": "^1.1.0",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0",
+ "@emotion/utils": "^1.2.0",
+ "@emotion/weak-memoize": "^0.3.0",
+ "hoist-non-react-statics": "^3.3.1"
+ }
+ },
+ "@emotion/serialize": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz",
+ "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==",
+ "requires": {
+ "@emotion/hash": "^0.9.0",
+ "@emotion/memoize": "^0.8.0",
+ "@emotion/unitless": "^0.8.0",
+ "@emotion/utils": "^1.2.0",
+ "csstype": "^3.0.2"
+ }
+ },
+ "@emotion/sheet": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz",
+ "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w=="
+ },
+ "@emotion/unitless": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
+ "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
+ },
+ "@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
+ "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
+ "requires": {}
+ },
+ "@emotion/utils": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
+ "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
+ },
+ "@emotion/weak-memoize": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
+ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
+ },
"@es-joy/jsdoccomment": {
"version": "0.20.1",
"dev": true,
@@ -20607,8 +20792,7 @@
}
},
"@jridgewell/resolve-uri": {
- "version": "3.0.5",
- "dev": true
+ "version": "3.0.5"
},
"@jridgewell/set-array": {
"version": "1.1.2",
@@ -20627,14 +20811,12 @@
}
},
"@jridgewell/sourcemap-codec": {
- "version": "1.4.11",
- "dev": true
+ "version": "1.4.11"
},
"@jridgewell/trace-mapping": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
- "dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -21090,8 +21272,7 @@
"dev": true
},
"@types/parse-json": {
- "version": "4.0.0",
- "dev": true
+ "version": "4.0.0"
},
"@types/prettier": {
"version": "2.4.4",
@@ -21131,6 +21312,14 @@
"redux": "^4.0.0"
}
},
+ "@types/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
@@ -21784,7 +21973,6 @@
},
"ansi-styles": {
"version": "3.2.1",
- "dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -22040,6 +22228,16 @@
"@types/babel__traverse": "^7.0.6"
}
},
+ "babel-plugin-macros": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+ "requires": {
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ }
+ },
"babel-plugin-polyfill-corejs2": {
"version": "0.3.1",
"dev": true,
@@ -22214,7 +22412,6 @@
},
"browserslist": {
"version": "4.19.3",
- "dev": true,
"requires": {
"caniuse-lite": "^1.0.30001312",
"electron-to-chromium": "^1.4.71",
@@ -22288,8 +22485,7 @@
}
},
"callsites": {
- "version": "3.1.0",
- "dev": true
+ "version": "3.1.0"
},
"camel-case": {
"version": "4.1.2",
@@ -22335,8 +22531,7 @@
"caniuse-lite": {
"version": "1.0.30001375",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
- "integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
- "dev": true
+ "integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw=="
},
"caseless": {
"version": "0.12.0",
@@ -22351,7 +22546,6 @@
},
"chalk": {
"version": "2.4.2",
- "dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -22359,8 +22553,7 @@
},
"dependencies": {
"escape-string-regexp": {
- "version": "1.0.5",
- "dev": true
+ "version": "1.0.5"
}
}
},
@@ -22675,7 +22868,6 @@
},
"convert-source-map": {
"version": "1.8.0",
- "dev": true,
"requires": {
"safe-buffer": "~5.1.1"
}
@@ -22784,7 +22976,6 @@
},
"cosmiconfig": {
"version": "7.0.1",
- "dev": true,
"requires": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
@@ -23137,7 +23328,6 @@
},
"debug": {
"version": "4.3.3",
- "dev": true,
"requires": {
"ms": "2.1.2"
}
@@ -23343,6 +23533,15 @@
"utila": "~0.4"
}
},
+ "dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "requires": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
"dom-serializer": {
"version": "1.3.2",
"dev": true,
@@ -23416,8 +23615,7 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.4.75",
- "dev": true
+ "version": "1.4.75"
},
"emittery": {
"version": "0.8.1",
@@ -23467,7 +23665,6 @@
},
"error-ex": {
"version": "1.3.2",
- "dev": true,
"requires": {
"is-arrayish": "^0.2.1"
}
@@ -23519,16 +23716,14 @@
}
},
"escalade": {
- "version": "3.1.1",
- "dev": true
+ "version": "3.1.1"
},
"escape-html": {
"version": "1.0.3",
"dev": true
},
"escape-string-regexp": {
- "version": "4.0.0",
- "dev": true
+ "version": "4.0.0"
},
"escodegen": {
"version": "2.0.0",
@@ -24373,6 +24568,11 @@
"version": "0.3.1",
"dev": true
},
+ "find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+ },
"find-up": {
"version": "5.0.0",
"dev": true,
@@ -24453,16 +24653,14 @@
"dev": true
},
"function-bind": {
- "version": "1.1.1",
- "dev": true
+ "version": "1.1.1"
},
"functional-red-black-tree": {
"version": "1.0.1",
"dev": true
},
"gensync": {
- "version": "1.0.0-beta.2",
- "dev": true
+ "version": "1.0.0-beta.2"
},
"get-caller-file": {
"version": "2.0.5",
@@ -24574,8 +24772,7 @@
}
},
"globals": {
- "version": "11.12.0",
- "dev": true
+ "version": "11.12.0"
},
"globby": {
"version": "11.1.0",
@@ -24640,7 +24837,6 @@
},
"has": {
"version": "1.0.3",
- "dev": true,
"requires": {
"function-bind": "^1.1.1"
}
@@ -24650,8 +24846,7 @@
"dev": true
},
"has-flag": {
- "version": "3.0.0",
- "dev": true
+ "version": "3.0.0"
},
"has-symbols": {
"version": "1.0.3",
@@ -24921,15 +25116,13 @@
},
"import-fresh": {
"version": "3.3.0",
- "dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
},
"dependencies": {
"resolve-from": {
- "version": "4.0.0",
- "dev": true
+ "version": "4.0.0"
}
}
},
@@ -25061,8 +25254,7 @@
}
},
"is-arrayish": {
- "version": "0.2.1",
- "dev": true
+ "version": "0.2.1"
},
"is-bigint": {
"version": "1.0.4",
@@ -25103,7 +25295,6 @@
},
"is-core-module": {
"version": "2.8.1",
- "dev": true,
"requires": {
"has": "^1.0.3"
}
@@ -26461,11 +26652,6 @@
}
}
},
- "jquery": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
- "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw=="
- },
"js-tokens": {
"version": "4.0.0"
},
@@ -26583,8 +26769,7 @@
}
},
"jsesc": {
- "version": "2.5.2",
- "dev": true
+ "version": "2.5.2"
},
"json-buffer": {
"version": "3.0.1",
@@ -26597,8 +26782,7 @@
"dev": true
},
"json-parse-even-better-errors": {
- "version": "2.3.1",
- "dev": true
+ "version": "2.3.1"
},
"json-schema": {
"version": "0.4.0",
@@ -26622,7 +26806,6 @@
},
"json5": {
"version": "2.2.0",
- "dev": true,
"requires": {
"minimist": "^1.2.5"
}
@@ -26715,8 +26898,7 @@
"dev": true
},
"lines-and-columns": {
- "version": "1.2.4",
- "dev": true
+ "version": "1.2.4"
},
"linkify-it": {
"version": "3.0.3",
@@ -26769,7 +26951,9 @@
}
},
"lodash": {
- "version": "4.17.21"
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash.debounce": {
"version": "4.0.8",
@@ -27176,8 +27360,7 @@
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
- "dev": true
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"minimist-options": {
"version": "4.1.0",
@@ -27205,8 +27388,7 @@
"dev": true
},
"ms": {
- "version": "2.1.2",
- "dev": true
+ "version": "2.1.2"
},
"multicast-dns": {
"version": "6.2.3",
@@ -27259,8 +27441,7 @@
"dev": true
},
"node-releases": {
- "version": "2.0.2",
- "dev": true
+ "version": "2.0.2"
},
"normalize-package-data": {
"version": "2.5.0",
@@ -27591,7 +27772,6 @@
},
"parent-module": {
"version": "1.0.1",
- "dev": true,
"requires": {
"callsites": "^3.0.0"
}
@@ -27610,7 +27790,6 @@
},
"parse-json": {
"version": "5.2.0",
- "dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -27647,16 +27826,14 @@
"dev": true
},
"path-parse": {
- "version": "1.0.7",
- "dev": true
+ "version": "1.0.7"
},
"path-to-regexp": {
"version": "0.1.7",
"dev": true
},
"path-type": {
- "version": "4.0.0",
- "dev": true
+ "version": "4.0.0"
},
"pend": {
"version": "1.2.0",
@@ -27667,8 +27844,7 @@
"dev": true
},
"picocolors": {
- "version": "1.0.0",
- "dev": true
+ "version": "1.0.0"
},
"picomatch": {
"version": "2.3.1",
@@ -28561,11 +28737,6 @@
"version": "2.0.1",
"dev": true
},
- "promise-polyfill": {
- "version": "8.2.3",
- "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.3.tgz",
- "integrity": "sha512-Og0+jCRQetV84U8wVjMNccfGCnMQ9mGs9Hv78QFe+pSDD3gWTpz0y+1QCuxy5d/vBFuZ3iwP2eycAkvqIMPmWg=="
- },
"prompts": {
"version": "2.4.2",
"dev": true,
@@ -28672,6 +28843,7 @@
},
"react": {
"version": "16.14.0",
+ "peer": true,
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
@@ -28719,10 +28891,35 @@
"version": "0.11.0",
"dev": true
},
+ "react-select": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.4.0.tgz",
+ "integrity": "sha512-CjE9RFLUvChd5SdlfG4vqxZd55AZJRrLrHzkQyTYeHlpOztqcgnyftYAolJ0SGsBev6zAs6qFrjm6KU3eo2hzg==",
+ "requires": {
+ "@babel/runtime": "^7.12.0",
+ "@emotion/cache": "^11.4.0",
+ "@emotion/react": "^11.8.1",
+ "@types/react-transition-group": "^4.4.0",
+ "memoize-one": "^5.0.0",
+ "prop-types": "^15.6.0",
+ "react-transition-group": "^4.3.0"
+ }
+ },
"react-slider": {
"version": "1.3.1",
"requires": {}
},
+ "react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ }
+ },
"read-cache": {
"version": "1.0.0",
"dev": true,
@@ -28964,7 +29161,6 @@
},
"resolve": {
"version": "1.22.0",
- "dev": true,
"requires": {
"is-core-module": "^2.8.1",
"path-parse": "^1.0.7",
@@ -29060,8 +29256,7 @@
}
},
"safe-buffer": {
- "version": "5.1.2",
- "dev": true
+ "version": "5.1.2"
},
"safer-buffer": {
"version": "2.1.2",
@@ -29120,8 +29315,7 @@
}
},
"semver": {
- "version": "6.3.0",
- "dev": true
+ "version": "6.3.0"
},
"send": {
"version": "0.17.2",
@@ -29320,8 +29514,7 @@
}
},
"source-map": {
- "version": "0.5.7",
- "dev": true
+ "version": "0.5.7"
},
"source-map-js": {
"version": "1.0.2",
@@ -29783,6 +29976,11 @@
}
}
},
+ "stylis": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
+ "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag=="
+ },
"sugarss": {
"version": "3.0.3",
"dev": true,
@@ -29792,7 +29990,6 @@
},
"supports-color": {
"version": "5.5.0",
- "dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@@ -29819,8 +30016,7 @@
}
},
"supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "dev": true
+ "version": "1.0.0"
},
"svg-parser": {
"version": "2.0.4",
@@ -30016,8 +30212,7 @@
"dev": true
},
"to-fast-properties": {
- "version": "2.0.0",
- "dev": true
+ "version": "2.0.0"
},
"to-regex-range": {
"version": "5.0.1",
@@ -30796,8 +30991,7 @@
"dev": true
},
"yaml": {
- "version": "1.10.2",
- "dev": true
+ "version": "1.10.2"
},
"yargs": {
"version": "17.3.1",
diff --git a/package.json b/package.json
index 012eb4d4ce..600f7fa068 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"cypress-file-upload": "^5.0.8",
"eslint-plugin-cypress": "^2.12.1",
"jsdoc": "^3.6.10",
+ "lodash": "^4.17.21",
"postcss-preset-env": "^7.0.1",
"terser-webpack-plugin": "^5.3.0",
"wp-hookdoc": "^0.2.0"
@@ -76,7 +77,8 @@
"facets-block-styles.min": "./assets/css/facets-block.css",
"related-posts-block-styles.min": "./assets/css/related-posts-block.css",
"sync-styles.min": "./assets/css/sync.css",
- "synonyms-styles.min": "./assets/css/synonyms.css"
+ "synonyms-styles.min": "./assets/css/synonyms.css",
+ "weighting-styles.min": "./assets/css/weighting.css"
},
"wpDependencyExternals": true
},
@@ -85,10 +87,7 @@
"@wordpress/icons": "^6.1.1",
"chart.js": "^2.9.4",
"focus-trap-react": "^8.8.2",
- "jquery": "^3.6.0",
- "promise-polyfill": "^8.2.1",
"prop-types": "^15.8.1",
- "react": "^16.14.0",
"react-beautiful-dnd": "^11.0.5",
"react-slider": "^1.3.1",
"uuid": "^8.3.2"
From b68c382e1e697c40d54304e677567d964a8f10cd Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Mon, 10 Oct 2022 01:18:30 +1100
Subject: [PATCH 04/63] WIP populate weighting screen with real data.
---
assets/css/weighting.css | 8 +
assets/js/weighting/components/post-type.js | 74 +--
.../weighting/components/post-type/group.js | 121 ++++
.../components/post-type/properties.js | 54 --
.../components/post-type/property.js | 40 +-
assets/js/weighting/config.js | 6 +
assets/js/weighting/index.js | 30 +-
assets/js/weighting/utilities.js | 0
includes/classes/Feature/Search/Weighting.php | 109 +++-
includes/dashboard.php | 11 +
package-lock.json | 554 ++++++------------
11 files changed, 455 insertions(+), 552 deletions(-)
create mode 100644 assets/js/weighting/components/post-type/group.js
delete mode 100644 assets/js/weighting/components/post-type/properties.js
create mode 100644 assets/js/weighting/config.js
create mode 100644 assets/js/weighting/utilities.js
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
index efff47d69e..d77d3c45e4 100644
--- a/assets/css/weighting.css
+++ b/assets/css/weighting.css
@@ -55,3 +55,11 @@
visibility: hidden;
}
}
+
+.ep-weighting-add-meta {
+ justify-content: start;
+
+ & .components-select-control__input.components-select-control__input.components-select-control__input {
+ min-height: 36px;
+ }
+}
diff --git a/assets/js/weighting/components/post-type.js b/assets/js/weighting/components/post-type.js
index bb06b751e7..7d151b5ce7 100644
--- a/assets/js/weighting/components/post-type.js
+++ b/assets/js/weighting/components/post-type.js
@@ -9,50 +9,31 @@ import { isEqual } from 'lodash';
/**
* Internal dependencies.
*/
-import Properties from './post-type/properties';
+import Group from './post-type/group';
import UndoButton from './common/undo-button';
/**
* Post type weighting settings component.
*
* @param {object} props Components props.
+ * @param {object[]} props.groups Field groups.
* @param {string} props.label Post type label.
* @param {Function} props.onChange Data change handler.
- * @param {object} props.originalValue Saved post type settings.
- * @param {object} props.value Current post type settings.
+ * @param {object} props.originalValues Saved post type settings.
+ * @param {object} props.values Current post type settings.
* @returns {WPElement} Component element.
*/
-export default ({ label, onChange, originalValue, value }) => {
- const isChanged = useMemo(() => !isEqual(originalValue, value), [originalValue, value]);
+export default ({ groups, label, onChange, originalValues, values }) => {
+ const isChanged = useMemo(() => !isEqual(originalValues, values), [originalValues, values]);
/**
- * Handle a change to post type indexing.
+ * Handle a change to the post type's setttings.
*
- * @param {boolean} indexable Is post type indexable.
+ * @param {Array} values Post type settings.
* @returns {void}
*/
- const onChangeIndexable = (indexable) => {
- onChange({ ...value, indexable });
- };
-
- /**
- * Handle a change to the post type's attribute setttings.
- *
- * @param {Array} attributes Attribute settings.
- * @returns {void}
- */
- const onChangeAttributes = (attributes) => {
- onChange({ ...value, attributes });
- };
-
- /**
- * Handle a change to the post type's taxonomy setttings.
- *
- * @param {Array} taxonomies Taxonomy settings.
- * @returns {void}
- */
- const onChangeTaxonomies = (taxonomies) => {
- onChange({ ...value, taxonomies });
+ const onChangeGroup = (values) => {
+ onChange(values);
};
/**
@@ -61,7 +42,7 @@ export default ({ label, onChange, originalValue, value }) => {
* @returns {void}
*/
const onReset = () => {
- onChange({ ...originalValue });
+ onChange(originalValues);
};
return (
@@ -72,11 +53,7 @@ export default ({ label, onChange, originalValue, value }) => {
{label}
-
+
{isChanged ? (
@@ -89,22 +66,19 @@ export default ({ label, onChange, originalValue, value }) => {
- {value.indexable ? (
- <>
-
- g.children.length !== 0)
+ .map(([key, { label, children }]) => (
+
- >
- ) : null}
+ ))}
);
};
diff --git a/assets/js/weighting/components/post-type/group.js b/assets/js/weighting/components/post-type/group.js
new file mode 100644
index 0000000000..3f6a52eeaf
--- /dev/null
+++ b/assets/js/weighting/components/post-type/group.js
@@ -0,0 +1,121 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button, PanelBody, PanelRow, SelectControl } from '@wordpress/components';
+import { useMemo, useState, WPElement } from '@wordpress/element';
+
+/**
+ * Internal dependencies.
+ */
+import Property from './property';
+
+/**
+ * Post type propertes component.
+ *
+ * @param {object} props Component props.
+ * @param {boolean} props.isEditable Whether to display as an editable list.
+ * @param {string} props.label Properties label.
+ * @param {Function} props.onChange Change handler.
+ * @param {object[]} props.originalValues Saved property values.
+ * @param {object[]} props.properties Post type properties.
+ * @param {object[]} props.values Current property values.
+ * @returns {WPElement} Component element.
+ */
+export default ({ isEditable, label, onChange, originalValues, properties, values }) => {
+ const [toAdd, setToAdd] = useState('');
+
+ /**
+ * Handle changes to a property.
+ *
+ * @param {object} value New property data.
+ * @param {number} key Property key.
+ * @returns {void}
+ */
+ const onChangeProperty = (value, key) => {
+ const newValues = { ...values, [key]: value };
+
+ onChange(newValues);
+ };
+
+ /**
+ * Handle selecting a new property to enable.
+ *
+ * @param {string} key Key of property to enable.
+ * @returns {void}
+ */
+ const onChangeToAdd = (key) => {
+ setToAdd(key);
+ };
+
+ /**
+ * Handle clicking to add a new property.
+ *
+ * @returns {void}
+ */
+ const onClickAdd = () => {
+ const value = { ...values[toAdd], enabled: true };
+ const newValues = { ...values, [toAdd]: value };
+
+ onChange(newValues);
+ setToAdd('');
+ };
+
+ /**
+ * Options for properties that can be added to the list of weightable
+ * properties.
+ */
+ const availableProperties = useMemo(() => {
+ return isEditable
+ ? Object.values(properties).map((p) => ({
+ label: p.label,
+ value: p.key,
+ disabled: values[p.key].enabled,
+ }))
+ : null;
+ }, [isEditable, properties, values]);
+
+ /**
+ * Properties that can be weighted.
+ *
+ * If the component is set to be editable this will only be properties that
+ * are indexed, otherwise it will be all properties.
+ */
+ const weightableProperties = useMemo(() => {
+ return Object.values(properties).filter((p) => (isEditable ? values[p.key].enabled : true));
+ }, [isEditable, properties, values]);
+
+ return (
+
+ {weightableProperties.map(({ key, label }) => (
+
+ {
+ onChangeProperty(value, key);
+ }}
+ />
+
+ ))}
+ {availableProperties ? (
+
+
+
+
+ Add
+
+
+ ) : null}
+
+ );
+};
diff --git a/assets/js/weighting/components/post-type/properties.js b/assets/js/weighting/components/post-type/properties.js
deleted file mode 100644
index dc0b75aac1..0000000000
--- a/assets/js/weighting/components/post-type/properties.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { PanelBody, PanelRow } from '@wordpress/components';
-import { WPElement } from '@wordpress/element';
-
-/**
- * Internal dependencies.
- */
-import Property from './property';
-
-/**
- * Post type propertes component.
- *
- * @param {object} props Component props.
- * @param {string} props.label Properties label.
- * @param {Function} props.onChange Change handler.
- * @param {object[]} props.originalValue Saved property values.
- * @param {object[]} props.value Current property values.
- * @returns {WPElement} Component element.
- */
-export default ({ label, onChange, originalValue, value }) => {
- /**
- * Handle changes to a property.
- *
- * @param {object} property New property data.
- * @param {number} index Index of the changed property.
- * @returns {void}
- */
- const onChangeProperty = (property, index) => {
- const newValue = [...value];
-
- newValue[index] = { ...value[index], ...property };
-
- onChange(newValue);
- };
-
- return (
-
- {value.map((value, index) => (
-
- {
- onChangeProperty(value, index);
- }}
- />
-
- ))}
-
- );
-};
diff --git a/assets/js/weighting/components/post-type/property.js b/assets/js/weighting/components/post-type/property.js
index b4715610fa..6d2e126255 100644
--- a/assets/js/weighting/components/post-type/property.js
+++ b/assets/js/weighting/components/post-type/property.js
@@ -23,7 +23,7 @@ import WeightControl from '../common/weight-control';
* @returns {WPElement} Component element.
*/
export default ({ label, onChange, originalValue, value }) => {
- const { indexable, searchable, weight } = value;
+ const { enabled = true, weight = 99 } = value;
/**
* Is the current value different to the original.
@@ -33,21 +33,11 @@ export default ({ label, onChange, originalValue, value }) => {
/**
* Handle change of indexable.
*
- * @param {boolean} indexable New indexable value.
+ * @param {boolean} enabled New indexable value.
* @returns {void}
*/
- const onChangeIndex = (indexable) => {
- onChange({ ...value, indexable, searchable: false });
- };
-
- /**
- * Handle change of searchable.
- *
- * @param {boolean} searchable New searchable value.
- * @returns {void}
- */
- const onChangeSearchable = (searchable) => {
- onChange({ ...value, indexable: true, searchable });
+ const onChangeEnabled = (enabled) => {
+ onChange({ ...value, enabled });
};
/**
@@ -65,8 +55,8 @@ export default ({ label, onChange, originalValue, value }) => {
*
* @returns {void}
*/
- const onUndo = () => {
- onChange({ ...originalValue });
+ const onReset = () => {
+ onChange(originalValue);
};
return (
@@ -76,29 +66,21 @@ export default ({ label, onChange, originalValue, value }) => {
-
+
-
+
diff --git a/assets/js/weighting/config.js b/assets/js/weighting/config.js
new file mode 100644
index 0000000000..c8b1826783
--- /dev/null
+++ b/assets/js/weighting/config.js
@@ -0,0 +1,6 @@
+/**
+ * Window dependencies.
+ */
+const { weightableFields, weightingConfiguration } = window.epWeighting;
+
+export { weightableFields, weightingConfiguration };
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index 29d5dab8a6..1f387798cc 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -8,7 +8,7 @@ import { cloneDeep, isEqual } from 'lodash';
/**
* Internal Dependencies.
*/
-import { dummyData } from './dummyData';
+import { weightableFields, weightingConfiguration } from './config';
import PostType from './components/post-type';
import Save from './components/save';
@@ -18,8 +18,8 @@ import Save from './components/save';
* @returns {WPElement} Element.
*/
const App = () => {
- const [data, setData] = useState(cloneDeep(dummyData));
- const [savedData, setSavedData] = useState(cloneDeep(dummyData));
+ const [data, setData] = useState(cloneDeep(weightingConfiguration));
+ const [savedData, setSavedData] = useState(cloneDeep(weightingConfiguration));
const [isBusy, setIsBusy] = useState(false);
/**
@@ -31,10 +31,13 @@ const App = () => {
* Handle data change.
*
* @param {Array} value Updated data.
+ * @param {string} postType Updated post type.
* @returns {void}
*/
- const onChange = (value) => {
- setData(value);
+ const onChangePostType = (value, postType) => {
+ const newData = { ...data, [postType]: value };
+
+ setData(newData);
};
/**
@@ -81,19 +84,16 @@ const App = () => {
- {data.map((value, index) => (
+ {Object.entries(weightableFields).map(([key, groups]) => (
{
- const newValue = [...data];
-
- newValue.splice(index, 1, value);
-
- onChange(newValue);
+ onChangePostType(value, key);
}}
- originalValue={savedData[index]}
- value={value}
+ originalValues={savedData[key]}
+ values={data[key]}
/>
))}
diff --git a/assets/js/weighting/utilities.js b/assets/js/weighting/utilities.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 783118c615..b9d86d09c0 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -8,6 +8,7 @@
namespace ElasticPress\Feature\Search;
use ElasticPress\Features;
+use ElasticPress\Indexables;
use ElasticPress\Indexable\Post\Post;
use ElasticPress\Utils as Utils;
@@ -40,32 +41,6 @@ public function setup() {
add_filter( 'ep_query_weighting_fields', [ $this, 'adjust_weight_for_cross_fields' ], 10, 5 );
}
- /**
- * Returns unique list of meta keys
- *
- * @param string $post_type Post type
- *
- * @return array
- */
- public function get_meta_keys_for_post_type( $post_type ) {
-
-
- $meta_keys = array();
- $posts = get_posts( array( 'post_type' => $post_type, 'limit' => -1 ) );
-
-
- foreach ( $posts as $post ) {
- $post_meta_keys = get_post_custom_keys( $post->ID );
- var_dump($post_meta_keys);
- $meta_keys = array_merge( $meta_keys, $post_meta_keys );
- }
-
- // Use array_unique to remove duplicate meta_keys that we received from all posts
- // Use array_values to reset the index of the array
- return array_values( array_unique( $meta_keys ) );
-
- }
-
/**
* Returns a grouping of all the fields that support weighting for the post type
*
@@ -125,6 +100,29 @@ public function get_weightable_fields_for_post_type( $post_type ) {
}
}
+ /**
+ * TODO: Meta keys per post type?
+ */
+ $fields['meta'] = [
+ 'label' => 'Metadata',
+ 'children' => [],
+ ];
+
+ try {
+ $meta_keys = Indexables::factory()->get( 'post' )->get_distinct_meta_field_keys();
+ } catch ( \Throwable $th ) {
+ $meta_keys = [];
+ }
+
+ foreach ( $meta_keys as $meta_key ) {
+ $key = "meta.$meta_key.value";
+
+ $fields['meta']['children'][$key] = [
+ 'key' => $key,
+ 'label' => $meta_key,
+ ];
+ }
+
/**
* Filter weighting fields for a post type
*
@@ -136,6 +134,23 @@ public function get_weightable_fields_for_post_type( $post_type ) {
return apply_filters( 'ep_weighting_fields_for_post_type', $fields, $post_type );
}
+ /**
+ * Get weightable fields for all searchable post types.
+ *
+ * @since 4.4.0
+ * @return array
+ */
+ public function get_weightable_fields() {
+ $weightable = array();
+ $post_types = Features::factory()->get_registered_feature( 'search' )->get_searchable_post_types();
+
+ foreach ( $post_types as $post_type ) {
+ $weightable[ $post_type ] = $this->get_weightable_fields_for_post_type( $post_type );
+ }
+
+ return $weightable;
+ }
+
/**
* Returns default settings for any post type
*
@@ -190,6 +205,26 @@ public function get_post_type_default_settings( $post_type ) {
}
}
+ /**
+ * TODO: Meta keys per post type?
+ */
+ $indexable = Indexables::factory()->get( 'post' );
+
+ try {
+ $meta_keys = $indexable->get_distinct_meta_field_keys();
+ } catch ( \Throwable $th ) {
+ $meta_keys = [];
+ }
+
+ foreach ( $meta_keys as $meta_key ) {
+ $key = "meta.$meta_key.value";
+
+ $post_type_defaults[ $key ] = [
+ 'enabled' => false,
+ 'weight' => 1,
+ ];
+ }
+
/**
* Filter weighting defaults for post type
*
@@ -217,6 +252,28 @@ public function get_weighting_configuration() {
return apply_filters( 'ep_weighting_configuration', get_option( 'elasticpress_weighting', [] ) );
}
+ /**
+ * Returns the current weighting configuration with defaults for any
+ * missing properties.
+ *
+ * @return array Current weighting configuration with defaults.
+ * @since 4.4.0
+ */
+ public function get_weighting_configuration_with_defaults() {
+ $search = Features::factory()->get_registered_feature( 'search' );
+ $post_types = $search->get_searchable_post_types();
+ $weighting = $this->get_weighting_configuration();
+
+ foreach ( $post_types as $post_type ) {
+ $config = isset( $weighting[ $post_type ] ) ? $weighting[ $post_type ] : array();
+ $default = $this->get_post_type_default_settings( $post_type );
+
+ $weighting[ $post_type ] = wp_parse_args( $config, $default );
+ }
+
+ return $weighting;
+ }
+
/**
* Adds the submenu page for controlling weighting
*/
diff --git a/includes/dashboard.php b/includes/dashboard.php
index cf1a4b2089..18f21c1bdb 100644
--- a/includes/dashboard.php
+++ b/includes/dashboard.php
@@ -506,6 +506,17 @@ function action_admin_enqueue_dashboard_scripts() {
Utils\get_asset_info( 'weighting-script', 'version' ),
true
);
+
+ $weighting = Features::factory()->get_registered_feature( 'search' )->weighting;
+
+ wp_localize_script(
+ 'ep_weighting_script',
+ 'epWeighting',
+ array(
+ 'weightableFields' => $weighting->get_weightable_fields(),
+ 'weightingConfiguration' => $weighting->get_weighting_configuration_with_defaults(),
+ )
+ );
}
if ( in_array( Screen::factory()->get_current_screen(), [ 'dashboard', 'install' ], true ) ) {
diff --git a/package-lock.json b/package-lock.json
index 60b033c52c..6b2d7f3f20 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,7 +15,6 @@
"focus-trap-react": "^8.8.2",
"prop-types": "^15.8.1",
"react-beautiful-dnd": "^11.0.5",
- "react-select": "^5.4.0",
"react-slider": "^1.3.1",
"uuid": "^8.3.2"
},
@@ -148,6 +147,7 @@
},
"node_modules/@ampproject/remapping": {
"version": "2.1.2",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.0"
@@ -158,6 +158,7 @@
},
"node_modules/@babel/code-frame": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/highlight": "^7.16.7"
@@ -168,6 +169,7 @@
},
"node_modules/@babel/compat-data": {
"version": "7.17.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -175,6 +177,7 @@
},
"node_modules/@babel/core": {
"version": "7.17.5",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.1.0",
@@ -220,6 +223,7 @@
},
"node_modules/@babel/generator": {
"version": "7.17.3",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.17.0",
@@ -255,6 +259,7 @@
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.16.4",
@@ -324,6 +329,7 @@
},
"node_modules/@babel/helper-environment-visitor": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -345,6 +351,7 @@
},
"node_modules/@babel/helper-function-name": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-get-function-arity": "^7.16.7",
@@ -357,6 +364,7 @@
},
"node_modules/@babel/helper-get-function-arity": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -367,6 +375,7 @@
},
"node_modules/@babel/helper-hoist-variables": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -388,6 +397,7 @@
},
"node_modules/@babel/helper-module-imports": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -398,6 +408,7 @@
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.17.6",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-environment-visitor": "^7.16.7",
@@ -428,6 +439,7 @@
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
"integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==",
+ "dev": true,
"engines": {
"node": ">=6.9.0"
}
@@ -462,6 +474,7 @@
},
"node_modules/@babel/helper-simple-access": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -483,6 +496,7 @@
},
"node_modules/@babel/helper-split-export-declaration": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.16.7"
@@ -493,6 +507,7 @@
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -500,6 +515,7 @@
},
"node_modules/@babel/helper-validator-option": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -521,6 +537,7 @@
},
"node_modules/@babel/helpers": {
"version": "7.17.2",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.16.7",
@@ -533,6 +550,7 @@
},
"node_modules/@babel/highlight": {
"version": "7.16.10",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.16.7",
@@ -545,6 +563,7 @@
},
"node_modules/@babel/parser": {
"version": "7.17.3",
+ "dev": true,
"license": "MIT",
"bin": {
"parser": "bin/babel-parser.js"
@@ -911,6 +930,7 @@
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
"integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.18.6"
},
@@ -1808,6 +1828,7 @@
},
"node_modules/@babel/template": {
"version": "7.16.7",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.16.7",
@@ -1820,6 +1841,7 @@
},
"node_modules/@babel/traverse": {
"version": "7.17.3",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.16.7",
@@ -1839,6 +1861,7 @@
},
"node_modules/@babel/types": {
"version": "7.17.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.16.7",
@@ -2013,117 +2036,6 @@
"ms": "^2.1.1"
}
},
- "node_modules/@emotion/babel-plugin": {
- "version": "11.10.2",
- "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz",
- "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==",
- "dependencies": {
- "@babel/helper-module-imports": "^7.16.7",
- "@babel/plugin-syntax-jsx": "^7.17.12",
- "@babel/runtime": "^7.18.3",
- "@emotion/hash": "^0.9.0",
- "@emotion/memoize": "^0.8.0",
- "@emotion/serialize": "^1.1.0",
- "babel-plugin-macros": "^3.1.0",
- "convert-source-map": "^1.5.0",
- "escape-string-regexp": "^4.0.0",
- "find-root": "^1.1.0",
- "source-map": "^0.5.7",
- "stylis": "4.0.13"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@emotion/cache": {
- "version": "11.10.3",
- "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz",
- "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==",
- "dependencies": {
- "@emotion/memoize": "^0.8.0",
- "@emotion/sheet": "^1.2.0",
- "@emotion/utils": "^1.2.0",
- "@emotion/weak-memoize": "^0.3.0",
- "stylis": "4.0.13"
- }
- },
- "node_modules/@emotion/hash": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
- "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
- },
- "node_modules/@emotion/memoize": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
- "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
- },
- "node_modules/@emotion/react": {
- "version": "11.10.4",
- "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz",
- "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==",
- "dependencies": {
- "@babel/runtime": "^7.18.3",
- "@emotion/babel-plugin": "^11.10.0",
- "@emotion/cache": "^11.10.0",
- "@emotion/serialize": "^1.1.0",
- "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0",
- "@emotion/utils": "^1.2.0",
- "@emotion/weak-memoize": "^0.3.0",
- "hoist-non-react-statics": "^3.3.1"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0",
- "react": ">=16.8.0"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@emotion/serialize": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz",
- "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==",
- "dependencies": {
- "@emotion/hash": "^0.9.0",
- "@emotion/memoize": "^0.8.0",
- "@emotion/unitless": "^0.8.0",
- "@emotion/utils": "^1.2.0",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/@emotion/sheet": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz",
- "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w=="
- },
- "node_modules/@emotion/unitless": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
- "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
- },
- "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
- "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
- "peerDependencies": {
- "react": ">=16.8.0"
- }
- },
- "node_modules/@emotion/utils": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
- "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
- },
- "node_modules/@emotion/weak-memoize": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
- "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
- },
"node_modules/@es-joy/jsdoccomment": {
"version": "0.20.1",
"dev": true,
@@ -2866,6 +2778,7 @@
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.0.5",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -2892,12 +2805,14 @@
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.11",
+ "dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
+ "dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -3603,6 +3518,7 @@
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/prettier": {
@@ -3650,14 +3566,6 @@
"redux": "^4.0.0"
}
},
- "node_modules/@types/react-transition-group": {
- "version": "4.4.5",
- "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
- "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
- "dependencies": {
- "@types/react": "*"
- }
- },
"node_modules/@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
@@ -4630,6 +4538,7 @@
},
"node_modules/ansi-styles": {
"version": "3.2.1",
+ "dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^1.9.0"
@@ -5052,20 +4961,6 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
- "node_modules/babel-plugin-macros": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
- "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
- "dependencies": {
- "@babel/runtime": "^7.12.5",
- "cosmiconfig": "^7.0.0",
- "resolve": "^1.19.0"
- },
- "engines": {
- "node": ">=10",
- "npm": ">=6"
- }
- },
"node_modules/babel-plugin-polyfill-corejs2": {
"version": "0.3.1",
"dev": true,
@@ -5324,6 +5219,7 @@
},
"node_modules/browserslist": {
"version": "4.19.3",
+ "dev": true,
"license": "MIT",
"dependencies": {
"caniuse-lite": "^1.0.30001312",
@@ -5449,6 +5345,7 @@
},
"node_modules/callsites": {
"version": "3.1.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5521,6 +5418,7 @@
"version": "1.0.30001375",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
"integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -5550,6 +5448,7 @@
},
"node_modules/chalk": {
"version": "2.4.2",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^3.2.1",
@@ -5562,6 +5461,7 @@
},
"node_modules/chalk/node_modules/escape-string-regexp": {
"version": "1.0.5",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.0"
@@ -6049,6 +5949,7 @@
},
"node_modules/convert-source-map": {
"version": "1.8.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.1"
@@ -6232,6 +6133,7 @@
},
"node_modules/cosmiconfig": {
"version": "7.0.1",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/parse-json": "^4.0.0",
@@ -6777,6 +6679,7 @@
},
"node_modules/debug": {
"version": "4.3.3",
+ "dev": true,
"license": "MIT",
"dependencies": {
"ms": "2.1.2"
@@ -7095,15 +6998,6 @@
"utila": "~0.4"
}
},
- "node_modules/dom-helpers": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
- "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
- "dependencies": {
- "@babel/runtime": "^7.8.7",
- "csstype": "^3.0.2"
- }
- },
"node_modules/dom-serializer": {
"version": "1.3.2",
"dev": true,
@@ -7212,6 +7106,7 @@
},
"node_modules/electron-to-chromium": {
"version": "1.4.75",
+ "dev": true,
"license": "ISC"
},
"node_modules/emittery": {
@@ -7297,6 +7192,7 @@
},
"node_modules/error-ex": {
"version": "1.3.2",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
@@ -7366,6 +7262,7 @@
},
"node_modules/escalade": {
"version": "3.1.1",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -7378,6 +7275,7 @@
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -8674,11 +8572,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/find-root": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
- "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
- },
"node_modules/find-up": {
"version": "5.0.0",
"dev": true,
@@ -8824,6 +8717,7 @@
},
"node_modules/function-bind": {
"version": "1.1.1",
+ "dev": true,
"license": "MIT"
},
"node_modules/functional-red-black-tree": {
@@ -8833,6 +8727,7 @@
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -9014,6 +8909,7 @@
},
"node_modules/globals": {
"version": "11.12.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -9116,6 +9012,7 @@
},
"node_modules/has": {
"version": "1.0.3",
+ "dev": true,
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.1"
@@ -9134,6 +9031,7 @@
},
"node_modules/has-flag": {
"version": "3.0.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -9579,6 +9477,7 @@
},
"node_modules/import-fresh": {
"version": "3.3.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -9593,6 +9492,7 @@
},
"node_modules/import-fresh/node_modules/resolve-from": {
"version": "4.0.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -9809,6 +9709,7 @@
},
"node_modules/is-arrayish": {
"version": "0.2.1",
+ "dev": true,
"license": "MIT"
},
"node_modules/is-bigint": {
@@ -9894,6 +9795,7 @@
},
"node_modules/is-core-module": {
"version": "2.8.1",
+ "dev": true,
"license": "MIT",
"dependencies": {
"has": "^1.0.3"
@@ -12220,6 +12122,7 @@
},
"node_modules/jsesc": {
"version": "2.5.2",
+ "dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -12241,6 +12144,7 @@
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
+ "dev": true,
"license": "MIT"
},
"node_modules/json-schema": {
@@ -12270,6 +12174,7 @@
},
"node_modules/json5": {
"version": "2.2.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"minimist": "^1.2.5"
@@ -12416,6 +12321,7 @@
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
+ "dev": true,
"license": "MIT"
},
"node_modules/linkify-it": {
@@ -13160,7 +13066,8 @@
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "dev": true
},
"node_modules/minimist-options": {
"version": "4.1.0",
@@ -13204,6 +13111,7 @@
},
"node_modules/ms": {
"version": "2.1.2",
+ "dev": true,
"license": "MIT"
},
"node_modules/multicast-dns": {
@@ -13282,6 +13190,7 @@
},
"node_modules/node-releases": {
"version": "2.0.2",
+ "dev": true,
"license": "MIT"
},
"node_modules/normalize-package-data": {
@@ -13812,6 +13721,7 @@
},
"node_modules/parent-module": {
"version": "1.0.1",
+ "dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
@@ -13839,6 +13749,7 @@
},
"node_modules/parse-json": {
"version": "5.2.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
@@ -13901,6 +13812,7 @@
},
"node_modules/path-parse": {
"version": "1.0.7",
+ "dev": true,
"license": "MIT"
},
"node_modules/path-to-regexp": {
@@ -13910,6 +13822,7 @@
},
"node_modules/path-type": {
"version": "4.0.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -13927,6 +13840,7 @@
},
"node_modules/picocolors": {
"version": "1.0.0",
+ "dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
@@ -15705,24 +15619,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/react-select": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.4.0.tgz",
- "integrity": "sha512-CjE9RFLUvChd5SdlfG4vqxZd55AZJRrLrHzkQyTYeHlpOztqcgnyftYAolJ0SGsBev6zAs6qFrjm6KU3eo2hzg==",
- "dependencies": {
- "@babel/runtime": "^7.12.0",
- "@emotion/cache": "^11.4.0",
- "@emotion/react": "^11.8.1",
- "@types/react-transition-group": "^4.4.0",
- "memoize-one": "^5.0.0",
- "prop-types": "^15.6.0",
- "react-transition-group": "^4.3.0"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
- }
- },
"node_modules/react-slider": {
"version": "1.3.1",
"license": "MIT",
@@ -15731,21 +15627,6 @@
"react": "^16 || ^17"
}
},
- "node_modules/react-transition-group": {
- "version": "4.4.5",
- "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
- "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
- "dependencies": {
- "@babel/runtime": "^7.5.5",
- "dom-helpers": "^5.0.1",
- "loose-envify": "^1.4.0",
- "prop-types": "^15.6.2"
- },
- "peerDependencies": {
- "react": ">=16.6.0",
- "react-dom": ">=16.6.0"
- }
- },
"node_modules/read-cache": {
"version": "1.0.0",
"dev": true,
@@ -16106,6 +15987,7 @@
},
"node_modules/resolve": {
"version": "1.22.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"is-core-module": "^2.8.1",
@@ -16268,6 +16150,7 @@
},
"node_modules/safe-buffer": {
"version": "5.1.2",
+ "dev": true,
"license": "MIT"
},
"node_modules/safer-buffer": {
@@ -16383,6 +16266,7 @@
},
"node_modules/semver": {
"version": "6.3.0",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -16646,6 +16530,7 @@
},
"node_modules/source-map": {
"version": "0.5.7",
+ "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -17327,11 +17212,6 @@
"node": ">=8"
}
},
- "node_modules/stylis": {
- "version": "4.0.13",
- "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
- "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag=="
- },
"node_modules/sugarss": {
"version": "3.0.3",
"dev": true,
@@ -17349,6 +17229,7 @@
},
"node_modules/supports-color": {
"version": "5.5.0",
+ "dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^3.0.0"
@@ -17390,6 +17271,7 @@
},
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -17698,6 +17580,7 @@
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -18951,6 +18834,7 @@
},
"node_modules/yaml": {
"version": "1.10.2",
+ "dev": true,
"license": "ISC",
"engines": {
"node": ">= 6"
@@ -19089,21 +18973,25 @@
},
"@ampproject/remapping": {
"version": "2.1.2",
+ "dev": true,
"requires": {
"@jridgewell/trace-mapping": "^0.3.0"
}
},
"@babel/code-frame": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/highlight": "^7.16.7"
}
},
"@babel/compat-data": {
- "version": "7.17.0"
+ "version": "7.17.0",
+ "dev": true
},
"@babel/core": {
"version": "7.17.5",
+ "dev": true,
"requires": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.16.7",
@@ -19133,6 +19021,7 @@
},
"@babel/generator": {
"version": "7.17.3",
+ "dev": true,
"requires": {
"@babel/types": "^7.17.0",
"jsesc": "^2.5.1",
@@ -19156,6 +19045,7 @@
},
"@babel/helper-compilation-targets": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/compat-data": "^7.16.4",
"@babel/helper-validator-option": "^7.16.7",
@@ -19200,6 +19090,7 @@
},
"@babel/helper-environment-visitor": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
@@ -19213,6 +19104,7 @@
},
"@babel/helper-function-name": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/helper-get-function-arity": "^7.16.7",
"@babel/template": "^7.16.7",
@@ -19221,12 +19113,14 @@
},
"@babel/helper-get-function-arity": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
},
"@babel/helper-hoist-variables": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
@@ -19240,12 +19134,14 @@
},
"@babel/helper-module-imports": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
},
"@babel/helper-module-transforms": {
"version": "7.17.6",
+ "dev": true,
"requires": {
"@babel/helper-environment-visitor": "^7.16.7",
"@babel/helper-module-imports": "^7.16.7",
@@ -19267,7 +19163,8 @@
"@babel/helper-plugin-utils": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
- "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw=="
+ "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==",
+ "dev": true
},
"@babel/helper-remap-async-to-generator": {
"version": "7.16.8",
@@ -19291,6 +19188,7 @@
},
"@babel/helper-simple-access": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
@@ -19304,15 +19202,18 @@
},
"@babel/helper-split-export-declaration": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/types": "^7.16.7"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.16.7"
+ "version": "7.16.7",
+ "dev": true
},
"@babel/helper-validator-option": {
- "version": "7.16.7"
+ "version": "7.16.7",
+ "dev": true
},
"@babel/helper-wrap-function": {
"version": "7.16.8",
@@ -19326,6 +19227,7 @@
},
"@babel/helpers": {
"version": "7.17.2",
+ "dev": true,
"requires": {
"@babel/template": "^7.16.7",
"@babel/traverse": "^7.17.0",
@@ -19334,6 +19236,7 @@
},
"@babel/highlight": {
"version": "7.16.10",
+ "dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.16.7",
"chalk": "^2.0.0",
@@ -19341,7 +19244,8 @@
}
},
"@babel/parser": {
- "version": "7.17.3"
+ "version": "7.17.3",
+ "dev": true
},
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
"version": "7.16.7",
@@ -19547,6 +19451,7 @@
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
"integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.18.6"
}
@@ -20081,6 +19986,7 @@
},
"@babel/template": {
"version": "7.16.7",
+ "dev": true,
"requires": {
"@babel/code-frame": "^7.16.7",
"@babel/parser": "^7.16.7",
@@ -20089,6 +19995,7 @@
},
"@babel/traverse": {
"version": "7.17.3",
+ "dev": true,
"requires": {
"@babel/code-frame": "^7.16.7",
"@babel/generator": "^7.17.3",
@@ -20104,6 +20011,7 @@
},
"@babel/types": {
"version": "7.17.0",
+ "dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.16.7",
"to-fast-properties": "^2.0.0"
@@ -20213,100 +20121,6 @@
}
}
},
- "@emotion/babel-plugin": {
- "version": "11.10.2",
- "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz",
- "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==",
- "requires": {
- "@babel/helper-module-imports": "^7.16.7",
- "@babel/plugin-syntax-jsx": "^7.17.12",
- "@babel/runtime": "^7.18.3",
- "@emotion/hash": "^0.9.0",
- "@emotion/memoize": "^0.8.0",
- "@emotion/serialize": "^1.1.0",
- "babel-plugin-macros": "^3.1.0",
- "convert-source-map": "^1.5.0",
- "escape-string-regexp": "^4.0.0",
- "find-root": "^1.1.0",
- "source-map": "^0.5.7",
- "stylis": "4.0.13"
- }
- },
- "@emotion/cache": {
- "version": "11.10.3",
- "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz",
- "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==",
- "requires": {
- "@emotion/memoize": "^0.8.0",
- "@emotion/sheet": "^1.2.0",
- "@emotion/utils": "^1.2.0",
- "@emotion/weak-memoize": "^0.3.0",
- "stylis": "4.0.13"
- }
- },
- "@emotion/hash": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
- "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
- },
- "@emotion/memoize": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
- "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
- },
- "@emotion/react": {
- "version": "11.10.4",
- "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz",
- "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==",
- "requires": {
- "@babel/runtime": "^7.18.3",
- "@emotion/babel-plugin": "^11.10.0",
- "@emotion/cache": "^11.10.0",
- "@emotion/serialize": "^1.1.0",
- "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0",
- "@emotion/utils": "^1.2.0",
- "@emotion/weak-memoize": "^0.3.0",
- "hoist-non-react-statics": "^3.3.1"
- }
- },
- "@emotion/serialize": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz",
- "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==",
- "requires": {
- "@emotion/hash": "^0.9.0",
- "@emotion/memoize": "^0.8.0",
- "@emotion/unitless": "^0.8.0",
- "@emotion/utils": "^1.2.0",
- "csstype": "^3.0.2"
- }
- },
- "@emotion/sheet": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz",
- "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w=="
- },
- "@emotion/unitless": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
- "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
- },
- "@emotion/use-insertion-effect-with-fallbacks": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
- "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
- "requires": {}
- },
- "@emotion/utils": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
- "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
- },
- "@emotion/weak-memoize": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
- "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
- },
"@es-joy/jsdoccomment": {
"version": "0.20.1",
"dev": true,
@@ -20792,7 +20606,8 @@
}
},
"@jridgewell/resolve-uri": {
- "version": "3.0.5"
+ "version": "3.0.5",
+ "dev": true
},
"@jridgewell/set-array": {
"version": "1.1.2",
@@ -20811,12 +20626,14 @@
}
},
"@jridgewell/sourcemap-codec": {
- "version": "1.4.11"
+ "version": "1.4.11",
+ "dev": true
},
"@jridgewell/trace-mapping": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
+ "dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
@@ -21272,7 +21089,8 @@
"dev": true
},
"@types/parse-json": {
- "version": "4.0.0"
+ "version": "4.0.0",
+ "dev": true
},
"@types/prettier": {
"version": "2.4.4",
@@ -21312,14 +21130,6 @@
"redux": "^4.0.0"
}
},
- "@types/react-transition-group": {
- "version": "4.4.5",
- "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz",
- "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==",
- "requires": {
- "@types/react": "*"
- }
- },
"@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
@@ -21973,6 +21783,7 @@
},
"ansi-styles": {
"version": "3.2.1",
+ "dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -22228,16 +22039,6 @@
"@types/babel__traverse": "^7.0.6"
}
},
- "babel-plugin-macros": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
- "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
- "requires": {
- "@babel/runtime": "^7.12.5",
- "cosmiconfig": "^7.0.0",
- "resolve": "^1.19.0"
- }
- },
"babel-plugin-polyfill-corejs2": {
"version": "0.3.1",
"dev": true,
@@ -22412,6 +22213,7 @@
},
"browserslist": {
"version": "4.19.3",
+ "dev": true,
"requires": {
"caniuse-lite": "^1.0.30001312",
"electron-to-chromium": "^1.4.71",
@@ -22485,7 +22287,8 @@
}
},
"callsites": {
- "version": "3.1.0"
+ "version": "3.1.0",
+ "dev": true
},
"camel-case": {
"version": "4.1.2",
@@ -22531,7 +22334,8 @@
"caniuse-lite": {
"version": "1.0.30001375",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
- "integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw=="
+ "integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
+ "dev": true
},
"caseless": {
"version": "0.12.0",
@@ -22546,6 +22350,7 @@
},
"chalk": {
"version": "2.4.2",
+ "dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -22553,7 +22358,8 @@
},
"dependencies": {
"escape-string-regexp": {
- "version": "1.0.5"
+ "version": "1.0.5",
+ "dev": true
}
}
},
@@ -22868,6 +22674,7 @@
},
"convert-source-map": {
"version": "1.8.0",
+ "dev": true,
"requires": {
"safe-buffer": "~5.1.1"
}
@@ -22976,6 +22783,7 @@
},
"cosmiconfig": {
"version": "7.0.1",
+ "dev": true,
"requires": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
@@ -23328,6 +23136,7 @@
},
"debug": {
"version": "4.3.3",
+ "dev": true,
"requires": {
"ms": "2.1.2"
}
@@ -23533,15 +23342,6 @@
"utila": "~0.4"
}
},
- "dom-helpers": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
- "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
- "requires": {
- "@babel/runtime": "^7.8.7",
- "csstype": "^3.0.2"
- }
- },
"dom-serializer": {
"version": "1.3.2",
"dev": true,
@@ -23615,7 +23415,8 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.4.75"
+ "version": "1.4.75",
+ "dev": true
},
"emittery": {
"version": "0.8.1",
@@ -23665,6 +23466,7 @@
},
"error-ex": {
"version": "1.3.2",
+ "dev": true,
"requires": {
"is-arrayish": "^0.2.1"
}
@@ -23716,14 +23518,16 @@
}
},
"escalade": {
- "version": "3.1.1"
+ "version": "3.1.1",
+ "dev": true
},
"escape-html": {
"version": "1.0.3",
"dev": true
},
"escape-string-regexp": {
- "version": "4.0.0"
+ "version": "4.0.0",
+ "dev": true
},
"escodegen": {
"version": "2.0.0",
@@ -24568,11 +24372,6 @@
"version": "0.3.1",
"dev": true
},
- "find-root": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
- "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
- },
"find-up": {
"version": "5.0.0",
"dev": true,
@@ -24653,14 +24452,16 @@
"dev": true
},
"function-bind": {
- "version": "1.1.1"
+ "version": "1.1.1",
+ "dev": true
},
"functional-red-black-tree": {
"version": "1.0.1",
"dev": true
},
"gensync": {
- "version": "1.0.0-beta.2"
+ "version": "1.0.0-beta.2",
+ "dev": true
},
"get-caller-file": {
"version": "2.0.5",
@@ -24772,7 +24573,8 @@
}
},
"globals": {
- "version": "11.12.0"
+ "version": "11.12.0",
+ "dev": true
},
"globby": {
"version": "11.1.0",
@@ -24837,6 +24639,7 @@
},
"has": {
"version": "1.0.3",
+ "dev": true,
"requires": {
"function-bind": "^1.1.1"
}
@@ -24846,7 +24649,8 @@
"dev": true
},
"has-flag": {
- "version": "3.0.0"
+ "version": "3.0.0",
+ "dev": true
},
"has-symbols": {
"version": "1.0.3",
@@ -25116,13 +24920,15 @@
},
"import-fresh": {
"version": "3.3.0",
+ "dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
},
"dependencies": {
"resolve-from": {
- "version": "4.0.0"
+ "version": "4.0.0",
+ "dev": true
}
}
},
@@ -25254,7 +25060,8 @@
}
},
"is-arrayish": {
- "version": "0.2.1"
+ "version": "0.2.1",
+ "dev": true
},
"is-bigint": {
"version": "1.0.4",
@@ -25295,6 +25102,7 @@
},
"is-core-module": {
"version": "2.8.1",
+ "dev": true,
"requires": {
"has": "^1.0.3"
}
@@ -26769,7 +26577,8 @@
}
},
"jsesc": {
- "version": "2.5.2"
+ "version": "2.5.2",
+ "dev": true
},
"json-buffer": {
"version": "3.0.1",
@@ -26782,7 +26591,8 @@
"dev": true
},
"json-parse-even-better-errors": {
- "version": "2.3.1"
+ "version": "2.3.1",
+ "dev": true
},
"json-schema": {
"version": "0.4.0",
@@ -26806,6 +26616,7 @@
},
"json5": {
"version": "2.2.0",
+ "dev": true,
"requires": {
"minimist": "^1.2.5"
}
@@ -26898,7 +26709,8 @@
"dev": true
},
"lines-and-columns": {
- "version": "1.2.4"
+ "version": "1.2.4",
+ "dev": true
},
"linkify-it": {
"version": "3.0.3",
@@ -27360,7 +27172,8 @@
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
- "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+ "dev": true
},
"minimist-options": {
"version": "4.1.0",
@@ -27388,7 +27201,8 @@
"dev": true
},
"ms": {
- "version": "2.1.2"
+ "version": "2.1.2",
+ "dev": true
},
"multicast-dns": {
"version": "6.2.3",
@@ -27441,7 +27255,8 @@
"dev": true
},
"node-releases": {
- "version": "2.0.2"
+ "version": "2.0.2",
+ "dev": true
},
"normalize-package-data": {
"version": "2.5.0",
@@ -27772,6 +27587,7 @@
},
"parent-module": {
"version": "1.0.1",
+ "dev": true,
"requires": {
"callsites": "^3.0.0"
}
@@ -27790,6 +27606,7 @@
},
"parse-json": {
"version": "5.2.0",
+ "dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@@ -27826,14 +27643,16 @@
"dev": true
},
"path-parse": {
- "version": "1.0.7"
+ "version": "1.0.7",
+ "dev": true
},
"path-to-regexp": {
"version": "0.1.7",
"dev": true
},
"path-type": {
- "version": "4.0.0"
+ "version": "4.0.0",
+ "dev": true
},
"pend": {
"version": "1.2.0",
@@ -27844,7 +27663,8 @@
"dev": true
},
"picocolors": {
- "version": "1.0.0"
+ "version": "1.0.0",
+ "dev": true
},
"picomatch": {
"version": "2.3.1",
@@ -28891,35 +28711,10 @@
"version": "0.11.0",
"dev": true
},
- "react-select": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.4.0.tgz",
- "integrity": "sha512-CjE9RFLUvChd5SdlfG4vqxZd55AZJRrLrHzkQyTYeHlpOztqcgnyftYAolJ0SGsBev6zAs6qFrjm6KU3eo2hzg==",
- "requires": {
- "@babel/runtime": "^7.12.0",
- "@emotion/cache": "^11.4.0",
- "@emotion/react": "^11.8.1",
- "@types/react-transition-group": "^4.4.0",
- "memoize-one": "^5.0.0",
- "prop-types": "^15.6.0",
- "react-transition-group": "^4.3.0"
- }
- },
"react-slider": {
"version": "1.3.1",
"requires": {}
},
- "react-transition-group": {
- "version": "4.4.5",
- "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
- "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
- "requires": {
- "@babel/runtime": "^7.5.5",
- "dom-helpers": "^5.0.1",
- "loose-envify": "^1.4.0",
- "prop-types": "^15.6.2"
- }
- },
"read-cache": {
"version": "1.0.0",
"dev": true,
@@ -29161,6 +28956,7 @@
},
"resolve": {
"version": "1.22.0",
+ "dev": true,
"requires": {
"is-core-module": "^2.8.1",
"path-parse": "^1.0.7",
@@ -29256,7 +29052,8 @@
}
},
"safe-buffer": {
- "version": "5.1.2"
+ "version": "5.1.2",
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -29315,7 +29112,8 @@
}
},
"semver": {
- "version": "6.3.0"
+ "version": "6.3.0",
+ "dev": true
},
"send": {
"version": "0.17.2",
@@ -29514,7 +29312,8 @@
}
},
"source-map": {
- "version": "0.5.7"
+ "version": "0.5.7",
+ "dev": true
},
"source-map-js": {
"version": "1.0.2",
@@ -29976,11 +29775,6 @@
}
}
},
- "stylis": {
- "version": "4.0.13",
- "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
- "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag=="
- },
"sugarss": {
"version": "3.0.3",
"dev": true,
@@ -29990,6 +29784,7 @@
},
"supports-color": {
"version": "5.5.0",
+ "dev": true,
"requires": {
"has-flag": "^3.0.0"
}
@@ -30016,7 +29811,8 @@
}
},
"supports-preserve-symlinks-flag": {
- "version": "1.0.0"
+ "version": "1.0.0",
+ "dev": true
},
"svg-parser": {
"version": "2.0.4",
@@ -30212,7 +30008,8 @@
"dev": true
},
"to-fast-properties": {
- "version": "2.0.0"
+ "version": "2.0.0",
+ "dev": true
},
"to-regex-range": {
"version": "5.0.1",
@@ -30991,7 +30788,8 @@
"dev": true
},
"yaml": {
- "version": "1.10.2"
+ "version": "1.10.2",
+ "dev": true
},
"yargs": {
"version": "17.3.1",
From 8dc36c81984dd67ca78732283a4d6d0ad41dd769 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Fri, 14 Oct 2022 00:08:15 +1100
Subject: [PATCH 05/63] WIP: Progress on dashboard, handle updated data format.
---
assets/css/weighting.css | 20 +-
.../components/{save.js => actions.js} | 13 +
.../components/common/delete-button.js | 19 ++
.../components/common/undo-button.js | 3 +
.../components/common/weight-control.js | 3 +
assets/js/weighting/components/post-type.js | 101 ++++++--
.../weighting/components/post-type/field.js | 123 ++++++++++
.../weighting/components/post-type/fields.js | 155 ++++++++++++
.../weighting/components/post-type/group.js | 121 ----------
.../components/post-type/property.js | 89 -------
assets/js/weighting/config.js | 6 -
assets/js/weighting/dummyData.js | 224 ------------------
assets/js/weighting/index.js | 79 +++---
assets/js/weighting/utilities.js | 0
.../classes/Feature/Documents/Documents.php | 5 +-
includes/classes/Feature/Search/Weighting.php | 70 +++---
.../Feature/SearchOrdering/SearchOrdering.php | 7 +-
.../Feature/WooCommerce/WooCommerce.php | 12 +-
includes/dashboard.php | 8 +-
19 files changed, 506 insertions(+), 552 deletions(-)
rename assets/js/weighting/components/{save.js => actions.js} (66%)
create mode 100644 assets/js/weighting/components/common/delete-button.js
create mode 100644 assets/js/weighting/components/post-type/field.js
create mode 100644 assets/js/weighting/components/post-type/fields.js
delete mode 100644 assets/js/weighting/components/post-type/group.js
delete mode 100644 assets/js/weighting/components/post-type/property.js
delete mode 100644 assets/js/weighting/config.js
delete mode 100644 assets/js/weighting/dummyData.js
delete mode 100644 assets/js/weighting/utilities.js
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
index d77d3c45e4..d93ad04a2e 100644
--- a/assets/css/weighting.css
+++ b/assets/css/weighting.css
@@ -1,12 +1,12 @@
#ep-weighting-screen {
& .components-panel {
- margin-bottom: 2rem;
+ margin-bottom: 1rem;
max-width: 800px;
}
}
-.ep-weighting-property {
+.ep-weighting-field {
align-items: center;
display: grid;
grid-gap: 1em;
@@ -28,27 +28,35 @@
margin-bottom: 0;
}
}
+
+ @media ( max-width: 600px ) {
+
+ & .components-range-control__wrapper {
+ display: none;
+ }
+ }
}
-.ep-weighting-property fieldset {
+.ep-weighting-field fieldset {
display: contents;
}
-.ep-weighting-property__name {
+.ep-weighting-field__name {
& h2 {
color: inherit;
- font-size: 15px;
+ font-size: 14px;
margin: 0;
}
}
-.ep-weighting-property__undo {
+.ep-weighting-field__undo {
grid-column-start: 5;
justify-self: end;
}
+.ep-weighting-delete,
.ep-weighting-undo {
&[disabled] {
diff --git a/assets/js/weighting/components/save.js b/assets/js/weighting/components/actions.js
similarity index 66%
rename from assets/js/weighting/components/save.js
rename to assets/js/weighting/components/actions.js
index 65cf401154..a79ceef680 100644
--- a/assets/js/weighting/components/save.js
+++ b/assets/js/weighting/components/actions.js
@@ -2,10 +2,23 @@
* WordPress dependencies.
*/
import { Button, Panel, PanelBody, PanelRow } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { undo } from '@wordpress/icons';
+/**
+ * Actions component.
+ *
+ * @param {object} props Component props.
+ * @param {boolean} props.isBusy Is the app busy?
+ * @param {boolean} props.isChanged Are there changes?
+ * @param {Function} props.onReset Reset handler.
+ * @returns {WPElement} Component element.
+ */
export default ({ isBusy, isChanged, onReset }) => {
+ /**
+ * Render.
+ */
return (
diff --git a/assets/js/weighting/components/common/delete-button.js b/assets/js/weighting/components/common/delete-button.js
new file mode 100644
index 0000000000..64856aae83
--- /dev/null
+++ b/assets/js/weighting/components/common/delete-button.js
@@ -0,0 +1,19 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
+import { close } from '@wordpress/icons';
+
+/**
+ * Undo button component.
+ *
+ * @param {object} props Component props.
+ * @returns {WPElement} Component element.
+ */
+export default (props) => {
+ /**
+ * Render.
+ */
+ return ;
+};
diff --git a/assets/js/weighting/components/common/undo-button.js b/assets/js/weighting/components/common/undo-button.js
index 04513b813b..8aebf8b307 100644
--- a/assets/js/weighting/components/common/undo-button.js
+++ b/assets/js/weighting/components/common/undo-button.js
@@ -12,5 +12,8 @@ import { undo } from '@wordpress/icons';
* @returns {WPElement} Component element.
*/
export default (props) => {
+ /**
+ * Render.
+ */
return ;
};
diff --git a/assets/js/weighting/components/common/weight-control.js b/assets/js/weighting/components/common/weight-control.js
index 3a02dd8f9b..1d63881aaf 100644
--- a/assets/js/weighting/components/common/weight-control.js
+++ b/assets/js/weighting/components/common/weight-control.js
@@ -12,5 +12,8 @@ import { __ } from '@wordpress/i18n';
* @returns {WPElement} Component element.
*/
export default (props) => {
+ /**
+ * Render.
+ */
return ;
};
diff --git a/assets/js/weighting/components/post-type.js b/assets/js/weighting/components/post-type.js
index 7d151b5ce7..87ef4a3844 100644
--- a/assets/js/weighting/components/post-type.js
+++ b/assets/js/weighting/components/post-type.js
@@ -9,7 +9,7 @@ import { isEqual } from 'lodash';
/**
* Internal dependencies.
*/
-import Group from './post-type/group';
+import Fields from './post-type/fields';
import UndoButton from './common/undo-button';
/**
@@ -24,20 +24,62 @@ import UndoButton from './common/undo-button';
* @returns {WPElement} Component element.
*/
export default ({ groups, label, onChange, originalValues, values }) => {
- const isChanged = useMemo(() => !isEqual(originalValues, values), [originalValues, values]);
+ const { fields, indexable = true, ...rest } = values;
+ const {
+ fields: originalFields,
+ indexable: originalIndexable = true,
+ ...originalRest
+ } = originalValues;
/**
- * Handle a change to the post type's setttings.
+ * The fields' values.
*
- * @param {Array} values Post type settings.
+ * `fields` and `indexable` are available on >4.4.0, while earlier versions
+ * will contain the fields data in `rest`.
+ */
+ const fieldsValues = useMemo(() => fields || rest, [fields, rest]);
+
+ /**
+ * The original fields' values.
+ *
+ * `fields` and `indexable` are available on >4.4.0, while earlier versions
+ * will contain the fields data in `rest`.
+ */
+ const originalFieldsValues = useMemo(
+ () => originalFields || originalRest,
+ [originalFields, originalRest],
+ );
+
+ /**
+ * Have any values changed?
+ */
+ const isChanged = useMemo(
+ () => !(indexable === originalIndexable && isEqual(fieldsValues, originalFieldsValues)),
+ [fieldsValues, indexable, originalIndexable, originalFieldsValues],
+ );
+
+ /**
+ * Handle change of indexable.
+ *
+ * @param {Array} indexable New indexable value.
+ * @returns {void}}
+ */
+ const onChangeIndexable = (indexable) => {
+ onChange({ fields: fieldsValues, indexable });
+ };
+
+ /**
+ * Handle a change to the post type's fields.
+ *
+ * @param {Array} fields New field values.
* @returns {void}
*/
- const onChangeGroup = (values) => {
- onChange(values);
+ const onChangeGroup = (fields) => {
+ onChange({ fields, indexable });
};
/**
- * Handle resetting settings for the post type.
+ * Handle resetting all data for the post type.
*
* @returns {void}
*/
@@ -45,17 +87,24 @@ export default ({ groups, label, onChange, originalValues, values }) => {
onChange(originalValues);
};
+ /**
+ * Render.
+ */
return (
-
-
+
+
{label}
-
-
+
+
-
- {Object.entries(groups)
- .filter(([, g]) => g.children.length !== 0)
- .map(([key, { label, children }]) => (
-
- ))}
+ {indexable
+ ? Object.entries(groups)
+ .filter(([, g]) => g.children.length !== 0)
+ .map(([key, { label, children }]) => (
+
+ ))
+ : null}
);
};
diff --git a/assets/js/weighting/components/post-type/field.js b/assets/js/weighting/components/post-type/field.js
new file mode 100644
index 0000000000..b59af5c688
--- /dev/null
+++ b/assets/js/weighting/components/post-type/field.js
@@ -0,0 +1,123 @@
+/**
+ * Wordpress Dependencies.
+ */
+import { CheckboxControl } from '@wordpress/components';
+import { useMemo, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { isEqual } from 'lodash';
+
+/**
+ * Internal dependencies.
+ */
+import DeleteButton from '../common/delete-button';
+import UndoButton from '../common/undo-button';
+import WeightControl from '../common/weight-control';
+
+/**
+ * Field settings component.
+ *
+ * @param {object} props Component props.
+ * @param {string} props.label Property label.
+ * @param {Function} props.onChange Change handler.
+ * @param {Function} props.onDelete Delete handler.
+ * @param {object} props.originalValue Original value.
+ * @param {object} props.value Values.
+ * @returns {WPElement} Component element.
+ */
+export default ({ label, onChange, onDelete, originalValue, value }) => {
+ const { enabled, indexable, searchable, weight } = value;
+ /**
+ * Is the current value different to the original.
+ */
+ const isChanged = useMemo(
+ () => !originalValue || !isEqual(originalValue, value),
+ [originalValue, value],
+ );
+
+ /**
+ * Handle change of indexable.
+ *
+ * @param {boolean} indexable New indexable value.
+ * @returns {void}
+ */
+ const onChangeIndexable = (indexable) => {
+ onChange({ weight, searchable: false, indexable });
+ };
+
+ /**
+ * Handle change of indexable.
+ *
+ * @param {boolean} searchable New searchable value.
+ * @returns {void}
+ */
+ const onChangeSearchable = (searchable) => {
+ onChange({ weight, indexable: true, searchable });
+ };
+
+ /**
+ * Handle change of weighting.
+ *
+ * @param {number} weight New weight value.
+ * @returns {void}
+ */
+ const onChangeWeight = (weight) => {
+ onChange({ indexable: true, searchable: true, weight });
+ };
+
+ /**
+ * Handle clicking undo.
+ *
+ * @returns {void}
+ */
+ const onReset = () => {
+ if (originalValue) {
+ onChange(originalValue);
+ } else if (onDelete) {
+ onDelete();
+ }
+ };
+
+ /**
+ * Render.
+ */
+ return (
+
+
+ {label}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/assets/js/weighting/components/post-type/fields.js b/assets/js/weighting/components/post-type/fields.js
new file mode 100644
index 0000000000..2d8d835336
--- /dev/null
+++ b/assets/js/weighting/components/post-type/fields.js
@@ -0,0 +1,155 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button, PanelBody, PanelRow, SelectControl } from '@wordpress/components';
+import { useMemo, useState, WPElement } from '@wordpress/element';
+
+/**
+ * Internal dependencies.
+ */
+import Field from './field';
+
+/**
+ * Post type propertes component.
+ *
+ * @param {object} props Component props.
+ * @param {object[]} props.fields Post type fields.
+ * @param {boolean} props.isEditable Whether to display as an editable list.
+ * @param {string} props.label Properties label.
+ * @param {Function} props.onChange Change handler.
+ * @param {object[]} props.originalValues Saved property values.
+ * @param {object[]} props.values Current property values.
+ * @returns {WPElement} Component element.
+ */
+export default ({ fields, isEditable, label, onChange, originalValues, values }) => {
+ const [toAdd, setToAdd] = useState('');
+
+ /**
+ * Handle changes to a property.
+ *
+ * @param {object} value New property data.
+ * @param {number} key Property key.
+ * @returns {void}
+ */
+ const onChangeProperty = (value, key) => {
+ onChange({ ...values, [key]: value });
+ };
+
+ /**
+ * Handle removing a property.
+ *
+ * @param {number} key Property key.
+ * @returns {void}
+ */
+ const onDeleteProperty = (key) => {
+ const newValues = { ...values };
+
+ delete newValues[key];
+
+ onChange(newValues);
+ };
+
+ /**
+ * Handle selecting a new property to enable.
+ *
+ * @param {string} key Key of property to enable.
+ * @returns {void}
+ */
+ const onChangeToAdd = (key) => {
+ setToAdd(key);
+ };
+
+ /**
+ * Handle clicking to add a new property.
+ *
+ * @returns {void}
+ */
+ const onClickAdd = () => {
+ const value = { indexable: true, searchable: false, weight: 1 };
+ const newValues = { ...values, [toAdd]: value };
+
+ onChange(newValues);
+ setToAdd('');
+ };
+
+ /**
+ * Weightable fields that can be added to the group, if it is editable.
+ */
+ const availableFields = useMemo(() => {
+ return isEditable
+ ? Object.values(fields).map((p) => ({
+ label: p.label,
+ value: p.key,
+ disabled: values?.[p.key]?.enable || values?.[p.key]?.indexable,
+ }))
+ : null;
+ }, [isEditable, fields, values]);
+
+ /**
+ * Fields that can be weighted.
+ *
+ * For editable groups fields are sorted to match the order of the saved
+ * configuration, to preserve the order in which the fields were added.
+ */
+ const weightableFields = useMemo(() => {
+ const weightableFields = Object.values(fields);
+
+ return isEditable
+ ? weightableFields.sort((a, b) => {
+ const { key: aKey } = a;
+ const { key: bKey } = b;
+
+ const keys = Object.keys(values);
+
+ return keys.indexOf(aKey) - keys.indexOf(bKey);
+ })
+ : weightableFields;
+ }, [isEditable, fields, values]);
+
+ /**
+ * Render.
+ */
+ return (
+
+ {weightableFields
+ .filter((p) => values[p.key])
+ .map(({ key, label }) => (
+
+ {
+ onChangeProperty(value, key);
+ }}
+ onDelete={
+ isEditable
+ ? () => {
+ onDeleteProperty(key);
+ }
+ : null
+ }
+ />
+
+ ))}
+ {availableFields ? (
+
+
+
+
+ Add
+
+
+ ) : null}
+
+ );
+};
diff --git a/assets/js/weighting/components/post-type/group.js b/assets/js/weighting/components/post-type/group.js
deleted file mode 100644
index 3f6a52eeaf..0000000000
--- a/assets/js/weighting/components/post-type/group.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Button, PanelBody, PanelRow, SelectControl } from '@wordpress/components';
-import { useMemo, useState, WPElement } from '@wordpress/element';
-
-/**
- * Internal dependencies.
- */
-import Property from './property';
-
-/**
- * Post type propertes component.
- *
- * @param {object} props Component props.
- * @param {boolean} props.isEditable Whether to display as an editable list.
- * @param {string} props.label Properties label.
- * @param {Function} props.onChange Change handler.
- * @param {object[]} props.originalValues Saved property values.
- * @param {object[]} props.properties Post type properties.
- * @param {object[]} props.values Current property values.
- * @returns {WPElement} Component element.
- */
-export default ({ isEditable, label, onChange, originalValues, properties, values }) => {
- const [toAdd, setToAdd] = useState('');
-
- /**
- * Handle changes to a property.
- *
- * @param {object} value New property data.
- * @param {number} key Property key.
- * @returns {void}
- */
- const onChangeProperty = (value, key) => {
- const newValues = { ...values, [key]: value };
-
- onChange(newValues);
- };
-
- /**
- * Handle selecting a new property to enable.
- *
- * @param {string} key Key of property to enable.
- * @returns {void}
- */
- const onChangeToAdd = (key) => {
- setToAdd(key);
- };
-
- /**
- * Handle clicking to add a new property.
- *
- * @returns {void}
- */
- const onClickAdd = () => {
- const value = { ...values[toAdd], enabled: true };
- const newValues = { ...values, [toAdd]: value };
-
- onChange(newValues);
- setToAdd('');
- };
-
- /**
- * Options for properties that can be added to the list of weightable
- * properties.
- */
- const availableProperties = useMemo(() => {
- return isEditable
- ? Object.values(properties).map((p) => ({
- label: p.label,
- value: p.key,
- disabled: values[p.key].enabled,
- }))
- : null;
- }, [isEditable, properties, values]);
-
- /**
- * Properties that can be weighted.
- *
- * If the component is set to be editable this will only be properties that
- * are indexed, otherwise it will be all properties.
- */
- const weightableProperties = useMemo(() => {
- return Object.values(properties).filter((p) => (isEditable ? values[p.key].enabled : true));
- }, [isEditable, properties, values]);
-
- return (
-
- {weightableProperties.map(({ key, label }) => (
-
- {
- onChangeProperty(value, key);
- }}
- />
-
- ))}
- {availableProperties ? (
-
-
-
-
- Add
-
-
- ) : null}
-
- );
-};
diff --git a/assets/js/weighting/components/post-type/property.js b/assets/js/weighting/components/post-type/property.js
deleted file mode 100644
index 6d2e126255..0000000000
--- a/assets/js/weighting/components/post-type/property.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Wordpress Dependencies.
- */
-import { CheckboxControl } from '@wordpress/components';
-import { useMemo, WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { isEqual } from 'lodash';
-
-/**
- * Internal dependencies.
- */
-import UndoButton from '../common/undo-button';
-import WeightControl from '../common/weight-control';
-
-/**
- * Property settings component.
- *
- * @param {object} props Component props.
- * @param {string} props.label Property label.
- * @param {Function} props.onChange Change handler.
- * @param {object} props.originalValue Original value.
- * @param {object} props.value Values.
- * @returns {WPElement} Component element.
- */
-export default ({ label, onChange, originalValue, value }) => {
- const { enabled = true, weight = 99 } = value;
-
- /**
- * Is the current value different to the original.
- */
- const isChanged = useMemo(() => !isEqual(originalValue, value), [originalValue, value]);
-
- /**
- * Handle change of indexable.
- *
- * @param {boolean} enabled New indexable value.
- * @returns {void}
- */
- const onChangeEnabled = (enabled) => {
- onChange({ ...value, enabled });
- };
-
- /**
- * Handle change of weighting.
- *
- * @param {number} weight New weight value.
- * @returns {void}
- */
- const onChangeWeight = (weight) => {
- onChange({ ...value, weight });
- };
-
- /**
- * Handle clicking undo.
- *
- * @returns {void}
- */
- const onReset = () => {
- onChange(originalValue);
- };
-
- return (
-
-
- {label}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
diff --git a/assets/js/weighting/config.js b/assets/js/weighting/config.js
deleted file mode 100644
index c8b1826783..0000000000
--- a/assets/js/weighting/config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Window dependencies.
- */
-const { weightableFields, weightingConfiguration } = window.epWeighting;
-
-export { weightableFields, weightingConfiguration };
diff --git a/assets/js/weighting/dummyData.js b/assets/js/weighting/dummyData.js
deleted file mode 100644
index 19c44464b6..0000000000
--- a/assets/js/weighting/dummyData.js
+++ /dev/null
@@ -1,224 +0,0 @@
-export const dummyData = [
- {
- label: 'Posts',
- name: 'post',
- indexable: true,
- order: 0,
-
- attributes: [
- {
- label: 'Title',
- name: 'post_title',
- indexable: true,
- searchable: true,
- weight: 40,
- },
- {
- label: 'Content',
- name: 'post_content',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Excerpt',
- name: 'post_excerpt',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Author',
- name: 'post_author',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- ],
-
- taxonomies: [
- {
- label: 'Categories',
- name: 'post_categories',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Tags',
- name: 'post_tags',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Formats',
- name: 'post_formats',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- ],
-
- meta: [
- // {
- // name: 'example_key',
- // searchable: false,
- // weight: 10,
- // },
- // {
- // name: 'another_key',
- // searchable: false,
- // weight: 10,
- // },
- // {
- // name: 'one_more_key',
- // searchable: false,
- // weight: 10,
- // },
- ],
- },
- {
- label: 'Pages',
- name: 'page',
- indexable: true,
- order: 1,
-
- attributes: [
- {
- label: 'Title',
- name: 'post_title',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Content',
- name: 'post_content',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Excerpt',
- name: 'post_excerpt',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Author',
- name: 'post_author',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- ],
-
- taxonomies: [
- {
- label: 'Categories',
- name: 'post_categories',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Tags',
- name: 'post_tags',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Formats',
- name: 'post_formats',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- ],
-
- meta: [],
- },
- {
- label: 'Product',
- name: 'product',
- indexable: true,
- order: 2,
-
- attributes: [
- {
- label: 'Title',
- name: 'post_title',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Content',
- name: 'post_content',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Excerpt',
- name: 'post_excerpt',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Author',
- name: 'post_author',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- ],
-
- taxonomies: [
- {
- label: 'Categories',
- name: 'post_categories',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Tags',
- name: 'post_tags',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- {
- label: 'Formats',
- name: 'post_formats',
- indexable: false,
- searchable: false,
- weight: 1,
- },
- ],
- meta: [],
- },
-];
-
-export const dummyMetaKeys = [
- {
- name: 'example_key',
- searchable: false,
- weight: 10,
- },
- {
- name: 'another_key',
- searchable: false,
- weight: 10,
- },
- {
- name: 'one_more_key',
- searchable: false,
- weight: 10,
- },
-];
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index 1f387798cc..eb7df0cc0f 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -8,36 +8,40 @@ import { cloneDeep, isEqual } from 'lodash';
/**
* Internal Dependencies.
*/
-import { weightableFields, weightingConfiguration } from './config';
+import Actions from './components/actions';
import PostType from './components/post-type';
-import Save from './components/save';
/**
- * component.
+ * Window dependencies.
+ */
+
+/**
+ * Weighting settings app.
*
+ * @param {object} props Component props.
+ * @param {object} props.weightableFields Weightable fields, indexed by post type.
+ * @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
* @returns {WPElement} Element.
*/
-const App = () => {
- const [data, setData] = useState(cloneDeep(weightingConfiguration));
- const [savedData, setSavedData] = useState(cloneDeep(weightingConfiguration));
+const App = ({ weightableFields, weightingConfiguration }) => {
+ const [currentData, setCurrentData] = useState({ ...weightingConfiguration });
+ const [savedData, setSavedData] = useState({ ...weightingConfiguration });
const [isBusy, setIsBusy] = useState(false);
/**
* Is the current data different to the saved data.
*/
- const isChanged = useMemo(() => !isEqual(data, savedData), [data, savedData]);
+ const isChanged = useMemo(() => !isEqual(currentData, savedData), [currentData, savedData]);
/**
* Handle data change.
*
- * @param {Array} value Updated data.
* @param {string} postType Updated post type.
+ * @param {Array} values Updated data.
* @returns {void}
*/
- const onChangePostType = (value, postType) => {
- const newData = { ...data, [postType]: value };
-
- setData(newData);
+ const onChangePostType = (postType, values) => {
+ setCurrentData({ ...currentData, [postType]: values });
};
/**
@@ -49,10 +53,14 @@ const App = () => {
const onSubmit = (event) => {
event.preventDefault();
- const savedData = cloneDeep(data);
+ const savedData = cloneDeep(currentData);
setIsBusy(true);
- setSavedData(savedData);
+
+ setTimeout(() => {
+ setSavedData(savedData);
+ setIsBusy(false);
+ }, 1000);
};
/**
@@ -60,12 +68,13 @@ const App = () => {
*
* @returns {void}
*/
- const onUndo = () => {
- const data = cloneDeep(savedData);
-
- setData(data);
+ const onReset = () => {
+ setCurrentData({ ...savedData });
};
+ /**
+ * Render.
+ */
return (
-
- {Object.entries(weightableFields).map(([key, groups]) => (
+ {Object.entries(weightableFields).map(([postType, { groups, label }]) => (
{
- onChangePostType(value, key);
+ key={postType}
+ label={label}
+ onChange={(values) => {
+ onChangePostType(postType, values);
}}
- originalValues={savedData[key]}
- values={data[key]}
+ originalValues={savedData[postType]}
+ values={currentData[postType]}
/>
))}
-
-
+
);
};
-render( , document.getElementById('ep-weighting-screen'));
+/**
+ * Initialize.
+ *
+ * @returns {void}
+ */
+const init = () => {
+ const { weightableFields, weightingConfiguration } = window.epWeighting;
+
+ render(
+ ,
+ document.getElementById('ep-weighting-screen'),
+ );
+};
+
+init();
diff --git a/assets/js/weighting/utilities.js b/assets/js/weighting/utilities.js
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/includes/classes/Feature/Documents/Documents.php b/includes/classes/Feature/Documents/Documents.php
index 78569c3345..d4e3a75d77 100644
--- a/includes/classes/Feature/Documents/Documents.php
+++ b/includes/classes/Feature/Documents/Documents.php
@@ -510,8 +510,9 @@ public function filter_weightable_fields_for_post_type( $fields, $post_type ) {
public function filter_attachment_post_type_weights( $weights, $post_type ) {
if ( 'attachment' === $post_type ) {
$weights['attachments.attachment.content'] = [
- 'enabled' => true,
- 'weight' => 0,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 0,
];
}
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index b9d86d09c0..c9cd5b42ea 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -145,7 +145,13 @@ public function get_weightable_fields() {
$post_types = Features::factory()->get_registered_feature( 'search' )->get_searchable_post_types();
foreach ( $post_types as $post_type ) {
- $weightable[ $post_type ] = $this->get_weightable_fields_for_post_type( $post_type );
+ $post_type_object = get_post_type_object( $post_type );
+ $post_type_labels = get_post_type_labels( $post_type_object );
+
+ $weightable[ $post_type ] = [
+ 'label' => $post_type_labels->menu_name,
+ 'groups' => $this->get_weightable_fields_for_post_type( $post_type ),
+ ];
}
return $weightable;
@@ -163,20 +169,24 @@ public function get_weightable_fields() {
public function get_post_type_default_settings( $post_type ) {
$post_type_defaults = [
'post_title' => [
- 'enabled' => true,
- 'weight' => 1,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 1,
],
'post_content' => [
- 'enabled' => true,
- 'weight' => 1,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 1,
],
'post_excerpt' => [
- 'enabled' => true,
- 'weight' => 1,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 1,
],
'author_name' => [
- 'enabled' => true,
- 'weight' => 1,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 1,
],
];
@@ -199,32 +209,13 @@ public function get_post_type_default_settings( $post_type ) {
foreach ( $enabled_by_default as $default_tax ) {
if ( in_array( $default_tax, $post_type_taxonomies, true ) ) {
$post_type_defaults[ 'terms.' . $default_tax . '.name' ] = [
- 'enabled' => true,
- 'weight' => 1,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 1,
];
}
}
- /**
- * TODO: Meta keys per post type?
- */
- $indexable = Indexables::factory()->get( 'post' );
-
- try {
- $meta_keys = $indexable->get_distinct_meta_field_keys();
- } catch ( \Throwable $th ) {
- $meta_keys = [];
- }
-
- foreach ( $meta_keys as $meta_key ) {
- $key = "meta.$meta_key.value";
-
- $post_type_defaults[ $key ] = [
- 'enabled' => false,
- 'weight' => 1,
- ];
- }
-
/**
* Filter weighting defaults for post type
*
@@ -253,22 +244,21 @@ public function get_weighting_configuration() {
}
/**
- * Returns the current weighting configuration with defaults for any
- * missing properties.
+ * Returns the default weighting configuration.
*
- * @return array Current weighting configuration with defaults.
+ * @return array Default weighting configuration.
* @since 4.4.0
*/
- public function get_weighting_configuration_with_defaults() {
+ public function get_default_weighting_configuration() {
$search = Features::factory()->get_registered_feature( 'search' );
$post_types = $search->get_searchable_post_types();
- $weighting = $this->get_weighting_configuration();
+ $weighting = [];
foreach ( $post_types as $post_type ) {
- $config = isset( $weighting[ $post_type ] ) ? $weighting[ $post_type ] : array();
- $default = $this->get_post_type_default_settings( $post_type );
-
- $weighting[ $post_type ] = wp_parse_args( $config, $default );
+ $weighting[ $post_type ] = [
+ 'indexable' => true,
+ 'fields' => $this->get_post_type_default_settings( $post_type ),
+ ];
}
return $weighting;
diff --git a/includes/classes/Feature/SearchOrdering/SearchOrdering.php b/includes/classes/Feature/SearchOrdering/SearchOrdering.php
index 78ed5ce75b..46078db1bf 100644
--- a/includes/classes/Feature/SearchOrdering/SearchOrdering.php
+++ b/includes/classes/Feature/SearchOrdering/SearchOrdering.php
@@ -601,9 +601,10 @@ public function filter_weighting_configuration( $weighting_configuration, $args
*/
public function filter_default_post_type_weights( $post_type_defaults, $post_type ) {
$post_type_defaults['terms.ep_custom_result.name'] = [
- 'enabled' => true,
- 'weight' => 9999,
- 'fuzziness' => false,
+ 'fuzziness' => false,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 9999,
];
return $post_type_defaults;
diff --git a/includes/classes/Feature/WooCommerce/WooCommerce.php b/includes/classes/Feature/WooCommerce/WooCommerce.php
index 02de2d950d..09e44ee584 100644
--- a/includes/classes/Feature/WooCommerce/WooCommerce.php
+++ b/includes/classes/Feature/WooCommerce/WooCommerce.php
@@ -769,13 +769,15 @@ public function add_product_default_post_type_weights( $defaults, $post_type ) {
}
$defaults['meta._sku.value'] = array(
- 'enabled' => true,
- 'weight' => 1,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 1,
);
$defaults['meta._variations_skus.value'] = array(
- 'enabled' => true,
- 'weight' => 1,
+ 'indexable' => true,
+ 'searchable' => true,
+ 'weight' => 1,
);
}
return $defaults;
@@ -820,7 +822,7 @@ public function setup() {
add_action( 'parse_query', [ $this, 'search_order' ], 11 );
add_filter( 'ep_term_suggest_post_type', [ $this, 'suggest_wc_add_post_type' ] );
add_filter( 'ep_facet_include_taxonomies', [ $this, 'add_product_attributes' ] );
- add_filter( 'ep_weighting_fields_for_post_type', [ $this, 'add_product_attributes_to_weighting' ], 10, 2 );
+ // add_filter( 'ep_weighting_fields_for_post_type', [ $this, 'add_product_attributes_to_weighting' ], 10, 2 );
add_filter( 'ep_weighting_default_post_type_weights', [ $this, 'add_product_default_post_type_weights' ], 10, 2 );
add_filter( 'ep_prepare_meta_data', [ $this, 'add_variations_skus_meta' ], 10, 2 );
add_filter( 'request', [ $this, 'admin_product_list_request_query' ], 9 );
diff --git a/includes/dashboard.php b/includes/dashboard.php
index 18f21c1bdb..e8c0feb5c1 100644
--- a/includes/dashboard.php
+++ b/includes/dashboard.php
@@ -509,12 +509,16 @@ function action_admin_enqueue_dashboard_scripts() {
$weighting = Features::factory()->get_registered_feature( 'search' )->weighting;
+ $weightable_fields = $weighting->get_weightable_fields();
+ $weighting_configuration = $weighting->get_weighting_configuration();
+ $weighting_default = $weighting->get_default_weighting_configuration();
+
wp_localize_script(
'ep_weighting_script',
'epWeighting',
array(
- 'weightableFields' => $weighting->get_weightable_fields(),
- 'weightingConfiguration' => $weighting->get_weighting_configuration_with_defaults(),
+ 'weightableFields' => $weightable_fields,
+ 'weightingConfiguration' => $weighting_configuration ? $weighting_configuration : $weighting_default,
)
);
}
From d1c4cd5362bb4f34099d691f4adfdcaac087f83f Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Thu, 20 Oct 2022 01:05:24 +1100
Subject: [PATCH 06/63] WIP: Implement manual management of meta.
---
assets/css/weighting.css | 23 +-
.../components/common/weight-control.js | 19 --
assets/js/weighting/components/post-type.js | 135 ------------
.../weighting/components/post-type/fields.js | 155 --------------
assets/js/weighting/components/weighting.js | 111 ++++++++++
.../components/{ => weighting}/actions.js | 0
.../components/weighting/post-type.js | 128 ++++++++++++
.../{ => weighting}/post-type/field.js | 44 ++--
.../components/weighting/post-type/fields.js | 197 ++++++++++++++++++
.../components/weighting/post-type/group.js | 70 +++++++
assets/js/weighting/index.js | 110 +---------
.../classes/Feature/Documents/Documents.php | 5 +-
includes/classes/Feature/Search/Weighting.php | 67 +++---
.../Feature/SearchOrdering/SearchOrdering.php | 7 +-
.../Feature/WooCommerce/WooCommerce.php | 20 +-
includes/classes/Upgrades.php | 29 +++
includes/dashboard.php | 5 +-
17 files changed, 630 insertions(+), 495 deletions(-)
delete mode 100644 assets/js/weighting/components/common/weight-control.js
delete mode 100644 assets/js/weighting/components/post-type.js
delete mode 100644 assets/js/weighting/components/post-type/fields.js
create mode 100644 assets/js/weighting/components/weighting.js
rename assets/js/weighting/components/{ => weighting}/actions.js (100%)
create mode 100644 assets/js/weighting/components/weighting/post-type.js
rename assets/js/weighting/components/{ => weighting}/post-type/field.js (66%)
create mode 100644 assets/js/weighting/components/weighting/post-type/fields.js
create mode 100644 assets/js/weighting/components/weighting/post-type/group.js
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
index d93ad04a2e..26e983ef70 100644
--- a/assets/css/weighting.css
+++ b/assets/css/weighting.css
@@ -1,16 +1,20 @@
#ep-weighting-screen {
+ max-width: 800px;
& .components-panel {
margin-bottom: 1rem;
- max-width: 800px;
+ }
+
+ & .components-toggle-control__label {
+ max-width: none;
}
}
.ep-weighting-field {
align-items: center;
display: grid;
- grid-gap: 1em;
- grid-template-columns: min(20%, 30ch) max-content max-content auto max-content;
+ grid-gap: 0.5em;
+ grid-template-columns: min(20%, 30ch) max-content auto max-content;
width: 100%;
& .components-base-control__field {
@@ -30,6 +34,7 @@
}
@media ( max-width: 600px ) {
+ grid-gap: 1em;
& .components-range-control__wrapper {
display: none;
@@ -42,16 +47,17 @@
}
.ep-weighting-field__name {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
& h2 {
- color: inherit;
- font-size: 14px;
margin: 0;
}
}
.ep-weighting-field__undo {
- grid-column-start: 5;
+ grid-column-start: 4;
justify-self: end;
}
@@ -66,8 +72,11 @@
.ep-weighting-add-meta {
justify-content: start;
+}
+
+.ep-weighting-add-meta__select {
- & .components-select-control__input.components-select-control__input.components-select-control__input {
+ & select.components-select-control__input {
min-height: 36px;
}
}
diff --git a/assets/js/weighting/components/common/weight-control.js b/assets/js/weighting/components/common/weight-control.js
deleted file mode 100644
index 1d63881aaf..0000000000
--- a/assets/js/weighting/components/common/weight-control.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { RangeControl } from '@wordpress/components';
-import { WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-
-/**
- * Weight control component.
- *
- * @param {object} props Component props.
- * @returns {WPElement} Component element.
- */
-export default (props) => {
- /**
- * Render.
- */
- return ;
-};
diff --git a/assets/js/weighting/components/post-type.js b/assets/js/weighting/components/post-type.js
deleted file mode 100644
index 87ef4a3844..0000000000
--- a/assets/js/weighting/components/post-type.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { CheckboxControl, Panel, PanelHeader } from '@wordpress/components';
-import { useMemo, WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { isEqual } from 'lodash';
-
-/**
- * Internal dependencies.
- */
-import Fields from './post-type/fields';
-import UndoButton from './common/undo-button';
-
-/**
- * Post type weighting settings component.
- *
- * @param {object} props Components props.
- * @param {object[]} props.groups Field groups.
- * @param {string} props.label Post type label.
- * @param {Function} props.onChange Data change handler.
- * @param {object} props.originalValues Saved post type settings.
- * @param {object} props.values Current post type settings.
- * @returns {WPElement} Component element.
- */
-export default ({ groups, label, onChange, originalValues, values }) => {
- const { fields, indexable = true, ...rest } = values;
- const {
- fields: originalFields,
- indexable: originalIndexable = true,
- ...originalRest
- } = originalValues;
-
- /**
- * The fields' values.
- *
- * `fields` and `indexable` are available on >4.4.0, while earlier versions
- * will contain the fields data in `rest`.
- */
- const fieldsValues = useMemo(() => fields || rest, [fields, rest]);
-
- /**
- * The original fields' values.
- *
- * `fields` and `indexable` are available on >4.4.0, while earlier versions
- * will contain the fields data in `rest`.
- */
- const originalFieldsValues = useMemo(
- () => originalFields || originalRest,
- [originalFields, originalRest],
- );
-
- /**
- * Have any values changed?
- */
- const isChanged = useMemo(
- () => !(indexable === originalIndexable && isEqual(fieldsValues, originalFieldsValues)),
- [fieldsValues, indexable, originalIndexable, originalFieldsValues],
- );
-
- /**
- * Handle change of indexable.
- *
- * @param {Array} indexable New indexable value.
- * @returns {void}}
- */
- const onChangeIndexable = (indexable) => {
- onChange({ fields: fieldsValues, indexable });
- };
-
- /**
- * Handle a change to the post type's fields.
- *
- * @param {Array} fields New field values.
- * @returns {void}
- */
- const onChangeGroup = (fields) => {
- onChange({ fields, indexable });
- };
-
- /**
- * Handle resetting all data for the post type.
- *
- * @returns {void}
- */
- const onReset = () => {
- onChange(originalValues);
- };
-
- /**
- * Render.
- */
- return (
-
-
-
-
-
{label}
-
-
-
-
-
- {isChanged ? (
-
- ) : null}
-
-
-
- {indexable
- ? Object.entries(groups)
- .filter(([, g]) => g.children.length !== 0)
- .map(([key, { label, children }]) => (
-
- ))
- : null}
-
- );
-};
diff --git a/assets/js/weighting/components/post-type/fields.js b/assets/js/weighting/components/post-type/fields.js
deleted file mode 100644
index 2d8d835336..0000000000
--- a/assets/js/weighting/components/post-type/fields.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Button, PanelBody, PanelRow, SelectControl } from '@wordpress/components';
-import { useMemo, useState, WPElement } from '@wordpress/element';
-
-/**
- * Internal dependencies.
- */
-import Field from './field';
-
-/**
- * Post type propertes component.
- *
- * @param {object} props Component props.
- * @param {object[]} props.fields Post type fields.
- * @param {boolean} props.isEditable Whether to display as an editable list.
- * @param {string} props.label Properties label.
- * @param {Function} props.onChange Change handler.
- * @param {object[]} props.originalValues Saved property values.
- * @param {object[]} props.values Current property values.
- * @returns {WPElement} Component element.
- */
-export default ({ fields, isEditable, label, onChange, originalValues, values }) => {
- const [toAdd, setToAdd] = useState('');
-
- /**
- * Handle changes to a property.
- *
- * @param {object} value New property data.
- * @param {number} key Property key.
- * @returns {void}
- */
- const onChangeProperty = (value, key) => {
- onChange({ ...values, [key]: value });
- };
-
- /**
- * Handle removing a property.
- *
- * @param {number} key Property key.
- * @returns {void}
- */
- const onDeleteProperty = (key) => {
- const newValues = { ...values };
-
- delete newValues[key];
-
- onChange(newValues);
- };
-
- /**
- * Handle selecting a new property to enable.
- *
- * @param {string} key Key of property to enable.
- * @returns {void}
- */
- const onChangeToAdd = (key) => {
- setToAdd(key);
- };
-
- /**
- * Handle clicking to add a new property.
- *
- * @returns {void}
- */
- const onClickAdd = () => {
- const value = { indexable: true, searchable: false, weight: 1 };
- const newValues = { ...values, [toAdd]: value };
-
- onChange(newValues);
- setToAdd('');
- };
-
- /**
- * Weightable fields that can be added to the group, if it is editable.
- */
- const availableFields = useMemo(() => {
- return isEditable
- ? Object.values(fields).map((p) => ({
- label: p.label,
- value: p.key,
- disabled: values?.[p.key]?.enable || values?.[p.key]?.indexable,
- }))
- : null;
- }, [isEditable, fields, values]);
-
- /**
- * Fields that can be weighted.
- *
- * For editable groups fields are sorted to match the order of the saved
- * configuration, to preserve the order in which the fields were added.
- */
- const weightableFields = useMemo(() => {
- const weightableFields = Object.values(fields);
-
- return isEditable
- ? weightableFields.sort((a, b) => {
- const { key: aKey } = a;
- const { key: bKey } = b;
-
- const keys = Object.keys(values);
-
- return keys.indexOf(aKey) - keys.indexOf(bKey);
- })
- : weightableFields;
- }, [isEditable, fields, values]);
-
- /**
- * Render.
- */
- return (
-
- {weightableFields
- .filter((p) => values[p.key])
- .map(({ key, label }) => (
-
- {
- onChangeProperty(value, key);
- }}
- onDelete={
- isEditable
- ? () => {
- onDeleteProperty(key);
- }
- : null
- }
- />
-
- ))}
- {availableFields ? (
-
-
-
-
- Add
-
-
- ) : null}
-
- );
-};
diff --git a/assets/js/weighting/components/weighting.js b/assets/js/weighting/components/weighting.js
new file mode 100644
index 0000000000..fae32fc43f
--- /dev/null
+++ b/assets/js/weighting/components/weighting.js
@@ -0,0 +1,111 @@
+/**
+ * WordPress dependencies.
+ */
+import { WPElement, useMemo, useState } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { cloneDeep, isEqual } from 'lodash';
+
+/**
+ * Internal Dependencies.
+ */
+import Actions from './weighting/actions';
+import PostType from './weighting/post-type';
+
+/**
+ * Weighting settings app.
+ *
+ * @param {object} props Component props.
+ * @param {object} props.weightableFields Weightable fields, indexed by post type.
+ * @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
+ * @returns {WPElement} Element.
+ */
+export default ({ weightableFields, weightingConfiguration }) => {
+ const [currentData, setCurrentData] = useState({ ...weightingConfiguration });
+ const [savedData, setSavedData] = useState({ ...weightingConfiguration });
+ const [isBusy, setIsBusy] = useState(false);
+
+ /**
+ * Is the current data different to the saved data.
+ */
+ const isChanged = useMemo(() => !isEqual(currentData, savedData), [currentData, savedData]);
+
+ /**
+ * Handle data change.
+ *
+ * @param {string} postType Updated post type.
+ * @param {Array} values Updated data.
+ * @returns {void}
+ */
+ const onChangePostType = (postType, values) => {
+ setCurrentData({ ...currentData, [postType]: values });
+ };
+
+ /**
+ * Handle resetting all settings.
+ *
+ * @returns {void}
+ */
+ const onReset = () => {
+ setCurrentData({ ...savedData });
+ };
+
+ /**
+ * Handle for submission.
+ *
+ * @param {Event} event Submit event.
+ * @returns {void}
+ */
+ const onSubmit = (event) => {
+ event.preventDefault();
+
+ const savedData = cloneDeep(currentData);
+
+ setIsBusy(true);
+
+ setTimeout(() => {
+ setSavedData(savedData);
+ setIsBusy(false);
+ }, 1000);
+ };
+
+ /**
+ * Render.
+ */
+ return (
+
+ );
+};
diff --git a/assets/js/weighting/components/actions.js b/assets/js/weighting/components/weighting/actions.js
similarity index 100%
rename from assets/js/weighting/components/actions.js
rename to assets/js/weighting/components/weighting/actions.js
diff --git a/assets/js/weighting/components/weighting/post-type.js b/assets/js/weighting/components/weighting/post-type.js
new file mode 100644
index 0000000000..effee68336
--- /dev/null
+++ b/assets/js/weighting/components/weighting/post-type.js
@@ -0,0 +1,128 @@
+/**
+ * WordPress dependencies.
+ */
+import { Panel, PanelHeader } from '@wordpress/components';
+import { useMemo, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { isEqual } from 'lodash';
+
+/**
+ * Internal dependencies.
+ */
+import UndoButton from '../common/undo-button';
+import Group from './post-type/group';
+
+/**
+ * Post type weighting settings component.
+ *
+ * @param {object} props Components props.
+ * @param {object[]} props.groups Field groups.
+ * @param {string} props.label Post type label.
+ * @param {Function} props.onChange Data change handler.
+ * @param {object} props.originalValues Saved post type settings.
+ * @param {object} props.values Current post type settings.
+ * @returns {WPElement} Component element.
+ */
+export default ({ groups, label, onChange, originalValues, values }) => {
+ /**
+ * Have any values changed?
+ */
+ const isChanged = useMemo(() => !isEqual(originalValues, values), [originalValues, values]);
+
+ /**
+ * The field groups to display.
+ *
+ * Filters out any groups without fields.
+ */
+ const fieldGroups = useMemo(
+ () =>
+ Object.entries(groups).reduce((previousValue, currentValue) => {
+ const [key, group] = currentValue;
+
+ if (Object.keys(group.children).length > 0) {
+ return [...previousValue, { key, ...group }];
+ }
+
+ return previousValue;
+ }, []),
+ [groups],
+ );
+
+ /**
+ * Handle a change to the post type's fields.
+ *
+ * @param {Array} fields New field values.
+ * @returns {void}
+ */
+ const onChangeFields = (fields) => {
+ onChange({ ...values, fields });
+ };
+
+ /**
+ * Handle change in meta management.
+ *
+ * When disabling manual meta management remove weighting settings for
+ * metadata.
+ *
+ * @param {Array} manageMeta New manage meta value.
+ * @returns {void}}
+ */
+ const onChangeManageMeta = (manageMeta) => {
+ if (manageMeta === false) {
+ const keys = Object.keys(groups.meta?.children || {});
+
+ for (const k of keys) {
+ delete values.fields[k];
+ }
+ }
+
+ onChange({ ...values, manage_meta: manageMeta });
+ };
+
+ /**
+ * Handle resetting all data for the post type.
+ *
+ * @returns {void}
+ */
+ const onReset = () => {
+ onChange(originalValues);
+ };
+
+ /**
+ * Render.
+ */
+ return (
+
+
+
+
+
{label}
+
+
+ {isChanged ? (
+
+ ) : null}
+
+
+
+ {fieldGroups.map(({ children, key, label }) => {
+ return (
+
+ );
+ })}
+
+ );
+};
diff --git a/assets/js/weighting/components/post-type/field.js b/assets/js/weighting/components/weighting/post-type/field.js
similarity index 66%
rename from assets/js/weighting/components/post-type/field.js
rename to assets/js/weighting/components/weighting/post-type/field.js
index b59af5c688..24bf53de18 100644
--- a/assets/js/weighting/components/post-type/field.js
+++ b/assets/js/weighting/components/weighting/post-type/field.js
@@ -1,7 +1,7 @@
/**
* Wordpress Dependencies.
*/
-import { CheckboxControl } from '@wordpress/components';
+import { CheckboxControl, RangeControl } from '@wordpress/components';
import { useMemo, WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { isEqual } from 'lodash';
@@ -9,9 +9,8 @@ import { isEqual } from 'lodash';
/**
* Internal dependencies.
*/
-import DeleteButton from '../common/delete-button';
-import UndoButton from '../common/undo-button';
-import WeightControl from '../common/weight-control';
+import DeleteButton from '../../common/delete-button';
+import UndoButton from '../../common/undo-button';
/**
* Field settings component.
@@ -25,7 +24,8 @@ import WeightControl from '../common/weight-control';
* @returns {WPElement} Component element.
*/
export default ({ label, onChange, onDelete, originalValue, value }) => {
- const { enabled, indexable, searchable, weight } = value;
+ const { enabled = false, weight = 0 } = value;
+
/**
* Is the current value different to the original.
*/
@@ -37,21 +37,11 @@ export default ({ label, onChange, onDelete, originalValue, value }) => {
/**
* Handle change of indexable.
*
- * @param {boolean} indexable New indexable value.
+ * @param {boolean} enabled New searchable value.
* @returns {void}
*/
- const onChangeIndexable = (indexable) => {
- onChange({ weight, searchable: false, indexable });
- };
-
- /**
- * Handle change of indexable.
- *
- * @param {boolean} searchable New searchable value.
- * @returns {void}
- */
- const onChangeSearchable = (searchable) => {
- onChange({ weight, indexable: true, searchable });
+ const onChangeSearchable = (enabled) => {
+ onChange({ weight, enabled });
};
/**
@@ -61,7 +51,7 @@ export default ({ label, onChange, onDelete, originalValue, value }) => {
* @returns {void}
*/
const onChangeWeight = (weight) => {
- onChange({ indexable: true, searchable: true, weight });
+ onChange({ enabled: true, weight });
};
/**
@@ -84,23 +74,19 @@ export default ({ label, onChange, onDelete, originalValue, value }) => {
{label}
-
-
-
-
diff --git a/assets/js/weighting/components/weighting/post-type/fields.js b/assets/js/weighting/components/weighting/post-type/fields.js
new file mode 100644
index 0000000000..d20a85629c
--- /dev/null
+++ b/assets/js/weighting/components/weighting/post-type/fields.js
@@ -0,0 +1,197 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button, PanelRow, SelectControl, ToggleControl } from '@wordpress/components';
+import { useMemo, useState, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies.
+ */
+import Field from './field';
+
+/**
+ * Post type propertes component.
+ *
+ * @param {object} props Component props.
+ * @param {object[]} props.fields Post type fields.
+ * @param {boolean} props.isEditable Whether to display as an editable list.
+ * @param {Function} props.onChange Change handler.
+ * @param {object[]} props.originalValues Saved property values.
+ * @param {object[]} props.values Current property values.
+ * @returns {WPElement} Component element.
+ */
+export default ({ fields, isEditable, onChange, originalValues, values }) => {
+ const [toAdd, setToAdd] = useState('');
+ const [showFeatureFields, setShowFeatureFields] = useState(false);
+
+ /**
+ * Weightable fields that can be added to the group, if it is editable.
+ *
+ * Fields that are automatically indexed by features are excluded, while
+ * fields that have already been added are disabled.
+ */
+ const availableFields = useMemo(() => {
+ return fields
+ .filter((f) => !f.used_by_feature)
+ .map((f) => ({
+ label: f.label,
+ value: f.key,
+ disabled: Object.prototype.hasOwnProperty.call(values, f.key),
+ }));
+ }, [fields, values]);
+
+ /**
+ * Fields that are automatically indexed by features.
+ */
+ const featureFields = useMemo(() => {
+ return fields.filter((f) => f.used_by_feature);
+ }, [fields]);
+
+ /**
+ * Fields that can be weighted.
+ *
+ * For editable groups fields are sorted to match the order of the saved
+ * configuration, to preserve the order in which the fields were added.
+ */
+ const weightedFields = useMemo(() => {
+ return fields
+ .filter((f) => !f.used_by_feature)
+ .filter((f) => Object.prototype.hasOwnProperty.call(values, f.key))
+ .sort((a, b) => {
+ const { key: aKey } = a;
+ const { key: bKey } = b;
+
+ const keys = Object.keys(values);
+
+ return keys.indexOf(aKey) - keys.indexOf(bKey);
+ });
+ }, [fields, values]);
+
+ /**
+ * Handle changes to a property.
+ *
+ * @param {object} value New property data.
+ * @param {number} key Property key.
+ * @returns {void}
+ */
+ const onChangeProperty = (value, key) => {
+ onChange({ ...values, [key]: value });
+ };
+
+ /**
+ * Handle selecting a new property to enable.
+ *
+ * @param {string} key Key of property to enable.
+ * @returns {void}
+ */
+ const onChangeToAdd = (key) => {
+ setToAdd(key);
+ };
+
+ /**
+ * Handle a change to whether fields automatically indexed by features are
+ * shown.
+ *
+ * @param {boolean} showFeatureFields Whether to show fields indexed by features.
+ * @returns {void}
+ */
+ const onChangeShowFeatureFields = (showFeatureFields) => {
+ setShowFeatureFields(showFeatureFields);
+ };
+
+ /**
+ * Handle clicking to add a new property.
+ *
+ * @returns {void}
+ */
+ const onClickAdd = () => {
+ const newValues = { ...values, [toAdd]: { enabled: false, weight: 0 } };
+
+ onChange(newValues);
+ setToAdd('');
+ };
+
+ /**
+ * Handle removing a field.
+ *
+ * @param {number} key field key.
+ * @returns {void}
+ */
+ const onDeleteField = (key) => {
+ const newValues = { ...values };
+
+ delete newValues[key];
+
+ onChange(newValues);
+ };
+
+ /**
+ * Render.
+ */
+ return (
+ <>
+ {featureFields.length > 0 ? (
+
+
+
+ ) : null}
+ {featureFields
+ .filter((f) => showFeatureFields || values?.[f.key]?.enabled === true)
+ .map(({ key, label }) => (
+
+ {
+ onChangeProperty(value, key);
+ }}
+ />
+
+ ))}
+ {(isEditable ? weightedFields : fields).map(({ key, label }) => (
+
+ {
+ onChangeProperty(value, key);
+ }}
+ onDelete={
+ isEditable
+ ? () => {
+ onDeleteField(key);
+ }
+ : null
+ }
+ />
+
+ ))}
+ {isEditable && availableFields ? (
+
+
+
+
+ {__('Add field', 'elasticpress')}
+
+
+ ) : null}
+ >
+ );
+};
diff --git a/assets/js/weighting/components/weighting/post-type/group.js b/assets/js/weighting/components/weighting/post-type/group.js
new file mode 100644
index 0000000000..1f2aa0e7b1
--- /dev/null
+++ b/assets/js/weighting/components/weighting/post-type/group.js
@@ -0,0 +1,70 @@
+/**
+ * WordPress dependencies.
+ */
+import { CheckboxControl, PanelBody, PanelRow } from '@wordpress/components';
+import { useMemo, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies.
+ */
+import Fields from './fields';
+
+/**
+ * Field group component.
+ *
+ * @param {object} props Component props.
+ * @param {object} props.fields Group fields.
+ * @param {string} props.label Group label.
+ * @param {boolean} props.manual Whether the fields are being managed manually.
+ * @param {Function} props.onChange Field change handler.
+ * @param {Function} props.onChangeManual Manual managment change handler.
+ * @param {object} props.originalValues Saved weighting values.
+ * @param {object} props.values Current weighting values.
+ * @returns {WPElement} Component element.
+ */
+export default ({ fields, label, manual, onChange, onChangeManual, originalValues, values }) => {
+ /**
+ * Whether to show the fields.
+ *
+ * Always show the fields unless the group has the option for manual
+ * management, in which case only show fields if manual management is
+ * enabled.
+ */
+ const showFields = useMemo(() => (onChangeManual ? manual : true), [manual, onChangeManual]);
+
+ /**
+ * Weightable fields.
+ */
+ const weightableFields = useMemo(() => Object.values(fields), [fields]);
+
+ /**
+ * Render.
+ */
+ return (
+
+ {onChangeManual ? (
+
+
+
+ ) : null}
+ {showFields ? (
+
+ ) : null}
+
+ );
+};
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index eb7df0cc0f..2a4fd68d63 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -1,113 +1,12 @@
/**
* WordPress dependencies.
*/
-import { render, WPElement, useMemo, useState } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { cloneDeep, isEqual } from 'lodash';
+import { render } from '@wordpress/element';
/**
* Internal Dependencies.
*/
-import Actions from './components/actions';
-import PostType from './components/post-type';
-
-/**
- * Window dependencies.
- */
-
-/**
- * Weighting settings app.
- *
- * @param {object} props Component props.
- * @param {object} props.weightableFields Weightable fields, indexed by post type.
- * @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
- * @returns {WPElement} Element.
- */
-const App = ({ weightableFields, weightingConfiguration }) => {
- const [currentData, setCurrentData] = useState({ ...weightingConfiguration });
- const [savedData, setSavedData] = useState({ ...weightingConfiguration });
- const [isBusy, setIsBusy] = useState(false);
-
- /**
- * Is the current data different to the saved data.
- */
- const isChanged = useMemo(() => !isEqual(currentData, savedData), [currentData, savedData]);
-
- /**
- * Handle data change.
- *
- * @param {string} postType Updated post type.
- * @param {Array} values Updated data.
- * @returns {void}
- */
- const onChangePostType = (postType, values) => {
- setCurrentData({ ...currentData, [postType]: values });
- };
-
- /**
- * Handle for submission.
- *
- * @param {Event} event Submit event.
- * @returns {void}
- */
- const onSubmit = (event) => {
- event.preventDefault();
-
- const savedData = cloneDeep(currentData);
-
- setIsBusy(true);
-
- setTimeout(() => {
- setSavedData(savedData);
- setIsBusy(false);
- }, 1000);
- };
-
- /**
- * Handle resetting all settings.
- *
- * @returns {void}
- */
- const onReset = () => {
- setCurrentData({ ...savedData });
- };
-
- /**
- * Render.
- */
- return (
-
- );
-};
+import Weighting from './components/weighting';
/**
* Initialize.
@@ -118,7 +17,10 @@ const init = () => {
const { weightableFields, weightingConfiguration } = window.epWeighting;
render(
-
,
+
,
document.getElementById('ep-weighting-screen'),
);
};
diff --git a/includes/classes/Feature/Documents/Documents.php b/includes/classes/Feature/Documents/Documents.php
index d4e3a75d77..78569c3345 100644
--- a/includes/classes/Feature/Documents/Documents.php
+++ b/includes/classes/Feature/Documents/Documents.php
@@ -510,9 +510,8 @@ public function filter_weightable_fields_for_post_type( $fields, $post_type ) {
public function filter_attachment_post_type_weights( $weights, $post_type ) {
if ( 'attachment' === $post_type ) {
$weights['attachments.attachment.content'] = [
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 0,
+ 'enabled' => true,
+ 'weight' => 0,
];
}
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index c9cd5b42ea..e564553413 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -100,9 +100,6 @@ public function get_weightable_fields_for_post_type( $post_type ) {
}
}
- /**
- * TODO: Meta keys per post type?
- */
$fields['meta'] = [
'label' => 'Metadata',
'children' => [],
@@ -114,12 +111,22 @@ public function get_weightable_fields_for_post_type( $post_type ) {
$meta_keys = [];
}
+ $allowed_protected_keys = apply_filters( 'ep_prepare_meta_allowed_protected_keys', [], $post );
+ $excluded_public_keys = apply_filters( 'ep_prepare_meta_excluded_public_keys', [], $post );
+
foreach ( $meta_keys as $meta_key ) {
$key = "meta.$meta_key.value";
- $fields['meta']['children'][$key] = [
- 'key' => $key,
- 'label' => $meta_key,
+ if ( in_array( $key, $excluded_public_keys, true ) ) {
+ continue;
+ }
+
+ $used_by_feature = in_array( $meta_key, $allowed_protected_keys, true );
+
+ $fields['meta']['children'][ $key ] = [
+ 'key' => $key,
+ 'label' => $meta_key,
+ 'used_by_feature' => $used_by_feature,
];
}
@@ -169,24 +176,20 @@ public function get_weightable_fields() {
public function get_post_type_default_settings( $post_type ) {
$post_type_defaults = [
'post_title' => [
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 1,
+ 'enabled' => true,
+ 'weight' => 1,
],
'post_content' => [
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 1,
+ 'enabled' => true,
+ 'weight' => 1,
],
'post_excerpt' => [
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 1,
+ 'enabled' => true,
+ 'weight' => 1,
],
'author_name' => [
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 1,
+ 'enabled' => true,
+ 'weight' => 1,
],
];
@@ -209,9 +212,8 @@ public function get_post_type_default_settings( $post_type ) {
foreach ( $enabled_by_default as $default_tax ) {
if ( in_array( $default_tax, $post_type_taxonomies, true ) ) {
$post_type_defaults[ 'terms.' . $default_tax . '.name' ] = [
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 1,
+ 'enabled' => true,
+ 'weight' => 1,
];
}
}
@@ -244,21 +246,28 @@ public function get_weighting_configuration() {
}
/**
- * Returns the default weighting configuration.
+ * Returns the current weighting configuration with defaults for any
+ * missing fields.
*
- * @return array Default weighting configuration.
+ * @return array Current weighting configuration with defaults.
* @since 4.4.0
*/
- public function get_default_weighting_configuration() {
+ public function get_weighting_configuration_with_defaults() {
$search = Features::factory()->get_registered_feature( 'search' );
$post_types = $search->get_searchable_post_types();
- $weighting = [];
+ $weighting = $this->get_weighting_configuration();
foreach ( $post_types as $post_type ) {
- $weighting[ $post_type ] = [
- 'indexable' => true,
- 'fields' => $this->get_post_type_default_settings( $post_type ),
- ];
+ $defaults = $this->get_post_type_default_settings( $post_type );
+
+ if ( isset( $weighting[ $post_type ] ) ) {
+ $weighting[ $post_type ]['fields'] = wp_parse_args( $weighting[ $post_type ]['fields'], $defaults );
+ } else {
+ $weighting[ $post_type ] = [
+ 'fields' => $defaults,
+ 'manage_meta' => false,
+ ];
+ }
}
return $weighting;
diff --git a/includes/classes/Feature/SearchOrdering/SearchOrdering.php b/includes/classes/Feature/SearchOrdering/SearchOrdering.php
index 46078db1bf..9293c21436 100644
--- a/includes/classes/Feature/SearchOrdering/SearchOrdering.php
+++ b/includes/classes/Feature/SearchOrdering/SearchOrdering.php
@@ -601,10 +601,9 @@ public function filter_weighting_configuration( $weighting_configuration, $args
*/
public function filter_default_post_type_weights( $post_type_defaults, $post_type ) {
$post_type_defaults['terms.ep_custom_result.name'] = [
- 'fuzziness' => false,
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 9999,
+ 'enabled' => true,
+ 'fuzziness' => false,
+ 'weight' => 9999,
];
return $post_type_defaults;
diff --git a/includes/classes/Feature/WooCommerce/WooCommerce.php b/includes/classes/Feature/WooCommerce/WooCommerce.php
index 09e44ee584..24476ba05f 100644
--- a/includes/classes/Feature/WooCommerce/WooCommerce.php
+++ b/includes/classes/Feature/WooCommerce/WooCommerce.php
@@ -736,6 +736,14 @@ public function add_product_attributes_to_weighting( $fields, $post_type ) {
unset( $fields['attributes']['children']['author_name'] );
}
+ if ( ! empty( $fields['meta']['children']['meta._sku.value'] ) ) {
+ unset( $fields['meta']['children']['meta._sku.value'] );
+ }
+
+ if ( ! empty( $fields['meta']['children']['meta._variations_skus.value'] ) ) {
+ unset( $fields['meta']['children']['meta._variations_skus.value'] );
+ }
+
$sku_key = 'meta._sku.value';
$fields['attributes']['children'][ $sku_key ] = array(
@@ -769,15 +777,13 @@ public function add_product_default_post_type_weights( $defaults, $post_type ) {
}
$defaults['meta._sku.value'] = array(
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 1,
+ 'enabled' => true,
+ 'weight' => 1,
);
$defaults['meta._variations_skus.value'] = array(
- 'indexable' => true,
- 'searchable' => true,
- 'weight' => 1,
+ 'enabled' => true,
+ 'weight' => 1,
);
}
return $defaults;
@@ -822,7 +828,7 @@ public function setup() {
add_action( 'parse_query', [ $this, 'search_order' ], 11 );
add_filter( 'ep_term_suggest_post_type', [ $this, 'suggest_wc_add_post_type' ] );
add_filter( 'ep_facet_include_taxonomies', [ $this, 'add_product_attributes' ] );
- // add_filter( 'ep_weighting_fields_for_post_type', [ $this, 'add_product_attributes_to_weighting' ], 10, 2 );
+ add_filter( 'ep_weighting_fields_for_post_type', [ $this, 'add_product_attributes_to_weighting' ], 10, 2 );
add_filter( 'ep_weighting_default_post_type_weights', [ $this, 'add_product_default_post_type_weights' ], 10, 2 );
add_filter( 'ep_prepare_meta_data', [ $this, 'add_variations_skus_meta' ], 10, 2 );
add_filter( 'request', [ $this, 'admin_product_list_request_query' ], 9 );
diff --git a/includes/classes/Upgrades.php b/includes/classes/Upgrades.php
index 51cbaebc15..37c13180ca 100644
--- a/includes/classes/Upgrades.php
+++ b/includes/classes/Upgrades.php
@@ -48,6 +48,7 @@ public function setup() {
'3.5.3' => [ 'upgrade_3_5_3', 'init' ],
'3.6.6' => [ 'upgrade_3_6_6', 'init' ],
'4.2.2' => [ 'upgrade_4_2_2', 'init' ],
+ '4.4.0' => [ 'upgrade_4_4_0', 'init' ],
];
array_walk( $routines, [ $this, 'run_upgrade_routine' ] );
@@ -185,6 +186,34 @@ public function upgrade_4_2_2() {
}
}
+ /**
+ * Upgrade routine of v4.4.0.
+ *
+ * Migrates weighting settings into a `fields` property of the weighting
+ * configuration and adds the `manage_meta` setting.
+ *
+ * @since 4.4.0
+ * @return void
+ */
+ public function upgrade_4_4_0() {
+ $weighting_configuration = get_option( 'elasticpress_weighting', [] );
+
+ if ( empty( $weighting_configuration ) ) {
+ return;
+ }
+
+ foreach ( $weighting_configuration as $post_type => $config ) {
+ if ( ! isset( $config['fields'] ) ) {
+ $weighting_configuration[ $post_type ] = [
+ 'fields' => $config,
+ 'manage_meta' => false,
+ ];
+ }
+ }
+
+ update_option( 'elasticpress_weighting', $weighting_configuration );
+ }
+
/**
* Adjust the upgrade sync notice to warn users about Instant Results.
*
diff --git a/includes/dashboard.php b/includes/dashboard.php
index e8c0feb5c1..279cf3fa1e 100644
--- a/includes/dashboard.php
+++ b/includes/dashboard.php
@@ -510,15 +510,14 @@ function action_admin_enqueue_dashboard_scripts() {
$weighting = Features::factory()->get_registered_feature( 'search' )->weighting;
$weightable_fields = $weighting->get_weightable_fields();
- $weighting_configuration = $weighting->get_weighting_configuration();
- $weighting_default = $weighting->get_default_weighting_configuration();
+ $weighting_configuration = $weighting->get_weighting_configuration_with_defaults();
wp_localize_script(
'ep_weighting_script',
'epWeighting',
array(
'weightableFields' => $weightable_fields,
- 'weightingConfiguration' => $weighting_configuration ? $weighting_configuration : $weighting_default,
+ 'weightingConfiguration' => $weighting_configuration,
)
);
}
From 0e48d7b78f6c800f5d9b803d2774372898a06654 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Thu, 20 Oct 2022 01:18:17 +1100
Subject: [PATCH 07/63] Revert unnecessary changes.
---
includes/classes/Feature/Search/Weighting.php | 19 ++++++-------------
.../Feature/SearchOrdering/SearchOrdering.php | 2 +-
package.json | 1 -
3 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index e564553413..99fd91f8fe 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -105,15 +105,15 @@ public function get_weightable_fields_for_post_type( $post_type ) {
'children' => [],
];
+ $allowed_protected_keys = apply_filters( 'ep_prepare_meta_allowed_protected_keys', [], $post );
+ $excluded_public_keys = apply_filters( 'ep_prepare_meta_excluded_public_keys', [], $post );
+
try {
$meta_keys = Indexables::factory()->get( 'post' )->get_distinct_meta_field_keys();
} catch ( \Throwable $th ) {
$meta_keys = [];
}
- $allowed_protected_keys = apply_filters( 'ep_prepare_meta_allowed_protected_keys', [], $post );
- $excluded_public_keys = apply_filters( 'ep_prepare_meta_excluded_public_keys', [], $post );
-
foreach ( $meta_keys as $meta_key ) {
$key = "meta.$meta_key.value";
@@ -340,17 +340,12 @@ public function render_settings_section( $post_type, $field, $current_values ) {
$weight = 0;
}
?>
-
+
-
- id="" name="weighting[][][enabled]">
- ">
-
-
- id="" name="weighting[][][enabled]">
- ">
+ id="" name="weighting[][][enabled]">
+ ">
@@ -362,8 +357,6 @@ public function render_settings_section( $post_type, $field, $current_values ) {
" name="weighting[][][weight]" >
-
-
true,
- 'fuzziness' => false,
'weight' => 9999,
+ 'fuzziness' => false,
];
return $post_type_defaults;
diff --git a/package.json b/package.json
index 600f7fa068..01f4e2e849 100644
--- a/package.json
+++ b/package.json
@@ -87,7 +87,6 @@
"@wordpress/icons": "^6.1.1",
"chart.js": "^2.9.4",
"focus-trap-react": "^8.8.2",
- "prop-types": "^15.8.1",
"react-beautiful-dnd": "^11.0.5",
"react-slider": "^1.3.1",
"uuid": "^8.3.2"
From 13672ac940d4cc0baa65bd1de6115be585338b2a Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Thu, 20 Oct 2022 02:09:09 +1100
Subject: [PATCH 08/63] Support saving settings.
---
assets/js/weighting/components/weighting.js | 26 ++-
assets/js/weighting/index.js | 3 +-
includes/classes/Feature/Search/Weighting.php | 164 ++++--------------
includes/dashboard.php | 2 +
4 files changed, 57 insertions(+), 138 deletions(-)
diff --git a/assets/js/weighting/components/weighting.js b/assets/js/weighting/components/weighting.js
index fae32fc43f..032dcccb3b 100644
--- a/assets/js/weighting/components/weighting.js
+++ b/assets/js/weighting/components/weighting.js
@@ -1,6 +1,7 @@
/**
* WordPress dependencies.
*/
+import apiFetch from '@wordpress/api-fetch';
import { WPElement, useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { cloneDeep, isEqual } from 'lodash';
@@ -15,11 +16,12 @@ import PostType from './weighting/post-type';
* Weighting settings app.
*
* @param {object} props Component props.
+ * @param {string} props.apiUrl API URL.
* @param {object} props.weightableFields Weightable fields, indexed by post type.
* @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
* @returns {WPElement} Element.
*/
-export default ({ weightableFields, weightingConfiguration }) => {
+export default ({ apiUrl, weightableFields, weightingConfiguration }) => {
const [currentData, setCurrentData] = useState({ ...weightingConfiguration });
const [savedData, setSavedData] = useState({ ...weightingConfiguration });
const [isBusy, setIsBusy] = useState(false);
@@ -55,17 +57,27 @@ export default ({ weightableFields, weightingConfiguration }) => {
* @param {Event} event Submit event.
* @returns {void}
*/
- const onSubmit = (event) => {
+ const onSubmit = async (event) => {
event.preventDefault();
- const savedData = cloneDeep(currentData);
+ try {
+ setIsBusy(true);
- setIsBusy(true);
+ const response = await apiFetch({
+ body: JSON.stringify(currentData),
+ method: 'POST',
+ url: apiUrl,
+ });
- setTimeout(() => {
- setSavedData(savedData);
+ const newCurrentdData = cloneDeep(response.data);
+ const newSavedData = cloneDeep(response.data);
+
+ setCurrentData(newCurrentdData);
+ setSavedData(newSavedData);
+ setIsBusy(false);
+ } catch {
setIsBusy(false);
- }, 1000);
+ }
};
/**
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index 2a4fd68d63..2e8b9fec4b 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -14,10 +14,11 @@ import Weighting from './components/weighting';
* @returns {void}
*/
const init = () => {
- const { weightableFields, weightingConfiguration } = window.epWeighting;
+ const { apiUrl, weightableFields, weightingConfiguration } = window.epWeighting;
render(
,
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 99fd91f8fe..520d816a12 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -37,6 +37,7 @@ public function setup() {
add_action( 'admin_menu', [ $this, 'add_weighting_submenu_page' ], 15 );
add_action( 'admin_post_ep-weighting', [ $this, 'handle_save' ] );
+ add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
add_filter( 'ep_formatted_args', [ $this, 'do_weighting' ], 20, 2 ); // After date decay, etc are injected
add_filter( 'ep_query_weighting_fields', [ $this, 'adjust_weight_for_cross_fields' ], 10, 5 );
}
@@ -299,99 +300,45 @@ public function render_settings_page() {
}
/**
- * Recursively renders each settings section and its children
+ * Register REST routes.
*
- * @param string $post_type Current post type we're rendering
- * @param array $field Current field to render
- * @param array $current_values Current stored weighting values
+ * @return void
+ * @since 4.4.0
*/
- public function render_settings_section( $post_type, $field, $current_values ) {
- if ( isset( $field['children'] ) && ! empty( $field['children'] ) ) :
- ?>
-
-
-
- render_settings_section( $post_type, $child, $current_values );
- }
- ?>
-
-
- get_post_type_default_settings( $post_type );
-
- $weight = isset( $post_type_settings[ $key ] ) && isset( $post_type_settings[ $key ]['weight'] ) ? (int) $post_type_settings[ $key ]['weight'] : 0;
-
- $range_disabled = '';
-
- $enabled = (
- isset( $post_type_settings ) &&
- isset( $post_type_settings[ $key ] ) &&
- isset( $post_type_settings[ $key ]['enabled'] )
- )
- ? boolval( $post_type_settings[ $key ]['enabled'] ) : false;
-
- if ( ! $enabled ) {
- $range_disabled = 'disabled="disabled" ';
- $weight = 0;
- }
- ?>
-
-
-
-
- id="" name="weighting[][][enabled]">
- ">
-
-
-
- ">
-
-
-
-
-
- " name="weighting[][][weight]" >
-
-
- [ $this, 'handle_save' ],
+ 'methods' => 'POST',
+ 'permission_callback' => function() {
+ return current_user_can( 'manage_options' );
+ },
+ ]
+ );
}
/**
- * Handles processing the new weighting values and saving them to the elasticpress.io service
+ * Handles processing the new weighting values and saving them to the
+ * elasticpress.io service.
+ *
+ * @param \WP_Rest_Request $request REST API request.
+ * @return void
*/
- public function handle_save() {
- if ( ! isset( $_POST['ep-weighting-nonce'] ) || ! wp_verify_nonce( $_POST['ep-weighting-nonce'], 'save-weighting' ) ) {
- return;
- }
+ public function handle_save( $request ) {
+ $json = $request->get_body();
- if ( ! current_user_can( 'manage_options' ) ) {
- return;
+ try {
+ $settings = json_decode( $json, true );
+ $settings = $this->save_weighting_configuration( $settings );
+
+ wp_send_json_success( $settings );
+ exit;
+ } catch ( \Exception $e ) {
+ wp_send_json_error( $e->getMessage() );
+ exit;
}
-
- $this->save_weighting_configuration( $_POST );
-
- $redirect_url = admin_url( 'admin.php?page=elasticpress-weighting' );
- $redirect_url = add_query_arg( 'settings-updated', true, $redirect_url );
-
- $this->redirect( $redirect_url );
- }
-
- /**
- * We need this method to test handle_save properly.
- *
- * @param string $redirect_url Redirect URL.
- */
- protected function redirect( $redirect_url ) {
- // @codeCoverageIgnoreStart
- wp_safe_redirect( $redirect_url );
- exit();
- // @codeCoverageIgnoreEnd
}
/**
@@ -403,50 +350,7 @@ protected function redirect( $redirect_url ) {
* @since 3.4.1
*/
public function save_weighting_configuration( $settings ) {
- $new_config = array();
- $previous_config_formatted = array();
- $current_config = $this->get_weighting_configuration();
-
- foreach ( $current_config as $post_type => $post_type_weighting ) {
- // This also ensures the string is safe, since this would return false otherwise
- if ( ! post_type_exists( $post_type ) ) {
- continue;
- }
-
- // We need a way to know if fields have been explicitly set before, let's compare a previous state against $_POST['weighting']
- foreach ( $post_type_weighting as $weighting_field => $weighting_values ) {
- $previous_config_formatted[ $post_type ][ sanitize_text_field( $weighting_field ) ] = [
- 'weight' => isset( $settings['weighting'][ $post_type ][ $weighting_field ]['weight'] ) ? intval( $settings['weighting'][ $post_type ][ $weighting_field ]['weight'] ) : 0,
- 'enabled' => isset( $settings['weighting'][ $post_type ][ $weighting_field ]['enabled'] ) && 'on' === $settings['weighting'][ $post_type ][ $weighting_field ]['enabled'] ? true : false,
- ];
- }
- }
-
- $search = Features::factory()->get_registered_feature( 'search' );
- $post_types = $search->get_searchable_post_types();
-
- foreach ( $post_types as $post_type ) {
- // This also ensures the string is safe, since this would return false otherwise
- if ( ! post_type_exists( $post_type ) ) {
- continue;
- }
-
- /** override default post_type settings while saving */
- $new_config[ $post_type ] = array();
-
- if ( isset( $settings['weighting'][ $post_type ] ) ) {
- foreach ( $settings['weighting'][ $post_type ] as $weighting_field => $weighting_values ) {
- $new_config[ $post_type ][ sanitize_text_field( $weighting_field ) ] = [
- 'weight' => isset( $weighting_values['weight'] ) ? intval( $weighting_values['weight'] ) : 0,
- 'enabled' => isset( $weighting_values['enabled'] ) && 'on' === $weighting_values['enabled'] ? true : false,
- ];
- }
- }
- }
-
- $final_config = array_replace_recursive( $previous_config_formatted, $new_config );
-
- update_option( 'elasticpress_weighting', $final_config );
+ update_option( 'elasticpress_weighting', $settings );
/**
* Fires right after the weighting configuration is saved.
@@ -456,7 +360,7 @@ public function save_weighting_configuration( $settings ) {
*/
do_action( 'ep_saved_weighting_configuration' );
- return $final_config;
+ return $settings;
}
/**
diff --git a/includes/dashboard.php b/includes/dashboard.php
index 279cf3fa1e..b7d15449bf 100644
--- a/includes/dashboard.php
+++ b/includes/dashboard.php
@@ -509,6 +509,7 @@ function action_admin_enqueue_dashboard_scripts() {
$weighting = Features::factory()->get_registered_feature( 'search' )->weighting;
+ $api_url = esc_url_raw( rest_url( 'elasticpress/v1/weighting' ) );
$weightable_fields = $weighting->get_weightable_fields();
$weighting_configuration = $weighting->get_weighting_configuration_with_defaults();
@@ -516,6 +517,7 @@ function action_admin_enqueue_dashboard_scripts() {
'ep_weighting_script',
'epWeighting',
array(
+ 'apiUrl' => $api_url,
'weightableFields' => $weightable_fields,
'weightingConfiguration' => $weighting_configuration,
)
From 74813a681fbc23fb6392c1f75631b17039209623 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Thu, 20 Oct 2022 02:12:03 +1100
Subject: [PATCH 09/63] Rename manage meta setting.
---
assets/js/weighting/components/weighting/post-type.js | 10 +++++-----
includes/classes/Feature/Search/Weighting.php | 4 ++--
includes/classes/Upgrades.php | 6 +++---
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/assets/js/weighting/components/weighting/post-type.js b/assets/js/weighting/components/weighting/post-type.js
index effee68336..5819249f5f 100644
--- a/assets/js/weighting/components/weighting/post-type.js
+++ b/assets/js/weighting/components/weighting/post-type.js
@@ -64,11 +64,11 @@ export default ({ groups, label, onChange, originalValues, values }) => {
* When disabling manual meta management remove weighting settings for
* metadata.
*
- * @param {Array} manageMeta New manage meta value.
+ * @param {Array} managingMeta New manage meta value.
* @returns {void}}
*/
- const onChangeManageMeta = (manageMeta) => {
- if (manageMeta === false) {
+ const onChangeManageMeta = (managingMeta) => {
+ if (managingMeta === false) {
const keys = Object.keys(groups.meta?.children || {});
for (const k of keys) {
@@ -76,7 +76,7 @@ export default ({ groups, label, onChange, originalValues, values }) => {
}
}
- onChange({ ...values, manage_meta: manageMeta });
+ onChange({ ...values, managing_meta: managingMeta });
};
/**
@@ -115,7 +115,7 @@ export default ({ groups, label, onChange, originalValues, values }) => {
fields={Object.values(children)}
key={key}
label={label}
- manual={key === 'meta' ? values.manage_meta : null}
+ manual={key === 'meta' ? values.managing_meta : null}
onChange={onChangeFields}
onChangeManual={key === 'meta' ? onChangeManageMeta : null}
originalValues={originalValues.fields}
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 520d816a12..972f60ca75 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -265,8 +265,8 @@ public function get_weighting_configuration_with_defaults() {
$weighting[ $post_type ]['fields'] = wp_parse_args( $weighting[ $post_type ]['fields'], $defaults );
} else {
$weighting[ $post_type ] = [
- 'fields' => $defaults,
- 'manage_meta' => false,
+ 'fields' => $defaults,
+ 'managing_meta' => false,
];
}
}
diff --git a/includes/classes/Upgrades.php b/includes/classes/Upgrades.php
index 37c13180ca..3519caeba2 100644
--- a/includes/classes/Upgrades.php
+++ b/includes/classes/Upgrades.php
@@ -190,7 +190,7 @@ public function upgrade_4_2_2() {
* Upgrade routine of v4.4.0.
*
* Migrates weighting settings into a `fields` property of the weighting
- * configuration and adds the `manage_meta` setting.
+ * configuration and adds the `managing_meta` setting.
*
* @since 4.4.0
* @return void
@@ -205,8 +205,8 @@ public function upgrade_4_4_0() {
foreach ( $weighting_configuration as $post_type => $config ) {
if ( ! isset( $config['fields'] ) ) {
$weighting_configuration[ $post_type ] = [
- 'fields' => $config,
- 'manage_meta' => false,
+ 'fields' => $config,
+ 'managing_meta' => false,
];
}
}
From 207291e5aebb204c69169f50b035464ae58f0cf5 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Fri, 21 Oct 2022 03:09:37 +1100
Subject: [PATCH 10/63] WIP: Implement global meta management control.
---
assets/css/weighting.css | 86 +------------------
assets/css/weighting/action.css | 6 ++
assets/css/weighting/add-new.css | 7 ++
assets/css/weighting/field.css | 50 +++++++++++
assets/css/weighting/screen.css | 15 ++++
.../components/common/delete-button.js | 8 +-
.../components/common/undo-button.js | 4 +-
assets/js/weighting/components/weighting.js | 80 +++++++++++++----
.../components/weighting/meta-mode.js | 36 ++++++++
.../components/weighting/post-type.js | 67 +++++----------
.../components/weighting/post-type/fields.js | 3 +-
.../components/weighting/post-type/group.js | 70 ---------------
assets/js/weighting/index.js | 3 +-
includes/classes/Feature/Search/Weighting.php | 59 ++++++-------
includes/classes/Upgrades.php | 29 -------
includes/dashboard.php | 2 +
16 files changed, 242 insertions(+), 283 deletions(-)
create mode 100644 assets/css/weighting/action.css
create mode 100644 assets/css/weighting/add-new.css
create mode 100644 assets/css/weighting/field.css
create mode 100644 assets/css/weighting/screen.css
create mode 100644 assets/js/weighting/components/weighting/meta-mode.js
delete mode 100644 assets/js/weighting/components/weighting/post-type/group.js
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
index 26e983ef70..5478309da2 100644
--- a/assets/css/weighting.css
+++ b/assets/css/weighting.css
@@ -1,82 +1,4 @@
-#ep-weighting-screen {
- max-width: 800px;
-
- & .components-panel {
- margin-bottom: 1rem;
- }
-
- & .components-toggle-control__label {
- max-width: none;
- }
-}
-
-.ep-weighting-field {
- align-items: center;
- display: grid;
- grid-gap: 0.5em;
- grid-template-columns: min(20%, 30ch) max-content auto max-content;
- width: 100%;
-
- & .components-base-control__field {
- margin-bottom: 0;
- }
-
- & .components-range-control {
-
- & .components-base-control__field {
- align-items: center;
- display: flex;
- }
-
- & .components-base-control__label {
- margin-bottom: 0;
- }
- }
-
- @media ( max-width: 600px ) {
- grid-gap: 1em;
-
- & .components-range-control__wrapper {
- display: none;
- }
- }
-}
-
-.ep-weighting-field fieldset {
- display: contents;
-}
-
-.ep-weighting-field__name {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-
- & h2 {
- margin: 0;
- }
-}
-
-.ep-weighting-field__undo {
- grid-column-start: 4;
- justify-self: end;
-}
-
-
-.ep-weighting-delete,
-.ep-weighting-undo {
-
- &[disabled] {
- visibility: hidden;
- }
-}
-
-.ep-weighting-add-meta {
- justify-content: start;
-}
-
-.ep-weighting-add-meta__select {
-
- & select.components-select-control__input {
- min-height: 36px;
- }
-}
+@import "weighting/action.css";
+@import "weighting/add-new.css";
+@import "weighting/field.css";
+@import "weighting/screen.css";
diff --git a/assets/css/weighting/action.css b/assets/css/weighting/action.css
new file mode 100644
index 0000000000..ba2084222e
--- /dev/null
+++ b/assets/css/weighting/action.css
@@ -0,0 +1,6 @@
+.ep-weighting-action {
+
+ &[disabled] {
+ visibility: hidden;
+ }
+}
diff --git a/assets/css/weighting/add-new.css b/assets/css/weighting/add-new.css
new file mode 100644
index 0000000000..88e9c45482
--- /dev/null
+++ b/assets/css/weighting/add-new.css
@@ -0,0 +1,7 @@
+.ep-weighting-add-new {
+ justify-content: start;
+
+ & .components-base-control .components-select-control .components-select-control__input {
+ min-height: 36px;
+ }
+}
diff --git a/assets/css/weighting/field.css b/assets/css/weighting/field.css
new file mode 100644
index 0000000000..8891dc4afd
--- /dev/null
+++ b/assets/css/weighting/field.css
@@ -0,0 +1,50 @@
+.ep-weighting-field {
+ align-items: center;
+ display: grid;
+ grid-gap: 0.5em;
+ grid-template-columns: min(20%, 30ch) max-content auto max-content;
+ width: 100%;
+
+ & .components-base-control__field {
+ margin-bottom: 0;
+ }
+
+ & .components-range-control {
+
+ & .components-base-control__field {
+ align-items: center;
+ display: flex;
+ }
+
+ & .components-base-control__label {
+ margin-bottom: 0;
+ }
+ }
+
+ @media ( max-width: 600px ) {
+ grid-gap: 1em;
+
+ & .components-range-control__wrapper {
+ display: none;
+ }
+ }
+}
+
+.ep-weighting-field fieldset {
+ display: contents;
+}
+
+.ep-weighting-field__name {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+
+ & h2 {
+ margin: 0;
+ }
+}
+
+.ep-weighting-field__undo {
+ grid-column-start: 4;
+ justify-self: end;
+}
diff --git a/assets/css/weighting/screen.css b/assets/css/weighting/screen.css
new file mode 100644
index 0000000000..f2ccc02e63
--- /dev/null
+++ b/assets/css/weighting/screen.css
@@ -0,0 +1,15 @@
+.ep-weighting-screen {
+ max-width: 800px;
+
+ & .components-panel {
+ margin-bottom: 1rem;
+ }
+
+ & .components-toggle-control__label {
+ max-width: none;
+ }
+
+ & .components-base-control__help {
+ margin-bottom: 0;
+ }
+}
diff --git a/assets/js/weighting/components/common/delete-button.js b/assets/js/weighting/components/common/delete-button.js
index 64856aae83..6a3d37a118 100644
--- a/assets/js/weighting/components/common/delete-button.js
+++ b/assets/js/weighting/components/common/delete-button.js
@@ -15,5 +15,11 @@ export default (props) => {
/**
* Render.
*/
- return ;
+ return (
+
+ );
};
diff --git a/assets/js/weighting/components/common/undo-button.js b/assets/js/weighting/components/common/undo-button.js
index 8aebf8b307..4188839cdb 100644
--- a/assets/js/weighting/components/common/undo-button.js
+++ b/assets/js/weighting/components/common/undo-button.js
@@ -15,5 +15,7 @@ export default (props) => {
/**
* Render.
*/
- return ;
+ return (
+
+ );
};
diff --git a/assets/js/weighting/components/weighting.js b/assets/js/weighting/components/weighting.js
index 032dcccb3b..1f2c598486 100644
--- a/assets/js/weighting/components/weighting.js
+++ b/assets/js/weighting/components/weighting.js
@@ -4,12 +4,13 @@
import apiFetch from '@wordpress/api-fetch';
import { WPElement, useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
-import { cloneDeep, isEqual } from 'lodash';
+import { isEqual } from 'lodash';
/**
* Internal Dependencies.
*/
import Actions from './weighting/actions';
+import MetaMode from './weighting/meta-mode';
import PostType from './weighting/post-type';
/**
@@ -17,19 +18,56 @@ import PostType from './weighting/post-type';
*
* @param {object} props Component props.
* @param {string} props.apiUrl API URL.
+ * @param {'auto'|'manual'} props.metaMode Metadata management mode.
* @param {object} props.weightableFields Weightable fields, indexed by post type.
* @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
* @returns {WPElement} Element.
*/
-export default ({ apiUrl, weightableFields, weightingConfiguration }) => {
- const [currentData, setCurrentData] = useState({ ...weightingConfiguration });
- const [savedData, setSavedData] = useState({ ...weightingConfiguration });
+export default ({ apiUrl, metaMode, weightableFields, weightingConfiguration }) => {
+ const [currentMetaMode, setCurrentMetaMode] = useState(metaMode);
+ const [currentWeightingConfiguration, setCurrentWeightingConfiguration] = useState({
+ ...weightingConfiguration,
+ });
+
+ const [savedMetaMode, setSavedMetaMode] = useState(metaMode);
+ const [savedWeightingConfiguration, setSavedWeightingConfiguration] = useState({
+ ...weightingConfiguration,
+ });
+
const [isBusy, setIsBusy] = useState(false);
/**
* Is the current data different to the saved data.
*/
- const isChanged = useMemo(() => !isEqual(currentData, savedData), [currentData, savedData]);
+ const isChanged = useMemo(
+ () =>
+ !(
+ currentMetaMode === savedMetaMode &&
+ isEqual(currentWeightingConfiguration, savedWeightingConfiguration)
+ ),
+ [
+ currentWeightingConfiguration,
+ currentMetaMode,
+ savedWeightingConfiguration,
+ savedMetaMode,
+ ],
+ );
+
+ /**
+ * Whether to show weighting for metadata.
+ */
+ const showMeta = useMemo(() => currentMetaMode === 'manual', [currentMetaMode]);
+
+ /**
+ * Handle meta mode change.
+ *
+ * @param {boolean} checked Is manual checked?
+ */
+ const onChangeMetaMode = (checked) => {
+ const metaMode = checked ? 'manual' : 'auto';
+
+ setCurrentMetaMode(metaMode);
+ };
/**
* Handle data change.
@@ -39,7 +77,7 @@ export default ({ apiUrl, weightableFields, weightingConfiguration }) => {
* @returns {void}
*/
const onChangePostType = (postType, values) => {
- setCurrentData({ ...currentData, [postType]: values });
+ setCurrentWeightingConfiguration({ ...currentWeightingConfiguration, [postType]: values });
};
/**
@@ -48,7 +86,8 @@ export default ({ apiUrl, weightableFields, weightingConfiguration }) => {
* @returns {void}
*/
const onReset = () => {
- setCurrentData({ ...savedData });
+ setCurrentMetaMode(savedMetaMode);
+ setCurrentWeightingConfiguration({ ...savedWeightingConfiguration });
};
/**
@@ -64,16 +103,21 @@ export default ({ apiUrl, weightableFields, weightingConfiguration }) => {
setIsBusy(true);
const response = await apiFetch({
- body: JSON.stringify(currentData),
+ body: JSON.stringify({
+ meta_mode: currentMetaMode,
+ weighting_configuration: currentWeightingConfiguration,
+ }),
+ headers: {
+ 'Content-Type': 'application/json',
+ },
method: 'POST',
url: apiUrl,
});
- const newCurrentdData = cloneDeep(response.data);
- const newSavedData = cloneDeep(response.data);
+ const { meta_mode, weighting_configuration } = response.data;
- setCurrentData(newCurrentdData);
- setSavedData(newSavedData);
+ setSavedWeightingConfiguration(weighting_configuration);
+ setSavedMetaMode(meta_mode);
setIsBusy(false);
} catch {
setIsBusy(false);
@@ -84,25 +128,26 @@ export default ({ apiUrl, weightableFields, weightingConfiguration }) => {
* Render.
*/
return (
-
diff --git a/assets/js/weighting/components/group.js b/assets/js/weighting/components/group.js
new file mode 100644
index 0000000000..fbd3a6c863
--- /dev/null
+++ b/assets/js/weighting/components/group.js
@@ -0,0 +1,165 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button, PanelRow, TextControl } from '@wordpress/components';
+import { useMemo, useState, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies.
+ */
+import Field from './field';
+import { useWeighting } from '../provider';
+
+/**
+ * Post type propertes component.
+ *
+ * @param {object} props Component props.
+ * @param {string} props.group Group.
+ * @param {string} props.postType Post type.
+ * @returns {WPElement} Component element.
+ */
+export default ({ group, postType }) => {
+ const { currentWeightingConfiguration, setWeightingForPostType, weightableFields } =
+ useWeighting();
+
+ /**
+ * State.
+ */
+ const [toAdd, setToAdd] = useState('');
+
+ /**
+ * Saved weighting values for this group's post type.
+ */
+ const values = currentWeightingConfiguration[postType];
+ const { fields } = weightableFields.find((w) => w.key === postType);
+
+ /**
+ * Whether this is the Metadata group.
+ */
+ const isMetadata = group === 'ep_metadata';
+
+ /**
+ * Fields that belond to this group.
+ */
+ const defaultFields = useMemo(() => fields.filter((f) => f.group === group), [fields, group]);
+
+ /**
+ * Custom fields.
+ *
+ * These are meta fields that have a saved weighting value but are not
+ * included in the list of weightable fields. This will be fields that
+ * were added manually using the UI.
+ */
+ const customFields = useMemo(() => {
+ if (!isMetadata) {
+ return [];
+ }
+
+ const fieldKeys = fields.map(({ key }) => key);
+
+ const customFields = Object.keys(values).reduce((customFields, key) => {
+ if (fieldKeys.includes(key)) {
+ return customFields;
+ }
+
+ const matches = key.match(/meta\.(?.*)\.value/);
+
+ if (!matches) {
+ return customFields;
+ }
+
+ const { label } = matches.groups;
+
+ customFields.push({
+ key,
+ label,
+ });
+
+ return customFields;
+ }, []);
+
+ return customFields;
+ }, [fields, isMetadata, values]);
+
+ /**
+ * Handle changes to a property.
+ *
+ * @param {object} value New property data.
+ * @param {number} key Property key.
+ * @returns {void}
+ */
+ const onChange = (value, key) => {
+ setWeightingForPostType(postType, { ...values, [key]: value });
+ };
+
+ /**
+ * Handle clicking to add a new property.
+ *
+ * @returns {void}
+ */
+ const onClick = () => {
+ const key = `meta.${toAdd}.value`;
+ const newValues = { ...values, [key]: { enabled: false, weight: 0 } };
+
+ setWeightingForPostType(postType, newValues);
+ setToAdd('');
+ };
+
+ /**
+ * Handle removing a field.
+ *
+ * @param {number} key field key.
+ * @returns {void}
+ */
+ const onDelete = (key) => {
+ const newValues = { ...values };
+
+ delete newValues[key];
+
+ setWeightingForPostType(postType, newValues);
+ };
+
+ return (
+ <>
+ {defaultFields.map(({ key, label }) => (
+
+ {
+ onChange(value, key);
+ }}
+ />
+
+ ))}
+ {customFields.map(({ key, label }) => (
+
+ {
+ onChange(value, key);
+ }}
+ onDelete={() => {
+ onDelete(key);
+ }}
+ />
+
+ ))}
+ {isMetadata ? (
+
+ setToAdd(toAdd)}
+ placeholder={__('Metadata key', 'elasticpress')}
+ value={toAdd}
+ />
+
+ {__('Add', 'elasticpress')}
+
+
+ ) : null}
+ >
+ );
+};
diff --git a/assets/js/weighting/components/post-type.js b/assets/js/weighting/components/post-type.js
new file mode 100644
index 0000000000..c0f0471e77
--- /dev/null
+++ b/assets/js/weighting/components/post-type.js
@@ -0,0 +1,49 @@
+/**
+ * WordPress dependencies.
+ */
+import { Panel, PanelBody, PanelHeader } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
+
+/**
+ * Internal dependencies.
+ */
+import { useWeighting } from '../provider';
+import Group from './group';
+
+/**
+ * Post type weighting settings component.
+ *
+ * @param {object} props Components props.
+ * @param {object[]} props.postType Post type.
+ * @returns {WPElement} Component element.
+ */
+export default ({ postType }) => {
+ const { isManual, weightableFields } = useWeighting();
+
+ const { label, groups } = weightableFields.find((f) => f.key === postType);
+
+ /**
+ * Render.
+ */
+ return (
+
+
+
+
+ {groups.map(({ key, label }) => {
+ const isMetadata = key === 'ep_metadata';
+
+ return !isMetadata || isManual ? (
+
+
+
+ ) : null;
+ })}
+
+ );
+};
diff --git a/assets/js/weighting/components/weighting.js b/assets/js/weighting/components/weighting.js
deleted file mode 100644
index 1d5bcd78e8..0000000000
--- a/assets/js/weighting/components/weighting.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import apiFetch from '@wordpress/api-fetch';
-import { withNotices } from '@wordpress/components';
-import { WPElement, useMemo, useState } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { isEqual } from 'lodash';
-
-/**
- * Internal Dependencies.
- */
-import { getMetaFieldsFromWeightingConfiguration, isFieldSyncedByFeature } from '../utilities';
-import Actions from './weighting/actions';
-import PostType from './weighting/post-type';
-
-/**
- * Weighting settings app.
- *
- * @param {object} props Component props.
- * @param {string} props.apiUrl API URL.
- * @param {'auto'|'manual'} props.metaMode Metadata management mode.
- * @param {object} props.noticeOperations Notice operations from withNotices.
- * @param {WPElement} props.noticeUI Notice UI from withNotices.
- * @param {string} props.syncUrl Sync URL.
- * @param {object} props.weightableFields Weightable fields, indexed by post type.
- * @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
- * @returns {WPElement} Element.
- */
-const Weighting = ({
- apiUrl,
- metaMode,
- noticeOperations,
- noticeUI,
- syncUrl,
- weightableFields,
- weightingConfiguration,
-}) => {
- const [currentWeightingConfiguration, setCurrentWeightingConfiguration] = useState({
- ...weightingConfiguration,
- });
-
- const [savedWeightingConfiguration, setSavedWeightingConfiguration] = useState({
- ...weightingConfiguration,
- });
-
- const [isBusy, setIsBusy] = useState(false);
-
- /**
- * Is the current data different to the saved data.
- */
- const isChanged = useMemo(
- () => !isEqual(currentWeightingConfiguration, savedWeightingConfiguration),
- [currentWeightingConfiguration, savedWeightingConfiguration],
- );
-
- /**
- * Is a sync going to be required?
- *
- * A sync is required whenever a new meta field is added unless that field
- * is already being synced by a feature. Removing a meta field does not
- * require a sync, but the user may choose to perform one if they need the
- * field removed from the index.
- *
- * @returns {boolean} Whether a sync is required.
- */
- const isSyncRequired = useMemo(() => {
- const savedMeta = getMetaFieldsFromWeightingConfiguration(savedWeightingConfiguration);
- const currentMeta = getMetaFieldsFromWeightingConfiguration(currentWeightingConfiguration);
-
- const newMeta = currentMeta.filter(
- (c) => !savedMeta.includes(c) && !isFieldSyncedByFeature(c, weightableFields),
- );
-
- return newMeta.length > 0;
- }, [currentWeightingConfiguration, savedWeightingConfiguration, weightableFields]);
-
- /**
- * Whether to show weighting for metadata.
- */
- const showMeta = useMemo(() => metaMode === 'manual', [metaMode]);
-
- /**
- * Handle data change.
- *
- * @param {string} postType Updated post type.
- * @param {Array} values Updated data.
- * @returns {void}
- */
- const onChangePostType = (postType, values) => {
- setCurrentWeightingConfiguration({
- ...currentWeightingConfiguration,
- [postType]: values,
- });
- };
-
- /**
- * Handle resetting all settings.
- *
- * @returns {void}
- */
- const onReset = () => {
- setCurrentWeightingConfiguration({ ...savedWeightingConfiguration });
- };
-
- /**
- * Handle for submission.
- *
- * @param {Event} event Submit event.
- * @returns {void}
- */
- const onSubmit = async (event) => {
- event.preventDefault();
-
- try {
- setIsBusy(true);
-
- const response = await apiFetch({
- body: JSON.stringify(currentWeightingConfiguration),
- headers: {
- 'Content-Type': 'application/json',
- },
- method: 'POST',
- url: apiUrl,
- });
-
- if (isSyncRequired) {
- window.location = syncUrl;
- return;
- }
-
- setSavedWeightingConfiguration(response.data);
-
- noticeOperations.createNotice({
- content: __('Search fields & weighting saved.', 'elasticpress'),
- status: 'success',
- });
- } catch {
- noticeOperations.createNotice({
- content: __('Whoops! Something went wrong. Please try again.', 'elasticpress'),
- status: 'error',
- });
- } finally {
- document.body.scrollIntoView({ behavior: 'smooth' });
-
- setIsBusy(false);
- }
- };
-
- /**
- * Render.
- */
- return (
-
- {__('Manage Search Fields & Weighting', 'elasticpress')}
- {noticeUI}
-
-
- {__(
- 'This dashboard enables you to select which fields ElasticPress should sync, whether to use those fields in searches, and how heavily to weight fields in the search algorithm. In general, increasing the Weight of a field will increase the relevancy score of a post that has matching text in that field.',
- 'elasticpress',
- )}
-
-
- {__(
- 'For example, adding more weight to the title attribute will cause search matches on the post title to appear more prominently.',
- 'elasticpress',
- )}
-
-
- {Object.entries(weightableFields).map(([postType, { groups, label }]) => {
- const originalValues = savedWeightingConfiguration[postType] || {};
- const values = currentWeightingConfiguration[postType] || {};
-
- return (
- {
- onChangePostType(postType, values);
- }}
- originalValues={originalValues}
- showMeta={showMeta}
- values={values}
- />
- );
- })}
-
-
- );
-};
-
-export default withNotices(Weighting);
diff --git a/assets/js/weighting/components/weighting/post-type.js b/assets/js/weighting/components/weighting/post-type.js
deleted file mode 100644
index 5f5c38673f..0000000000
--- a/assets/js/weighting/components/weighting/post-type.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Panel, PanelBody, PanelHeader } from '@wordpress/components';
-import { useMemo, WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { isEqual } from 'lodash';
-
-/**
- * Internal dependencies.
- */
-import Fields from './post-type/fields';
-import UndoButton from '../common/undo-button';
-
-/**
- * Post type weighting settings component.
- *
- * @param {object} props Components props.
- * @param {object[]} props.groups Field groups.
- * @param {string} props.label Post type label.
- * @param {Function} props.onChange Data change handler.
- * @param {object} props.originalValues Saved post type settings.
- * @param {boolean} props.showMeta Whether to show the meta group.
- * @param {object} props.values Current post type settings.
- * @returns {WPElement} Component element.
- */
-export default ({ groups, label, onChange, originalValues, showMeta, values }) => {
- /**
- * Have any values changed?
- */
- const isChanged = useMemo(() => !isEqual(originalValues, values), [originalValues, values]);
-
- /**
- * The field groups to display.
- *
- * Filters out any groups without fields.
- */
- const fieldGroups = useMemo(
- () =>
- Object.entries(groups).reduce((previousValue, currentValue) => {
- const [key, group] = currentValue;
-
- if (Object.keys(group.children).length > 0) {
- return [...previousValue, { key, ...group }];
- }
-
- return previousValue;
- }, []),
- [groups],
- );
-
- /**
- * Handle resetting all data for the post type.
- *
- * @returns {void}
- */
- const onReset = () => {
- onChange(originalValues);
- };
-
- /**
- * Render.
- */
- return (
-
-
-
-
-
{label}
-
-
- {isChanged ? (
-
- ) : null}
-
-
-
- {fieldGroups.map(({ children, key, label }) => {
- const isMeta = key === 'ep_metadata';
- const fields = Object.values(children);
-
- return !isMeta || showMeta ? (
-
-
-
- ) : null;
- })}
-
- );
-};
diff --git a/assets/js/weighting/components/weighting/post-type/fields.js b/assets/js/weighting/components/weighting/post-type/fields.js
deleted file mode 100644
index 14e167e44c..0000000000
--- a/assets/js/weighting/components/weighting/post-type/fields.js
+++ /dev/null
@@ -1,196 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Button, PanelRow, SelectControl, ToggleControl } from '@wordpress/components';
-import { useMemo, useState, WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-
-/**
- * Internal dependencies.
- */
-import Field from './field';
-
-/**
- * Post type propertes component.
- *
- * @param {object} props Component props.
- * @param {object[]} props.fields Post type fields.
- * @param {boolean} props.isEditable Whether to display as an editable list.
- * @param {Function} props.onChange Change handler.
- * @param {object[]} props.originalValues Saved property values.
- * @param {object[]} props.values Current property values.
- * @returns {WPElement} Component element.
- */
-export default ({ fields, isEditable, onChange, originalValues, values }) => {
- const [toAdd, setToAdd] = useState('');
- const [showFeatureFields, setShowFeatureFields] = useState(false);
-
- /**
- * Weightable fields that can be added to the group, if it is editable.
- *
- * Fields that are automatically synced by features are excluded, while
- * fields that have already been added are disabled.
- */
- const availableFields = useMemo(() => {
- return fields
- .filter((f) => !f.used_by_feature)
- .map((f) => ({
- label: f.label,
- value: f.key,
- disabled: Object.prototype.hasOwnProperty.call(values, f.key),
- }));
- }, [fields, values]);
-
- /**
- * Fields that are automatically synced by features.
- */
- const featureFields = useMemo(() => {
- return fields.filter((f) => f.used_by_feature);
- }, [fields]);
-
- /**
- * Fields that can be weighted.
- *
- * For editable groups fields are sorted to match the order of the saved
- * configuration, to preserve the order in which the fields were added.
- */
- const weightedFields = useMemo(() => {
- return fields
- .filter((f) => !f.used_by_feature)
- .filter((f) => Object.prototype.hasOwnProperty.call(values, f.key))
- .sort((a, b) => {
- const { key: aKey } = a;
- const { key: bKey } = b;
-
- const keys = Object.keys(values);
-
- return keys.indexOf(aKey) - keys.indexOf(bKey);
- });
- }, [fields, values]);
-
- /**
- * Handle changes to a property.
- *
- * @param {object} value New property data.
- * @param {number} key Property key.
- * @returns {void}
- */
- const onChangeProperty = (value, key) => {
- onChange({ ...values, [key]: value });
- };
-
- /**
- * Handle selecting a new property to enable.
- *
- * @param {string} key Key of property to enable.
- * @returns {void}
- */
- const onChangeToAdd = (key) => {
- setToAdd(key);
- };
-
- /**
- * Handle a change to whether fields automatically synced by features are
- * shown.
- *
- * @param {boolean} showFeatureFields Whether to show fields synced by features.
- * @returns {void}
- */
- const onChangeShowFeatureFields = (showFeatureFields) => {
- setShowFeatureFields(showFeatureFields);
- };
-
- /**
- * Handle clicking to add a new property.
- *
- * @returns {void}
- */
- const onClickAdd = () => {
- const newValues = { ...values, [toAdd]: { enabled: false, weight: 0 } };
-
- onChange(newValues);
- setToAdd('');
- };
-
- /**
- * Handle removing a field.
- *
- * @param {number} key field key.
- * @returns {void}
- */
- const onDeleteField = (key) => {
- const newValues = { ...values };
-
- delete newValues[key];
-
- onChange(newValues);
- };
-
- /**
- * Render.
- */
- return (
- <>
- {featureFields.length > 0 ? (
-
-
-
- ) : null}
- {featureFields
- .filter((f) => showFeatureFields || values?.[f.key]?.enabled === true)
- .map(({ key, label }) => (
-
- {
- onChangeProperty(value, key);
- }}
- />
-
- ))}
- {(isEditable ? weightedFields : fields).map(({ key, label }) => (
-
- {
- onChangeProperty(value, key);
- }}
- onDelete={
- isEditable
- ? () => {
- onDeleteField(key);
- }
- : null
- }
- />
-
- ))}
- {isEditable && availableFields ? (
-
-
-
-
- {__('Add field', 'elasticpress')}
-
-
- ) : null}
- >
- );
-};
diff --git a/assets/js/weighting/config.js b/assets/js/weighting/config.js
new file mode 100644
index 0000000000..5ee2464a03
--- /dev/null
+++ b/assets/js/weighting/config.js
@@ -0,0 +1,3 @@
+const { apiUrl, metaMode, syncUrl, weightableFields, weightingConfiguration } = window.epWeighting;
+
+export { apiUrl, metaMode, syncUrl, weightableFields, weightingConfiguration };
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index d60b84b7e4..4cf62a8417 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -1,32 +1,36 @@
/**
* WordPress dependencies.
*/
-import { render } from '@wordpress/element';
+import { createRoot, render, WPElement } from '@wordpress/element';
/**
* Internal Dependencies.
*/
-import Weighting from './components/weighting';
+import { apiUrl, metaMode, syncUrl, weightableFields, weightingConfiguration } from './config';
+import WeightingProvider from './provider';
+import SettingsPage from './apps/settings-page';
/**
- * Initialize.
+ * App component.
*
- * @returns {void}
+ * @returns {WPElement} App component.
*/
-const init = () => {
- const { apiUrl, metaMode, syncUrl, weightableFields, weightingConfiguration } =
- window.epWeighting;
+const App = () => (
+
+
+
+);
- render(
- ,
- document.getElementById('ep-weighting-screen'),
- );
-};
+if (typeof createRoot === 'function') {
+ const root = createRoot(document.getElementById('ep-weighting-screen'));
-init();
+ root.render( );
+} else {
+ render( , document.getElementById('ep-weighting-screen'));
+}
diff --git a/assets/js/weighting/provider.js b/assets/js/weighting/provider.js
new file mode 100644
index 0000000000..d5db4518f5
--- /dev/null
+++ b/assets/js/weighting/provider.js
@@ -0,0 +1,149 @@
+/**
+ * WordPress dependencies.
+ */
+import apiFetch from '@wordpress/api-fetch';
+import { withNotices } from '@wordpress/components';
+import { createContext, WPElement, useContext, useMemo, useState } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+import { isEqual } from 'lodash';
+
+/**
+ * Instant Results context.
+ */
+const Context = createContext();
+
+/**
+ * Weighting settings app.
+ *
+ * @param {object} props Component props.
+ * @param {string} props.apiUrl API URL.
+ * @param {Function} props.children Component children.
+ * @param {'auto'|'manual'} props.metaMode Metadata management mode.
+ * @param {object} props.noticeOperations Notice operations from withNotices.
+ * @param {WPElement} props.noticeUI Notice UI from withNotices.
+ * @param {object} props.weightableFields Weightable fields, indexed by post type.
+ * @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
+ * @returns {WPElement} Element.
+ */
+const WeightingProvider = ({
+ apiUrl,
+ children,
+ metaMode,
+ noticeOperations,
+ noticeUI,
+ weightableFields,
+ weightingConfiguration,
+}) => {
+ const [currentWeightingConfiguration, setCurrentWeightingConfiguration] = useState({
+ ...weightingConfiguration,
+ });
+
+ const [savedWeightingConfiguration, setSavedWeightingConfiguration] = useState({
+ ...weightingConfiguration,
+ });
+
+ const [isBusy, setIsBusy] = useState(false);
+
+ /**
+ * Is the current data different to the saved data.
+ */
+ const isChanged = useMemo(
+ () => !isEqual(currentWeightingConfiguration, savedWeightingConfiguration),
+ [currentWeightingConfiguration, savedWeightingConfiguration],
+ );
+
+ /**
+ * Whether to show weighting for metadata.
+ */
+ const isManual = useMemo(() => metaMode === 'manual', [metaMode]);
+
+ /**
+ * Handle data change.
+ *
+ * @param {string} postType Post type to update.
+ * @param {Array} values New valus.
+ * @returns {void}
+ */
+ const setWeightingForPostType = (postType, values) => {
+ setCurrentWeightingConfiguration({
+ ...currentWeightingConfiguration,
+ [postType]: values,
+ });
+ };
+
+ /**
+ * Handle resetting all settings.
+ *
+ * @returns {void}
+ */
+ const reset = () => {
+ setCurrentWeightingConfiguration({ ...savedWeightingConfiguration });
+ };
+
+ /**
+ * Save settings.
+ *
+ * @returns {void}
+ */
+ const save = async () => {
+ try {
+ setIsBusy(true);
+
+ const response = await apiFetch({
+ body: JSON.stringify(currentWeightingConfiguration),
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ method: 'POST',
+ url: apiUrl,
+ });
+
+ setSavedWeightingConfiguration(response.data);
+
+ noticeOperations.createNotice({
+ content: __('Search fields & weighting saved.', 'elasticpress'),
+ status: 'success',
+ });
+ } catch {
+ noticeOperations.createNotice({
+ content: __('Whoops! Something went wrong. Please try again.', 'elasticpress'),
+ status: 'error',
+ });
+ } finally {
+ document.body.scrollIntoView({ behavior: 'smooth' });
+
+ setIsBusy(false);
+ }
+ };
+
+ // eslint-disable-next-line react/jsx-no-constructed-context-values
+ const contextValue = {
+ currentWeightingConfiguration,
+ isBusy,
+ isChanged,
+ isManual,
+ noticeOperations,
+ noticeUI,
+ reset,
+ save,
+ savedWeightingConfiguration,
+ setWeightingForPostType,
+ weightableFields,
+ };
+
+ /**
+ * Render.
+ */
+ return {children} ;
+};
+
+export default withNotices(WeightingProvider);
+
+/**
+ * Use the API Search context.
+ *
+ * @returns {object} API Search Context.
+ */
+export const useWeighting = () => {
+ return useContext(Context);
+};
diff --git a/assets/js/weighting/utilities.js b/assets/js/weighting/utilities.js
deleted file mode 100644
index 364fbdb0df..0000000000
--- a/assets/js/weighting/utilities.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Get a list of meta fields from the weighting configuration.
- *
- * @param {object} weightingConfiguration Weighting configuration.
- * @returns {Array} Meta fields.
- */
-export const getMetaFieldsFromWeightingConfiguration = (weightingConfiguration) => {
- const fields = Object.values(weightingConfiguration)
- .map((v) => Object.keys(v))
- .flat();
-
- return fields.filter((f) => f.startsWith('meta.'));
-};
-
-/**
- * Is a field synced by a feature?
- *
- * @param {string} field Field name.
- * @param {object} weightableFields Weightable fields.
- * @returns {boolean} If the field is synced by a feature.
- */
-export const isFieldSyncedByFeature = (field, weightableFields) => {
- return Object.values(weightableFields)
- .map((v) => Object.values(v.groups))
- .flat()
- .map((g) => Object.values(g.children))
- .flat()
- .some((c) => c.key === field && c.used_by_feature === true);
-};
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 23502ea074..17181b663a 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -122,12 +122,12 @@ public function get_weightable_fields_for_post_type( $post_type ) {
continue;
}
- $used_by_feature = in_array( $meta_key, $allowed_protected_keys, true );
+ $required = in_array( $meta_key, $allowed_protected_keys, true );
$fields['ep_metadata']['children'][ $key ] = [
- 'key' => $key,
- 'label' => $meta_key,
- 'used_by_feature' => true,
+ 'key' => $key,
+ 'label' => $meta_key,
+ 'required' => $required,
];
}
@@ -145,7 +145,7 @@ public function get_weightable_fields_for_post_type( $post_type ) {
/**
* Get weightable fields for all searchable post types.
*
- * @since 4.4.0
+ * @since 5.0.0
* @return array
*/
public function get_weightable_fields() {
@@ -156,9 +156,32 @@ public function get_weightable_fields() {
$post_type_object = get_post_type_object( $post_type );
$post_type_labels = get_post_type_labels( $post_type_object );
- $weightable[ $post_type ] = [
+ $weightable_fields = $this->get_weightable_fields_for_post_type( $post_type );
+
+ $groups = [];
+ $fields = [];
+
+ foreach ( $weightable_fields as $group => $weightable_field ) {
+ $groups[] = [
+ 'key' => $group,
+ 'label' => $weightable_field['label'],
+ ];
+
+ foreach ( $weightable_field['children'] as $field ) {
+ $fields[] = [
+ 'group' => $group,
+ 'key' => $field['key'],
+ 'label' => $field['label'],
+ 'required' => isset( $field['required'] ) ? $field['required'] : false,
+ ];
+ }
+ }
+
+ $weightable[] = [
+ 'key' => $post_type,
'label' => $post_type_labels->menu_name,
- 'groups' => $this->get_weightable_fields_for_post_type( $post_type ),
+ 'groups' => $groups,
+ 'fields' => $fields,
];
}
diff --git a/includes/classes/Feature/WooCommerce/Products.php b/includes/classes/Feature/WooCommerce/Products.php
index b5b08217fa..ed501ebd60 100644
--- a/includes/classes/Feature/WooCommerce/Products.php
+++ b/includes/classes/Feature/WooCommerce/Products.php
@@ -285,6 +285,8 @@ public function add_product_attributes_to_weighting( $fields, $post_type ) {
$sku_key = 'meta._sku.value';
+ unset( $fields['ep_metadata']['children'][ $sku_key ] );
+
$fields['attributes']['children'][ $sku_key ] = array(
'key' => $sku_key,
'label' => __( 'SKU', 'elasticpress' ),
@@ -292,6 +294,8 @@ public function add_product_attributes_to_weighting( $fields, $post_type ) {
$variations_skus_key = 'meta._variations_skus.value';
+ unset( $fields['ep_metadata']['children'][ $variations_skus_key ] );
+
$fields['attributes']['children'][ $variations_skus_key ] = array(
'key' => $variations_skus_key,
'label' => __( 'Variations SKUs', 'elasticpress' ),
diff --git a/includes/dashboard.php b/includes/dashboard.php
index da3c5f69b2..66c0c07018 100644
--- a/includes/dashboard.php
+++ b/includes/dashboard.php
@@ -510,7 +510,6 @@ function action_admin_enqueue_dashboard_scripts() {
$api_url = esc_url_raw( rest_url( 'elasticpress/v1/weighting' ) );
$meta_mode = $weighting->get_meta_mode();
- $sync_url = admin_url( 'admin.php?page=elasticpress-sync&do_sync' );
$weightable_fields = $weighting->get_weightable_fields();
$weighting_configuration = $weighting->get_weighting_configuration_with_defaults();
@@ -520,7 +519,6 @@ function action_admin_enqueue_dashboard_scripts() {
array(
'apiUrl' => $api_url,
'metaMode' => $meta_mode,
- 'syncUrl' => $sync_url,
'weightableFields' => $weightable_fields,
'weightingConfiguration' => $weighting_configuration,
)
From c7f454089ba2c8961384d3598ce6f5dda6f1a180 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 12 Sep 2023 21:11:42 +1000
Subject: [PATCH 38/63] Update package-lock.json.
---
package-lock.json | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/package-lock.json b/package-lock.json
index e355ff4b93..0096cb1acb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18390,6 +18390,15 @@
"ms": "^2.1.1"
}
},
+ "node_modules/simple-bin-help/node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
@@ -33959,6 +33968,12 @@
"requires": {
"ms": "^2.1.1"
}
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
}
}
},
From 0e56b999f62bd2df18b95918b9500d5a85d97bd4 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 12 Sep 2023 21:25:16 +1000
Subject: [PATCH 39/63] Rearrange for cleaner diff.
---
includes/classes/Feature/Search/Weighting.php | 70 ++++++++++---------
1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 17181b663a..b1da572c97 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -356,10 +356,37 @@ public function render_settings_section( $post_type, $field, $current_values ) {
_doing_it_wrong(
__METHOD__,
esc_html( 'Weighting sections display are now handled via React components.' ),
- 'ElasticPress 4.4.0'
+ 'ElasticPress 5.0.0'
);
}
+ /**
+ * DEPRECATED. Handles processing the new weighting values and saving them
+ * to the elasticpress.io service.
+ */
+ public function handle_save() {
+ _doing_it_wrong(
+ __METHOD__,
+ esc_html( 'Weighting settings are now updated using the REST API.' ),
+ 'ElasticPress 5.0.0'
+ );
+
+ if ( ! isset( $_POST['ep-weighting-nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['ep-weighting-nonce'] ), 'save-weighting' ) ) {
+ return;
+ }
+
+ if ( ! current_user_can( Utils\get_capability() ) ) {
+ return;
+ }
+
+ $this->save_weighting_configuration( $_POST );
+
+ $redirect_url = admin_url( 'admin.php?page=elasticpress-weighting' );
+ $redirect_url = add_query_arg( 'settings-updated', true, $redirect_url );
+
+ $this->redirect( $redirect_url );
+ }
+
/**
* DEPRECATED. We need this method to test handle_save properly.
*
@@ -368,9 +395,14 @@ public function render_settings_section( $post_type, $field, $current_values ) {
protected function redirect( $redirect_url ) {
_doing_it_wrong(
__METHOD__,
- esc_html( 'Weighting sections display are now handled via React components.' ),
- 'ElasticPress 4.4.0'
+ esc_html( 'Weighting settings are now updated using the REST API, and do not redirect server-side.' ),
+ 'ElasticPress 5.0.0'
);
+
+ // @codeCoverageIgnoreStart
+ wp_safe_redirect( $redirect_url );
+ exit();
+ // @codeCoverageIgnoreEnd
}
/**
@@ -385,7 +417,7 @@ public function save_weighting_configuration( $settings ) {
_doing_it_wrong(
__METHOD__,
esc_html( 'Weighting sections display are now handled via React components.' ),
- 'ElasticPress 4.4.0'
+ 'ElasticPress 5.0.0'
);
$new_config = array();
@@ -455,7 +487,7 @@ public function register_rest_routes() {
'elasticpress/v1',
'weighting',
[
- 'callback' => [ $this, 'handle_save' ],
+ 'callback' => [ $this, 'update_weighting' ],
'methods' => 'POST',
'permission_callback' => function() {
return current_user_can( Utils\get_capability() );
@@ -471,12 +503,7 @@ public function register_rest_routes() {
* @param \WP_Rest_Request $request REST API request.
* @return void
*/
- public function handle_save( $request = null ) {
- if ( ! $request ) {
- $this->deprecated_handle_save();
- return;
- }
-
+ public function update_weighting( $request = null ) {
$meta_mode = $this->get_meta_mode();
$weighting = $request->get_json_params();
@@ -810,25 +837,4 @@ public function adjust_weight_for_cross_fields( $weighted_field, $field, $weight
}
return $weighted_field;
}
-
- /**
- * Old function that handled processing weighting values and saving them to the elasticpress.io service.
- */
- final protected function deprecated_handle_save() {
- _doing_it_wrong(
- __METHOD__,
- esc_html( 'Weighting sections display are now handled via React components.' ),
- 'ElasticPress 4.4.0'
- );
-
- if ( ! isset( $_POST['ep-weighting-nonce'] ) || ! wp_verify_nonce( $_POST['ep-weighting-nonce'], 'save-weighting' ) ) {
- return;
- }
-
- if ( ! current_user_can( 'manage_options' ) ) {
- return;
- }
-
- $this->save_weighting_configuration( $_POST );
- }
}
From a8b3bdb3b89127d176111a9a701888a21a837c56 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 12 Sep 2023 22:37:53 +1000
Subject: [PATCH 40/63] Update validation of custom fields.
---
includes/classes/Feature/Search/Weighting.php | 95 +++----------------
1 file changed, 14 insertions(+), 81 deletions(-)
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index b1da572c97..a86c88cf82 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -370,21 +370,6 @@ public function handle_save() {
esc_html( 'Weighting settings are now updated using the REST API.' ),
'ElasticPress 5.0.0'
);
-
- if ( ! isset( $_POST['ep-weighting-nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['ep-weighting-nonce'] ), 'save-weighting' ) ) {
- return;
- }
-
- if ( ! current_user_can( Utils\get_capability() ) ) {
- return;
- }
-
- $this->save_weighting_configuration( $_POST );
-
- $redirect_url = admin_url( 'admin.php?page=elasticpress-weighting' );
- $redirect_url = add_query_arg( 'settings-updated', true, $redirect_url );
-
- $this->redirect( $redirect_url );
}
/**
@@ -398,19 +383,14 @@ protected function redirect( $redirect_url ) {
esc_html( 'Weighting settings are now updated using the REST API, and do not redirect server-side.' ),
'ElasticPress 5.0.0'
);
-
- // @codeCoverageIgnoreStart
- wp_safe_redirect( $redirect_url );
- exit();
- // @codeCoverageIgnoreEnd
}
/**
- * DEPRECATED. Save weighting configuration for each searchable post_type
+ * DEPRECATED. Save weighting configuration for each searchable post_type.
*
* @param array $settings weighting settings
*
- * @return array final settings
+ * @return void
* @since 3.4.1
*/
public function save_weighting_configuration( $settings ) {
@@ -419,61 +399,6 @@ public function save_weighting_configuration( $settings ) {
esc_html( 'Weighting sections display are now handled via React components.' ),
'ElasticPress 5.0.0'
);
-
- $new_config = array();
- $previous_config_formatted = array();
- $current_config = $this->get_weighting_configuration();
-
- foreach ( $current_config as $post_type => $post_type_weighting ) {
- // This also ensures the string is safe, since this would return false otherwise
- if ( ! post_type_exists( $post_type ) ) {
- continue;
- }
-
- // We need a way to know if fields have been explicitly set before, let's compare a previous state against $_POST['weighting']
- foreach ( $post_type_weighting as $weighting_field => $weighting_values ) {
- $previous_config_formatted[ $post_type ][ sanitize_text_field( $weighting_field ) ] = [
- 'weight' => isset( $settings['weighting'][ $post_type ][ $weighting_field ]['weight'] ) ? intval( $settings['weighting'][ $post_type ][ $weighting_field ]['weight'] ) : 0,
- 'enabled' => isset( $settings['weighting'][ $post_type ][ $weighting_field ]['enabled'] ) && 'on' === $settings['weighting'][ $post_type ][ $weighting_field ]['enabled'] ? true : false,
- ];
- }
- }
-
- $search = Features::factory()->get_registered_feature( 'search' );
- $post_types = $search->get_searchable_post_types();
-
- foreach ( $post_types as $post_type ) {
- // This also ensures the string is safe, since this would return false otherwise
- if ( ! post_type_exists( $post_type ) ) {
- continue;
- }
-
- /** override default post_type settings while saving */
- $new_config[ $post_type ] = array();
-
- if ( isset( $settings['weighting'][ $post_type ] ) ) {
- foreach ( $settings['weighting'][ $post_type ] as $weighting_field => $weighting_values ) {
- $new_config[ $post_type ][ sanitize_text_field( $weighting_field ) ] = [
- 'weight' => isset( $weighting_values['weight'] ) ? intval( $weighting_values['weight'] ) : 0,
- 'enabled' => isset( $weighting_values['enabled'] ) && 'on' === $weighting_values['enabled'] ? true : false,
- ];
- }
- }
- }
-
- $final_config = array_replace_recursive( $previous_config_formatted, $new_config );
-
- update_option( 'elasticpress_weighting', $final_config );
-
- /**
- * Fires right after the weighting configuration is saved.
- *
- * @since 3.5.x
- * @hook ep_saved_weighting_configuration
- */
- do_action( 'ep_saved_weighting_configuration' );
-
- return $final_config;
}
/**
@@ -508,16 +433,24 @@ public function update_weighting( $request = null ) {
$weighting = $request->get_json_params();
/**
- * If metadata is not being managed manually, remove any metadata
- * fields that do not belong to the metadata group from the weighting
- * configuration.
+ * If metadata is not being managed manually, remove any custom
+ * fields that have not been registered as weightable fields.
*/
if ( 'manual' !== $meta_mode ) {
foreach ( $weighting as $post_type => $fields ) {
$weightable_fields = $this->get_weightable_fields_for_post_type( $post_type );
foreach ( $fields as $key => $value ) {
- if ( isset( $weightable_fields['ep_metadata']['children'][ $key ] ) ) {
+ $is_weightable = false;
+
+ foreach ( $weightable_fields as $group ) {
+ if ( isset( $group['children'][ $key ] ) ) {
+ $is_weightable = true;
+ continue;
+ }
+ }
+
+ if ( ! $is_weightable ) {
unset( $weighting[ $post_type ][ $key ] );
}
}
From 0661a10397f064984d1363eeb9910c809ae376b8 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 12 Sep 2023 22:43:04 +1000
Subject: [PATCH 41/63] Update @since versions.
---
includes/classes/Feature/Search/Weighting.php | 22 +++++++++++--------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index a86c88cf82..ef412c020b 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -37,10 +37,9 @@ public function setup() {
}
add_action( 'admin_menu', [ $this, 'add_weighting_submenu_page' ], 15 );
- add_action( 'admin_post_ep-weighting', [ $this, 'handle_save' ] );
- add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
add_filter( 'ep_formatted_args', [ $this, 'do_weighting' ], 20, 2 ); // After date decay, etc are injected
add_filter( 'ep_query_weighting_fields', [ $this, 'adjust_weight_for_cross_fields' ], 10, 5 );
+ add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
}
/**
@@ -274,7 +273,7 @@ public function get_weighting_configuration() {
* missing fields.
*
* @return array Current weighting configuration with defaults.
- * @since 4.4.0
+ * @since 5.0.0
*/
public function get_weighting_configuration_with_defaults() {
$search = Features::factory()->get_registered_feature( 'search' );
@@ -346,11 +345,12 @@ public function render_settings_page() {
}
/**
- * DEPRECATED. Recursively renders each settings section and its children.
+ * Recursively renders each settings section and its children.
*
* @param string $post_type Current post type we're rendering
* @param array $field Current field to render
* @param array $current_values Current stored weighting values
+ * @deprecated
*/
public function render_settings_section( $post_type, $field, $current_values ) {
_doing_it_wrong(
@@ -361,8 +361,10 @@ public function render_settings_section( $post_type, $field, $current_values ) {
}
/**
- * DEPRECATED. Handles processing the new weighting values and saving them
+ * Handles processing the new weighting values and saving them
* to the elasticpress.io service.
+ *
+ * @deprecated
*/
public function handle_save() {
_doing_it_wrong(
@@ -373,9 +375,10 @@ public function handle_save() {
}
/**
- * DEPRECATED. We need this method to test handle_save properly.
+ * We need this method to test handle_save properly.
*
* @param string $redirect_url Redirect URL.
+ * @deprecated
*/
protected function redirect( $redirect_url ) {
_doing_it_wrong(
@@ -386,12 +389,12 @@ protected function redirect( $redirect_url ) {
}
/**
- * DEPRECATED. Save weighting configuration for each searchable post_type.
+ * Save weighting configuration for each searchable post_type.
*
* @param array $settings weighting settings
- *
* @return void
* @since 3.4.1
+ * @deprecated
*/
public function save_weighting_configuration( $settings ) {
_doing_it_wrong(
@@ -405,7 +408,7 @@ public function save_weighting_configuration( $settings ) {
* Register REST routes.
*
* @return void
- * @since 4.4.0
+ * @since 5.0.0
*/
public function register_rest_routes() {
register_rest_route(
@@ -427,6 +430,7 @@ public function register_rest_routes() {
*
* @param \WP_Rest_Request $request REST API request.
* @return void
+ * @since 5.0.0
*/
public function update_weighting( $request = null ) {
$meta_mode = $this->get_meta_mode();
From 3c5c48a71d73ba7ce9f4965345fc041074bf8cb7 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 12 Sep 2023 22:50:56 +1000
Subject: [PATCH 42/63] Fix PHPCS issues. Remove redundant test.
---
tests/php/indexables/TestPost.php | 50 ++++---------------------------
1 file changed, 6 insertions(+), 44 deletions(-)
diff --git a/tests/php/indexables/TestPost.php b/tests/php/indexables/TestPost.php
index d70fe898c7..2b1e2b74de 100644
--- a/tests/php/indexables/TestPost.php
+++ b/tests/php/indexables/TestPost.php
@@ -3878,21 +3878,24 @@ public function testPrepareMetaManual() {
// Set default weighting
$weighting_default = $weighting->get_weighting_configuration_with_defaults();
+
$set_default_weighting = function() use ( $weighting_default ) {
return $weighting_default;
};
+
add_filter( 'ep_weighting_configuration', $set_default_weighting );
$post_id = $this->ep_factory->post->create(
[
'meta_input' => [
- 'test_meta_1' => 'value 1',
- 'test_meta_2' => 'value 2',
+ 'test_meta_1' => 'value 1',
+ 'test_meta_2' => 'value 2',
'_test_private_meta_1' => 'private value 1',
'_test_private_meta_2' => 'private value 2',
- ]
+ ],
]
);
+
$post = get_post( $post_id );
$prepared_meta = ElasticPress\Indexables::factory()->get( 'post' )->prepare_meta( $post );
@@ -8088,47 +8091,6 @@ public function testGetAllDistinctValues() {
}
/**
- * Tests get_distinct_meta_field_keys_db
- *
- * @return void
- * @group post
- */
- public function testGetDistinctMetaFieldKeysDb() {
- global $wpdb;
-
- $indexable = \ElasticPress\Indexables::factory()->get( 'post' );
-
- $meta_keys = $wpdb->get_col( "SELECT DISTINCT meta_key FROM {$wpdb->postmeta} ORDER BY meta_key" );
- $this->assertSame( $meta_keys, $indexable->get_distinct_meta_field_keys_db() );
-
- /**
- * Test the `ep_post_pre_meta_keys_db` filter
- */
- $return_custom_array = function() {
- return [ 'totally_custom_key' ];
- };
- add_filter( 'ep_post_pre_meta_keys_db', $return_custom_array );
-
- $num_queries = $wpdb->num_queries;
- $this->assertGreaterThan( 0, $num_queries );
-
- $this->assertSame( [ 'totally_custom_key' ], $indexable->get_distinct_meta_field_keys_db() );
- $this->assertSame( $num_queries, $wpdb->num_queries );
-
- remove_filter( 'ep_post_pre_meta_keys_db', $return_custom_array );
-
- /**
- * Test the `ep_post_pre_meta_keys_db` filter
- */
- $return_custom_array = function( $meta_keys ) {
- return array_merge( $meta_keys, [ 'custom_key' ] );
- };
- add_filter( 'ep_post_meta_keys_db', $return_custom_array );
-
- $this->assertSame( array_merge( $meta_keys, [ 'custom_key' ] ), $indexable->get_distinct_meta_field_keys_db() );
- }
-
- /*
* Tests search term wrapped in html tags.
*/
public function testHighlightTags() {
From 38aecdb55e58a6b319eeaada831bccea58c98808 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 12 Sep 2023 23:07:24 +1000
Subject: [PATCH 43/63] Update custom field test.
---
tests/cypress/integration/features/search/weighting.cy.js | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/tests/cypress/integration/features/search/weighting.cy.js b/tests/cypress/integration/features/search/weighting.cy.js
index 68b127aa19..bf5d34af97 100644
--- a/tests/cypress/integration/features/search/weighting.cy.js
+++ b/tests/cypress/integration/features/search/weighting.cy.js
@@ -225,11 +225,9 @@ describe('Post Search Feature - Weighting Functionality', () => {
.closest('fieldset')
.find('input[type="number"]')
.clearThenType(100);
- cy.get('@panel')
- .find('select')
- .should('contain', '_my_custom_field')
- .select('_my_custom_field');
- cy.get('@panel').find('button').contains('Add field').click();
+ cy.get('@panel').find('button').contains('Metadata').click();
+ cy.get('@panel').find('input[type="text"]').clearThenType('_my_custom_field');
+ cy.get('@panel').find('button').contains('Add').click();
cy.get('@panel')
.find('fieldset')
.contains('_my_custom_field')
From 5ce47263d3b6e5d486cfaac5ee557cf2cd360f2d Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Wed, 13 Sep 2023 02:15:56 +1000
Subject: [PATCH 44/63] Only show custom fields for relevant post types.
---
includes/classes/Feature/Search/Weighting.php | 4 ++++
includes/classes/Feature/WooCommerce/Orders.php | 11 ++++++++---
includes/classes/Feature/WooCommerce/Products.php | 11 ++++++++---
3 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index ef412c020b..039d2517a9 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -108,9 +108,13 @@ public function get_weightable_fields_for_post_type( $post_type ) {
$empty_post = new \WP_Post( new \stdClass() );
+ $empty_post->post_type = $post_type;
+
/** This filter is documented in includes/classes/Indexable/Post/Post.php */
$allowed_protected_keys = apply_filters( 'ep_prepare_meta_allowed_protected_keys', [], $empty_post );
+ sort( $allowed_protected_keys, SORT_STRING );
+
/** This filter is documented in includes/classes/Indexable/Post/Post.php */
$excluded_public_keys = apply_filters( 'ep_prepare_meta_excluded_public_keys', [], $empty_post );
diff --git a/includes/classes/Feature/WooCommerce/Orders.php b/includes/classes/Feature/WooCommerce/Orders.php
index e44ca2a249..f3fcad1b4e 100644
--- a/includes/classes/Feature/WooCommerce/Orders.php
+++ b/includes/classes/Feature/WooCommerce/Orders.php
@@ -39,7 +39,7 @@ public function __construct( WooCommerce $woocommerce ) {
*/
public function setup() {
add_filter( 'ep_sync_insert_permissions_bypass', [ $this, 'bypass_order_permissions_check' ], 10, 2 );
- add_filter( 'ep_prepare_meta_allowed_protected_keys', [ $this, 'allow_meta_keys' ] );
+ add_filter( 'ep_prepare_meta_allowed_protected_keys', [ $this, 'allow_meta_keys' ], 10, 2 );
add_filter( 'ep_post_sync_args_post_prepare_meta', [ $this, 'add_order_items_search' ], 20, 2 );
add_filter( 'ep_pc_skip_post_content_cleanup', [ $this, 'keep_order_fields' ], 20, 2 );
add_action( 'parse_query', [ $this, 'maybe_hook_woocommerce_search_fields' ], 1 );
@@ -86,10 +86,15 @@ public function get_admin_searchable_post_types() {
/**
* Index WooCommerce orders meta fields
*
- * @param array $meta Existing post meta
+ * @param array $meta Existing post meta
+ * @param \WP_Post $post Post object.
* @return array
*/
- public function allow_meta_keys( $meta ) {
+ public function allow_meta_keys( $meta, $post ) {
+ if ( ! in_array( $post->post_type, [ 'shop_order', 'shop_order_refund' ], true ) ) {
+ return $meta;
+ }
+
return array_unique(
array_merge(
$meta,
diff --git a/includes/classes/Feature/WooCommerce/Products.php b/includes/classes/Feature/WooCommerce/Products.php
index ed501ebd60..45e92f0939 100644
--- a/includes/classes/Feature/WooCommerce/Products.php
+++ b/includes/classes/Feature/WooCommerce/Products.php
@@ -41,7 +41,7 @@ public function __construct( WooCommerce $woocommerce ) {
*/
public function setup() {
add_action( 'ep_formatted_args', [ $this, 'price_filter' ], 10, 3 );
- add_filter( 'ep_prepare_meta_allowed_protected_keys', [ $this, 'allow_meta_keys' ] );
+ add_filter( 'ep_prepare_meta_allowed_protected_keys', [ $this, 'allow_meta_keys' ], 10, 2 );
add_filter( 'ep_sync_taxonomies', [ $this, 'sync_taxonomies' ] );
add_filter( 'ep_term_suggest_post_type', [ $this, 'suggest_wc_add_post_type' ] );
add_filter( 'ep_facet_include_taxonomies', [ $this, 'add_product_attributes' ] );
@@ -128,10 +128,15 @@ public function price_filter( $args, $query_args, $query ) {
/**
* Index WooCommerce products meta fields
*
- * @param array $meta Existing post meta
+ * @param array $meta Existing post meta
+ * @param \WP_Post $post Post object.
* @return array
*/
- public function allow_meta_keys( $meta ) {
+ public function allow_meta_keys( $meta, $post ) {
+ if ( 'product' !== $post->post_type ) {
+ return $meta;
+ }
+
return array_unique(
array_merge(
$meta,
From aee10b27bf779faf89ca56e5d5be9cf05f9b288f Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Wed, 13 Sep 2023 02:16:10 +1000
Subject: [PATCH 45/63] Remove undo functionality.
---
assets/js/weighting/components/actions.js | 21 ++------
.../components/common/delete-button.js | 25 ----------
.../components/common/undo-button.js | 21 --------
assets/js/weighting/components/field.js | 49 +++----------------
assets/js/weighting/provider.js | 29 +----------
package.json | 1 -
6 files changed, 12 insertions(+), 134 deletions(-)
delete mode 100644 assets/js/weighting/components/common/delete-button.js
delete mode 100644 assets/js/weighting/components/common/undo-button.js
diff --git a/assets/js/weighting/components/actions.js b/assets/js/weighting/components/actions.js
index ad3ac95329..32979d0778 100644
--- a/assets/js/weighting/components/actions.js
+++ b/assets/js/weighting/components/actions.js
@@ -4,7 +4,6 @@
import { Button } from '@wordpress/components';
import { WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
-import { undo } from '@wordpress/icons';
import { useWeighting } from '../provider';
/**
@@ -13,26 +12,14 @@ import { useWeighting } from '../provider';
* @returns {WPElement} Component element.
*/
export default () => {
- const { isBusy, isChanged, reset } = useWeighting();
+ const { isBusy } = useWeighting();
/**
* Render.
*/
return (
- <>
-
- {__('Save Changes', 'elasticpress')}
-
-
-
- {__('Undo All Changes', 'elasticpress')}
-
- >
+
+ {__('Save Changes', 'elasticpress')}
+
);
};
diff --git a/assets/js/weighting/components/common/delete-button.js b/assets/js/weighting/components/common/delete-button.js
deleted file mode 100644
index 528ec2dfd8..0000000000
--- a/assets/js/weighting/components/common/delete-button.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Button } from '@wordpress/components';
-import { WPElement } from '@wordpress/element';
-import { trash } from '@wordpress/icons';
-
-/**
- * Undo button component.
- *
- * @param {object} props Component props.
- * @returns {WPElement} Component element.
- */
-export default (props) => {
- /**
- * Render.
- */
- return (
-
- );
-};
diff --git a/assets/js/weighting/components/common/undo-button.js b/assets/js/weighting/components/common/undo-button.js
deleted file mode 100644
index 4188839cdb..0000000000
--- a/assets/js/weighting/components/common/undo-button.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Button } from '@wordpress/components';
-import { WPElement } from '@wordpress/element';
-import { undo } from '@wordpress/icons';
-
-/**
- * Undo button component.
- *
- * @param {object} props Component props.
- * @returns {WPElement} Component element.
- */
-export default (props) => {
- /**
- * Render.
- */
- return (
-
- );
-};
diff --git a/assets/js/weighting/components/field.js b/assets/js/weighting/components/field.js
index 5e4d93d795..8477456aa9 100644
--- a/assets/js/weighting/components/field.js
+++ b/assets/js/weighting/components/field.js
@@ -1,16 +1,10 @@
/**
* WordPress Dependencies.
*/
-import { CheckboxControl, RangeControl } from '@wordpress/components';
-import { useMemo, useState, WPElement } from '@wordpress/element';
+import { Button, CheckboxControl, RangeControl } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
-import { isEqual } from 'lodash';
-
-/**
- * Internal dependencies.
- */
-import DeleteButton from './common/delete-button';
-import UndoButton from './common/undo-button';
+import { trash } from '@wordpress/icons';
/**
* Field settings component.
@@ -25,19 +19,6 @@ import UndoButton from './common/undo-button';
export default ({ label, onChange, onDelete, value }) => {
const { enabled = false, weight = 0 } = value;
- /**
- * State.
- */
- const [originalValue] = useState(value);
-
- /**
- * Is the current value different to the original.
- */
- const isChanged = useMemo(
- () => !originalValue || !isEqual(originalValue, value),
- [originalValue, value],
- );
-
/**
* Handle change of searchable.
*
@@ -58,19 +39,6 @@ export default ({ label, onChange, onDelete, value }) => {
onChange({ enabled: true, weight });
};
- /**
- * Handle clicking undo.
- *
- * @returns {void}
- */
- const onReset = () => {
- if (originalValue) {
- onChange(originalValue);
- } else if (onDelete) {
- onDelete();
- }
- };
-
/**
* Render.
*/
@@ -95,14 +63,11 @@ export default ({ label, onChange, onDelete, value }) => {
value={weight}
/>
-
-
-
+
diff --git a/assets/js/weighting/provider.js b/assets/js/weighting/provider.js
index d5db4518f5..6c2dcf00af 100644
--- a/assets/js/weighting/provider.js
+++ b/assets/js/weighting/provider.js
@@ -5,7 +5,6 @@ import apiFetch from '@wordpress/api-fetch';
import { withNotices } from '@wordpress/components';
import { createContext, WPElement, useContext, useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
-import { isEqual } from 'lodash';
/**
* Instant Results context.
@@ -38,20 +37,8 @@ const WeightingProvider = ({
...weightingConfiguration,
});
- const [savedWeightingConfiguration, setSavedWeightingConfiguration] = useState({
- ...weightingConfiguration,
- });
-
const [isBusy, setIsBusy] = useState(false);
- /**
- * Is the current data different to the saved data.
- */
- const isChanged = useMemo(
- () => !isEqual(currentWeightingConfiguration, savedWeightingConfiguration),
- [currentWeightingConfiguration, savedWeightingConfiguration],
- );
-
/**
* Whether to show weighting for metadata.
*/
@@ -71,15 +58,6 @@ const WeightingProvider = ({
});
};
- /**
- * Handle resetting all settings.
- *
- * @returns {void}
- */
- const reset = () => {
- setCurrentWeightingConfiguration({ ...savedWeightingConfiguration });
- };
-
/**
* Save settings.
*
@@ -89,7 +67,7 @@ const WeightingProvider = ({
try {
setIsBusy(true);
- const response = await apiFetch({
+ await apiFetch({
body: JSON.stringify(currentWeightingConfiguration),
headers: {
'Content-Type': 'application/json',
@@ -98,8 +76,6 @@ const WeightingProvider = ({
url: apiUrl,
});
- setSavedWeightingConfiguration(response.data);
-
noticeOperations.createNotice({
content: __('Search fields & weighting saved.', 'elasticpress'),
status: 'success',
@@ -120,13 +96,10 @@ const WeightingProvider = ({
const contextValue = {
currentWeightingConfiguration,
isBusy,
- isChanged,
isManual,
noticeOperations,
noticeUI,
- reset,
save,
- savedWeightingConfiguration,
setWeightingForPostType,
weightableFields,
};
diff --git a/package.json b/package.json
index 1e62a194e5..bb0223fefb 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,6 @@
"husky": "^8.0.3",
"jsdoc": "^3.6.10",
"lint-staged": "^13.2.0",
- "lodash": "^4.17.21",
"postcss-preset-env": "^7.0.1",
"terser-webpack-plugin": "^5.3.0",
"wp-hookdoc": "^0.2.0"
From 06ed936cdb9519743b559bced5bc7f3de43b5de6 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Wed, 13 Sep 2023 20:40:03 +1000
Subject: [PATCH 46/63] Add notices. Tweak styles.
---
assets/css/weighting.css | 12 +++++
assets/css/weighting/add-new.css | 5 +-
assets/css/weighting/field.css | 10 +++-
assets/css/weighting/screen.css | 2 +
assets/js/weighting/apps/settings-page.js | 64 ++++++++++++++---------
assets/js/weighting/components/group.js | 30 ++++++++++-
assets/js/weighting/provider.js | 37 +++++--------
7 files changed, 104 insertions(+), 56 deletions(-)
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
index b97b9014e8..ab8ed3e6eb 100644
--- a/assets/css/weighting.css
+++ b/assets/css/weighting.css
@@ -6,3 +6,15 @@
html.wp-toolbar {
background: transparent;
}
+
+.components-snackbar-list {
+ bottom: 40px;
+ left: 0;
+ padding: 0 16px;
+ position: fixed;
+
+ @media (min-width: 600px) {
+ left: auto;
+ padding: 0;
+ }
+}
diff --git a/assets/css/weighting/add-new.css b/assets/css/weighting/add-new.css
index 88e9c45482..7a1845885e 100644
--- a/assets/css/weighting/add-new.css
+++ b/assets/css/weighting/add-new.css
@@ -1,7 +1,10 @@
.ep-weighting-add-new {
+ align-items: flex-end;
+ gap: 4px;
justify-content: start;
+ margin-top: 16px;
- & .components-base-control .components-select-control .components-select-control__input {
+ & .components-base-control .components-text-control__input {
min-height: 36px;
}
}
diff --git a/assets/css/weighting/field.css b/assets/css/weighting/field.css
index 5b1e648563..f3f42e332b 100644
--- a/assets/css/weighting/field.css
+++ b/assets/css/weighting/field.css
@@ -33,9 +33,15 @@
}
@media ( max-width: 600px ) {
+ grid-template-columns: 1fr 1fr 1fr max-content;
- & .components-range-control__wrapper {
- display: none;
+ & .ep-weighting-field__weighting {
+ display: flex;
+ justify-content: end;
+
+ & .components-range-control__wrapper {
+ display: none;
+ }
}
}
}
diff --git a/assets/css/weighting/screen.css b/assets/css/weighting/screen.css
index 9298f73a80..cf6e71a9c8 100644
--- a/assets/css/weighting/screen.css
+++ b/assets/css/weighting/screen.css
@@ -1,4 +1,6 @@
.ep-weighting-screen {
+ margin-left: auto;
+ margin-right: auto;
max-width: 800px;
& .components-panel {
diff --git a/assets/js/weighting/apps/settings-page.js b/assets/js/weighting/apps/settings-page.js
index 1e302b380e..2ce947e6c7 100644
--- a/assets/js/weighting/apps/settings-page.js
+++ b/assets/js/weighting/apps/settings-page.js
@@ -1,8 +1,11 @@
/**
* WordPress dependencies.
*/
+import { SnackbarList } from '@wordpress/components';
+import { useDispatch, useSelect } from '@wordpress/data';
import { WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
+import { store as noticeStore } from '@wordpress/notices';
/**
* Internal Dependencies.
@@ -17,7 +20,15 @@ import { useWeighting } from '../provider';
* @returns {WPElement} Element.
*/
export default () => {
- const { noticeUI, save, weightableFields } = useWeighting();
+ const { removeNotice } = useDispatch(noticeStore);
+
+ const { notices } = useSelect((select) => {
+ return {
+ notices: select(noticeStore).getNotices(),
+ };
+ }, []);
+
+ const { save, weightableFields } = useWeighting();
/**
* Submit event.
@@ -30,31 +41,32 @@ export default () => {
save();
};
- /**
- * Render.
- */
return (
-
- {__('Manage Search Fields & Weighting', 'elasticpress')}
- {noticeUI}
-
-
- {__(
- 'This dashboard enables you to select which fields ElasticPress should sync, whether to use those fields in searches, and how heavily to weight fields in the search algorithm. In general, increasing the Weight of a field will increase the relevancy score of a post that has matching text in that field.',
- 'elasticpress',
- )}
-
-
- {__(
- 'For example, adding more weight to the title attribute will cause search matches on the post title to appear more prominently.',
- 'elasticpress',
- )}
-
-
- {weightableFields.map(({ key }) => {
- return ;
- })}
-
-
+ <>
+
+
+ {__('Manage Search Fields & Weighting', 'elasticpress')}
+
+
+
+ {__(
+ 'This dashboard enables you to select which fields ElasticPress should sync, whether to use those fields in searches, and how heavily to weight fields in the search algorithm. In general, increasing the Weight of a field will increase the relevancy score of a post that has matching text in that field.',
+ 'elasticpress',
+ )}
+
+
+ {__(
+ 'For example, adding more weight to the title attribute will cause search matches on the post title to appear more prominently.',
+ 'elasticpress',
+ )}
+
+
+ {weightableFields.map(({ key }) => {
+ return ;
+ })}
+
+
+ removeNotice(notice)} />
+ >
);
};
diff --git a/assets/js/weighting/components/group.js b/assets/js/weighting/components/group.js
index fbd3a6c863..b4a2b4649d 100644
--- a/assets/js/weighting/components/group.js
+++ b/assets/js/weighting/components/group.js
@@ -2,8 +2,10 @@
* WordPress dependencies.
*/
import { Button, PanelRow, TextControl } from '@wordpress/components';
+import { useDispatch } from '@wordpress/data';
import { useMemo, useState, WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
+import { __, sprintf } from '@wordpress/i18n';
+import { store as noticeStore } from '@wordpress/notices';
/**
* Internal dependencies.
@@ -20,6 +22,8 @@ import { useWeighting } from '../provider';
* @returns {WPElement} Component element.
*/
export default ({ group, postType }) => {
+ const { createNotice } = useDispatch(noticeStore);
+
const { currentWeightingConfiguration, setWeightingForPostType, weightableFields } =
useWeighting();
@@ -100,6 +104,15 @@ export default ({ group, postType }) => {
*/
const onClick = () => {
const key = `meta.${toAdd}.value`;
+
+ const isDefaultField = defaultFields.some((f) => f.key === key);
+ const isCustomField = customFields.some((f) => f.key === key);
+
+ if (isDefaultField || isCustomField) {
+ createNotice('info', sprintf(__('%s is already being synced.', 'elasticpress'), toAdd));
+ return;
+ }
+
const newValues = { ...values, [key]: { enabled: false, weight: 0 } };
setWeightingForPostType(postType, newValues);
@@ -120,6 +133,18 @@ export default ({ group, postType }) => {
setWeightingForPostType(postType, newValues);
};
+ /**
+ * Handle pressing Enter key when adding a field.
+ *
+ * @param {Event} event Keydown event.
+ */
+ const onKeyDown = (event) => {
+ if (event.key === 'Enter') {
+ event.preventDefault();
+ onClick();
+ }
+ };
+
return (
<>
{defaultFields.map(({ key, label }) => (
@@ -150,8 +175,9 @@ export default ({ group, postType }) => {
{isMetadata ? (
setToAdd(toAdd)}
+ onKeyDown={onKeyDown}
placeholder={__('Metadata key', 'elasticpress')}
value={toAdd}
/>
diff --git a/assets/js/weighting/provider.js b/assets/js/weighting/provider.js
index 6c2dcf00af..0862ed800b 100644
--- a/assets/js/weighting/provider.js
+++ b/assets/js/weighting/provider.js
@@ -2,9 +2,10 @@
* WordPress dependencies.
*/
import apiFetch from '@wordpress/api-fetch';
-import { withNotices } from '@wordpress/components';
+import { useDispatch } from '@wordpress/data';
import { createContext, WPElement, useContext, useMemo, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
+import { store as noticeStore } from '@wordpress/notices';
/**
* Instant Results context.
@@ -18,21 +19,13 @@ const Context = createContext();
* @param {string} props.apiUrl API URL.
* @param {Function} props.children Component children.
* @param {'auto'|'manual'} props.metaMode Metadata management mode.
- * @param {object} props.noticeOperations Notice operations from withNotices.
- * @param {WPElement} props.noticeUI Notice UI from withNotices.
* @param {object} props.weightableFields Weightable fields, indexed by post type.
* @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
* @returns {WPElement} Element.
*/
-const WeightingProvider = ({
- apiUrl,
- children,
- metaMode,
- noticeOperations,
- noticeUI,
- weightableFields,
- weightingConfiguration,
-}) => {
+export default ({ apiUrl, children, metaMode, weightableFields, weightingConfiguration }) => {
+ const { createNotice } = useDispatch(noticeStore);
+
const [currentWeightingConfiguration, setCurrentWeightingConfiguration] = useState({
...weightingConfiguration,
});
@@ -76,18 +69,16 @@ const WeightingProvider = ({
url: apiUrl,
});
- noticeOperations.createNotice({
- content: __('Search fields & weighting saved.', 'elasticpress'),
- status: 'success',
+ createNotice('success', __('Settings saved.', 'elasticpress'), {
+ isDismissible: true,
});
- } catch {
- noticeOperations.createNotice({
- content: __('Whoops! Something went wrong. Please try again.', 'elasticpress'),
- status: 'error',
+ } catch (e) {
+ console.error(e); // eslint-disable-line no-console
+
+ createNotice('error', __('Something went wrong. Please try again.', 'elasticpress'), {
+ isDismissible: true,
});
} finally {
- document.body.scrollIntoView({ behavior: 'smooth' });
-
setIsBusy(false);
}
};
@@ -97,8 +88,6 @@ const WeightingProvider = ({
currentWeightingConfiguration,
isBusy,
isManual,
- noticeOperations,
- noticeUI,
save,
setWeightingForPostType,
weightableFields,
@@ -110,8 +99,6 @@ const WeightingProvider = ({
return {children} ;
};
-export default withNotices(WeightingProvider);
-
/**
* Use the API Search context.
*
From bf5ea7fc3423ea89aa2e0b43a43031982c84e922 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Sat, 16 Sep 2023 04:50:37 +1000
Subject: [PATCH 47/63] Ensure custom results taxonomy is not public.
---
includes/classes/Feature/Search/Weighting.php | 2 +-
includes/classes/Feature/SearchOrdering/SearchOrdering.php | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 039d2517a9..06d02e3376 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -84,7 +84,7 @@ public function get_weightable_fields_for_post_type( $post_type ) {
$taxonomies = array_intersect( $public_taxonomies, $post_type_taxonomies );
- if ( $taxonomies ) {
+ if ( ! empty( $taxonomies ) ) {
$fields['taxonomies'] = [
'label' => __( 'Taxonomies', 'elasticpress' ),
'children' => [],
diff --git a/includes/classes/Feature/SearchOrdering/SearchOrdering.php b/includes/classes/Feature/SearchOrdering/SearchOrdering.php
index 33529ed924..45bd8ea880 100644
--- a/includes/classes/Feature/SearchOrdering/SearchOrdering.php
+++ b/includes/classes/Feature/SearchOrdering/SearchOrdering.php
@@ -334,6 +334,7 @@ public function register_post_type() {
'show_admin_column' => false,
'query_var' => false,
'rewrite' => false,
+ 'public' => false,
);
/** Features Class @var Features $features */
From 1d09602936e2633060ba9d447d14efe4abe54b65 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Sat, 16 Sep 2023 05:12:56 +1000
Subject: [PATCH 48/63] Small tweaks.
---
assets/css/weighting.css | 1 +
assets/css/weighting/field.css | 2 +-
assets/css/weighting/post-type.css | 6 +++++
assets/js/weighting/apps/settings-page.js | 15 ++++++-------
assets/js/weighting/components/actions.js | 25 ---------------------
assets/js/weighting/components/post-type.js | 7 +-----
6 files changed, 16 insertions(+), 40 deletions(-)
create mode 100644 assets/css/weighting/post-type.css
delete mode 100644 assets/js/weighting/components/actions.js
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
index ab8ed3e6eb..a37f356d0a 100644
--- a/assets/css/weighting.css
+++ b/assets/css/weighting.css
@@ -1,6 +1,7 @@
@import "weighting/action.css";
@import "weighting/add-new.css";
@import "weighting/field.css";
+@import "weighting/post-type.css";
@import "weighting/screen.css";
html.wp-toolbar {
diff --git a/assets/css/weighting/field.css b/assets/css/weighting/field.css
index f3f42e332b..3d6d208436 100644
--- a/assets/css/weighting/field.css
+++ b/assets/css/weighting/field.css
@@ -56,7 +56,7 @@
white-space: nowrap;
& h2 {
- margin: 0;
+ font-size: 1rem;
}
}
diff --git a/assets/css/weighting/post-type.css b/assets/css/weighting/post-type.css
new file mode 100644
index 0000000000..5a4a19f8d5
--- /dev/null
+++ b/assets/css/weighting/post-type.css
@@ -0,0 +1,6 @@
+.ep-weighting-post-type {
+
+ & .components-panel__header h2 {
+ font-size: 1rem;
+ }
+}
diff --git a/assets/js/weighting/apps/settings-page.js b/assets/js/weighting/apps/settings-page.js
index 2ce947e6c7..613a4ee603 100644
--- a/assets/js/weighting/apps/settings-page.js
+++ b/assets/js/weighting/apps/settings-page.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies.
*/
-import { SnackbarList } from '@wordpress/components';
+import { Button, SnackbarList } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { WPElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
@@ -10,7 +10,6 @@ import { store as noticeStore } from '@wordpress/notices';
/**
* Internal Dependencies.
*/
-import Actions from '../components/actions';
import PostType from '../components/post-type';
import { useWeighting } from '../provider';
@@ -28,7 +27,7 @@ export default () => {
};
}, []);
- const { save, weightableFields } = useWeighting();
+ const { isBusy, save, weightableFields } = useWeighting();
/**
* Submit event.
@@ -44,10 +43,8 @@ export default () => {
return (
<>
-
- {__('Manage Search Fields & Weighting', 'elasticpress')}
-
-
+
{__('Manage Search Fields & Weighting', 'elasticpress')}
+
{__(
'This dashboard enables you to select which fields ElasticPress should sync, whether to use those fields in searches, and how heavily to weight fields in the search algorithm. In general, increasing the Weight of a field will increase the relevancy score of a post that has matching text in that field.',
@@ -64,7 +61,9 @@ export default () => {
{weightableFields.map(({ key }) => {
return ;
})}
-
+
+ {__('Save Changes', 'elasticpress')}
+
removeNotice(notice)} />
>
diff --git a/assets/js/weighting/components/actions.js b/assets/js/weighting/components/actions.js
deleted file mode 100644
index 32979d0778..0000000000
--- a/assets/js/weighting/components/actions.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Button } from '@wordpress/components';
-import { WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { useWeighting } from '../provider';
-
-/**
- * Actions component.
- *
- * @returns {WPElement} Component element.
- */
-export default () => {
- const { isBusy } = useWeighting();
-
- /**
- * Render.
- */
- return (
-
- {__('Save Changes', 'elasticpress')}
-
- );
-};
diff --git a/assets/js/weighting/components/post-type.js b/assets/js/weighting/components/post-type.js
index c0f0471e77..b1e7b16931 100644
--- a/assets/js/weighting/components/post-type.js
+++ b/assets/js/weighting/components/post-type.js
@@ -28,12 +28,7 @@ export default ({ postType }) => {
return (
-
+ {label}
{groups.map(({ key, label }) => {
const isMetadata = key === 'ep_metadata';
From b29937ba38a432cc7b6a95d11f7fddab6c743b32 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Thu, 28 Sep 2023 08:37:47 +1000
Subject: [PATCH 49/63] Implement SettingsScreenProvider for weighting
settings.
---
assets/css/weighting.css | 21 ------
assets/css/weighting/post-type.css | 6 --
assets/js/sync-ui/index.js | 30 ++++----
assets/js/weighting/apps/settings-page.js | 71 -------------------
assets/js/weighting/apps/weighting.js | 64 +++++++++++++++++
assets/js/weighting/components/group.js | 10 ++-
assets/js/weighting/components/post-type.js | 4 +-
.../weighting => js/weighting/css}/action.css | 0
.../weighting/css}/add-new.css | 0
.../weighting => js/weighting/css}/field.css | 0
.../weighting/css/post-type.css} | 10 ++-
assets/js/weighting/index.js | 31 +++++---
assets/js/weighting/provider.js | 28 +++-----
assets/js/weighting/style.css | 4 ++
includes/dashboard.php | 7 +-
package.json | 1 -
16 files changed, 129 insertions(+), 158 deletions(-)
delete mode 100644 assets/css/weighting.css
delete mode 100644 assets/css/weighting/post-type.css
delete mode 100644 assets/js/weighting/apps/settings-page.js
create mode 100644 assets/js/weighting/apps/weighting.js
rename assets/{css/weighting => js/weighting/css}/action.css (100%)
rename assets/{css/weighting => js/weighting/css}/add-new.css (100%)
rename assets/{css/weighting => js/weighting/css}/field.css (100%)
rename assets/{css/weighting/screen.css => js/weighting/css/post-type.css} (70%)
create mode 100644 assets/js/weighting/style.css
diff --git a/assets/css/weighting.css b/assets/css/weighting.css
deleted file mode 100644
index a37f356d0a..0000000000
--- a/assets/css/weighting.css
+++ /dev/null
@@ -1,21 +0,0 @@
-@import "weighting/action.css";
-@import "weighting/add-new.css";
-@import "weighting/field.css";
-@import "weighting/post-type.css";
-@import "weighting/screen.css";
-
-html.wp-toolbar {
- background: transparent;
-}
-
-.components-snackbar-list {
- bottom: 40px;
- left: 0;
- padding: 0 16px;
- position: fixed;
-
- @media (min-width: 600px) {
- left: auto;
- padding: 0;
- }
-}
diff --git a/assets/css/weighting/post-type.css b/assets/css/weighting/post-type.css
deleted file mode 100644
index 5a4a19f8d5..0000000000
--- a/assets/css/weighting/post-type.css
+++ /dev/null
@@ -1,6 +0,0 @@
-.ep-weighting-post-type {
-
- & .components-panel__header h2 {
- font-size: 1rem;
- }
-}
diff --git a/assets/js/sync-ui/index.js b/assets/js/sync-ui/index.js
index a88a2051c2..a162a2b9bc 100644
--- a/assets/js/sync-ui/index.js
+++ b/assets/js/sync-ui/index.js
@@ -34,20 +34,24 @@ import './style.css';
* @returns {WPElement} App component.
*/
const App = () => (
-
-
-
+
+
+
-
-
-
+
+
+
);
if (typeof createRoot === 'function') {
diff --git a/assets/js/weighting/apps/settings-page.js b/assets/js/weighting/apps/settings-page.js
deleted file mode 100644
index 613a4ee603..0000000000
--- a/assets/js/weighting/apps/settings-page.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * WordPress dependencies.
- */
-import { Button, SnackbarList } from '@wordpress/components';
-import { useDispatch, useSelect } from '@wordpress/data';
-import { WPElement } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { store as noticeStore } from '@wordpress/notices';
-
-/**
- * Internal Dependencies.
- */
-import PostType from '../components/post-type';
-import { useWeighting } from '../provider';
-
-/**
- * Weighting settings app.
- *
- * @returns {WPElement} Element.
- */
-export default () => {
- const { removeNotice } = useDispatch(noticeStore);
-
- const { notices } = useSelect((select) => {
- return {
- notices: select(noticeStore).getNotices(),
- };
- }, []);
-
- const { isBusy, save, weightableFields } = useWeighting();
-
- /**
- * Submit event.
- *
- * @param {Event} event Submit event.
- */
- const onSubmit = (event) => {
- event.preventDefault();
-
- save();
- };
-
- return (
- <>
-
- {__('Manage Search Fields & Weighting', 'elasticpress')}
-
-
- {__(
- 'This dashboard enables you to select which fields ElasticPress should sync, whether to use those fields in searches, and how heavily to weight fields in the search algorithm. In general, increasing the Weight of a field will increase the relevancy score of a post that has matching text in that field.',
- 'elasticpress',
- )}
-
-
- {__(
- 'For example, adding more weight to the title attribute will cause search matches on the post title to appear more prominently.',
- 'elasticpress',
- )}
-
-
- {weightableFields.map(({ key }) => {
- return ;
- })}
-
- {__('Save Changes', 'elasticpress')}
-
-
- removeNotice(notice)} />
- >
- );
-};
diff --git a/assets/js/weighting/apps/weighting.js b/assets/js/weighting/apps/weighting.js
new file mode 100644
index 0000000000..b536a08ede
--- /dev/null
+++ b/assets/js/weighting/apps/weighting.js
@@ -0,0 +1,64 @@
+/**
+ * WordPress dependencies.
+ */
+import { Button } from '@wordpress/components';
+import { WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal Dependencies.
+ */
+import { useSettingsScreen } from '../../settings-screen';
+import PostType from '../components/post-type';
+import { useWeightingSettings } from '../provider';
+
+/**
+ * Weighting settings app.
+ *
+ * @returns {WPElement} Element.
+ */
+export default () => {
+ const { createNotice } = useSettingsScreen();
+ const { isBusy, save, weightableFields } = useWeightingSettings();
+
+ /**
+ * Submit event.
+ *
+ * @param {Event} event Submit event.
+ */
+ const onSubmit = async (event) => {
+ event.preventDefault();
+
+ try {
+ await save();
+ createNotice('success', __('Settings saved.', 'elasticpress'));
+ } catch (e) {
+ createNotice('error', __('Something went wrong. Please try again.', 'elasticpress'));
+ }
+ };
+
+ return (
+ <>
+
+ {__(
+ 'This dashboard enables you to select which fields ElasticPress should sync, whether to use those fields in searches, and how heavily to weight fields in the search algorithm. In general, increasing the Weight of a field will increase the relevancy score of a post that has matching text in that field.',
+ 'elasticpress',
+ )}
+
+
+ {__(
+ 'For example, adding more weight to the title attribute will cause search matches on the post title to appear more prominently.',
+ 'elasticpress',
+ )}
+
+
+ {weightableFields.map(({ key }) => {
+ return ;
+ })}
+
+ {__('Save Changes', 'elasticpress')}
+
+
+ >
+ );
+};
diff --git a/assets/js/weighting/components/group.js b/assets/js/weighting/components/group.js
index b4a2b4649d..0d55eec505 100644
--- a/assets/js/weighting/components/group.js
+++ b/assets/js/weighting/components/group.js
@@ -2,16 +2,15 @@
* WordPress dependencies.
*/
import { Button, PanelRow, TextControl } from '@wordpress/components';
-import { useDispatch } from '@wordpress/data';
import { useMemo, useState, WPElement } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
-import { store as noticeStore } from '@wordpress/notices';
/**
* Internal dependencies.
*/
+import { useSettingsScreen } from '../../settings-screen';
+import { useWeightingSettings } from '../provider';
import Field from './field';
-import { useWeighting } from '../provider';
/**
* Post type propertes component.
@@ -22,10 +21,9 @@ import { useWeighting } from '../provider';
* @returns {WPElement} Component element.
*/
export default ({ group, postType }) => {
- const { createNotice } = useDispatch(noticeStore);
-
+ const { createNotice } = useSettingsScreen();
const { currentWeightingConfiguration, setWeightingForPostType, weightableFields } =
- useWeighting();
+ useWeightingSettings();
/**
* State.
diff --git a/assets/js/weighting/components/post-type.js b/assets/js/weighting/components/post-type.js
index b1e7b16931..a5af21f6a1 100644
--- a/assets/js/weighting/components/post-type.js
+++ b/assets/js/weighting/components/post-type.js
@@ -7,7 +7,7 @@ import { WPElement } from '@wordpress/element';
/**
* Internal dependencies.
*/
-import { useWeighting } from '../provider';
+import { useWeightingSettings } from '../provider';
import Group from './group';
/**
@@ -18,7 +18,7 @@ import Group from './group';
* @returns {WPElement} Component element.
*/
export default ({ postType }) => {
- const { isManual, weightableFields } = useWeighting();
+ const { isManual, weightableFields } = useWeightingSettings();
const { label, groups } = weightableFields.find((f) => f.key === postType);
diff --git a/assets/css/weighting/action.css b/assets/js/weighting/css/action.css
similarity index 100%
rename from assets/css/weighting/action.css
rename to assets/js/weighting/css/action.css
diff --git a/assets/css/weighting/add-new.css b/assets/js/weighting/css/add-new.css
similarity index 100%
rename from assets/css/weighting/add-new.css
rename to assets/js/weighting/css/add-new.css
diff --git a/assets/css/weighting/field.css b/assets/js/weighting/css/field.css
similarity index 100%
rename from assets/css/weighting/field.css
rename to assets/js/weighting/css/field.css
diff --git a/assets/css/weighting/screen.css b/assets/js/weighting/css/post-type.css
similarity index 70%
rename from assets/css/weighting/screen.css
rename to assets/js/weighting/css/post-type.css
index cf6e71a9c8..0b765587aa 100644
--- a/assets/css/weighting/screen.css
+++ b/assets/js/weighting/css/post-type.css
@@ -1,10 +1,8 @@
-.ep-weighting-screen {
- margin-left: auto;
- margin-right: auto;
- max-width: 800px;
+.ep-weighting-post-type {
+ margin-bottom: 16px;
- & .components-panel {
- margin-bottom: 1rem;
+ & .components-panel__header h2 {
+ font-size: 14px;
}
& .components-toggle-control__label {
diff --git a/assets/js/weighting/index.js b/assets/js/weighting/index.js
index 4cf62a8417..869332d50d 100644
--- a/assets/js/weighting/index.js
+++ b/assets/js/weighting/index.js
@@ -2,13 +2,20 @@
* WordPress dependencies.
*/
import { createRoot, render, WPElement } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
/**
* Internal Dependencies.
*/
+import { SettingsScreenProvider } from '../settings-screen';
import { apiUrl, metaMode, syncUrl, weightableFields, weightingConfiguration } from './config';
-import WeightingProvider from './provider';
-import SettingsPage from './apps/settings-page';
+import { WeightingSettingsProvider } from './provider';
+import Weighting from './apps/weighting';
+
+/**
+ * Styles.
+ */
+import './style.css';
/**
* App component.
@@ -16,15 +23,17 @@ import SettingsPage from './apps/settings-page';
* @returns {WPElement} App component.
*/
const App = () => (
-
-
-
+
+
+
+
+
);
if (typeof createRoot === 'function') {
diff --git a/assets/js/weighting/provider.js b/assets/js/weighting/provider.js
index 0862ed800b..8fb37f2473 100644
--- a/assets/js/weighting/provider.js
+++ b/assets/js/weighting/provider.js
@@ -2,10 +2,7 @@
* WordPress dependencies.
*/
import apiFetch from '@wordpress/api-fetch';
-import { useDispatch } from '@wordpress/data';
import { createContext, WPElement, useContext, useMemo, useState } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
-import { store as noticeStore } from '@wordpress/notices';
/**
* Instant Results context.
@@ -23,9 +20,13 @@ const Context = createContext();
* @param {object} props.weightingConfiguration Weighting configuration, indexed by post type.
* @returns {WPElement} Element.
*/
-export default ({ apiUrl, children, metaMode, weightableFields, weightingConfiguration }) => {
- const { createNotice } = useDispatch(noticeStore);
-
+export const WeightingSettingsProvider = ({
+ apiUrl,
+ children,
+ metaMode,
+ weightableFields,
+ weightingConfiguration,
+}) => {
const [currentWeightingConfiguration, setCurrentWeightingConfiguration] = useState({
...weightingConfiguration,
});
@@ -57,9 +58,9 @@ export default ({ apiUrl, children, metaMode, weightableFields, weightingConfigu
* @returns {void}
*/
const save = async () => {
- try {
- setIsBusy(true);
+ setIsBusy(true);
+ try {
await apiFetch({
body: JSON.stringify(currentWeightingConfiguration),
headers: {
@@ -68,16 +69,9 @@ export default ({ apiUrl, children, metaMode, weightableFields, weightingConfigu
method: 'POST',
url: apiUrl,
});
-
- createNotice('success', __('Settings saved.', 'elasticpress'), {
- isDismissible: true,
- });
} catch (e) {
console.error(e); // eslint-disable-line no-console
-
- createNotice('error', __('Something went wrong. Please try again.', 'elasticpress'), {
- isDismissible: true,
- });
+ throw e;
} finally {
setIsBusy(false);
}
@@ -104,6 +98,6 @@ export default ({ apiUrl, children, metaMode, weightableFields, weightingConfigu
*
* @returns {object} API Search Context.
*/
-export const useWeighting = () => {
+export const useWeightingSettings = () => {
return useContext(Context);
};
diff --git a/assets/js/weighting/style.css b/assets/js/weighting/style.css
new file mode 100644
index 0000000000..8ab58bb81c
--- /dev/null
+++ b/assets/js/weighting/style.css
@@ -0,0 +1,4 @@
+@import "./css/action.css";
+@import "./css/add-new.css";
+@import "./css/field.css";
+@import "./css/post-type.css";
diff --git a/includes/dashboard.php b/includes/dashboard.php
index 99a2945c30..6c7de26ae4 100644
--- a/includes/dashboard.php
+++ b/includes/dashboard.php
@@ -472,13 +472,12 @@ function action_admin_enqueue_dashboard_scripts() {
}
if ( 'weighting' === Screen::factory()->get_current_screen() ) {
- wp_enqueue_style( 'wp-edit-post' );
wp_enqueue_style(
'ep_weighting_styles',
- EP_URL . 'dist/css/weighting-styles.css',
- Utils\get_asset_info( 'weighting-styles', 'dependencies' ),
- Utils\get_asset_info( 'weighting-styles', 'version' )
+ EP_URL . 'dist/css/weighting-script.css',
+ [ 'wp-components', 'wp-edit-post' ],
+ Utils\get_asset_info( 'weighting-script', 'version' )
);
wp_enqueue_script(
diff --git a/package.json b/package.json
index cb5bb23f5c..8cfecdc16f 100644
--- a/package.json
+++ b/package.json
@@ -89,7 +89,6 @@
"related-posts-block-styles": "./assets/css/related-posts-block.css",
"status-report-styles": "./assets/css/status-report.css",
"synonyms-styles": "./assets/css/synonyms.css",
- "weighting-styles": "./assets/css/weighting.css",
"woocommerce-order-search-styles": "./assets/css/woocommerce/admin/orders.css"
},
"wpDependencyExternals": true
From d3bc1bd1e93fb899ed1b25ea95788f2d15f7dd4f Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 24 Oct 2023 22:30:53 +1100
Subject: [PATCH 50/63] Add fields to weighting for Facets tests.
---
assets/js/weighting/apps/weighting.js | 2 +-
.../cypress/integration/features/facets.cy.js | 25 +++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/assets/js/weighting/apps/weighting.js b/assets/js/weighting/apps/weighting.js
index b536a08ede..000e55d372 100644
--- a/assets/js/weighting/apps/weighting.js
+++ b/assets/js/weighting/apps/weighting.js
@@ -56,7 +56,7 @@ export default () => {
return ;
})}
- {__('Save Changes', 'elasticpress')}
+ {__('Save changes', 'elasticpress')}
>
diff --git a/tests/cypress/integration/features/facets.cy.js b/tests/cypress/integration/features/facets.cy.js
index 100e178c62..2f5197629f 100644
--- a/tests/cypress/integration/features/facets.cy.js
+++ b/tests/cypress/integration/features/facets.cy.js
@@ -19,6 +19,31 @@ describe('Facets Feature', { tags: '@slow' }, () => {
wp_delete_post( $post, true );
}
`);
+
+ cy.updateWeighting();
+
+ cy.visitAdminPage('admin.php?page=elasticpress-weighting');
+
+ cy.intercept('/wp-json/elasticpress/v1/weighting*').as('apiRequest');
+ cy.contains('h2', 'Posts').closest('.components-panel').as('postsPanel');
+
+ cy.get('@postsPanel').contains('button', 'Metadata').click();
+
+ cy.get('@postsPanel').find('input[type="text"]').as('metaInput');
+ cy.get('@postsPanel').contains('button', 'Add').as('metaAdd');
+
+ cy.get('@metaInput').clearThenType('meta_field_1');
+ cy.get('@metaAdd').click();
+ cy.get('@metaInput').clearThenType('meta_field_2');
+ cy.get('@metaAdd').click();
+ cy.get('@metaInput').clearThenType('numeric_meta_field');
+ cy.get('@metaAdd').click();
+ cy.get('@metaInput').clearThenType('non_numeric_meta_field');
+ cy.get('@metaAdd').click();
+
+ cy.contains('button', 'Save changes').click();
+
+ cy.wait('@apiRequest');
});
/**
From 5b7a6f0564c6cdcd492673532f28f1d7721857ff Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 24 Oct 2023 22:36:37 +1100
Subject: [PATCH 51/63] Update posts indexable test.
---
tests/cypress/integration/indexables/post.cy.js | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/tests/cypress/integration/indexables/post.cy.js b/tests/cypress/integration/indexables/post.cy.js
index b30719ca75..275216b3e2 100644
--- a/tests/cypress/integration/indexables/post.cy.js
+++ b/tests/cypress/integration/indexables/post.cy.js
@@ -9,8 +9,17 @@ describe('Post Indexable', () => {
// Make sure post categories are searchable.
cy.visitAdminPage('admin.php?page=elasticpress-weighting');
- cy.get('#post-terms\\.category\\.name-enabled').check();
- cy.get('#submit').click();
+ cy.intercept('/wp-json/elasticpress/v1/weighting*').as('apiRequest');
+
+ cy.contains('h2', 'Posts').closest('.components-panel').as('postsPanel');
+ cy.get('@postsPanel')
+ .contains('legend', 'Categories')
+ .closest('fieldset')
+ .find('input[type="checkbox"]')
+ .check();
+
+ cy.contains('button', 'Save changes').click();
+ cy.wait('@apiRequest');
cy.setPerIndexCycle();
cy.visitAdminPage('edit-tags.php?taxonomy=category');
From 72cde58e473d366ee3b27f10b285db2ecef94e49 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Tue, 24 Oct 2023 23:16:32 +1100
Subject: [PATCH 52/63] Fix button label in weighting tests.
---
tests/cypress/integration/features/search/weighting.cy.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/cypress/integration/features/search/weighting.cy.js b/tests/cypress/integration/features/search/weighting.cy.js
index bf5d34af97..83fd2a8f30 100644
--- a/tests/cypress/integration/features/search/weighting.cy.js
+++ b/tests/cypress/integration/features/search/weighting.cy.js
@@ -70,7 +70,7 @@ describe('Post Search Feature - Weighting Functionality', () => {
* Save weighting settings.
*/
cy.intercept('/wp-json/elasticpress/v1/weighting*').as('apiRequest');
- cy.get('button').contains('Save Changes').click();
+ cy.contains('button', 'Save changes').click();
cy.wait('@apiRequest');
/**
@@ -146,7 +146,7 @@ describe('Post Search Feature - Weighting Functionality', () => {
* Save weighting settings.
*/
cy.intercept('/wp-json/elasticpress/v1/weighting*').as('apiRequest');
- cy.get('button').contains('Save Changes').click();
+ cy.contains('button', 'Save changes').click();
cy.wait('@apiRequest');
/**
@@ -239,7 +239,7 @@ describe('Post Search Feature - Weighting Functionality', () => {
* Save weighting settings.
*/
cy.intercept('/wp-json/elasticpress/v1/weighting*').as('apiRequest');
- cy.get('button').contains('Save Changes').click();
+ cy.contains('button', 'Save changes').click();
cy.wait('@apiRequest');
/**
@@ -281,7 +281,7 @@ describe('Post Search Feature - Weighting Functionality', () => {
* Save weighting settings.
*/
cy.intercept('/wp-json/elasticpress/v1/weighting*').as('apiRequest');
- cy.get('button').contains('Save Changes').click();
+ cy.contains('button', 'Save changes').click();
cy.wait('@apiRequest');
/**
From 46ead924af594bdfa4795370e03cc827c36c3a9c Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Wed, 25 Oct 2023 00:51:33 +1100
Subject: [PATCH 53/63] Fix weighting test.
---
tests/cypress/integration/features/search/weighting.cy.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/cypress/integration/features/search/weighting.cy.js b/tests/cypress/integration/features/search/weighting.cy.js
index 83fd2a8f30..c643fe17b3 100644
--- a/tests/cypress/integration/features/search/weighting.cy.js
+++ b/tests/cypress/integration/features/search/weighting.cy.js
@@ -260,7 +260,6 @@ describe('Post Search Feature - Weighting Functionality', () => {
* Update the weighting so the meta field is weighted higher.
*/
cy.visitAdminPage('admin.php?page=elasticpress-weighting');
- cy.get('.components-panel__body-title').contains('Metadata').should('exist');
cy.get('.components-panel__header')
.contains('Posts')
.closest('.components-panel')
@@ -270,6 +269,7 @@ describe('Post Search Feature - Weighting Functionality', () => {
.closest('fieldset')
.find('input[type="number"]')
.clearThenType(1);
+ cy.get('@panel').find('button').contains('Metadata').click();
cy.get('@panel')
.find('fieldset')
.contains('_my_custom_field')
@@ -307,12 +307,12 @@ describe('Post Search Feature - Weighting Functionality', () => {
cy.get('.components-panel__body-title').contains('Metadata').should('not.exist');
/**
- * With automatic meta management the post with a value in a public key
+ * With automatic meta management the post with a value in content
* should be returned, but the post with the value in a protected key
* should not be.
*/
cy.visit('/?s=abc123');
cy.get('.entry-title').contains('Test meta weighting, post content').should('exist');
- cy.get('.entry-title').contains('Test meta weighting, post meta').should('exist');
+ cy.get('.entry-title').contains('Test meta weighting, post meta').should('not.exist');
});
});
From ee931286ffbed66179f1167cc64f7d5fbcd994b7 Mon Sep 17 00:00:00 2001
From: Jacob Peattie
Date: Wed, 25 Oct 2023 01:42:59 +1100
Subject: [PATCH 54/63] Add message about syncing.
---
assets/js/weighting/components/group.js | 4 ++++
assets/js/weighting/css/add-new.css | 8 +++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/assets/js/weighting/components/group.js b/assets/js/weighting/components/group.js
index 0d55eec505..8334a7681a 100644
--- a/assets/js/weighting/components/group.js
+++ b/assets/js/weighting/components/group.js
@@ -173,6 +173,10 @@ export default ({ group, postType }) => {
{isMetadata ? (
setToAdd(toAdd)}
onKeyDown={onKeyDown}
diff --git a/assets/js/weighting/css/add-new.css b/assets/js/weighting/css/add-new.css
index 7a1845885e..68d468c376 100644
--- a/assets/js/weighting/css/add-new.css
+++ b/assets/js/weighting/css/add-new.css
@@ -1,10 +1,16 @@
.ep-weighting-add-new {
- align-items: flex-end;
+ align-items: start;
gap: 4px;
justify-content: start;
margin-top: 16px;
+ max-width: 100%;
+ width: 50ch;
& .components-base-control .components-text-control__input {
min-height: 36px;
}
+
+ & .components-button {
+ margin-top: calc(1.4 * 11px + 8px);
+ }
}
From a2a7398662997c624982386f9904dbda2850f3ff Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 15:38:49 -0300
Subject: [PATCH 55/63] Adjust unit tests for the weighting dashboard
---
includes/classes/Feature/Search/Weighting.php | 28 +-
tests/php/features/TestWeighting.php | 248 ++++++++----------
2 files changed, 132 insertions(+), 144 deletions(-)
diff --git a/includes/classes/Feature/Search/Weighting.php b/includes/classes/Feature/Search/Weighting.php
index 06d02e3376..4a7324edc1 100644
--- a/includes/classes/Feature/Search/Weighting.php
+++ b/includes/classes/Feature/Search/Weighting.php
@@ -429,17 +429,25 @@ public function register_rest_routes() {
}
/**
- * Handles processing the new weighting values and saving them to the
- * elasticpress.io service.
+ * Handles processing the new weighting values and saving them.
*
* @param \WP_Rest_Request $request REST API request.
- * @return void
+ * @return array
* @since 5.0.0
*/
public function update_weighting( $request = null ) {
$meta_mode = $this->get_meta_mode();
$weighting = $request->get_json_params();
+ $post_types = Features::factory()->get_registered_feature( 'search' )->get_searchable_post_types();
+
+ // Add default fields for post types not sent.
+ foreach ( $post_types as $post_type ) {
+ if ( ! isset( $weighting[ $post_type ] ) ) {
+ $weighting[ $post_type ] = [];
+ }
+ }
+
/**
* If metadata is not being managed manually, remove any custom
* fields that have not been registered as weightable fields.
@@ -465,6 +473,13 @@ public function update_weighting( $request = null ) {
}
}
+ // Cleanup any post type sent (or added via filters) that does not exist.
+ foreach ( $weighting as $post_type => $fields ) {
+ if ( ! post_type_exists( $post_type ) ) {
+ unset( $weighting[ $post_type ] );
+ }
+ }
+
update_option( 'elasticpress_weighting', $weighting );
/**
@@ -475,9 +490,10 @@ public function update_weighting( $request = null ) {
*/
do_action( 'ep_saved_weighting_configuration' );
- wp_send_json_success( $weighting );
-
- exit;
+ return [
+ 'data' => $weighting,
+ 'success' => true,
+ ];
}
/**
diff --git a/tests/php/features/TestWeighting.php b/tests/php/features/TestWeighting.php
index b436b2ca32..d4aefb6b57 100644
--- a/tests/php/features/TestWeighting.php
+++ b/tests/php/features/TestWeighting.php
@@ -20,44 +20,42 @@ class TestWeighting extends BaseTestCase {
* @var array
*/
public $weighting_settings = [
- 'weighting' => [
- 'post' => [
- 'post_title' => [
- 'weight' => 1,
- 'enabled' => 'on',
- ],
- 'post_content' => [
- 'weight' => 1,
- 'enabled' => 'on',
- ],
- 'post_excerpt' => [
- 'weight' => 1,
- 'enabled' => 'on',
- ],
+ 'post' => [
+ 'post_title' => [
+ 'weight' => 1,
+ 'enabled' => 'on',
+ ],
+ 'post_content' => [
+ 'weight' => 1,
+ 'enabled' => 'on',
+ ],
+ 'post_excerpt' => [
+ 'weight' => 1,
+ 'enabled' => 'on',
+ ],
- 'author_name' => [
- 'weight' => 0,
- 'enabled' => 'on',
- ],
+ 'author_name' => [
+ 'weight' => 0,
+ 'enabled' => 'on',
+ ],
+ ],
+ 'page' => [
+ 'post_title' => [
+ 'weight' => 1,
+ 'enabled' => 'on',
+ ],
+ 'post_content' => [
+ 'weight' => 1,
+ 'enabled' => 'on',
+ ],
+ 'post_excerpt' => [
+ 'weight' => 1,
+ 'enabled' => 'on',
],
- 'page' => [
- 'post_title' => [
- 'weight' => 1,
- 'enabled' => 'on',
- ],
- 'post_content' => [
- 'weight' => 1,
- 'enabled' => 'on',
- ],
- 'post_excerpt' => [
- 'weight' => 1,
- 'enabled' => 'on',
- ],
- 'author_name' => [
- 'weight' => 0,
- 'enabled' => false,
- ],
+ 'author_name' => [
+ 'weight' => 0,
+ 'enabled' => false,
],
],
];
@@ -109,29 +107,26 @@ public function get_weighting_feature() {
}
/**
- * Test searchable post_types exist after configuration change
+ * Test searchable post_types exist after configuration change with meta mode 'auto'
*
- * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::save_weighting_configuration
+ * @group weighting
+ * @since 5.0.0
*/
- public function testWeightablePostType() {
+ public function test_weightable_post_type_auto() {
$search = ElasticPress\Features::factory()->get_registered_feature( 'search' );
$searchable_post_types = $search->get_searchable_post_types();
$weighting_settings = [
- 'weighting' => [
- 'post' => [
- 'post_title' => [
- 'enabled' => 'on',
- 'weight' => 1,
- ],
+ 'post' => [
+ 'post_title' => [
+ 'enabled' => 'on',
+ 'weight' => 1,
],
],
];
- $this->get_weighting_feature()->save_weighting_configuration( $weighting_settings );
-
- $weighting_configuration = $this->get_weighting_feature()->get_weighting_configuration();
+ $weighting_configuration = $this->save_weighting_configuration( $weighting_settings );
$this->assertEquals( count( $searchable_post_types ), count( array_keys( $weighting_configuration ) ) );
@@ -141,10 +136,21 @@ public function testWeightablePostType() {
/**
* Test settings toggle
*
+ * @since 5.0.0
+ * @group weighting
* @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::save_weighting_configuration
*/
- public function testWeightingConfiguration() {
+ public function test_weighting_configuration_deprecated() {
+ $this->get_weighting_feature()->save_weighting_configuration( [] );
+ }
+ /**
+ * Test saving weighting configuration
+ *
+ * @since 5.0.0
+ * @group weighting
+ */
+ public function test_weighting_configuration() {
$weighting_ep_test = $this->get_weighting_feature()->get_post_type_default_settings( 'ep_test' );
$this->assertEquals( true, $weighting_ep_test['post_title']['enabled'] );
@@ -152,26 +158,24 @@ public function testWeightingConfiguration() {
$this->assertEmpty( $weighting_configuration );
$weighting_settings = [
- 'weighting' => [
- 'post' => [
- 'post_title' => [
- 'enabled' => 'on',
- 'weight' => 1,
- ],
+ 'post' => [
+ 'post_title' => [
+ 'enabled' => true,
+ 'weight' => 1,
],
],
];
// enable post_title weighting
- $this->get_weighting_feature()->save_weighting_configuration( $weighting_settings );
- $weighting_configuration = $this->get_weighting_feature()->get_weighting_configuration();
+
+ $weighting_configuration = $this->save_weighting_configuration( $weighting_settings );
$this->assertEquals( true, $weighting_configuration['post']['post_title']['enabled'] );
$this->assertEquals( 1, $weighting_configuration['post']['post_title']['weight'] );
// disable post_title weighting
- $weighting_settings['weighting']['post']['post_title']['enabled'] = '';
- $this->get_weighting_feature()->save_weighting_configuration( $weighting_settings );
- $weighting_configuration = $this->get_weighting_feature()->get_weighting_configuration();
+ $weighting_settings['post']['post_title']['enabled'] = false;
+
+ $weighting_configuration = $this->save_weighting_configuration( $weighting_settings );
$this->assertEquals( false, $weighting_configuration['post']['post_title']['enabled'] );
}
@@ -183,7 +187,6 @@ public function testWeightingConfiguration() {
*
* @since 3.6.5
* @group weighting
- * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::save_weighting_configuration
*/
public function testWeightingDefaultEnabledTaxonomies() {
// By default, `post_format` should not be enabled, only `category` and `post_tag`.
@@ -208,8 +211,7 @@ function ( $taxs, $post_type ) {
$this->assertTrue( $post_default_config['terms.post_format.name']['enabled'] );
// `$this->weighting_settings` does not have post_format. So, once saved, the configuration should not have it enabled too.
- $this->get_weighting_feature()->save_weighting_configuration( $this->weighting_settings );
- $weighting_configuration = $this->get_weighting_feature()->get_weighting_configuration();
+ $weighting_configuration = $this->save_weighting_configuration( $this->weighting_settings );
$this->assertArrayNotHasKey( 'post_format', $weighting_configuration['post'] );
$this->assertArrayNotHasKey( 'terms.post_format.name', $weighting_configuration['post'] );
}
@@ -255,80 +257,35 @@ public function testRenderSettingsPage() {
$this->assertStringContainsString( 'id="ep-weighting-screen"', $content );
}
- /**
- * Test the `render_settings_page` method (success)
- */
- public function testRenderSettingsPageSaveSuccess() {
- $_GET['settings-updated'] = true;
- ob_start();
- $this->get_weighting_feature()->render_settings_page();
- $content = ob_get_clean();
-
- $this->assertStringContainsString( 'Changes Saved', $content );
- }
-
- /**
- * Test the `render_settings_page` method (failed)
- */
- public function testRenderSettingsPageSaveFailed() {
- $_GET['settings-updated'] = false;
- ob_start();
- $this->get_weighting_feature()->render_settings_page();
- $content = ob_get_clean();
-
- $this->assertStringContainsString( 'An error occurred when saving', $content );
- }
-
/**
* Test the `handle_save` method
*
- * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::deprecated_handle_save
- * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::save_weighting_configuration
+ * @since 5.0.0
+ * @group weighting
+ * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::handle_save
*/
- public function testHandleSave() {
- $weighting_class = $this->getMockBuilder( 'ElasticPress\Feature\Search\Weighting' )
- ->setMethods( [ 'redirect' ] )
- ->getMock();
-
- $_POST['ep-weighting-nonce'] = false;
- $this->assertEquals( null, $weighting_class->handle_save() );
-
- // Change to non admin user
- wp_set_current_user( $this->factory->user->create( array( 'role' => 'author' ) ) );
-
- $_POST['ep-weighting-nonce'] = wp_create_nonce( 'save-weighting' );
- $this->assertEquals( null, $weighting_class->handle_save() );
-
- wp_set_current_user( $this->factory->user->create( array( 'role' => 'administrator' ) ) );
- $_POST = [
- 'ep-weighting-nonce' => wp_create_nonce( 'save-weighting' ),
- 'weighting' => [
- 'post' => [
- 'post_title' => [
- 'enabled' => 'on',
- 'weight' => 1,
- ],
- ],
- ],
- ];
-
- $weighting_class->expects( $this->once() )->method( 'redirect' );
- $weighting_class->handle_save();
+ public function test_handle_save() {
+ $this->get_weighting_feature()->handle_save();
}
/**
* Test the `save_weighting_configuration` method (invalid post type)
*
- * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::save_weighting_configuration
+ * @group weighting
*/
public function testSaveWeightingConfigurationInvalidPostType() {
+ add_filter(
+ 'ep_meta_mode',
+ function () {
+ return 'auto';
+ }
+ );
+
$weighting_settings = [
- 'weighting' => [
- 'post' => [
- 'post_title' => [
- 'enabled' => 'on',
- 'weight' => 1,
- ],
+ 'post' => [
+ 'post_title' => [
+ 'enabled' => 'on',
+ 'weight' => 1,
],
],
];
@@ -347,7 +304,7 @@ function( $config ) {
}
);
- $this->assertNotContains( 'invalid_post_type', $this->get_weighting_feature()->save_weighting_configuration( $weighting_settings ) );
+ $this->assertNotContains( 'invalid_post_type', array_keys( $this->save_weighting_configuration( $weighting_settings ) ) );
}
/**
@@ -355,15 +312,16 @@ function( $config ) {
*/
public function testRecursivelyInjectWeightsToFieldsInvalidArgs() {
$invalid_args = '';
- $this->assertEquals( null, $this->get_weighting_feature()->recursively_inject_weights_to_fields( $invalid_args, $this->weighting_settings['weighting']['post'] ) );
+ $this->assertEquals( null, $this->get_weighting_feature()->recursively_inject_weights_to_fields( $invalid_args, $this->weighting_settings['post'] ) );
}
/**
* Test the `post_type_has_fields` method
*
- * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::save_weighting_configuration
+ * @since 5.0.0
+ * @group weighting
*/
- public function testPostTypeHasFieldsWithDefaultConfig() {
+ public function test_post_type_has_fields_with_default_config() {
$this->assertTrue( $this->get_weighting_feature()->post_type_has_fields( 'post' ) );
}
@@ -373,16 +331,14 @@ public function testPostTypeHasFieldsWithDefaultConfig() {
public function testPostTypeHasFieldsWithCustomConfig() {
// Test with configuration saved for post only, page will return false.
$weighting_settings = [
- 'weighting' => [
- 'post' => [
- 'post_title' => [
- 'enabled' => 'on',
- 'weight' => 1,
- ],
+ 'post' => [
+ 'post_title' => [
+ 'enabled' => 'on',
+ 'weight' => 1,
],
],
];
- $this->get_weighting_feature()->save_weighting_configuration( $weighting_settings );
+ $this->save_weighting_configuration( $weighting_settings );
$this->assertTrue( $this->get_weighting_feature()->post_type_has_fields( 'post' ) );
$this->assertFalse( $this->get_weighting_feature()->post_type_has_fields( 'page' ) );
@@ -464,10 +420,11 @@ public function testDoWeightingWithDefaultConfig() {
/**
* Test the `do_weighting` method (with the custom config)
*
- * @expectedIncorrectUsage ElasticPress\Feature\Search\Weighting::save_weighting_configuration
+ * @since 5.0.0
+ * @group weighting
*/
- public function testDoWeightingWithCustomConfig() {
- $this->get_weighting_feature()->save_weighting_configuration( $this->weighting_settings );
+ public function test_do_weighting_with_custom_config() {
+ $this->save_weighting_configuration( $this->weighting_settings );
$new_formatted_args = $this->get_weighting_feature()->do_weighting( ...$this->getArgs() );
@@ -535,4 +492,19 @@ public function testApplyFilterWhenWeightingConfigWasNotSaved() {
['bool']['should'][0]['multi_match'];
$this->assertEquals( [ 'post_content_filtered^40' ], $query_multi_match['fields'] );
}
+
+ /**
+ * Save the weighting configuration using the REST API endpoint
+ *
+ * @param array $settings New settings
+ * @return array
+ */
+ protected function save_weighting_configuration( $settings ) {
+ $request = new \WP_REST_Request( 'POST', '/elasticpress/v1/update_weighting' );
+ $request->set_header( 'Content-Type', 'application/json' );
+ $request->set_body( wp_json_encode( $settings ) );
+ $this->get_weighting_feature()->update_weighting( $request );
+
+ return $this->get_weighting_feature()->get_weighting_configuration();
+ }
}
From f63f8f40c953d9533767fd5546b86f166e4afcf3 Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 16:43:27 -0300
Subject: [PATCH 56/63] Delete elasticpress_weighting on uninstall
---
uninstall.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/uninstall.php b/uninstall.php
index 95c7cb312a..782eea27cf 100644
--- a/uninstall.php
+++ b/uninstall.php
@@ -44,6 +44,8 @@ class EP_Uninstaller {
'ep_bulk_setting',
'ep_sync_history',
+ 'elasticpress_weighting',
+
// Admin notices options
'ep_hide_host_error_notice',
'ep_hide_es_below_compat_notice',
From 18b432781f9d090de974e724e85995a3f5f93081 Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 16:44:00 -0300
Subject: [PATCH 57/63] Use defaults when the weighting config was not saved
---
includes/classes/Indexable/Post/Post.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/classes/Indexable/Post/Post.php b/includes/classes/Indexable/Post/Post.php
index 8e65367815..13d173e5ba 100644
--- a/includes/classes/Indexable/Post/Post.php
+++ b/includes/classes/Indexable/Post/Post.php
@@ -2492,7 +2492,7 @@ protected function parse_tax_query_field( string $field ) : string {
protected function filter_allowed_metas_manual( $metas, $post ) {
$filtered_metas = [];
- $weighting = \ElasticPress\Features::factory()->get_registered_feature( 'search' )->weighting->get_weighting_configuration();
+ $weighting = \ElasticPress\Features::factory()->get_registered_feature( 'search' )->weighting->get_weighting_configuration_with_defaults();
if ( empty( $post->post_type ) || empty( $weighting[ $post->post_type ] ) ) {
return $filtered_metas;
}
From 8cf25c54b4c42e540cb852cd06307a43ca913893 Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 17:13:48 -0300
Subject: [PATCH 58/63] Allow ep_exclude_from_search by default
---
includes/classes/Feature/Search/Search.php | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/includes/classes/Feature/Search/Search.php b/includes/classes/Feature/Search/Search.php
index c43781077e..415d5b6df9 100644
--- a/includes/classes/Feature/Search/Search.php
+++ b/includes/classes/Feature/Search/Search.php
@@ -107,6 +107,7 @@ public function search_setup() {
add_action( 'ep_highlighting_pre_add_highlight', [ $this, 'allow_excerpt_html' ] );
add_action( 'init', [ $this, 'register_meta' ], 20 );
+ add_filter( 'ep_prepare_meta_allowed_keys', [ $this, 'add_exclude_from_search' ] );
add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_block_editor_assets' ] );
add_filter( 'ep_post_filters', [ $this, 'exclude_posts_from_search' ], 10, 3 );
add_action( 'post_submitbox_misc_actions', [ $this, 'output_exclude_from_search_setting' ] );
@@ -688,6 +689,18 @@ public function register_meta() {
);
}
+ /**
+ * Add ep_exclude_from_search to the allowed meta fields list.
+ *
+ * @since 5.0.0
+ * @param array $keys List of allowed meta fields
+ * @return array
+ */
+ public function add_exclude_from_search( $keys ) {
+ $keys[] = 'ep_exclude_from_search';
+ return $keys;
+ }
+
/**
* Enqueue block editor assets.
*/
From cb49f96f9a63b9d26a27c5082aadf24885b77e81 Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 17:13:56 -0300
Subject: [PATCH 59/63] Adjust testTooManyFieldsNoticeInAdmin
---
tests/php/TestAdminNotices.php | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/php/TestAdminNotices.php b/tests/php/TestAdminNotices.php
index db86ec4920..fec5b424fd 100644
--- a/tests/php/TestAdminNotices.php
+++ b/tests/php/TestAdminNotices.php
@@ -561,6 +561,13 @@ function() use ( $es_version ) {
* @since 4.4.0
*/
public function testTooManyFieldsNoticeInAdmin() {
+ add_filter(
+ 'ep_prepare_meta_allowed_keys',
+ function( $allowed_metakeys ) {
+ return array_merge( $allowed_metakeys, [ 'meta_key_1', 'meta_key_2', 'meta_key_3', 'meta_key_4' ] );
+ }
+ );
+
add_filter(
'ep_total_field_limit',
function() {
From 72e5f8fd8cd2b0572a5492d6b28c361c015858ae Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 18:06:12 -0300
Subject: [PATCH 60/63] If a type is not searchable, do not apply weighting
config
---
includes/classes/Indexable/Post/Post.php | 35 +++++++++++++++---------
tests/php/features/TestFacetTypeMeta.php | 7 +++++
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/includes/classes/Indexable/Post/Post.php b/includes/classes/Indexable/Post/Post.php
index 13d173e5ba..e1e9e124e3 100644
--- a/includes/classes/Indexable/Post/Post.php
+++ b/includes/classes/Indexable/Post/Post.php
@@ -2491,26 +2491,35 @@ protected function parse_tax_query_field( string $field ) : string {
*/
protected function filter_allowed_metas_manual( $metas, $post ) {
$filtered_metas = [];
+ $search_feature = \ElasticPress\Features::factory()->get_registered_feature( 'search' );
- $weighting = \ElasticPress\Features::factory()->get_registered_feature( 'search' )->weighting->get_weighting_configuration_with_defaults();
- if ( empty( $post->post_type ) || empty( $weighting[ $post->post_type ] ) ) {
+ if ( empty( $post->post_type ) ) {
+ return $filtered_metas;
+ }
+
+ $weighting = $search_feature->weighting->get_weighting_configuration_with_defaults();
+ $is_searchable = in_array( $search_feature, $search_feature->get_searchable_post_types(), true );
+ if ( empty( $weighting[ $post->post_type ] ) && $is_searchable ) {
return $filtered_metas;
}
/** This filter is documented in includes/classes/Indexable/Post/Post.php */
$allowed_protected_keys = apply_filters( 'ep_prepare_meta_allowed_protected_keys', [], $post );
- $selected_keys = array_map(
- function ( $field ) {
- if ( false === strpos( $field, 'meta.' ) ) {
- return null;
- }
- $field_name_parts = explode( '.', $field );
- return $field_name_parts[1];
- },
- array_keys( $weighting[ $post->post_type ] )
- );
- $selected_keys = array_filter( $selected_keys );
+ $selected_keys = [];
+ if ( ! empty( $weighting[ $post->post_type ] ) ) {
+ $selected_keys = array_map(
+ function ( $field ) {
+ if ( false === strpos( $field, 'meta.' ) ) {
+ return null;
+ }
+ $field_name_parts = explode( '.', $field );
+ return $field_name_parts[1];
+ },
+ array_keys( $weighting[ $post->post_type ] )
+ );
+ $selected_keys = array_filter( $selected_keys );
+ }
/**
* Filter indexable meta keys for posts
diff --git a/tests/php/features/TestFacetTypeMeta.php b/tests/php/features/TestFacetTypeMeta.php
index b49c5ea2c6..e3252ff9a6 100644
--- a/tests/php/features/TestFacetTypeMeta.php
+++ b/tests/php/features/TestFacetTypeMeta.php
@@ -146,6 +146,13 @@ public function testSetWpQueryAggs() {
* @group facets
*/
public function testGetMetaValues() {
+ add_filter(
+ 'ep_prepare_meta_allowed_keys',
+ function( $allowed_metakeys ) {
+ return array_merge( $allowed_metakeys, [ 'new_meta_key_1', 'new_meta_key_2' ] );
+ }
+ );
+
$facet_feature = Features::factory()->get_registered_feature( 'facets' );
$facet_type = $facet_feature->types['meta'];
From f0b728496d20e0f52ab170c0ec09b3c72ffb0e9b Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 19:14:27 -0300
Subject: [PATCH 61/63] Fix TestPost normalizing all meta key names
---
tests/php/indexables/TestPost.php | 202 +++++++++++++++++-------------
1 file changed, 117 insertions(+), 85 deletions(-)
diff --git a/tests/php/indexables/TestPost.php b/tests/php/indexables/TestPost.php
index e15031c35a..f0ffce19aa 100644
--- a/tests/php/indexables/TestPost.php
+++ b/tests/php/indexables/TestPost.php
@@ -50,6 +50,25 @@ public function set_up() {
// Need to call this since it's hooked to init
ElasticPress\Features::factory()->get_registered_feature( 'search' )->search_setup();
+
+ // Allow some meta fields to be indexed.
+ add_filter(
+ 'ep_prepare_meta_allowed_keys',
+ function( $allowed_metakeys ) {
+ return array_merge(
+ $allowed_metakeys,
+ [
+ 'test_key',
+ 'test_key1',
+ 'test_key2',
+ 'test_key3',
+ 'test_key4',
+ 'test_key5',
+ 'test_key6',
+ ]
+ );
+ }
+ );
}
/**
@@ -3443,21 +3462,21 @@ public function testMetaQueryMultipleArray() {
$this->ep_factory->post->create(
array(
'post_content' => 'findme',
- 'meta_input' => array( 'meta_key_1' => '1' ),
+ 'meta_input' => array( 'test_key1' => '1' ),
)
);
$this->ep_factory->post->create(
array(
'post_content' => 'findme',
- 'meta_input' => array( 'meta_key_1' => '1' ),
+ 'meta_input' => array( 'test_key1' => '1' ),
)
);
$this->ep_factory->post->create(
array(
'post_content' => 'findme',
'meta_input' => array(
- 'meta_key_1' => '1',
- 'meta_key_2' => '4',
+ 'test_key1' => '1',
+ 'test_key2' => '4',
),
)
);
@@ -3465,8 +3484,8 @@ public function testMetaQueryMultipleArray() {
array(
'post_content' => 'findme',
'meta_input' => array(
- 'meta_key_1' => '1',
- 'meta_key_2' => '0',
+ 'test_key1' => '1',
+ 'test_key2' => '0',
),
)
);
@@ -3474,8 +3493,8 @@ public function testMetaQueryMultipleArray() {
array(
'post_content' => 'findme',
'meta_input' => array(
- 'meta_key_1' => '1',
- 'meta_key_3' => '4',
+ 'test_key1' => '1',
+ 'test_key3' => '4',
),
)
);
@@ -3486,7 +3505,7 @@ public function testMetaQueryMultipleArray() {
's' => 'findme',
'meta_query' => array(
array(
- 'key' => 'meta_key_2',
+ 'key' => 'test_key2',
'value' => '0',
'compare' => '>=',
),
@@ -3504,18 +3523,18 @@ public function testMetaQueryMultipleArray() {
'meta_query' => array(
'relation' => 'AND',
array(
- 'key' => 'meta_key_1',
+ 'key' => 'test_key1',
'value' => '1',
),
array(
'relation' => 'OR',
array(
- 'key' => 'meta_key_2',
+ 'key' => 'test_key2',
'value' => '2',
'compare' => '>=',
),
array(
- 'key' => 'meta_key_3',
+ 'key' => 'test_key3',
'value' => '4',
),
),
@@ -3836,9 +3855,9 @@ public function testPrepareMeta() {
'value 2',
);
- add_post_meta( $post_id, 'test_meta_1', 'value 1' );
- add_post_meta( $post_id, 'test_meta_1', 'value 2' );
- add_post_meta( $post_id, 'test_meta_1', $meta_values );
+ add_post_meta( $post_id, 'test_key1', 'value 1' );
+ add_post_meta( $post_id, 'test_key1', 'value 2' );
+ add_post_meta( $post_id, 'test_key1', $meta_values );
add_post_meta( $post_id, '_test_private_meta_1', 'value 1' );
add_post_meta( $post_id, '_test_private_meta_1', 'value 2' );
add_post_meta( $post_id, '_test_private_meta_1', $meta_values );
@@ -3849,14 +3868,20 @@ public function testPrepareMeta() {
$meta_2 = ElasticPress\Indexables::factory()->get( 'post' )->prepare_meta( $post );
+ add_filter(
+ 'ep_meta_mode',
+ function () {
+ return 'auto';
+ }
+ );
add_filter( 'ep_prepare_meta_excluded_public_keys', array( $this, 'filter_ep_prepare_meta_excluded_public_keys' ) );
$meta_3 = ElasticPress\Indexables::factory()->get( 'post' )->prepare_meta( $post );
$this->assertTrue( is_array( $meta_1 ) && 1 === count( $meta_1 ) );
- $this->assertTrue( is_array( $meta_1 ) && array_key_exists( 'test_meta_1', $meta_1 ) );
+ $this->assertTrue( is_array( $meta_1 ) && array_key_exists( 'test_key1', $meta_1 ) );
$this->assertTrue( is_array( $meta_2 ) && 2 === count( $meta_2 ) );
- $this->assertTrue( is_array( $meta_2 ) && array_key_exists( 'test_meta_1', $meta_2 ) && array_key_exists( '_test_private_meta_1', $meta_2 ) );
+ $this->assertTrue( is_array( $meta_2 ) && array_key_exists( 'test_key1', $meta_2 ) && array_key_exists( '_test_private_meta_1', $meta_2 ) );
$this->assertTrue( is_array( $meta_3 ) && 1 === count( $meta_3 ) );
$this->assertTrue( is_array( $meta_3 ) && array_key_exists( '_test_private_meta_1', $meta_3 ) );
}
@@ -3892,8 +3917,8 @@ public function testPrepareMetaManual() {
$post_id = $this->ep_factory->post->create(
[
'meta_input' => [
- 'test_meta_1' => 'value 1',
- 'test_meta_2' => 'value 2',
+ 'not_allowed_key1' => 'value 1',
+ 'not_allowed_key2' => 'value 2',
'_test_private_meta_1' => 'private value 1',
'_test_private_meta_2' => 'private value 2',
],
@@ -3925,18 +3950,18 @@ public function testPrepareMetaManual() {
$this->assertInstanceOf( '\WP_Post', $post );
$this->assertIsArray( $fields );
- $fields[] = 'test_meta_1';
+ $fields[] = 'not_allowed_key1';
return $fields;
};
add_filter( 'ep_prepare_meta_allowed_keys', $add_meta_via_allowed, 10, 2 );
$prepared_meta = ElasticPress\Indexables::factory()->get( 'post' )->prepare_meta( $post );
- $this->assertSame( [ 'test_meta_1', '_test_private_meta_1' ], array_keys( $prepared_meta ) );
+ $this->assertSame( [ 'not_allowed_key1', '_test_private_meta_1' ], array_keys( $prepared_meta ) );
// Set changed weighting
remove_filter( 'ep_weighting_configuration', $set_default_weighting );
$set_changed_weighting = function() use ( $weighting_default ) {
- $weighting_default['post']['meta.test_meta_2.value'] = [
+ $weighting_default['post']['meta.test_key2.value'] = [
'enabled' => true,
'weight' => 1,
];
@@ -3950,7 +3975,7 @@ public function testPrepareMetaManual() {
$prepared_meta = ElasticPress\Indexables::factory()->get( 'post' )->prepare_meta( $post );
$this->assertSame(
- [ 'test_meta_1', 'test_meta_2', '_test_private_meta_1', '_test_private_meta_2' ],
+ [ 'not_allowed_key1', '_test_private_meta_1', '_test_private_meta_2' ],
array_keys( $prepared_meta )
);
}
@@ -3977,7 +4002,7 @@ public function filter_ep_prepare_meta_allowed_protected_keys( $meta_keys ) {
*/
public function filter_ep_prepare_meta_excluded_public_keys( $meta_keys ) {
- $meta_keys[] = 'test_meta_1';
+ $meta_keys[] = 'test_key1';
return $meta_keys;
@@ -3999,7 +4024,7 @@ public function testEmptyMetaKey() {
'value 1',
'value 2',
);
- add_post_meta( $post_id, 'test_meta_1', $meta_values );
+ add_post_meta( $post_id, 'test_key1', $meta_values );
$wpdb->insert(
$wpdb->postmeta,
@@ -4019,7 +4044,7 @@ public function testEmptyMetaKey() {
$this->assertIsArray( $meta_data );
$this->assertCount( 1, $meta_data );
- $this->assertArrayHasKey( 'test_meta_1', $meta_data );
+ $this->assertArrayHasKey( 'test_key1', $meta_data );
}
/**
@@ -4179,7 +4204,7 @@ public function testMetaKeyQueryMix() {
'post_content' => 'post content findme',
'meta_input' => array(
'test_key' => 5,
- 'test_key_2' => 'aaa',
+ 'test_key2' => 'aaa',
),
)
);
@@ -4191,7 +4216,7 @@ public function testMetaKeyQueryMix() {
'meta_value_num' => 5,
'meta_query' => array(
array(
- 'key' => 'test_key_2',
+ 'key' => 'test_key2',
'value' => 'aaa',
),
),
@@ -6882,7 +6907,7 @@ public function testParseOrderbyMetaValueParams( $meta_value_type, $es_type, $me
$posts = [];
foreach ( $meta_values as $value ) {
- $posts[] = $this->ep_factory->post->create( [ 'meta_input' => [ 'custom_meta_key' => $value ] ] );
+ $posts[] = $this->ep_factory->post->create( [ 'meta_input' => [ 'test_key' => $value ] ] );
}
ElasticPress\Elasticsearch::factory()->refresh_indices();
@@ -6891,14 +6916,14 @@ public function testParseOrderbyMetaValueParams( $meta_value_type, $es_type, $me
'fields' => 'ids',
'orderby' => 'meta_value' . ( $meta_value_type ? "_{$meta_value_type}" : '' ),
'order' => 'asc',
- 'meta_key' => 'custom_meta_key',
+ 'meta_key' => 'test_key',
];
$assert_callback = function( $args ) use ( &$method_executed, $es_type ) {
$method_executed = true;
- $this->assertArrayHasKey( "meta.custom_meta_key.{$es_type}", $args['sort'][0] );
- $this->assertSame( 'asc', $args['sort'][0][ "meta.custom_meta_key.{$es_type}" ]['order'] );
+ $this->assertArrayHasKey( "meta.test_key.{$es_type}", $args['sort'][0] );
+ $this->assertSame( 'asc', $args['sort'][0][ "meta.test_key.{$es_type}" ]['order'] );
return $args;
};
@@ -6933,7 +6958,7 @@ public function testParseOrderbyMetaValueWithoutMetaKeyParams( $meta_value_type,
'order' => 'asc',
'meta_query' => [
[
- 'key' => 'custom_meta_key',
+ 'key' => 'test_key',
'compare' => 'EXISTS',
],
],
@@ -6942,8 +6967,8 @@ public function testParseOrderbyMetaValueWithoutMetaKeyParams( $meta_value_type,
$assert_callback = function( $args ) use ( &$method_executed, $es_type ) {
$method_executed = true;
- $this->assertArrayHasKey( "meta.custom_meta_key.{$es_type}", $args['sort'][0] );
- $this->assertSame( 'asc', $args['sort'][0][ "meta.custom_meta_key.{$es_type}" ]['order'] );
+ $this->assertArrayHasKey( "meta.test_key.{$es_type}", $args['sort'][0] );
+ $this->assertSame( 'asc', $args['sort'][0][ "meta.test_key.{$es_type}" ]['order'] );
return $args;
};
@@ -6975,11 +7000,11 @@ public function testParseOrderbyMetaQueryTypes( $meta_value_type, $es_type ) {
'order' => 'asc',
'meta_query' => [
[
- 'key' => 'unused_key',
+ 'key' => 'test_key1',
'type' => 'NUMERIC',
],
'named_clause' => [
- 'key' => 'custom_meta_key',
+ 'key' => 'test_key',
'type' => $meta_value_type,
],
],
@@ -6988,8 +7013,8 @@ public function testParseOrderbyMetaQueryTypes( $meta_value_type, $es_type ) {
$assert_callback = function( $args ) use ( &$method_executed, $es_type ) {
$method_executed = true;
- $this->assertArrayHasKey( "meta.custom_meta_key.{$es_type}", $args['sort'][0] );
- $this->assertSame( 'asc', $args['sort'][0][ "meta.custom_meta_key.{$es_type}" ]['order'] );
+ $this->assertArrayHasKey( "meta.test_key.{$es_type}", $args['sort'][0] );
+ $this->assertSame( 'asc', $args['sort'][0][ "meta.test_key.{$es_type}" ]['order'] );
return $args;
};
@@ -7430,7 +7455,7 @@ public function testPostSyncQueueEPKill() {
// Turn on the filter to kill syncing.
add_filter( 'ep_post_sync_kill', '__return_true' );
- update_post_meta( $post_id, 'custom_key', 123 );
+ update_post_meta( $post_id, 'test_key', 123 );
// Make sure sync queue is still empty when meta is updated for
// an existing post.
@@ -7449,7 +7474,7 @@ public function testPostSyncQueueEPKill() {
remove_filter( 'ep_post_sync_kill', '__return_true' );
// Now verify the queue when this filter is not enabled.
- update_post_meta( $post_id, 'custom_key', 456 );
+ update_post_meta( $post_id, 'test_key', 456 );
$this->assertNotEmpty( ElasticPress\Indexables::factory()->get( 'post' )->sync_manager->get_sync_queue() );
@@ -7653,8 +7678,8 @@ public function testDeleteAllMetadata() {
array(
'post_title' => 'one',
'meta_input' => array(
- 'common_meta_one' => 'lorem',
- 'common_meta_two' => 'ipsum',
+ 'test_key1' => 'lorem',
+ 'test_key2' => 'ipsum',
),
)
);
@@ -7662,13 +7687,13 @@ public function testDeleteAllMetadata() {
array(
'post_title' => 'two',
'meta_input' => array(
- 'common_meta_one' => 'lorem',
- 'common_meta_two' => 'ipsum',
+ 'test_key1' => 'lorem',
+ 'test_key2' => 'ipsum',
),
)
);
- delete_metadata( 'post', null, 'common_meta_one', 'lorem', true );
+ delete_metadata( 'post', null, 'test_key1', 'lorem', true );
ElasticPress\Indexables::factory()->get( 'post' )->sync_manager->index_sync_queue();
ElasticPress\Elasticsearch::factory()->refresh_indices();
@@ -7677,7 +7702,7 @@ public function testDeleteAllMetadata() {
array(
'post_type' => 'post',
'ep_integrate' => true,
- 'meta_key' => 'common_meta_one',
+ 'meta_key' => 'test_key1',
'meta_value' => 'lorem',
)
);
@@ -7689,7 +7714,7 @@ public function testDeleteAllMetadata() {
array(
'post_type' => 'post',
'ep_integrate' => true,
- 'meta_key' => 'common_meta_two',
+ 'meta_key' => 'test_key2',
'meta_value' => 'ipsum',
)
);
@@ -8006,6 +8031,12 @@ public function testIsMetaAllowed() {
$meta_protected = '_meta';
$meta_protected_allowed = '_meta_allowed';
+ add_filter(
+ 'ep_prepare_meta_allowed_keys',
+ function( $allowed_metakeys ) {
+ return array_merge( $allowed_metakeys, [ 'meta' ] );
+ }
+ );
add_filter(
'ep_prepare_meta_allowed_protected_keys',
function () use ( $meta_protected_allowed ) {
@@ -8020,12 +8051,13 @@ function () use ( $meta_not_protected_excluded ) {
);
$indexable = \ElasticPress\Indexables::factory()->get( 'post' );
+ $post = new \WP_Post( (object) [ 'post_type' => 'post' ] );
- $this->assertTrue( $indexable->is_meta_allowed( $meta_not_protected, null ) );
- $this->assertTrue( $indexable->is_meta_allowed( $meta_protected_allowed, null ) );
+ $this->assertTrue( $indexable->is_meta_allowed( $meta_not_protected, $post ) );
+ $this->assertTrue( $indexable->is_meta_allowed( $meta_protected_allowed, $post ) );
- $this->assertFalse( $indexable->is_meta_allowed( $meta_not_protected_excluded, null ) );
- $this->assertFalse( $indexable->is_meta_allowed( $meta_protected, null ) );
+ $this->assertFalse( $indexable->is_meta_allowed( $meta_not_protected_excluded, $post ) );
+ $this->assertFalse( $indexable->is_meta_allowed( $meta_protected, $post ) );
}
/**
@@ -8037,16 +8069,16 @@ function () use ( $meta_not_protected_excluded ) {
public function testGetDistinctMetaFieldKeys() {
$indexable = \ElasticPress\Indexables::factory()->get( 'post' );
- $this->ep_factory->post->create( array( 'meta_input' => array( 'new_meta_key_1' => '' ) ) );
- $this->ep_factory->post->create( array( 'meta_input' => array( 'new_meta_key_2' => '' ) ) );
+ $this->ep_factory->post->create( array( 'meta_input' => array( 'test_key1' => '' ) ) );
+ $this->ep_factory->post->create( array( 'meta_input' => array( 'test_key2' => '' ) ) );
ElasticPress\Elasticsearch::factory()->refresh_indices();
$distinct_meta_field_keys = $indexable->get_distinct_meta_field_keys();
$this->assertIsArray( $distinct_meta_field_keys );
- $this->assertContains( 'new_meta_key_1', $distinct_meta_field_keys );
- $this->assertContains( 'new_meta_key_2', $distinct_meta_field_keys );
+ $this->assertContains( 'test_key1', $distinct_meta_field_keys );
+ $this->assertContains( 'test_key2', $distinct_meta_field_keys );
}
/**
@@ -8058,36 +8090,36 @@ public function testGetDistinctMetaFieldKeys() {
public function testGetAllDistinctValues() {
$indexable = \ElasticPress\Indexables::factory()->get( 'post' );
- $this->ep_factory->post->create( array( 'meta_input' => array( 'new_meta_key_1' => 'foo' ) ) );
- $this->ep_factory->post->create( array( 'meta_input' => array( 'new_meta_key_1' => 'bar' ) ) );
- $this->ep_factory->post->create( array( 'meta_input' => array( 'new_meta_key_1' => 'foobar' ) ) );
+ $this->ep_factory->post->create( array( 'meta_input' => array( 'test_key1' => 'foo' ) ) );
+ $this->ep_factory->post->create( array( 'meta_input' => array( 'test_key1' => 'bar' ) ) );
+ $this->ep_factory->post->create( array( 'meta_input' => array( 'test_key1' => 'foobar' ) ) );
- $this->ep_factory->post->create( array( 'meta_input' => array( 'new_meta_key_2' => 'lorem' ) ) );
- $this->ep_factory->post->create( array( 'meta_input' => array( 'new_meta_key_2' => 'ipsum' ) ) );
+ $this->ep_factory->post->create( array( 'meta_input' => array( 'test_key2' => 'lorem' ) ) );
+ $this->ep_factory->post->create( array( 'meta_input' => array( 'test_key2' => 'ipsum' ) ) );
ElasticPress\Elasticsearch::factory()->refresh_indices();
- $distinct_values = $indexable->get_all_distinct_values( 'meta.new_meta_key_1.raw' );
+ $distinct_values = $indexable->get_all_distinct_values( 'meta.test_key1.raw' );
$this->assertCount( 3, $distinct_values );
$this->assertContains( 'foo', $distinct_values );
$this->assertContains( 'bar', $distinct_values );
$this->assertContains( 'foobar', $distinct_values );
- $distinct_values = $indexable->get_all_distinct_values( 'meta.new_meta_key_1.raw', 1 );
+ $distinct_values = $indexable->get_all_distinct_values( 'meta.test_key1.raw', 1 );
$this->assertCount( 1, $distinct_values );
$this->assertContains( 'bar', $distinct_values );
$change_bucket_size = function( $count, $field ) {
- return ( 'meta.new_meta_key_1.raw' === $field ) ? 1 : $count;
+ return ( 'meta.test_key1.raw' === $field ) ? 1 : $count;
};
add_filter( 'ep_post_all_distinct_values', $change_bucket_size, 10, 2 );
- $distinct_values_1 = $indexable->get_all_distinct_values( 'meta.new_meta_key_1.raw' );
+ $distinct_values_1 = $indexable->get_all_distinct_values( 'meta.test_key1.raw' );
$this->assertCount( 1, $distinct_values_1 );
$this->assertContains( 'bar', $distinct_values_1 );
- $distinct_values_2 = $indexable->get_all_distinct_values( 'meta.new_meta_key_2.raw' );
+ $distinct_values_2 = $indexable->get_all_distinct_values( 'meta.test_key2.raw' );
$this->assertCount( 2, $distinct_values_2 );
$this->assertContains( 'lorem', $distinct_values_2 );
$this->assertContains( 'ipsum', $distinct_values_2 );
@@ -8558,7 +8590,7 @@ public function testGetDistinctMetaFieldKeysDbPerPostType() {
$this->setupDistinctMetaFieldKeysDbPerPostType();
- $meta_keys = [ '_private_key', 'test_key_1', 'test_key_2' ];
+ $meta_keys = [ '_private_key', 'test_key1', 'test_key2' ];
$this->assertSame( $meta_keys, $indexable->get_distinct_meta_field_keys_db_per_post_type( 'ep_test' ) );
/**
@@ -8640,8 +8672,8 @@ public function testGetIndexableMetaKeysPerPostType() {
'post_type' => 'ep_test',
'meta_input' => [
'_private_key' => 'private-meta',
- 'test_key_1' => 'meta value 1',
- 'test_key_2' => 'meta value 2.1',
+ 'test_key1' => 'meta value 1',
+ 'test_key2' => 'meta value 2.1',
],
]
);
@@ -8649,21 +8681,21 @@ public function testGetIndexableMetaKeysPerPostType() {
[
'post_type' => 'ep_test_2',
'meta_input' => [
- 'test_key_2' => 'meta value 2.2',
- 'test_key_3' => 'meta value 3',
+ 'test_key2' => 'meta value 2.2',
+ 'test_key3' => 'meta value 3',
],
]
);
- $meta_keys = [ 'test_key_1', 'test_key_2' ];
+ $meta_keys = [ 'test_key1', 'test_key2' ];
$this->assertEqualsCanonicalizing( $meta_keys, $indexable->get_indexable_meta_keys_per_post_type( 'ep_test' ) );
$change_allowed_meta = function () {
- return [ 'test_key_1' => 'meta value 1' ];
+ return [ 'test_key1' => 'meta value 1' ];
};
add_filter( 'ep_prepare_meta_data', $change_allowed_meta );
- $meta_keys = [ 'test_key_1' ];
+ $meta_keys = [ 'test_key1' ];
$this->assertEqualsCanonicalizing( $meta_keys, $indexable->get_indexable_meta_keys_per_post_type( 'ep_test' ) );
}
@@ -8681,8 +8713,8 @@ public function testGetPredictedIndexableMetaKeys() {
'post_type' => 'ep_test',
'meta_input' => [
'_private_key' => 'private-meta',
- 'test_key_1' => 'meta value 1',
- 'test_key_2' => 'meta value 2.1',
+ 'test_key1' => 'meta value 1',
+ 'test_key2' => 'meta value 2.1',
],
]
);
@@ -8690,21 +8722,21 @@ public function testGetPredictedIndexableMetaKeys() {
[
'post_type' => 'ep_test_2',
'meta_input' => [
- 'test_key_2' => 'meta value 2.2',
- 'test_key_3' => 'meta value 3',
+ 'test_key2' => 'meta value 2.2',
+ 'test_key3' => 'meta value 3',
],
]
);
- $meta_keys = [ 'test_key_1', 'test_key_2', 'test_key_3' ];
+ $meta_keys = [ 'test_key1', 'test_key2', 'test_key3' ];
$this->assertEqualsCanonicalizing( $meta_keys, $indexable->get_predicted_indexable_meta_keys() );
$change_allowed_meta = function () {
- return [ 'test_key_1' => 'meta value 1' ];
+ return [ 'test_key1' => 'meta value 1' ];
};
add_filter( 'ep_prepare_meta_data', $change_allowed_meta );
- $meta_keys = [ 'test_key_1' ];
+ $meta_keys = [ 'test_key1' ];
$this->assertEqualsCanonicalizing( $meta_keys, $indexable->get_predicted_indexable_meta_keys() );
}
@@ -8750,8 +8782,8 @@ protected function setupDistinctMetaFieldKeysDbPerPostType() {
'post_type' => 'ep_test',
'meta_input' => [
'_private_key' => 'private-meta',
- 'test_key_1' => 'meta value 1',
- 'test_key_2' => 'meta value 2.1',
+ 'test_key1' => 'meta value 1',
+ 'test_key2' => 'meta value 2.1',
],
]
);
@@ -8759,8 +8791,8 @@ protected function setupDistinctMetaFieldKeysDbPerPostType() {
[
'post_type' => 'ep_test_2',
'meta_input' => [
- 'test_key_2' => 'meta value 2.2',
- 'test_key_3' => 'meta value 3',
+ 'test_key2' => 'meta value 2.2',
+ 'test_key3' => 'meta value 3',
],
]
);
From 68d1213614b599da048af6bcce767620b4fc5ef8 Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 19:17:48 -0300
Subject: [PATCH 62/63] Fix lint
---
tests/php/indexables/TestPost.php | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tests/php/indexables/TestPost.php b/tests/php/indexables/TestPost.php
index f0ffce19aa..412e9936b5 100644
--- a/tests/php/indexables/TestPost.php
+++ b/tests/php/indexables/TestPost.php
@@ -3961,7 +3961,7 @@ public function testPrepareMetaManual() {
// Set changed weighting
remove_filter( 'ep_weighting_configuration', $set_default_weighting );
$set_changed_weighting = function() use ( $weighting_default ) {
- $weighting_default['post']['meta.test_key2.value'] = [
+ $weighting_default['post']['meta.test_key2.value'] = [
'enabled' => true,
'weight' => 1,
];
@@ -4203,7 +4203,7 @@ public function testMetaKeyQueryMix() {
array(
'post_content' => 'post content findme',
'meta_input' => array(
- 'test_key' => 5,
+ 'test_key' => 5,
'test_key2' => 'aaa',
),
)
@@ -8672,8 +8672,8 @@ public function testGetIndexableMetaKeysPerPostType() {
'post_type' => 'ep_test',
'meta_input' => [
'_private_key' => 'private-meta',
- 'test_key1' => 'meta value 1',
- 'test_key2' => 'meta value 2.1',
+ 'test_key1' => 'meta value 1',
+ 'test_key2' => 'meta value 2.1',
],
]
);
@@ -8713,8 +8713,8 @@ public function testGetPredictedIndexableMetaKeys() {
'post_type' => 'ep_test',
'meta_input' => [
'_private_key' => 'private-meta',
- 'test_key1' => 'meta value 1',
- 'test_key2' => 'meta value 2.1',
+ 'test_key1' => 'meta value 1',
+ 'test_key2' => 'meta value 2.1',
],
]
);
@@ -8782,8 +8782,8 @@ protected function setupDistinctMetaFieldKeysDbPerPostType() {
'post_type' => 'ep_test',
'meta_input' => [
'_private_key' => 'private-meta',
- 'test_key1' => 'meta value 1',
- 'test_key2' => 'meta value 2.1',
+ 'test_key1' => 'meta value 1',
+ 'test_key2' => 'meta value 2.1',
],
]
);
From e35af9b86ffecd3825bf97b53c9c3b4f1489bf9e Mon Sep 17 00:00:00 2001
From: Felipe Elia
Date: Wed, 25 Oct 2023 19:48:24 -0300
Subject: [PATCH 63/63] Fix testIndexableContentReport
---
tests/php/screen/TestStatusReport.php | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/tests/php/screen/TestStatusReport.php b/tests/php/screen/TestStatusReport.php
index 8ce68f74e2..9c63158f25 100644
--- a/tests/php/screen/TestStatusReport.php
+++ b/tests/php/screen/TestStatusReport.php
@@ -236,6 +236,15 @@ public function testIndexableContentReport() {
$meta_fields = array();
$distinct_meta_keys = array();
+ $allow_metakeys = function ( $keys ) use ( $post_types ) {
+ $keys[] = 'shared_meta_key';
+ foreach ( $post_types as $post_type ) {
+ $keys[] = "unique_meta_key_{$post_type}";
+ }
+ return $keys;
+ };
+ add_filter( 'ep_prepare_meta_allowed_keys', $allow_metakeys );
+
foreach ( $post_types as $post_type ) {
$this->ep_factory->post->create_many(
10,