import debounce from '@ringcentral-integration/commons/lib/debounce'; import clsx from 'clsx'; import PropTypes from 'prop-types'; import { includes } from 'ramda'; import React, { Component } from 'react'; import AddContactIcon from '../../assets/images/ContactAdd.svg'; import RefreshingIcon from '../../assets/images/OvalLoading.svg'; import RefreshContactIcon from '../../assets/images/RetryIcon.svg'; import ContactList from '../ContactList'; import { ContactSourceFilter } from '../ContactSourceFilter'; import Panel from '../Panel'; import { SearchInput } from '../SearchInput'; import { SpinnerOverlay } from '../SpinnerOverlay'; import i18n from './i18n'; import styles from './styles.scss'; // @ts-expect-error const AddContact = ({ className, onClick }) => { return (
); }; AddContact.propTypes = { className: PropTypes.string, onClick: PropTypes.func.isRequired, }; AddContact.defaultProps = { className: undefined, }; const RefreshContacts = ({ // @ts-expect-error className, // @ts-expect-error onRefresh, // @ts-expect-error refreshing, // @ts-expect-error currentLocale, }) => { let icon = null; let iconWrapClass = null; if (refreshing) { iconWrapClass = styles.refreshingIcon; icon = ( ); } else { iconWrapClass = styles.refreshIcon; icon = ( ); } return (
{icon}
); }; RefreshContacts.propTypes = { className: PropTypes.string, currentLocale: PropTypes.string.isRequired, onRefresh: PropTypes.func.isRequired, refreshing: PropTypes.bool.isRequired, }; RefreshContacts.defaultProps = { className: undefined, }; class ContactsView extends Component { // @ts-expect-error constructor(props) { super(props); this.state = { searchString: props.searchString, lastInputTimestamp: 0, unfold: false, contentHeight: 0, contentWidth: 0, refreshing: false, }; // @ts-expect-error this.contactList = React.createRef(); // @ts-expect-error this.contentWrapper = React.createRef(); // @ts-expect-error this.onUnfoldChange = (unfold) => { this.setState({ unfold, }); }; } calculateContentSize = () => { if ( // @ts-expect-error this.contentWrapper && // @ts-expect-error this.contentWrapper.current && // @ts-expect-error this.contentWrapper.current.getBoundingClientRect ) { // @ts-expect-error const rect = this.contentWrapper.current.getBoundingClientRect(); return { contentHeight: rect.bottom - rect.top, contentWidth: rect.right - rect.left, }; } return { contentHeight: 0, contentWidth: 0, }; }; // @ts-expect-error componentDidMount() { // @ts-expect-error this._mounted = true; // @ts-expect-error const { onVisitPage } = this.props; if (typeof onVisitPage === 'function') { onVisitPage(); } this.setState({ ...this.calculateContentSize(), }); window.addEventListener('resize', this.onResize); } // @ts-expect-error UNSAFE_componentWillUpdate(nextProps, nextState) { // @ts-expect-error const { lastInputTimestamp } = this.state; // @ts-expect-error const { searchString: searchStringProp } = this.props; // sync search string from other app instance const isNotEditing = Date.now() - lastInputTimestamp > 2000; if (isNotEditing && nextProps.searchString !== searchStringProp) { nextState.searchString = nextProps.searchString; } // default to the first contact source when current selected contact source is removed if (!includes(nextProps.searchSource, nextProps.contactSourceNames)) { // @ts-expect-error const { searchString } = this.state; this.search({ searchSource: nextProps.contactSourceNames[0], searchString, }); } } // @ts-expect-error componentWillUnmount() { // @ts-expect-error this._mounted = false; window.removeEventListener('resize', this.onResize); } // @ts-expect-error onSearchInputChange = (ev) => { this.setState( { searchString: ev.target.value, lastInputTimestamp: Date.now(), }, () => { // @ts-expect-error const { searchString } = this.state; // @ts-expect-error const { searchSource } = this.props; this.search({ searchString, searchSource, }); }, ); }; // @ts-expect-error onSourceSelect = (searchSource) => { if ( // @ts-expect-error this.contactList && // @ts-expect-error this.contactList.current && // @ts-expect-error this.contactList.current.resetScrollTop ) { // @ts-expect-error this.contactList.current.resetScrollTop(); } // @ts-expect-error const { searchString } = this.state; this.search({ searchSource, searchString, }); }; onResize = debounce(() => { // @ts-expect-error if (this._mounted) { this.setState({ ...this.calculateContentSize(), }); } }, 300); onRefresh = async () => { // @ts-expect-error const { onRefresh } = this.props; if (typeof onRefresh === 'function') { this.setState({ refreshing: true }, async () => { await onRefresh(); this.setState({ refreshing: false }); }); } }; // @ts-expect-error search({ searchSource, searchString }) { // @ts-expect-error const { onSearchContact } = this.props; if (typeof onSearchContact === 'function') { onSearchContact({ searchSource, searchString, }); } } // @ts-expect-error render() { const { // @ts-expect-error currentLocale, // @ts-expect-error contactGroups, // @ts-expect-error contactSourceNames, // @ts-expect-error searchSource, // @ts-expect-error isSearching, // @ts-expect-error showSpinner, // @ts-expect-error getAvatarUrl, // @ts-expect-error getPresence, // @ts-expect-error onItemSelect, // @ts-expect-error contactSourceFilterRenderer: Filter, // @ts-expect-error sourceNodeRenderer, // @ts-expect-error onRefresh, // @ts-expect-error bottomNotice, // @ts-expect-error bottomNoticeHeight, children, // @ts-expect-error currentSiteCode, // @ts-expect-error isMultipleSiteEnabled, } = this.props; // @ts-expect-error const { refreshing, searchString, unfold, contentWidth, contentHeight } = this.state; const showRefresh = typeof onRefresh === 'function'; const refreshButton = showRefresh ? ( ) : null; return (
{refreshButton}
{showSpinner ? : null} {children}
); } } // @ts-expect-error ContactsView.propTypes = { currentLocale: PropTypes.string.isRequired, contactGroups: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string.isRequired, caption: PropTypes.string.isRequired, contacts: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string, type: PropTypes.string, name: PropTypes.string, extensionNumber: PropTypes.string, email: PropTypes.string, profileImageUrl: PropTypes.string, presence: PropTypes.object, contactStatus: PropTypes.string, }), ).isRequired, }), ).isRequired, contactSourceNames: PropTypes.arrayOf(PropTypes.string).isRequired, getAvatarUrl: PropTypes.func.isRequired, getPresence: PropTypes.func.isRequired, showSpinner: PropTypes.bool.isRequired, currentSiteCode: PropTypes.string, isMultipleSiteEnabled: PropTypes.bool, searchSource: PropTypes.string, searchString: PropTypes.string, isSearching: PropTypes.bool, onItemSelect: PropTypes.func, onSearchContact: PropTypes.func, contactSourceFilterRenderer: PropTypes.func, sourceNodeRenderer: PropTypes.func, onVisitPage: PropTypes.func, onRefresh: PropTypes.func, bottomNotice: PropTypes.func, bottomNoticeHeight: PropTypes.number, children: PropTypes.node, }; // @ts-expect-error ContactsView.defaultProps = { searchSource: undefined, searchString: undefined, isSearching: false, onItemSelect: undefined, onSearchContact: undefined, contactSourceFilterRenderer: ContactSourceFilter, sourceNodeRenderer: undefined, onVisitPage: undefined, children: undefined, onRefresh: undefined, bottomNotice: undefined, bottomNoticeHeight: 0, currentSiteCode: '', isMultipleSiteEnabled: false, }; export default ContactsView;