aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/issues/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps/issues/utils.js')
-rw-r--r--server/sonar-web/src/main/js/apps/issues/utils.js229
1 files changed, 229 insertions, 0 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/utils.js b/server/sonar-web/src/main/js/apps/issues/utils.js
new file mode 100644
index 00000000000..3c9d8a235ed
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/issues/utils.js
@@ -0,0 +1,229 @@
+/*
+ * 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 { isNil, omitBy } from 'lodash';
+import { searchMembers } from '../../api/organizations';
+import { searchUsers } from '../../api/users';
+
+export type RawQuery = { [string]: string };
+
+export type Query = {|
+ assigned: boolean,
+ assignees: Array<string>,
+ authors: Array<string>,
+ createdAfter: string,
+ createdAt: string,
+ createdBefore: string,
+ createdInLast: string,
+ directories: Array<string>,
+ facetMode: string,
+ files: Array<string>,
+ issues: Array<string>,
+ languages: Array<string>,
+ modules: Array<string>,
+ projects: Array<string>,
+ resolved: boolean,
+ resolutions: Array<string>,
+ rules: Array<string>,
+ severities: Array<string>,
+ sinceLeakPeriod: boolean,
+ statuses: Array<string>,
+ tags: Array<string>,
+ types: Array<string>
+|};
+
+export type Paging = {
+ pageIndex: number,
+ pageSize: number,
+ total: number
+};
+
+const parseAsBoolean = (value: ?string, defaultValue: boolean = true): boolean =>
+ value === 'false' ? false : value === 'true' ? true : defaultValue;
+
+const parseAsString = (value: ?string): string => value || '';
+
+const parseAsStringArray = (value: ?string): Array<string> => value ? value.split(',') : [];
+
+const parseAsFacetMode = (facetMode: string) =>
+ facetMode === 'debt' || facetMode === 'effort' ? 'effort' : 'count';
+
+export const parseQuery = (query: RawQuery): Query => ({
+ assigned: parseAsBoolean(query.assigned),
+ assignees: parseAsStringArray(query.assignees),
+ authors: parseAsStringArray(query.authors),
+ createdAfter: parseAsString(query.createdAfter),
+ createdAt: parseAsString(query.createdAt),
+ createdBefore: parseAsString(query.createdBefore),
+ createdInLast: parseAsString(query.createdInLast),
+ directories: parseAsStringArray(query.directories),
+ facetMode: parseAsFacetMode(query.facetMode),
+ files: parseAsStringArray(query.fileUuids),
+ issues: parseAsStringArray(query.issues),
+ languages: parseAsStringArray(query.languages),
+ modules: parseAsStringArray(query.moduleUuids),
+ projects: parseAsStringArray(query.projectUuids),
+ resolved: parseAsBoolean(query.resolved),
+ resolutions: parseAsStringArray(query.resolutions),
+ rules: parseAsStringArray(query.rules),
+ severities: parseAsStringArray(query.severities),
+ sinceLeakPeriod: parseAsBoolean(query.sinceLeakPeriod, false),
+ statuses: parseAsStringArray(query.statuses),
+ tags: parseAsStringArray(query.tags),
+ types: parseAsStringArray(query.types)
+});
+
+export const getOpen = (query: RawQuery) => query.open;
+
+export const areMyIssuesSelected = (query: RawQuery): boolean => query.myIssues === 'true';
+
+const serializeString = (value: string): ?string => value || undefined;
+
+const serializeValue = (value: Array<string>): ?string => value.length ? value.join() : undefined;
+
+export const serializeQuery = (query: Query): RawQuery => {
+ const filter = {
+ assigned: query.assigned ? undefined : 'false',
+ assignees: serializeValue(query.assignees),
+ authors: serializeValue(query.authors),
+ createdAfter: serializeString(query.createdAfter),
+ createdAt: serializeString(query.createdAt),
+ createdBefore: serializeString(query.createdBefore),
+ createdInLast: serializeString(query.createdInLast),
+ directories: serializeValue(query.directories),
+ facetMode: query.facetMode === 'effort' ? serializeString(query.facetMode) : undefined,
+ fileUuids: serializeValue(query.files),
+ issues: serializeValue(query.issues),
+ languages: serializeValue(query.languages),
+ moduleUuids: serializeValue(query.modules),
+ projectUuids: serializeValue(query.projects),
+ resolved: query.resolved ? undefined : 'false',
+ resolutions: serializeValue(query.resolutions),
+ severities: serializeValue(query.severities),
+ sinceLeakPeriod: query.sinceLeakPeriod ? 'true' : undefined,
+ statuses: serializeValue(query.statuses),
+ rules: serializeValue(query.rules),
+ tags: serializeValue(query.tags),
+ types: serializeValue(query.types)
+ };
+ return omitBy(filter, isNil);
+};
+
+const areArraysEqual = (a: Array<string>, b: Array<string>) => {
+ if (a.length !== b.length) {
+ return false;
+ }
+ for (let i = 0; i < a.length; i++) {
+ if (a[i] !== b[i]) {
+ return false;
+ }
+ }
+ return true;
+};
+
+export const areQueriesEqual = (a: RawQuery, b: RawQuery) => {
+ const parsedA: Query = parseQuery(a);
+ const parsedB: Query = parseQuery(b);
+
+ const keysA = Object.keys(parsedA);
+ const keysB = Object.keys(parsedB);
+
+ if (keysA.length !== keysB.length) {
+ return false;
+ }
+
+ return keysA.every(
+ key =>
+ Array.isArray(parsedA[key]) && Array.isArray(parsedB[key])
+ ? areArraysEqual(parsedA[key], parsedB[key])
+ : parsedA[key] === parsedB[key]
+ );
+};
+
+type RawFacet = {
+ property: string,
+ values: Array<{ val: string, count: number }>
+};
+
+export type Facet = { [string]: number };
+
+export const parseFacets = (facets: Array<RawFacet>): { [string]: Facet } => {
+ // for readability purpose
+ const propertyMapping = {
+ fileUuids: 'files',
+ moduleUuids: 'modules',
+ projectUuids: 'projects'
+ };
+
+ const result = {};
+ facets.forEach(facet => {
+ const values = {};
+ facet.values.forEach(value => {
+ values[value.val] = value.count;
+ });
+ const finalProperty = propertyMapping[facet.property] || facet.property;
+ result[finalProperty] = values;
+ });
+ return result;
+};
+
+export type ReferencedComponent = {
+ key: string,
+ name: string,
+ organization: string,
+ path: string
+};
+
+export type ReferencedUser = {
+ avatar: string,
+ name: string
+};
+
+export type ReferencedLanguage = {
+ name: string
+};
+
+export type Component = {
+ key: string,
+ organization: string,
+ qualifier: string
+};
+
+export type CurrentUser =
+ | { isLoggedIn: false }
+ | { isLoggedIn: true, email?: string, login: string, name: string };
+
+export const searchAssignees = (query: string, component?: Component) => {
+ return component
+ ? searchMembers({ organization: component.organization, ps: 50, q: query }).then(response =>
+ response.users.map(user => ({
+ avatar: user.avatar,
+ label: user.name,
+ value: user.login
+ })))
+ : searchUsers(query, 50).then(response =>
+ response.users.map(user => ({
+ // TODO this WS returns no avatar
+ avatar: user.avatar,
+ email: user.email,
+ label: user.name,
+ value: user.login
+ })));
+};