UNPKG

@chayns-components/person-finder

Version:

A set of beautiful React components for developing your own applications with chayns.

334 lines (332 loc) 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.usePersonFinder = exports.default = exports.PersonFinderContext = void 0; var _react = _interopRequireWildcard(require("react")); var _lodash = _interopRequireDefault(require("lodash.throttle")); var _personFinder = require("../types/personFinder"); var _get = require("../api/friends/get"); var _post = require("../api/friends/post"); var _delete = require("../api/friends/delete"); var _personFinder2 = require("../utils/personFinder"); var _uac = require("../utils/uac"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const THROTTLE_INTERVAL = 500; const PersonFinderContext = exports.PersonFinderContext = /*#__PURE__*/(0, _react.createContext)({ data: undefined, updateData: undefined, friends: undefined, addFriend: undefined, removeFriend: undefined, activeFilter: undefined, updateActiveFilter: undefined, search: undefined, updateSearch: undefined, loadMore: undefined, loadingState: undefined, updateLoadingState: undefined, tags: undefined, setTags: undefined }); PersonFinderContext.displayName = 'PersonFinderContext'; const usePersonFinder = () => (0, _react.useContext)(PersonFinderContext); exports.usePersonFinder = usePersonFinder; const PersonFinderProvider = ({ children, friendsPriority, filterTypes, defaultEntries, excludedEntryIds, shouldShowOwnUser = false, uacFilter }) => { const [data, setData] = (0, _react.useState)(); const [friends, setFriends] = (0, _react.useState)(); const [uacUsers, setUacUsers] = (0, _react.useState)(); const [activeFilter, setActiveFilter] = (0, _react.useState)(); const [search, setSearch] = (0, _react.useState)(''); const [tags, setTags] = (0, _react.useState)((defaultEntries === null || defaultEntries === void 0 ? void 0 : defaultEntries.map(({ id, name }) => ({ id, text: name }))) ?? []); const [loadingState, setLoadingState] = (0, _react.useState)({ [_personFinder.PersonFinderFilterTypes.PERSON]: _personFinder.LoadingState.None, [_personFinder.PersonFinderFilterTypes.SITE]: _personFinder.LoadingState.None }); const dataRef = (0, _react.useRef)(); const updateActiveFilter = (0, _react.useCallback)(filter => { setActiveFilter(filter); }, []); const updateData = (0, _react.useCallback)((key, newData) => { setData(prevState => ({ ...prevState, [key]: newData })); }, []); const appendData = (0, _react.useCallback)((key, newData) => { setData(prevState => { var _prevState$key, _prevState$key2; const oldEntries = prevState && (_prevState$key = prevState[key]) !== null && _prevState$key !== void 0 && _prevState$key.entries ? (_prevState$key2 = prevState[key]) === null || _prevState$key2 === void 0 ? void 0 : _prevState$key2.entries : []; return { ...prevState, [key]: { ...newData, entries: [...oldEntries, ...newData.entries] } }; }); }, []); const updateLoadingState = (0, _react.useCallback)((key, state) => { setLoadingState(prev => ({ ...prev, [key]: state })); }, []); const updateSearch = (0, _react.useCallback)(value => { setSearch(value); }, []); const loadMore = (0, _react.useCallback)(key => { updateLoadingState(key, _personFinder.LoadingState.Pending); const current = data === null || data === void 0 ? void 0 : data[key]; if (!current) { updateLoadingState(key, _personFinder.LoadingState.Error); return; } void (0, _personFinder2.loadData)({ searchString: search ?? '', filter: [key], skipMap: { [key]: current.skip } }).then(result => { const newData = result === null || result === void 0 ? void 0 : result[key]; if (newData) { appendData(key, newData); } }).finally(() => { updateLoadingState(key, _personFinder.LoadingState.Success); }); }, [updateLoadingState, data, search, appendData]); const addFriend = (0, _react.useCallback)(personId => { void (0, _post.postFriends)(personId).then(result => { if (result) { const { firstName, lastName, verificationState } = result; setFriends(prev => [...(prev ?? []), { id: personId, isVerified: verificationState === 1, commonSites: 0, firstName, lastName, type: _personFinder.PersonFinderFilterTypes.PERSON }]); } }); }, []); const removeFriend = (0, _react.useCallback)(personId => { void (0, _delete.deleteFriends)(personId).then(wasSuccessful => { if (wasSuccessful) { setFriends(prev => prev === null || prev === void 0 ? void 0 : prev.filter(({ id }) => id !== personId)); } }); }, []); (0, _react.useEffect)(() => { if (!filterTypes.includes(_personFinder.PersonFinderFilterTypes.PERSON)) { return; } void (0, _get.getFriends)().then(result => { if (result) { setFriends(result.map(({ personId, firstName, lastName, verificationState }) => ({ lastName, firstName, id: personId, commonSites: 0, isVerified: verificationState === 1, type: _personFinder.PersonFinderFilterTypes.PERSON }))); } }); }, [filterTypes]); const latestArgsRef = (0, _react.useRef)(null); const latestHandledRequestRef = (0, _react.useRef)(0); const throttledRequest = (0, _react.useRef)((0, _lodash.default)(async () => { const args = latestArgsRef.current; if (!args) return; const { search: searchString, filter } = args; const requestTimestamp = Date.now(); filter.forEach(key => { updateLoadingState(key, _personFinder.LoadingState.Pending); }); const result = await (0, _personFinder2.loadData)({ searchString, filter, skipMap: {} }); if (requestTimestamp < latestHandledRequestRef.current) { return; } latestHandledRequestRef.current = requestTimestamp; if (!result) return; Object.entries(result).forEach(([keyString, value]) => { const key = keyString; if (key === _personFinder.PersonFinderFilterTypes.PERSON && friendsPriority === _personFinder.Priority.HIGH && friends) { const friendIds = new Set(friends.map(f => f.id)); const serverFriendEntries = value.entries.filter(entry => friendIds.has(entry.id)); const serverFriendIds = new Set(serverFriendEntries.map(f => f.id)); const missingFriends = friends.filter(f => !serverFriendIds.has(f.id)).filter(f => { var _f$firstName, _f$lastName; return ((_f$firstName = f.firstName) === null || _f$firstName === void 0 ? void 0 : _f$firstName.toLowerCase().includes(searchString.toLowerCase())) || ((_f$lastName = f.lastName) === null || _f$lastName === void 0 ? void 0 : _f$lastName.toLowerCase().includes(searchString.toLowerCase())); }); const otherEntries = value.entries.filter(entry => !friendIds.has(entry.id)); updateData(key, { ...value, entries: [...serverFriendEntries, ...missingFriends, ...otherEntries] }); } else { updateData(key, value); } updateLoadingState(key, value.entries.length === 0 ? _personFinder.LoadingState.Error : _personFinder.LoadingState.Success); }); }, THROTTLE_INTERVAL, { leading: false, trailing: true })).current; (0, _react.useEffect)(() => { dataRef.current = data; }, [data]); const searchData = (0, _react.useCallback)(({ filter }) => { const tmpData = dataRef.current; filter.forEach(key => { updateLoadingState(key, _personFinder.LoadingState.Pending); if (tmpData && tmpData[key]) { // Add all Types that are not searched by a request const entries = tmpData[key].entries; const filteredEntries = entries.filter(({ name }) => name.toLowerCase().includes(search.toLowerCase())); updateData(key, { entries: filteredEntries, searchString: search, count: filteredEntries.length, skip: filteredEntries.length }); updateLoadingState(key, filteredEntries.length === 0 ? _personFinder.LoadingState.Error : _personFinder.LoadingState.Success); } }); }, [search, updateData, updateLoadingState]); const searchLocal = (0, _react.useCallback)(() => { if (search.length < 3) { return; } updateLoadingState(_personFinder.PersonFinderFilterTypes.PERSON, _personFinder.LoadingState.Pending); const searchedUsers = []; uacUsers === null || uacUsers === void 0 || uacUsers.forEach(entry => { if (entry.firstName.toLowerCase().includes(search.toLowerCase()) || entry.lastName.toLowerCase().includes(search.toLowerCase()) || entry.id.toLowerCase().includes(search.toLowerCase())) { searchedUsers.push(entry); } }); updateData(_personFinder.PersonFinderFilterTypes.PERSON, { entries: searchedUsers, searchString: search, count: searchedUsers.length, skip: searchedUsers.length }); updateLoadingState(_personFinder.PersonFinderFilterTypes.PERSON, searchedUsers.length === 0 ? _personFinder.LoadingState.Error : _personFinder.LoadingState.Success); }, [search, uacUsers, updateData, updateLoadingState]); (0, _react.useEffect)(() => { if (!search) return; const active = activeFilter ?? filterTypes; if (uacFilter) { searchLocal(); } else if (active !== null && active !== void 0 && active.includes(_personFinder.PersonFinderFilterTypes.UAC)) { searchData({ filter: [_personFinder.PersonFinderFilterTypes.UAC] }); } else { latestArgsRef.current = { search, filter: active }; throttledRequest(); } }, [filterTypes, search, activeFilter, friends, friendsPriority, updateData, updateLoadingState, throttledRequest, searchData, uacFilter, searchLocal]); (0, _react.useEffect)(() => () => { throttledRequest.cancel(); }, [throttledRequest]); // load initial data (0, _react.useEffect)(() => { if (uacFilter) { void (0, _uac.getUsersByGroups)(uacFilter).then(users => { setUacUsers(users); }); return; } if (filterTypes.includes(_personFinder.PersonFinderFilterTypes.UAC) && search === '') { void (0, _uac.getUACGroups)().then(result => { setData({ uac: { entries: result, searchString: '', skip: result.length, count: result.length } }); }); } if (friendsPriority === _personFinder.Priority.HIGH && filterTypes.includes(_personFinder.PersonFinderFilterTypes.PERSON) && friends && search === '') { setData({ person: { entries: friends, searchString: '', skip: friends.length, count: friends.length } }); } }, [filterTypes, friends, friendsPriority, search, uacFilter]); const providerValue = (0, _react.useMemo)(() => ({ data: (0, _personFinder2.filterDataByKeys)(data, activeFilter, { excludedEntryIds, shouldShowOwnUser }), updateData, activeFilter, updateActiveFilter, friends, addFriend, removeFriend, search, updateSearch, loadMore, loadingState, updateLoadingState, setTags, tags }), [activeFilter, addFriend, data, excludedEntryIds, friends, loadMore, loadingState, removeFriend, search, shouldShowOwnUser, tags, updateActiveFilter, updateData, updateLoadingState, updateSearch]); return /*#__PURE__*/_react.default.createElement(PersonFinderContext.Provider, { value: providerValue }, children); }; PersonFinderProvider.displayName = 'PersonFinderProvider'; var _default = exports.default = PersonFinderProvider; //# sourceMappingURL=PersonFinderProvider.js.map