index.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import * as React from 'react';
  2. import {RouteComponentProps} from 'react-router';
  3. import EmptyStateWarning from 'app/components/emptyStateWarning';
  4. import ErrorBoundary from 'app/components/errorBoundary';
  5. import LoadingIndicator from 'app/components/loadingIndicator';
  6. import PageHeading from 'app/components/pageHeading';
  7. import Pagination from 'app/components/pagination';
  8. import {Panel} from 'app/components/panels';
  9. import {t} from 'app/locale';
  10. import {PageContent} from 'app/styles/organization';
  11. import space from 'app/styles/space';
  12. import {Activity, Organization} from 'app/types';
  13. import routeTitle from 'app/utils/routeTitle';
  14. import withOrganization from 'app/utils/withOrganization';
  15. import AsyncView from 'app/views/asyncView';
  16. import ActivityFeedItem from './activityFeedItem';
  17. type Props = {
  18. organization: Organization;
  19. } & RouteComponentProps<{orgId: string}, {}> &
  20. AsyncView['props'];
  21. type State = {
  22. activity: Activity[];
  23. } & AsyncView['state'];
  24. class OrganizationActivity extends AsyncView<Props, State> {
  25. getTitle() {
  26. const {orgId} = this.props.params;
  27. return routeTitle(t('Activity'), orgId);
  28. }
  29. getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
  30. return [['activity', `/organizations/${this.props.params.orgId}/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, disableReport = 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, disableReport);
  49. }
  50. renderBody() {
  51. const {loading, activity, activityPageLinks} = this.state;
  52. return (
  53. <PageContent>
  54. <PageHeading withMargins>{t('Activity')}</PageHeading>
  55. <Panel>
  56. {loading && <LoadingIndicator />}
  57. {!loading && !activity?.length && this.renderEmpty()}
  58. {!loading && activity?.length > 0 && (
  59. <div data-test-id="activity-feed-list">
  60. {activity.map(item => (
  61. <ErrorBoundary
  62. mini
  63. css={{marginBottom: space(1), borderRadius: 0}}
  64. key={item.id}
  65. >
  66. <ActivityFeedItem organization={this.props.organization} item={item} />
  67. </ErrorBoundary>
  68. ))}
  69. </div>
  70. )}
  71. </Panel>
  72. {activityPageLinks && (
  73. <Pagination pageLinks={activityPageLinks} {...this.props} />
  74. )}
  75. </PageContent>
  76. );
  77. }
  78. }
  79. export default withOrganization(OrganizationActivity);