@atlaskit/global-search
Version:
A cross-product search component (batteries included)
155 lines (134 loc) • 4.91 kB
JavaScript
import { utils } from '@atlaskit/util-service-support';
import { AnalyticsType, ContentType, ResultType } from '../model/Result';
const RECENT_ITEMS_PATH = 'rest/internal/2/productsearch/recent';
const PERMISSIONS_PATH = 'rest/api/2/mypermissions?permissions=USER_PICKER';
export const DEFAULT_RECENT_ITEMS_COUNT = {
issues: 8,
boards: 2,
projects: 2,
filters: 2
};
/**
* Jira client to reterive recent items from jira
*/
var JiraResponseGroup;
(function (JiraResponseGroup) {
JiraResponseGroup["Issues"] = "quick-search-issues";
JiraResponseGroup["Projects"] = "quick-search-projects";
JiraResponseGroup["Boards"] = "quick-search-boards";
JiraResponseGroup["Filters"] = "quick-search-filters";
})(JiraResponseGroup || (JiraResponseGroup = {}));
const JiraResponseGroupToContentType = {
[JiraResponseGroup.Issues]: ContentType.JiraIssue,
[JiraResponseGroup.Boards]: ContentType.JiraBoard,
[JiraResponseGroup.Filters]: ContentType.JiraFilter,
[JiraResponseGroup.Projects]: ContentType.JiraProject
};
export default class JiraClientImpl {
constructor(url, cloudId, isUserAnonymous) {
this.serviceConfig = {
url: url
};
this.cloudId = cloudId;
this.isUserAnonymous = isUserAnonymous;
} // Unused, just to mute ts lint
getCloudId() {
return this.cloudId;
}
/**
*
* @param searchSessionId unique id for each session
* @param recentItemCounts number of items to return for every recent item type defaults to {@link #defaultRecentItemCounts}
* @returns a promise resolved to recent items array throws if any error occurs in reqeust or if parsing or transforming response fails
*/
async getRecentItems(searchSessionId, recentItemCounts = DEFAULT_RECENT_ITEMS_COUNT) {
if (this.isUserAnonymous) {
return [];
}
const options = {
path: RECENT_ITEMS_PATH,
queryParams: {
counts: this.getRecentCountQueryParam(recentItemCounts),
search_id: searchSessionId
}
};
const recentItems = (await utils.requestService(this.serviceConfig, options)) || [];
const reduced = recentItems.filter(group => JiraResponseGroupToContentType.hasOwnProperty(group.id)).map(group => this.recentItemGroupToItems(group)).reduce((acc, item) => [...acc, ...item], []);
return reduced;
}
async canSearchUsers() {
if (this.isUserAnonymous) {
return false;
}
if (typeof this.canSearchUsersCache === 'boolean') {
return Promise.resolve(this.canSearchUsersCache);
}
const options = {
path: PERMISSIONS_PATH
};
const permissionsResponse = await utils.requestService(this.serviceConfig, options);
this.canSearchUsersCache = permissionsResponse && permissionsResponse.permissions && permissionsResponse.permissions.USER_PICKER && permissionsResponse.permissions.USER_PICKER.havePermission;
return !!this.canSearchUsersCache;
}
recentItemGroupToItems(group) {
const {
id,
items
} = group;
return items.map(item => this.recentItemToResultItem(item, id));
}
recentItemToResultItem(item, jiraGroup) {
const containerId = this.getContainerId(item, jiraGroup);
const contentType = JiraResponseGroupToContentType[jiraGroup];
const resultId = '' + item.id;
return {
resultType: ResultType.JiraObjectResult,
resultId,
name: item.title,
href: item.url,
analyticsType: AnalyticsType.RecentJira,
avatarUrl: item.avatarUrl,
containerId: containerId,
contentType,
...this.getTypeSpecificAttributes(item, jiraGroup)
};
}
getContainerId(item, jiraGroup) {
return jiraGroup === JiraResponseGroup.Filters ? item.attributes && item.attributes.ownerId : item.attributes && item.attributes.containerId;
}
getTypeSpecificAttributes(item, jiraGroup) {
switch (jiraGroup) {
case JiraResponseGroup.Filters:
return {
containerName: item.metadata,
objectKey: 'Filters'
};
case JiraResponseGroup.Projects:
return {
containerName: item.metadata
};
case JiraResponseGroup.Issues:
const issueType = item.attributes && item.attributes.issueTypeName;
return {
containerName: issueType ? issueType : item.metadata,
objectKey: issueType ? item.metadata : undefined
};
case JiraResponseGroup.Boards:
return {
containerName: item.attributes ? item.attributes.containerName : item.metadata
};
}
}
/**
* Private method to construct a valid value for the 'counts' query param
* for the Jira recent API. The format is as follows:
*
* ?counts=issues=8,boards=2,projects=2,filters=2
*
* @param recentCounts
*/
getRecentCountQueryParam(recentCounts) {
const keys = Object.keys(recentCounts);
return keys.map(key => `${key}=${recentCounts[key]}`).join(',');
}
}