import {Fragment, useCallback, useEffect, useMemo, useState} from 'react'; // eslint-disable-next-line no-restricted-imports import {withRouter, WithRouterProps} from 'react-router'; import EmptyMessage from 'sentry/components/emptyMessage'; import CompactIssue from 'sentry/components/issues/compactIssue'; import LoadingError from 'sentry/components/loadingError'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import Pagination from 'sentry/components/pagination'; import {Panel, PanelBody} from 'sentry/components/panels'; import {IconSearch} from 'sentry/icons'; import {t} from 'sentry/locale'; import space from 'sentry/styles/space'; import {Group} from 'sentry/types'; import useApi from 'sentry/utils/useApi'; interface IssueListProps extends WithRouterProps { endpoint: string; emptyText?: string; noBorder?: boolean; noMargin?: boolean; pagination?: boolean; query?: Record; renderEmpty?: () => React.ReactElement; } interface IssueListState { data: Array; issueIds: Array; pageLinks: string | null; status: 'loading' | 'error' | 'success'; } function IssueList({ endpoint, emptyText, query, location, pagination, renderEmpty, noBorder, noMargin, }: IssueListProps): React.ReactElement { const api = useApi(); const [state, setState] = useState({ issueIds: [], status: 'loading', pageLinks: null, data: [], }); const fetchIssueListData = useCallback(() => { api.clear(); api.request(endpoint, { method: 'GET', query: { ...query, ...(location?.query?.cursor ? {cursor: location.query.cursor} : {}), }, success: (data, _, resp) => { setState({ data, status: 'success', issueIds: data.map(item => item.id), pageLinks: resp?.getResponseHeader('Link') ?? null, }); }, error: () => { setState(prevState => ({...prevState, status: 'error'})); }, }); }, [query, endpoint, location.query, api]); // TODO: location should always be passed as a prop, check why we have this const hasLocation = !!location; useEffect(() => { if (!hasLocation) { return; } setState({issueIds: [], status: 'loading', pageLinks: null, data: []}); fetchIssueListData(); }, [fetchIssueListData, hasLocation]); const panelStyles = useMemo(() => { const styles: React.CSSProperties = { ...(noBorder ? {border: 0, borderRadius: 0} : {}), ...(noMargin ? {marginBottom: 0} : {}), }; return styles; }, [noBorder, noMargin]); return ( {state.status === 'loading' ? (
) : state.status === 'error' ? (
) : state.issueIds.length > 0 ? ( {state.data.map(issue => ( ))} ) : renderEmpty ? ( renderEmpty() ) : ( }> {emptyText ?? t('Nothing to show here, move along.')} )} {pagination && state.pageLinks && }
); } export {IssueList}; export default withRouter(IssueList);