PluginProbe
ElasticPress / 5.0.0
ElasticPress v5.0.0
5.3.5 5.3.4 3.6.5 3.6.6 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.7.0 4.7.1 4.7.2 5.0.0 5.0.1 5.0.2 All 108 releases
elasticpress / assets / js / weighting / components / group.js

group.js in ElasticPress 5.0.0, at assets/js/weighting/components/group.js

195 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * WordPress dependencies.
3 */
4 import { Button, PanelRow, TextControl } from '@wordpress/components';
5 import { useMemo, useState, WPElement } from '@wordpress/element';
6 import { __, sprintf } from '@wordpress/i18n';
7
8 /**
9 * Internal dependencies.
10 */
11 import { useSettingsScreen } from '../../settings-screen';
12 import { useWeightingSettings } from '../provider';
13 import Field from './field';
14
15 /**
16 * Post type propertes component.
17 *
18 * @param {object} props Component props.
19 * @param {string} props.group Group.
20 * @param {string} props.postType Post type.
21 * @returns {WPElement} Component element.
22 */
23 export default ({ group, postType }) => {
24 const { createNotice } = useSettingsScreen();
25 const { currentWeightingConfiguration, setWeightingForPostType, weightableFields } =
26 useWeightingSettings();
27
28 /**
29 * State.
30 */
31 const [toAdd, setToAdd] = useState('');
32
33 /**
34 * Saved weighting values for this group's post type.
35 */
36 const values = currentWeightingConfiguration[postType];
37 const { fields } = weightableFields.find((w) => w.key === postType);
38
39 /**
40 * Whether this is the Metadata group.
41 */
42 const isMetadata = group === 'ep_metadata';
43
44 /**
45 * Fields that belond to this group.
46 */
47 const defaultFields = useMemo(() => fields.filter((f) => f.group === group), [fields, group]);
48
49 /**
50 * Custom fields.
51 *
52 * These are meta fields that have a saved weighting value but are not
53 * included in the list of weightable fields. This will be fields that
54 * were added manually using the UI.
55 */
56 const customFields = useMemo(() => {
57 if (!isMetadata) {
58 return [];
59 }
60
61 const fieldKeys = fields.map(({ key }) => key);
62
63 const customFields = Object.keys(values).reduce((customFields, key) => {
64 if (fieldKeys.includes(key)) {
65 return customFields;
66 }
67
68 const matches = key.match(/meta\.(?<label>.*)\.value/);
69
70 if (!matches) {
71 return customFields;
72 }
73
74 const { label } = matches.groups;
75
76 customFields.push({
77 key,
78 label,
79 });
80
81 return customFields;
82 }, []);
83
84 return customFields;
85 }, [fields, isMetadata, values]);
86
87 /**
88 * Handle changes to a property.
89 *
90 * @param {object} value New property data.
91 * @param {number} key Property key.
92 * @returns {void}
93 */
94 const onChange = (value, key) => {
95 setWeightingForPostType(postType, { ...values, [key]: value });
96 };
97
98 /**
99 * Handle clicking to add a new property.
100 *
101 * @returns {void}
102 */
103 const onClick = () => {
104 const key = `meta.${toAdd}.value`;
105
106 const isDefaultField = defaultFields.some((f) => f.key === key);
107 const isCustomField = customFields.some((f) => f.key === key);
108
109 if (isDefaultField || isCustomField) {
110 /* translators: Field name */
111 createNotice('info', sprintf(__('%s is already being synced.', 'elasticpress'), toAdd));
112 return;
113 }
114
115 const newValues = { ...values, [key]: { enabled: false, weight: 0 } };
116
117 setWeightingForPostType(postType, newValues);
118 setToAdd('');
119 };
120
121 /**
122 * Handle removing a field.
123 *
124 * @param {number} key field key.
125 * @returns {void}
126 */
127 const onDelete = (key) => {
128 const newValues = { ...values };
129
130 delete newValues[key];
131
132 setWeightingForPostType(postType, newValues);
133 };
134
135 /**
136 * Handle pressing Enter key when adding a field.
137 *
138 * @param {Event} event Keydown event.
139 */
140 const onKeyDown = (event) => {
141 if (event.key === 'Enter') {
142 event.preventDefault();
143 onClick();
144 }
145 };
146
147 return (
148 <>
149 {defaultFields.map(({ key, label }) => (
150 <PanelRow key={key}>
151 <Field
152 label={label}
153 value={values[key] || {}}
154 onChange={(value) => {
155 onChange(value, key);
156 }}
157 />
158 </PanelRow>
159 ))}
160 {customFields.map(({ key, label }) => (
161 <PanelRow key={key}>
162 <Field
163 label={label}
164 value={values[key] || {}}
165 onChange={(value) => {
166 onChange(value, key);
167 }}
168 onDelete={() => {
169 onDelete(key);
170 }}
171 />
172 </PanelRow>
173 ))}
174 {isMetadata ? (
175 <PanelRow className="ep-weighting-add-new">
176 <TextControl
177 help={__(
178 'Make sure to Sync after adding new fields to ensure that the fields are synced for any existing content that uses them.',
179 'elasticpress',
180 )}
181 label={__('Add field', 'elasticpress')}
182 onChange={(toAdd) => setToAdd(toAdd)}
183 onKeyDown={onKeyDown}
184 placeholder={__('Metadata key', 'elasticpress')}
185 value={toAdd}
186 />
187 <Button disabled={!toAdd} isSecondary onClick={onClick} variant="secondary">
188 {__('Add', 'elasticpress')}
189 </Button>
190 </PanelRow>
191 ) : null}
192 </>
193 );
194 };
195