You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

issues.ts 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import throwGlobalError from '../app/utils/throwGlobalError';
  21. import getCoverageStatus from '../components/SourceViewer/helpers/getCoverageStatus';
  22. import { getJSON, post, postJSON, RequestData } from '../helpers/request';
  23. import { IssueResponse, RawIssuesResponse } from '../types/issues';
  24. type FacetName =
  25. | 'assigned_to_me'
  26. | 'assignees'
  27. | 'author'
  28. | 'createdAt'
  29. | 'cwe'
  30. | 'directories'
  31. | 'files'
  32. | 'languages'
  33. | 'owaspTop10'
  34. | 'projects'
  35. | 'reporters'
  36. | 'resolutions'
  37. | 'rules'
  38. | 'sansTop25'
  39. | 'severities'
  40. | 'statuses'
  41. | 'tags'
  42. | 'types';
  43. export function searchIssues(query: RequestData): Promise<RawIssuesResponse> {
  44. return getJSON('/api/issues/search', query).catch(throwGlobalError);
  45. }
  46. export function getFacets(
  47. query: RequestData,
  48. facets: FacetName[]
  49. ): Promise<{
  50. facets: Array<{ property: string; values: T.FacetValue[] }>;
  51. response: RawIssuesResponse;
  52. }> {
  53. const data = {
  54. ...query,
  55. facets: facets.join(),
  56. ps: 1,
  57. additionalFields: '_all'
  58. };
  59. return searchIssues(data).then(r => {
  60. return { facets: r.facets, response: r };
  61. });
  62. }
  63. export function getFacet(
  64. query: RequestData,
  65. facet: FacetName
  66. ): Promise<{ facet: { count: number; val: string }[]; response: RawIssuesResponse }> {
  67. return getFacets(query, [facet]).then(r => {
  68. return { facet: r.facets[0].values, response: r.response };
  69. });
  70. }
  71. export function searchIssueTags(data: {
  72. project?: string;
  73. ps?: number;
  74. q?: string;
  75. }): Promise<string[]> {
  76. return getJSON('/api/issues/tags', data)
  77. .then(r => r.tags)
  78. .catch(throwGlobalError);
  79. }
  80. export function getIssueChangelog(issue: string): Promise<{ changelog: T.IssueChangelog[] }> {
  81. return getJSON('/api/issues/changelog', { issue }).catch(throwGlobalError);
  82. }
  83. export function getIssueFilters() {
  84. return getJSON('/api/issue_filters/search').then(r => r.issueFilters);
  85. }
  86. export function addIssueComment(data: { issue: string; text: string }): Promise<IssueResponse> {
  87. return postJSON('/api/issues/add_comment', data);
  88. }
  89. export function deleteIssueComment(data: { comment: string }): Promise<IssueResponse> {
  90. return postJSON('/api/issues/delete_comment', data);
  91. }
  92. export function editIssueComment(data: { comment: string; text: string }): Promise<IssueResponse> {
  93. return postJSON('/api/issues/edit_comment', data);
  94. }
  95. export function setIssueAssignee(data: {
  96. issue: string;
  97. assignee?: string;
  98. }): Promise<IssueResponse> {
  99. return postJSON('/api/issues/assign', data);
  100. }
  101. export function setIssueSeverity(data: { issue: string; severity: string }): Promise<any> {
  102. return postJSON('/api/issues/set_severity', data);
  103. }
  104. export function setIssueTags(data: { issue: string; tags: string }): Promise<IssueResponse> {
  105. return postJSON('/api/issues/set_tags', data);
  106. }
  107. export function setIssueTransition(data: {
  108. issue: string;
  109. transition: string;
  110. }): Promise<IssueResponse> {
  111. return postJSON('/api/issues/do_transition', data);
  112. }
  113. export function setIssueType(data: { issue: string; type: string }): Promise<IssueResponse> {
  114. return postJSON('/api/issues/set_type', data);
  115. }
  116. export function bulkChangeIssues(issueKeys: string[], query: RequestData): Promise<void> {
  117. return post('/api/issues/bulk_change', { issues: issueKeys.join(), ...query });
  118. }
  119. export function searchIssueAuthors(data: {
  120. project?: string;
  121. ps?: number;
  122. q?: string;
  123. }): Promise<string[]> {
  124. return getJSON('/api/issues/authors', data).then(r => r.authors, throwGlobalError);
  125. }
  126. export function getIssueFlowSnippets(issueKey: string): Promise<T.Dict<T.SnippetsByComponent>> {
  127. return getJSON('/api/sources/issue_snippets', { issueKey }).then(result => {
  128. Object.keys(result).forEach(k => {
  129. if (result[k].sources) {
  130. result[k].sources = result[k].sources.reduce(
  131. (lineMap: T.Dict<T.SourceLine>, line: T.SourceLine) => {
  132. line.coverageStatus = getCoverageStatus(line);
  133. lineMap[line.line] = line;
  134. return lineMap;
  135. },
  136. {}
  137. );
  138. }
  139. });
  140. return result;
  141. });
  142. }