index.tsx 3.1 KB

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