@pnp/spfx-controls-react
Version:
Reusable React controls for SharePoint Framework solutions
238 lines • 10.4 kB
JavaScript
;
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