UNPKG

@pnp/spfx-controls-react

Version:

Reusable React controls for SharePoint Framework solutions

238 lines • 10.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SitePicker = void 0; var tslib_1 = require("tslib"); var React = tslib_1.__importStar(require("react")); var findIndex_1 = tslib_1.__importDefault(require("lodash/findIndex")); var orderBy_1 = tslib_1.__importDefault(require("lodash/orderBy")); var react_1 = require("@fluentui/react"); var react_hooks_1 = require("@fluentui/react-hooks"); var telemetry = tslib_1.__importStar(require("../../common/telemetry")); var GeneralHelper_1 = require("../../common/utilities/GeneralHelper"); var SPSitesService_1 = require("../../services/SPSitesService"); var styles = (0, react_1.mergeStyleSets)({ loadingSpinnerContainer: { width: '100%', textAlign: 'center', marginTop: '8px', }, searchBox: { margin: '4px 0', }, siteOption: { display: 'flex', whiteSpace: 'nowrap', alignItems: 'center', }, siteOptionCheckbox: { display: 'inline-block', marginRight: '4px', }, siteOptionContent: { display: 'flex', flexDirection: 'column', minWidth: '0', padding: '4px 0', }, siteOptionTitle: { lineHeight: '18px', overflow: 'hidden', textOverflow: 'ellipsis', }, siteOptionUrl: { fontSize: '12px', lineHeight: '14px', fontWeight: '300', overflow: 'hidden', textOverflow: 'ellipsis', }, customChevronContainer: { display: 'flex', gap: '10px', }, }); var SitePicker = function (props) { var label = props.label, disabled = props.disabled, context = props.context, initialSites = props.initialSites, multiSelect = props.multiSelect, mode = props.mode, limitToCurrentSiteCollection = props.limitToCurrentSiteCollection, allowSearch = props.allowSearch, propOrderBy = props.orderBy, isDesc = props.isDesc, onChange = props.onChange, placeholder = props.placeholder, searchPlaceholder = props.searchPlaceholder, deferredSearchTime = props.deferredSearchTime, className = props.className, selectedSites = props.selectedSites, trimDuplicates = props.trimDuplicates, additionalQuery = props.additionalQuery, hubsiteId = props.hubsiteId; var _a = React.useState(), isLoading = _a[0], setIsLoading = _a[1]; var _b = React.useState(), sites = _b[0], setSites = _b[1]; var _c = React.useState(), allSites = _c[0], setAllSites = _c[1]; var _d = React.useState(), filteredSites = _d[0], setFilteredSites = _d[1]; var _e = React.useState(), searchQuery = _e[0], setSearchQuery = _e[1]; var async = (0, react_hooks_1.useAsync)(); var onSearchChange = React.useCallback(function (e, newSearchQuery) { if (!allSites) { return; } var loweredNewSearchQuery = newSearchQuery.toLowerCase(); var newFilteredSites = allSites.filter(function (s) { return s.title && s.title.toLowerCase().indexOf(loweredNewSearchQuery) !== -1; }); setSearchQuery(newSearchQuery); setFilteredSites(newFilteredSites); }, [allSites]); var clearItems = React.useCallback(function (event) { event.stopPropagation(); return setSites([]); }, [sites]); var CustomChevron = function () { if (sites && sites.length > 0) { return (React.createElement("div", { className: styles.customChevronContainer }, React.createElement(react_1.Icon, { iconName: "Cancel", onClick: clearItems }), React.createElement(react_1.Icon, { iconName: "ChevronDown" }))); } return (React.createElement("div", { className: styles.customChevronContainer }, React.createElement(react_1.Icon, { iconName: "ChevronDown" }))); }; var onSelectionChange = React.useCallback(function (e, item, index) { var newSelectedSites = []; if (multiSelect !== false) { newSelectedSites = sites ? tslib_1.__spreadArray([], sites, true) : []; var existingIndex = (0, findIndex_1.default)(newSelectedSites, function (s) { return s.url === item.key; }); if (existingIndex >= 0) { newSelectedSites.splice(existingIndex, 1); } else if (item.data) { newSelectedSites.push(tslib_1.__assign({}, item.data)); } } else if (item.data) { newSelectedSites = [ tslib_1.__assign({}, item.data), ]; } if (onChange) { onChange(newSelectedSites); } setSites(newSelectedSites); //console.log(`onselction change set sites to ${newSelectedSites[0].title}`); }, [sites, multiSelect, onChange]); var getOptions = React.useCallback(function () { if (!allSites) { return [ { key: 'spinner', text: '', itemType: react_1.SelectableOptionMenuItemType.Header, }, ]; } var result = []; if (allowSearch !== false) { result.push({ key: 'search', text: '', itemType: react_1.SelectableOptionMenuItemType.Header, }); } var selectedSitesIds = sites ? sites.map(function (s) { return s.url; }) : []; if (filteredSites) { filteredSites.forEach(function (s) { result.push({ key: s.url, text: s.title, data: s, selected: selectedSitesIds.indexOf(s.url) !== -1, }); }); } return result; }, [allowSearch, sites, filteredSites, allSites]); var onRenderOption = function (option, defaultRender) { if (!props) { return null; } if (option.itemType === react_1.SelectableOptionMenuItemType.Header) { if (option.key === 'search') { return (React.createElement(react_1.SearchBox, { placeholder: searchPlaceholder, value: searchQuery, onChange: async.debounce(onSearchChange, deferredSearchTime || 200), className: styles.searchBox })); } else if (option.key === 'spinner') { // // This happens when the dropdown is opened for the first time. // That's when we want to load the sites // setIsLoading(true); return (React.createElement("div", { className: styles.loadingSpinnerContainer }, React.createElement(react_1.Spinner, { size: react_1.SpinnerSize.medium }))); } } // {multiSelect !== false && <Checkbox className={styles.siteOptionCheckbox} checked={option.selected} disabled={option.disabled} />} return (React.createElement("div", { className: styles.siteOption }, React.createElement("div", { className: styles.siteOptionContent }, React.createElement("span", { className: styles.siteOptionTitle }, option.text), React.createElement("span", { className: styles.siteOptionUrl }, (0, GeneralHelper_1.toRelativeUrl)(option.data ? option.data.url : ''))))); }; React.useEffect(function () { telemetry.track('ReactSitePicker'); }, []); React.useEffect(function () { setSites(selectedSites); // console.log(`firt useeffect set sites to ${selectedSites[0].title}`); if (!allSites) { setIsLoading(true); } }, [selectedSites]); React.useEffect(function () { if (!initialSites) { return; } setSites(function (osites) { if (!osites) { // we want to set the state one time only // console.log(`second useeffect part a set sites to ${initialSites[0].title}`); return initialSites; } // console.log(`second useeffect part b set sites to ${sites[0].title}`); return sites; }); if (!allSites) { setIsLoading(true); } }, [initialSites, allSites]); React.useEffect(function () { if (!context || !isLoading) { return; } setSearchQuery(''); setFilteredSites([]); var promise; switch (mode) { case 'hub': promise = (0, SPSitesService_1.getHubSites)(context); break; case 'associatedsites': promise = (0, SPSitesService_1.getAssociatedSites)(context, trimDuplicates === true, hubsiteId); break; default: promise = (0, SPSitesService_1.getAllSites)(context, mode !== 'site', limitToCurrentSiteCollection, trimDuplicates === true, additionalQuery); break; } promise .then(function (newSites) { var copy = (0, orderBy_1.default)(newSites, [propOrderBy || 'title'], [isDesc ? 'desc' : 'asc']); setAllSites(copy); setIsLoading(false); }) .catch(function () { // no-op; }); }, [context, isLoading, mode, limitToCurrentSiteCollection]); React.useEffect(function () { setAllSites(function (s) { if (!s) { return s; } var copy = (0, orderBy_1.default)(s, [propOrderBy || 'title'], [isDesc ? 'desc' : 'asc']); return copy; }); }, [propOrderBy, isDesc]); React.useEffect(function () { if (!allSites) { return; } setFilteredSites(tslib_1.__spreadArray([], allSites, true)); }, [allSites]); return (React.createElement(React.Fragment, null, React.createElement(react_1.Dropdown, { label: label, placeholder: placeholder, onRenderCaretDown: CustomChevron, options: getOptions(), selectedKey: multiSelect === false && !!sites && !!sites[0] ? sites[0].url : [], selectedKeys: multiSelect !== false && !!sites ? sites.map(function (s) { return s.url; }) : [], disabled: disabled, multiSelect: multiSelect !== false, onRenderOption: onRenderOption, onChange: onSelectionChange, notifyOnReselect: true, className: className, styles: props.styles }))); }; exports.SitePicker = SitePicker; //# sourceMappingURL=SitePicker.js.map