From ada37519f0074ea307c216a88a56db3908ca7560 Mon Sep 17 00:00:00 2001 From: Nishanth Date: Sun, 24 Dec 2023 07:15:15 +0000 Subject: [PATCH 1/4] changed to functional component --- .gitpod.yml | 11 + .../Search/widgets/SelectMetadataField.jsx | 325 ++++++++---------- 2 files changed, 159 insertions(+), 177 deletions(-) create mode 100644 .gitpod.yml diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000000..fadb744a96 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,11 @@ +# This configuration file was automatically generated by Gitpod. +# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) +# and commit this file to your remote git repository to share the goodness with others. + +# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart + +tasks: + - init: pnpm install && pnpm run build && make + command: pnpm run start + + diff --git a/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx b/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx index 1d9f8e80d6..5d6e217708 100644 --- a/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx +++ b/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx @@ -3,8 +3,8 @@ * @module components/manage/Widgets/SelectWidget */ -import { map, intersection, filter, toPairs, groupBy } from 'lodash'; -import React, { Component } from 'react'; +import { map, filter, toPairs, groupBy } from 'lodash'; +import { useEffect } from 'react'; import PropTypes from 'prop-types'; import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import { compose } from 'redux'; @@ -30,187 +30,158 @@ const messages = defineMessages({ }); /** - * SelectWidget component class. + * SelectWidget component function. * @function SelectWidget * @returns {string} Markup of the component. */ -class SelectWidget extends Component { - /** - * Property types. - * @property {Object} propTypes Property types. - * @static - */ - static propTypes = { - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - description: PropTypes.string, - required: PropTypes.bool, - error: PropTypes.arrayOf(PropTypes.string), - loading: PropTypes.bool, - value: PropTypes.oneOfType([ - PropTypes.object, - PropTypes.string, - PropTypes.bool, - ]), - onChange: PropTypes.func.isRequired, - onBlur: PropTypes.func, - onClick: PropTypes.func, - onEdit: PropTypes.func, - onDelete: PropTypes.func, - wrapped: PropTypes.bool, - querystring: PropTypes.object, - }; - - /** - * Default properties - * @property {Object} defaultProps Default properties. - * @static - */ - static defaultProps = { - description: null, - required: false, - items: { - vocabulary: null, - }, - widgetOptions: { - vocabulary: null, - }, - error: [], - choices: [], - loading: false, - value: null, - onChange: () => {}, - onBlur: () => {}, - onClick: () => {}, - onEdit: null, - onDelete: null, - }; - - state = { - selectedOption: this.props.value - ? { label: this.props.value.title, value: this.props.value.value } - : {}, - }; - - /** - * Component did mount - * @method componentDidMount - * @returns {undefined} - */ - componentDidMount() { - if (!this.props.choices && this.props.vocabBaseUrl) { - this.props.getVocabulary({ vocabNameOrURL: this.props.vocabBaseUrl }); +const SelectWidget = (props) => { + // const [selectedOption, setSelectedOption] = useState( + // props.value + // ? { label: props.value.title, value: props.value.value } + // : {} + // ); + + const { choices, vocabBaseUrl, getVocabulary } = props; + + useEffect(() => { + if (!choices && vocabBaseUrl) { + getVocabulary({ vocabNameOrURL: vocabBaseUrl }); } - } - - /** - * Initiate search with new query - * @method loadOptions - * @param {string} search Search query. - * @param {string} previousOptions The previous options rendered. - * @param {string} additional Additional arguments to pass to the next loadOptions. - * @returns {undefined} - */ - loadOptions = (search, previousOptions, additional) => { - let hasMore = this.props.itemsTotal > previousOptions.length; - if (hasMore) { - const offset = this.state.search !== search ? 0 : additional.offset; - this.props.getVocabulary({ - vocabNameOrURL: this.props.vocabBaseUrl, - query: search, - start: offset, - }); - this.setState({ search }); - - return { - options: - intersection(previousOptions, this.props.choices).length === - this.props.choices.length - ? [] - : this.props.choices, - hasMore: hasMore, - additional: { - offset: offset === additional.offset ? offset + 25 : offset, - }, - }; - } - return null; - }; - - /* Customized to pass object instead of plain string value */ - handleChange = (selectedOption) => { - this.setState({ selectedOption }); - this.props.onChange(this.props.id, { - value: selectedOption.value, - title: selectedOption.label, - }); - }; - - /** - * Render method. - * @method render - * @returns {string} Markup for the component. - */ - render() { - const { - id, - // choices, - value, - onChange, - placeholder, - querystring, - filterOptions = identity, - } = this.props; - const isDisabled = false; - const { indexes = [] } = querystring; - - const Select = this.props.reactSelect.default; - - return ( - - item[1].group), + ), + (group) => ({ + label: group[0], + options: map( + filter(group[1], (item) => item[1].enabled), + (field) => ({ + label: field[1].title, + value: field[0], + }), ), - (group) => ({ - label: group[0], - options: map( - filter(group[1], (item) => item[1].enabled), - (field) => ({ - label: field[1].title, - value: field[0], - }), - ), - }), - )} - styles={customSelectStyles} - theme={selectTheme} - components={{ DropdownIndicator, Option }} - value={{ value: value?.value, label: indexes[value?.value]?.title }} - onChange={(data) => { - let dataValue = []; - if (Array.isArray(data)) { - for (let obj of data) { - dataValue.push(obj.value); - } - return onChange(id, dataValue); + }), + )} + styles={customSelectStyles} + theme={selectTheme} + components={{ DropdownIndicator, Option }} + value={{ + value: value?.value, + label: indexes[value?.value]?.title, + }} + onChange={(data) => { + let dataValue = []; + if (Array.isArray(data)) { + for (let obj of data) { + dataValue.push(obj.value); } - return onChange(id, data); - }} - /> - - ); - } -} + return onChange(id, dataValue); + } + return onChange(id, data); + }} + /> + + ); +}; + +SelectWidget.propTypes = { + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + description: PropTypes.string, + required: PropTypes.bool, + error: PropTypes.arrayOf(PropTypes.string), + loading: PropTypes.bool, + value: PropTypes.oneOfType([ + PropTypes.object, + PropTypes.string, + PropTypes.bool, + ]), + onChange: PropTypes.func.isRequired, + onBlur: PropTypes.func, + onClick: PropTypes.func, + onEdit: PropTypes.func, + onDelete: PropTypes.func, + wrapped: PropTypes.bool, + querystring: PropTypes.object, +}; + +SelectWidget.defaultProps = { + description: null, + required: false, + items: { + vocabulary: null, + }, + widgetOptions: { + vocabulary: null, + }, + error: [], + choices: [], + loading: false, + value: null, + onChange: () => {}, + onBlur: () => {}, + onClick: () => {}, + onEdit: null, + onDelete: null, +}; export default compose( withQueryString, From 1787f169c25fb4104539580d2b8b6ae8df85ff95 Mon Sep 17 00:00:00 2001 From: Nishanth Date: Sun, 24 Dec 2023 07:30:11 +0000 Subject: [PATCH 2/4] added changelog entry --- packages/volto/news/5570.internal | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/volto/news/5570.internal diff --git a/packages/volto/news/5570.internal b/packages/volto/news/5570.internal new file mode 100644 index 0000000000..3875d2fb70 --- /dev/null +++ b/packages/volto/news/5570.internal @@ -0,0 +1 @@ +Refactored src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx to functional component. @lorstenoplo \ No newline at end of file From c73b95b7f12afb0cb16d348feeddcfe32beae3f3 Mon Sep 17 00:00:00 2001 From: Nishanth <69671750+lorstenoplo@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:19:47 +0530 Subject: [PATCH 3/4] Update packages/volto/news/5570.internal Co-authored-by: Steve Piercy --- packages/volto/news/5570.internal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/volto/news/5570.internal b/packages/volto/news/5570.internal index 3875d2fb70..7b26c18db0 100644 --- a/packages/volto/news/5570.internal +++ b/packages/volto/news/5570.internal @@ -1 +1 @@ -Refactored src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx to functional component. @lorstenoplo \ No newline at end of file +Refactored the `SelectWidget` component to a functional component. @lorstenoplo \ No newline at end of file From 996ffa73a95f97e1652aaf6451f3fe725421eebd Mon Sep 17 00:00:00 2001 From: lorstenoplo Date: Thu, 11 Jan 2024 23:20:09 +0530 Subject: [PATCH 4/4] removed gipod.yml, removed comments --- .gitpod.yml | 11 ----- .../Search/widgets/SelectMetadataField.jsx | 40 ------------------- 2 files changed, 51 deletions(-) delete mode 100644 .gitpod.yml diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index fadb744a96..0000000000 --- a/.gitpod.yml +++ /dev/null @@ -1,11 +0,0 @@ -# This configuration file was automatically generated by Gitpod. -# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) -# and commit this file to your remote git repository to share the goodness with others. - -# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart - -tasks: - - init: pnpm install && pnpm run build && make - command: pnpm run start - - diff --git a/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx b/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx index 5d6e217708..41a1bad625 100644 --- a/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx +++ b/packages/volto/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx @@ -35,12 +35,6 @@ const messages = defineMessages({ * @returns {string} Markup of the component. */ const SelectWidget = (props) => { - // const [selectedOption, setSelectedOption] = useState( - // props.value - // ? { label: props.value.title, value: props.value.value } - // : {} - // ); - const { choices, vocabBaseUrl, getVocabulary } = props; useEffect(() => { @@ -49,40 +43,6 @@ const SelectWidget = (props) => { } }, [choices, vocabBaseUrl, getVocabulary]); - // const loadOptions = (search, previousOptions, additional) => { - // let hasMore = props.itemsTotal > previousOptions.length; - // if (hasMore) { - // const offset = selectedOption.search !== search ? 0 : additional.offset; - // props.getVocabulary({ - // vocabNameOrURL: props.vocabBaseUrl, - // query: search, - // start: offset, - // }); - // setSelectedOption({ search }); - - // return { - // options: - // intersection(previousOptions, props.choices).length === - // props.choices.length - // ? [] - // : props.choices, - // hasMore: hasMore, - // additional: { - // offset: offset === additional.offset ? offset + 25 : offset, - // }, - // }; - // } - // return null; - // }; - - // const handleChange = (selectedOption) => { - // setSelectedOption(selectedOption); - // props.onChange(props.id, { - // value: selectedOption.value, - // title: selectedOption.label, - // }); - // }; - const { id, value,