diff options
Diffstat (limited to 'server/sonar-web/src/main/js/helpers/issues.js')
-rw-r--r-- | server/sonar-web/src/main/js/helpers/issues.js | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/helpers/issues.js b/server/sonar-web/src/main/js/helpers/issues.js new file mode 100644 index 00000000000..3a1e509f790 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/issues.js @@ -0,0 +1,121 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +// @flow +import sortBy from 'lodash/sortBy'; +import { SEVERITIES } from './constants'; + +type TextRange = { + startLine: number, + endLine: number, + startOffset: number, + endOffset: number +}; + +type Comment = { + login: string +}; + +type User = { + login: string +}; + +type RawIssue = { + assignee?: string, + author: string, + comments?: Array<Comment>, + component: string, + line?: number, + project: string, + rule: string, + status: string, + subProject?: string, + textRange?: TextRange +}; + +export const sortBySeverity = (issues: Array<*>) => ( + sortBy(issues, issue => SEVERITIES.indexOf(issue.severity)) +); + +const injectRelational = ( + issue: RawIssue | Comment, + source?: Array<*>, + baseField: string, + lookupField: string +) => { + const newFields = {}; + const baseValue = issue[baseField]; + if (baseValue != null && source != null) { + const lookupValue = source.find(candidate => candidate[lookupField] === baseValue); + if (lookupValue != null) { + Object.keys(lookupValue).forEach(key => { + const newKey = baseField + key.charAt(0).toUpperCase() + key.slice(1); + newFields[newKey] = lookupValue[key]; + }); + } + } + return newFields; +}; + +const injectCommentsRelational = (issue: RawIssue, users?: Array<User>) => { + if (!issue.comments) { + return {}; + } + const comments = issue.comments.map(comment => ({ + ...comment, + author: comment.login, + login: undefined, + ...injectRelational(comment, users, 'author', 'login') + })); + return { comments }; +}; + +const prepareClosed = (issue: RawIssue) => { + return issue.status === 'CLOSED' ? { flows: undefined } : {}; +}; + +const ensureTextRange = (issue: RawIssue) => { + return issue.line && !issue.textRange ? { + textRange: { + startLine: issue.line, + endLine: issue.line, + startOffset: 0, + endOffset: 999999 + } + } : {}; +}; + +export const parseIssueFromResponse = ( + issue: RawIssue, + components?: Array<*>, + users?: Array<*>, + rules?: Array<*> +) => { + return { + ...issue, + ...injectRelational(issue, components, 'component', 'key'), + ...injectRelational(issue, components, 'project', 'key'), + ...injectRelational(issue, components, 'subProject', 'key'), + ...injectRelational(issue, rules, 'rule', 'key'), + ...injectRelational(issue, users, 'assignee', 'login'), + ...injectCommentsRelational(issue, users), + ...prepareClosed(issue), + ...ensureTextRange(issue) + }; +}; |