index.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {RouteComponentProps} from 'react-router';
  2. import EmptyStateWarning from 'sentry/components/emptyStateWarning';
  3. import ErrorBoundary from 'sentry/components/errorBoundary';
  4. import LoadingIndicator from 'sentry/components/loadingIndicator';
  5. import PageHeading from 'sentry/components/pageHeading';
  6. import Pagination from 'sentry/components/pagination';
  7. import {Panel} from 'sentry/components/panels';
  8. import {t} from 'sentry/locale';
  9. import {PageContent} from 'sentry/styles/organization';
  10. import space from 'sentry/styles/space';
  11. import {Activity, Organization} from 'sentry/types';
  12. import routeTitle from 'sentry/utils/routeTitle';
  13. import withOrganization from 'sentry/utils/withOrganization';
  14. import AsyncView from 'sentry/views/asyncView';
  15. import ActivityFeedItem from './activityFeedItem';
  16. type Props = {
  17. organization: Organization;
  18. } & RouteComponentProps<{orgId: string}, {}> &
  19. AsyncView['props'];
  20. type State = {
  21. activity: Activity[];
  22. } & AsyncView['state'];
  23. class OrganizationActivity extends AsyncView<Props, State> {
  24. getTitle() {
  25. const {orgId} = this.props.params;
  26. return routeTitle(t('Activity'), orgId, false);
  27. }
  28. getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
  29. return [['activity', `/organizations/${this.props.params.orgId}/activity/`]];
  30. }
  31. renderLoading() {
  32. return this.renderBody();
  33. }
  34. renderEmpty() {
  35. return (
  36. <EmptyStateWarning>
  37. <p>{t('Nothing to show here, move along.')}</p>
  38. </EmptyStateWarning>
  39. );
  40. }
  41. renderError(error?: Error, disableLog = false): React.ReactNode {
  42. const {errors} = this.state;
  43. const notFound = Object.values(errors).find(resp => resp && resp.status === 404);
  44. if (notFound) {
  45. return this.renderBody();
  46. }
  47. return super.renderError(error, disableLog);
  48. }
  49. renderBody() {
  50. const {loading, activity, activityPageLinks} = this.state;
  51. return (
  52. <PageContent>
  53. <PageHeading withMargins>{t('Activity')}</PageHeading>
  54. <Panel>
  55. {loading && <LoadingIndicator />}
  56. {!loading && !activity?.length && this.renderEmpty()}
  57. {!loading && activity?.length > 0 && (
  58. <div data-test-id="activity-feed-list">
  59. {activity.map(item => (
  60. <ErrorBoundary
  61. mini
  62. css={{marginBottom: space(1), borderRadius: 0}}
  63. key={item.id}
  64. >
  65. <ActivityFeedItem organization={this.props.organization} item={item} />
  66. </ErrorBoundary>
  67. ))}
  68. </div>
  69. )}
  70. </Panel>
  71. {activityPageLinks && (
  72. <Pagination pageLinks={activityPageLinks} {...this.props} />
  73. )}
  74. </PageContent>
  75. );
  76. }
  77. }
  78. export default withOrganization(OrganizationActivity);