UNPKG

@appbuckets/react-ui-smart-components

Version:

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

292 lines (285 loc) 9.35 kB
'use strict'; var _tslib = require('../_virtual/_tslib.js'); var React = require('react'); var arraySort = require('array-sort'); var reactAppClient = require('@appbuckets/react-app-client'); function _interopDefaultLegacy(e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty( n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; }, } ); } }); } n['default'] = e; return Object.freeze(n); } var React__namespace = /*#__PURE__*/ _interopNamespace(React); var arraySort__default = /*#__PURE__*/ _interopDefaultLegacy(arraySort); // 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 = _tslib.__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( _tslib.__assign(_tslib.__assign({}, defaultProps), props) ) : overridePropsBuilder; /** Merge all props */ var componentProps = _tslib.__assign( _tslib.__assign(_tslib.__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 = _tslib.__rest(componentProps, [ 'filter', 'options', 'requestConfig', 'reloadDataOnMenuOpen', 'sort', 'Selector', ]); /* -------- * Rebuild Options using Sorter and Filter * -------- */ var _e = _tslib.__read( React__namespace.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__default['default'](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 = _tslib.__read( React__namespace.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 = _tslib.__rest(_g, ['url', 'method']); // eslint-disable-next-line clientRequest = reactAppClient.useClientRequest({ url: url, method: method, request: _tslib.__assign( _tslib.__assign({}, restRequestConfig), userDefinedRequestConfig ), }); } /* -------- * Hooks and State Definition * -------- */ var _h = _tslib.__read( React__namespace.useState(function () { return getOptionsList( defaultDefinedOptions || userDefinedOptions || [] ); }), 2 ), options = _h[0], setOptions = _h[1]; var _j = _tslib.__read(React__namespace.useState(isAPISelector), 2), isInitiallyLoading = _j[0], setInitiallyLoading = _j[1]; /* -------- * Data Reloading Hook * -------- */ if (isAPISelector && clientRequest) { // eslint-disable-next-line React__namespace.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__namespace.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__namespace.createElement( Selector, _tslib.__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; } module.exports = buildSelector;