Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fetchInitialResults prop to ContentSearch #124

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e040716
Add `fetchOnFocus` prop to ContentSearch
xipasduarte Jul 7, 2022
b405da3
Enable `fetchOnFocus` for empty ContentPickers
xipasduarte Jul 7, 2022
62fa1bb
Fix logic after adding state and onBlur.
xipasduarte Jul 8, 2022
4547c23
Correct typo and remove duplicate props.
xipasduarte Jul 8, 2022
9d762ac
New test block with just the Content Search component.
xipasduarte Jul 8, 2022
c18fe57
Cypress test script for Content Search logic with .
xipasduarte Jul 8, 2022
64a87e6
Cypress test script for new ContentPicker experience with focus.
xipasduarte Jul 8, 2022
a1e59c8
Replace `fetchOnFocus` with `fetchInitialResults`
xipasduarte Aug 5, 2022
63350b3
Add conditinal check for prop.
xipasduarte Aug 5, 2022
2677644
Add `fetchInitialResults` to `ContentPicker`
xipasduarte Aug 9, 2022
d7e695c
Merge branch 'develop' into issue-43/content-picker-focus-fetch
xipasduarte Sep 15, 2022
46c6d67
Merge branch 'develop' into issue-43/content-picker-focus-fetch
xipasduarte Nov 28, 2022
c62942d
Merge branch 'develop' into issue-43/content-picker-focus-fetch
fabiankaegy Dec 15, 2022
9edcfa3
Merge branch 'develop' into issue-43/content-picker-focus-fetch
fabiankaegy Dec 15, 2022
d28148b
Merge branch 'develop' into issue-43/content-picker-focus-fetch
fabiankaegy Dec 15, 2022
53c85a4
Merge branch 'develop' into issue-43/content-picker-focus-fetch
fabiankaegy Mar 2, 2023
a068f52
Merge branch 'develop' into issue-43/content-picker-focus-fetch
xipasduarte Apr 13, 2023
1ea3001
Update index.js
fabiankaegy May 24, 2023
2f891d5
Update readme.md
fabiankaegy May 24, 2023
e5c8bed
Merge branch 'develop' into issue-43/content-picker-focus-fetch
fabiankaegy May 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions components/content-picker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const ContentPickerWrapper = styled('div')`
* @param {boolean} props.uniqueContentItems whether or not the picker should only show unique items
* @param {boolean} props.excludeCurrentPost whether or not to exclude the current post from the picker
* @param {number} props.perPage number of items to show per page
* @param {boolean} props.fetchInitialResults whether or not to fetch initial results on mount
* @returns {*} React JSX
*/
const ContentPicker = ({
Expand All @@ -66,6 +67,7 @@ const ContentPicker = ({
uniqueContentItems,
excludeCurrentPost,
perPage,
fetchInitialResults,
}) => {
const currentPostId = select('core/editor')?.getCurrentPostId();

Expand Down Expand Up @@ -129,6 +131,7 @@ const ContentPicker = ({
mode={mode}
queryFilter={queryFilter}
perPage={perPage}
fetchInitialResults={fetchInitialResults}
/>
) : (
label && (
Expand Down Expand Up @@ -186,6 +189,7 @@ ContentPicker.defaultProps = {
excludeCurrentPost: true,
multiPickedLabel: __('You have selected the following items:', '10up-block-components'),
singlePickedLabel: __('You have selected the following item:', '10up-block-components'),
fetchInitialResults: false,
};

ContentPicker.propTypes = {
Expand All @@ -203,6 +207,7 @@ ContentPicker.propTypes = {
excludeCurrentPost: PropTypes.bool,
maxContentItems: PropTypes.number,
perPage: PropTypes.number,
fetchInitialResults: PropTypes.bool,
};

export { ContentPicker };
25 changes: 13 additions & 12 deletions components/content-picker/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ function MyComponent( props ) {

| Name | Type | Default | Description |
|----------------------|------------|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `onPickChange` | `function` | `undefined` | Callback function the list of picked content gets changed |
| `queryFilter` | `function` | `undefined` | Function called to allow you to customize the query before is made. It's advisable to use `useCallback` to save this parameter |
| `label` | `string` | `''` | Renders a label for the Search Field. |
| `mode` | `string` | `'post'` | One of: `post`, `user`, `term` |
| `placeholder` | `string` | `''` | Renders placeholder text inside the Search Field. |
| `contentTypes` | `array` | `[ 'post', 'page' ]` | Names of the post types or taxonomies that should get searched |
| `maxContentItems` | `number` | `1` | Max number of items a user can select. |
| `isOrderable` | `bool` | `false` | When true, will allow the user to order items. Must be used in conjunction with `maxContentItems > 1` |
| `uniqueContentItems` | `bool` | `true` | Prevent duplicate items from being picked. |
| `excludeCurrentPost` | `bool` | `true` | Don't allow user to pick the current post. Only applicable on the editor screen. |
| `content` | `array` | `[]` | Array of items to pre-populate picker with. Must be in the format of: `[{id: 1, type: 'post', uuid: '...',}, {id: 1, uuid: '...', type: 'page'},... ]`. You cannot provide terms and posts to the same picker. `uuid` was added as of version 1.5.0. It is only used as the React component list key in the admin. If it is not included, `id` will be used which will cause errors if you select the same post twice. |
| `perPage` | `number` | `50` | Number of items to show during search |
| `onPickChange` | `function` | `undefined` | Callback function the list of picked content gets changed |
| `queryFilter` | `function` | `undefined` | Function called to allow you to customize the query before is made. It's advisable to use `useCallback` to save this parameter |
| `label` | `string` | `''` | Renders a label for the Search Field. |
| `mode` | `string` | `'post'` | One of: `post`, `user`, `term` |
| `placeholder` | `string` | `''` | Renders placeholder text inside the Search Field. |
| `contentTypes` | `array` | `[ 'post', 'page' ]` | Names of the post types or taxonomies that should get searched |
| `maxContentItems` | `number` | `1` | Max number of items a user can select. |
| `isOrderable` | `bool` | `false` | When true, will allow the user to order items. Must be used in conjunction with `maxContentItems > 1` |
| `uniqueContentItems` | `bool` | `true` | Prevent duplicate items from being picked. |
| `excludeCurrentPost` | `bool` | `true` | Don't allow user to pick the current post. Only applicable on the editor screen. |
| `content` | `array` | `[]` | Array of items to pre-populate picker with. Must be in the format of: `[{id: 1, type: 'post', uuid: '...',}, {id: 1, uuid: '...', type: 'page'},... ]`. You cannot provide terms and posts to the same picker. `uuid` was added as of version 1.5.0. It is only used as the React component list key in the admin. If it is not included, `id` will be used which will cause errors if you select the same post twice. |
| `perPage` | `number` | `50` | Number of items to show during search
| `fetchInitialResults` | `bool` | `false` | Fetch initial results to present when focusing the search input | |
__NOTE:__ Content picker cannot validate that posts you pass it via `content` prop actually exist. If a post does not exist, it will not render as one of the picked items but will still be passed back as picked items if new items are picked/sorted. Therefore, on save you need to validate that all the picked posts/terms actually exist.

The `contentTypes` will get used in a Rest Request to the `search` endpoint as the `subtypes`:
Expand Down
27 changes: 22 additions & 5 deletions components/content-search/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ const ContentSearch = ({
queryFilter,
excludeItems,
renderItemType,
fetchInitialResults,
}) => {
const [searchString, setSearchString] = useState('');
const [searchQueries, setSearchQueries] = useState({});
const [selectedItem, setSelectedItem] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
const [isFocused, setIsFocused] = useState(false);

const mounted = useRef(true);

Expand Down Expand Up @@ -132,17 +134,17 @@ const ContentSearch = ({
/**
* handleSearchStringChange
*
* Using the keyword and the list of tags that are linked to the parent block
* search for posts/terms that match and return them to the autocomplete component.
* Using the keyword and the list of tags that are linked to the parent
* block search for posts/terms/users that match and return them to the
* autocomplete component.
*
* @param {string} keyword search query string
* @param {string} page page query string
*/
const handleSearchStringChange = (keyword, page) => {
// Reset page and query on empty keyword.
if (keyword.trim() === '') {
setSearchString(keyword);
setCurrentPage(1);
return;
}

const preparedQuery = prepareSearchQuery(keyword, page);
Expand Down Expand Up @@ -180,9 +182,15 @@ const ContentSearch = ({
};

useEffect(() => {
// Trigger initial fetch if enabled.
if (fetchInitialResults) {
handleSearchStringChange('', 1);
}

return () => {
mounted.current = false;
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
Expand Down Expand Up @@ -304,6 +312,7 @@ const ContentSearch = ({
}
const hasSearchString = !!searchString.length;
const hasSearchResults = searchResults && !!searchResults.length;
const hasInitialResults = fetchInitialResults && isFocused;

const listCSS = css`
/* stylelint-disable */
Expand Down Expand Up @@ -346,9 +355,15 @@ const ContentSearch = ({
}}
placeholder={placeholder}
autoComplete="off"
onFocus={() => {
setIsFocused(true);
}}
onBlur={() => {
setIsFocused(false);
}}
/>

{hasSearchString ? (
{hasSearchString || hasInitialResults ? (
<>
<ul className={`${NAMESPACE}-list`} css={listCSS}>
{isLoading && currentPage === 1 && (
Expand Down Expand Up @@ -427,6 +442,7 @@ ContentSearch.defaultProps = {
console.log('Select!'); // eslint-disable-line no-console
},
renderItemType: undefined,
fetchInitialResults: false,
};

ContentSearch.propTypes = {
Expand All @@ -439,6 +455,7 @@ ContentSearch.propTypes = {
label: PropTypes.string,
perPage: PropTypes.number,
renderItemType: PropTypes.func,
fetchInitialResults: PropTypes.bool,
};

export { ContentSearch };
Loading