UNPKG

@appbuckets/react-ui-smart-components

Version:

UI Extended Components that work with @appbuckets/react-client and @appbuckets/react-ui

253 lines (250 loc) 8.3 kB
import { __rest, __assign, __read } from '../_virtual/_tslib.js'; import * as React from 'react'; import arraySort from 'array-sort'; import { useClientRequest } from '@appbuckets/react-app-client'; // eslint-disable-next-line max-len function buildSelector(config) { var /** Component Options */ displayName = config.displayName, DefaultDefinedSelector = config.Selector, defaultGetOptionValue = config.getOptionValue, defaultGetOptionLabel = config.getOptionLabel, /** Props Builder */ defaultPropsBuilder = config.defaultProps, overridePropsBuilder = config.overrideProps, /** Client Request Configuration */ defaultReloadDataOnMenuOpen = config.reloadDataOnMenuOpen, request = config.request, useHook = config.useHook, /** Data Manipulation */ defaultDefinedFilter = config.filter, defaultDefinedOptions = config.options, defaultDefinedSort = config.sort, /** Text Options */ defaultPlaceholder = config.placeholder, defaultNoOptionsMessage = config.noOptionsMessage; /** Define the SelectorWrapper */ var SelectorWrapper = function (props) { var _a, _b, _c, _d; var UserDefinedSelector = props.Selector, restProps = __rest(props, ['Selector']); /* -------- * Build the Component Props * using defined default props * builder and override props * -------- */ /** Compute Default Props */ var defaultProps = typeof defaultPropsBuilder === 'function' ? defaultPropsBuilder(restProps) : defaultPropsBuilder; /** Compute override Props */ var overrideProps = typeof overridePropsBuilder === 'function' ? overridePropsBuilder(__assign(__assign({}, defaultProps), props)) : overridePropsBuilder; /** Merge all props */ var componentProps = __assign( __assign(__assign({}, defaultProps), props), overrideProps ); /** Get Selector Props */ var userDefinedFilter = componentProps.filter, userDefinedOptions = componentProps.options, userDefinedRequestConfig = componentProps.requestConfig, userDefinedReloadDataOnMenuOpen = componentProps.reloadDataOnMenuOpen, userDefinedSort = componentProps.sort, OverrideSelector = componentProps.Selector, restSelectProps = __rest(componentProps, [ 'filter', 'options', 'requestConfig', 'reloadDataOnMenuOpen', 'sort', 'Selector', ]); /* -------- * Rebuild Options using Sorter and Filter * -------- */ var _e = __read( React.useState(function () { return typeof useHook === 'function'; }), 1 ), hasHook = _e[0]; var hookResult = hasHook ? useHook() : undefined; var getOptionsList = function (optionsList) { /** Build Data */ var data = typeof optionsList === 'function' ? optionsList(props, hookResult) : optionsList; /** Filter Data */ var filter = defaultDefinedFilter !== null && defaultDefinedFilter !== void 0 ? defaultDefinedFilter : userDefinedFilter; var filteredData = typeof filter === 'function' ? data.filter(filter) : data; /** Get Sorter */ var sort = defaultDefinedSort !== null && defaultDefinedSort !== void 0 ? defaultDefinedSort : userDefinedSort; return Array.isArray(sort) ? arraySort(filteredData, sort) : filteredData; }; /** * In this special case, useClientRequest hook will * be called conditionally. * It means that once a selector has been initialized using * an API request it could not change to plain data selector * without showing a React Warning. * To prevent any accidentally change of this behaviour * isAPISelector will be saved as a state variable to never * change on component using */ var _f = __read( React.useState( (typeof request === 'object' && request !== null) || typeof request === 'function' ), 1 ), isAPISelector = _f[0]; var clientRequest = null; if (isAPISelector) { var _g = typeof request === 'function' ? request(componentProps) : request, url = _g.url, method = _g.method, restRequestConfig = __rest(_g, ['url', 'method']); // eslint-disable-next-line clientRequest = useClientRequest({ url: url, method: method, request: __assign( __assign({}, restRequestConfig), userDefinedRequestConfig ), }); } /* -------- * Hooks and State Definition * -------- */ var _h = __read( React.useState(function () { return getOptionsList( defaultDefinedOptions || userDefinedOptions || [] ); }), 2 ), options = _h[0], setOptions = _h[1]; var _j = __read(React.useState(isAPISelector), 2), isInitiallyLoading = _j[0], setInitiallyLoading = _j[1]; /* -------- * Data Reloading Hook * -------- */ if (isAPISelector && clientRequest) { // eslint-disable-next-line React.useEffect( function () { if (!clientRequest || clientRequest.isLoading) { return; } if (clientRequest.error) { return; } setOptions(getOptionsList(clientRequest.response)); setInitiallyLoading(false); }, // eslint-disable-next-line [clientRequest, clientRequest.isLoading, clientRequest.response] ); } /* -------- * Handlers * -------- */ var handleMenuOpen = React.useCallback( function (nothing, selectProps) { var mustReload = defaultReloadDataOnMenuOpen !== null && defaultReloadDataOnMenuOpen !== void 0 ? defaultReloadDataOnMenuOpen : userDefinedReloadDataOnMenuOpen; if (clientRequest && mustReload) { clientRequest.reload(); } if (restSelectProps.onMenuOpen) { restSelectProps.onMenuOpen(nothing, selectProps); } }, [clientRequest, restSelectProps, userDefinedReloadDataOnMenuOpen] ); // @ts-ignore var Selector = (_a = OverrideSelector !== null && OverrideSelector !== void 0 ? OverrideSelector : UserDefinedSelector) !== null && _a !== void 0 ? _a : DefaultDefinedSelector; var isLoading = isInitiallyLoading || !!(clientRequest === null || clientRequest === void 0 ? void 0 : clientRequest.isLoading); var isDisabled = restSelectProps.disabled || !!(clientRequest === null || clientRequest === void 0 ? void 0 : clientRequest.error); /** Return the Selector Component */ return ( // @ts-ignore React.createElement( Selector, __assign( { isClearable: true, getOptionValue: defaultGetOptionValue, getOptionLabel: defaultGetOptionLabel, }, restSelectProps, { defaultValue: restSelectProps.defaultValue, noOptionsMessage: (_b = restSelectProps.noOptionsMessage) !== null && _b !== void 0 ? _b : defaultNoOptionsMessage, placeholder: (_c = restSelectProps.placeholder) !== null && _c !== void 0 ? _c : defaultPlaceholder, name: (_d = restSelectProps.name) !== null && _d !== void 0 ? _d : 'unnamed-selector', danger: restSelectProps.danger || !!(clientRequest === null || clientRequest === void 0 ? void 0 : clientRequest.error), disabled: isLoading || isDisabled, loading: isLoading, options: options, onMenuOpen: handleMenuOpen, } ) ) ); }; /** Set the Display Name */ SelectorWrapper.displayName = displayName; /** Return the Wrapped Component */ return SelectorWrapper; } export { buildSelector as default };