groupEventAttachments.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // eslint-disable-next-line no-restricted-imports
  2. import {withRouter, WithRouterProps} from 'react-router';
  3. import pick from 'lodash/pick';
  4. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  5. import AsyncComponent from 'sentry/components/asyncComponent';
  6. import EmptyStateWarning from 'sentry/components/emptyStateWarning';
  7. import * as Layout from 'sentry/components/layouts/thirds';
  8. import LoadingIndicator from 'sentry/components/loadingIndicator';
  9. import Pagination from 'sentry/components/pagination';
  10. import {Panel, PanelBody} from 'sentry/components/panels';
  11. import {t} from 'sentry/locale';
  12. import {IssueAttachment} from 'sentry/types';
  13. import GroupEventAttachmentsFilter from './groupEventAttachmentsFilter';
  14. import GroupEventAttachmentsTable from './groupEventAttachmentsTable';
  15. type Props = {
  16. projectSlug: string;
  17. } & WithRouterProps<{groupId: string; orgId: string}> &
  18. AsyncComponent['props'];
  19. type State = {
  20. deletedAttachments: string[];
  21. eventAttachments?: IssueAttachment[];
  22. } & AsyncComponent['state'];
  23. class GroupEventAttachments extends AsyncComponent<Props, State> {
  24. getDefaultState() {
  25. return {
  26. ...super.getDefaultState(),
  27. deletedAttachments: [],
  28. };
  29. }
  30. getEndpoints(): ReturnType<AsyncComponent['getEndpoints']> {
  31. const {params, location} = this.props;
  32. return [
  33. [
  34. 'eventAttachments',
  35. `/issues/${params.groupId}/attachments/`,
  36. {
  37. query: {
  38. ...pick(location.query, ['cursor', 'environment', 'types']),
  39. limit: 50,
  40. },
  41. },
  42. ],
  43. ];
  44. }
  45. handleDelete = async (deletedAttachmentId: string) => {
  46. const {params, projectSlug} = this.props;
  47. const attachment = this.state?.eventAttachments?.find(
  48. item => item.id === deletedAttachmentId
  49. );
  50. if (!attachment) {
  51. return;
  52. }
  53. this.setState(prevState => ({
  54. deletedAttachments: [...prevState.deletedAttachments, deletedAttachmentId],
  55. }));
  56. try {
  57. await this.api.requestPromise(
  58. `/projects/${params.orgId}/${projectSlug}/events/${attachment.event_id}/attachments/${attachment.id}/`,
  59. {
  60. method: 'DELETE',
  61. }
  62. );
  63. } catch (error) {
  64. addErrorMessage('An error occurred while deleteting the attachment');
  65. }
  66. };
  67. renderNoQueryResults() {
  68. return (
  69. <EmptyStateWarning>
  70. <p>{t('No crash reports found')}</p>
  71. </EmptyStateWarning>
  72. );
  73. }
  74. renderEmpty() {
  75. return (
  76. <EmptyStateWarning>
  77. <p>{t('No attachments found')}</p>
  78. </EmptyStateWarning>
  79. );
  80. }
  81. renderLoading() {
  82. return this.renderBody();
  83. }
  84. renderInnerBody() {
  85. const {projectSlug, params, location} = this.props;
  86. const {loading, eventAttachments, deletedAttachments} = this.state;
  87. if (loading) {
  88. return <LoadingIndicator />;
  89. }
  90. if (eventAttachments && eventAttachments.length > 0) {
  91. return (
  92. <GroupEventAttachmentsTable
  93. attachments={eventAttachments}
  94. orgId={params.orgId}
  95. projectId={projectSlug}
  96. groupId={params.groupId}
  97. onDelete={this.handleDelete}
  98. deletedAttachments={deletedAttachments}
  99. />
  100. );
  101. }
  102. if (location.query.types) {
  103. return this.renderNoQueryResults();
  104. }
  105. return this.renderEmpty();
  106. }
  107. renderBody() {
  108. return (
  109. <Layout.Body>
  110. <Layout.Main fullWidth>
  111. <GroupEventAttachmentsFilter />
  112. <Panel className="event-list">
  113. <PanelBody>{this.renderInnerBody()}</PanelBody>
  114. </Panel>
  115. <Pagination pageLinks={this.state.eventAttachmentsPageLinks} />
  116. </Layout.Main>
  117. </Layout.Body>
  118. );
  119. }
  120. }
  121. export default withRouter(GroupEventAttachments);