import React, { useCallback, useEffect, useState } from 'react'; import { __, sprintf } from "@wordpress/i18n"; import ReactSelect from "react-select"; import { isArray, isObject, merge, useBuilderContext, useOptions, valueExists, when, withLabel, wpFetch } from 'quickbuilder'; import Tippy from '@tippyjs/react'; // Install with `npm install @tippyjs/react` import 'tippy.js/dist/tippy.css'; // Tippy.js styles import '../../scss/model-select.scss'; const CustomOption = (props) => { const { data, innerRef, innerProps, isFocused, isSelected, selectProps, // Contains classNamePrefix } = props; // Construct class names using classNamePrefix const prefix = selectProps.classNamePrefix || 'react-select'; const optionClassName = `${prefix}__option`; const focusedClassName = isFocused ? `${optionClassName}--is-focused` : ''; const selectedClassName = isSelected ? `${optionClassName}--is-selected` : ''; return (
{data.label} {data.tooltip && ( )}
); }; const EmbedModelSelect = (props) => { const builderContext = useBuilderContext(); let { id, name, multiple, placeholder, search = false, onChange, parentIndex } = props; const { options, selectedOption, setOptions, setData } = useOptions(props, 'options'); const [sOption, setSOption] = useState(null); const [isLoading, setIsLoading] = useState(false); const [isAjaxComplete, setIsAjaxComplete] = useState(false); const handleMenuOpen = () => { if (props.ajax && (!props.ajax.rules || when(props.ajax.rules, builderContext.values))) { setIsLoading(true); let data = {}; Object.keys(props?.ajax.data).map(singleData => { if (props?.ajax.data[singleData].indexOf('@') > -1) { let eligibleKey = props?.ajax.data[singleData].substr(1); data[singleData] = builderContext.values?.[eligibleKey]; } else { data[singleData] = props?.ajax.data[singleData]; } }); if (!isAjaxComplete) { return wpFetch({ path: props?.ajax.api, data: data }).then((response) => { setIsLoading(false); const arrayMerge = merge(props.options, response, 'value'); builderContext.setFormField([...parentIndex, 'options'], arrayMerge); setData({ options: arrayMerge, parentIndex: [...parentIndex, 'options'] }); return response; }); } } }; const handleMenuClose = () => { setIsLoading(false); }; useEffect(() => { if (!isArray(sOption) && isObject(sOption)) { onChange({ target: { type: 'select', name, value: sOption.value, options, multiple }, }); } if (isArray(sOption)) { onChange({ target: { type: 'select', name, value: sOption.map(item => item.value), options, multiple }, }); } }, [sOption]); useEffect(() => { handleMenuOpen(); }, []); useEffect(() => { if (props?.menuOpen) { handleMenuOpen(); } }, [props?.menuOpen]); const handleOptionChange = useCallback((option) => { if (isArray(option) && props?.filterValue?.length > 0) { const origialValues = option; let values = origialValues; let filterValue = props?.filterValue ?? ['all']; if (!isArray(filterValue)) { filterValue = [filterValue]; } if (origialValues?.length > 1 && valueExists(origialValues.map(item => item.value), filterValue)) { values = origialValues.filter((item) => !filterValue.includes(item?.value)); } option = values; } setSOption(option); }, [name, id, parentIndex]); // Conditional components prop const selectComponents = props.options_tooltip ? { Option: CustomOption } : undefined; return (
option?.disabled} onChange={handleOptionChange} components={selectComponents} // Conditional rendering of tooltip-enabled options /> {betterdocs_admin?.count_new_docs > 0 && (
{sprintf( __('Sync pending posts (%d)', 'betterdocs'), betterdocs_admin?.count_new_docs )}
)}
); }; export default withLabel(EmbedModelSelect);