UNPKG

@atlaskit/mention

Version:

A React component used to display user profiles in a list for 'Mention' functionality

218 lines 10.7 kB
import * as tslib_1 from "tslib"; import { utils as serviceUtils, } from '@atlaskit/util-service-support'; import { UserType, UserAccessLevel, } from '../types'; import MentionResource from './MentionResource'; import debug from '../util/logger'; var MAX_QUERY_TEAMS = 20; /** * Provides a Javascript API to fetch users and teams * In future we will have a new endpoint to return both users and teams, we can * remove this class at this point */ var TeamMentionResource = /** @class */ (function (_super) { tslib_1.__extends(TeamMentionResource, _super); function TeamMentionResource(userMentionConfig, teamMentionConfig) { var _this = _super.call(this, userMentionConfig) || this; _this.lastSearchQuery = ''; _this.verifyMentionConfig(teamMentionConfig); _this.teamMentionConfig = teamMentionConfig; _this.lastReturnedSearchTeam = 0; return _this; } TeamMentionResource.prototype.filter = function (query, contextIdentifier) { this.lastSearchQuery = query; if (!query) { this.remoteInitialStateTeamAndUsers(contextIdentifier); } else { this.updateActiveSearches(query); // both user and team requests start at the same time var getUserPromise = this.remoteUserSearch(query, contextIdentifier); var getTeamsPromise = this.remoteTeamSearch(query, contextIdentifier); this.handleBothRequests(query, getUserPromise, getTeamsPromise); } }; /** * Returns the initial mention display list before a search is performed for the specified * container. */ TeamMentionResource.prototype.remoteInitialStateTeamAndUsers = function (contextIdentifier) { return tslib_1.__awaiter(this, void 0, void 0, function () { var emptyQuery, getUserPromise, queryParams, options, getTeamsPromise; return tslib_1.__generator(this, function (_a) { emptyQuery = ''; getUserPromise = _super.prototype.remoteInitialState.call(this, contextIdentifier); queryParams = this.getQueryParamsOfTeamMentionConfig(contextIdentifier); options = { path: 'bootstrap', queryParams: queryParams, }; getTeamsPromise = serviceUtils.requestService(this.teamMentionConfig, options); this.handleBothRequests(emptyQuery, getUserPromise, getTeamsPromise); return [2 /*return*/]; }); }); }; /** * Both user and team requests are not blocked together * If users request arrives first, show users. Show teams when team request arrives. * If team request arrives first, block waiting for user request, then show both * If one errors, show the non-erroring one * If both error, show error */ TeamMentionResource.prototype.handleBothRequests = function (query, userRequest, teamRequest) { return tslib_1.__awaiter(this, void 0, void 0, function () { var searchTime, accumulatedResults, notifyWhenOneRequestDone, userResults, userRequestError, teamRequestError, error_1, teamsResult, error_2; var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: searchTime = Date.now(); accumulatedResults = { mentions: [], query: query, }; notifyWhenOneRequestDone = function (results, hasTeamResults) { // just update UI for the last query string if (query !== _this.lastSearchQuery) { return; } accumulatedResults = { mentions: tslib_1.__spread(accumulatedResults.mentions, results.mentions), query: query, }; // we need to calculate different `duration` for user and team request. if (hasTeamResults) { _this.notify(searchTime, accumulatedResults, query); } else { _super.prototype.notify.call(_this, searchTime, accumulatedResults, query); } }; userRequestError = null; teamRequestError = null; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, userRequest]; case 2: // user requests finishes, update the UI, don't need to wait for team requests userResults = _a.sent(); notifyWhenOneRequestDone(userResults, false); return [3 /*break*/, 4]; case 3: error_1 = _a.sent(); userRequestError = error_1; return [3 /*break*/, 4]; case 4: _a.trys.push([4, 6, , 7]); return [4 /*yield*/, teamRequest]; case 5: teamsResult = _a.sent(); // update search time after team results returns notifyWhenOneRequestDone(Array.isArray(teamsResult) ? this.convertTeamResultToMentionResult(teamsResult, query) : teamsResult, true); return [3 /*break*/, 7]; case 6: error_2 = _a.sent(); teamRequestError = error_2; return [3 /*break*/, 7]; case 7: // both requests fail, show one of errors in UI if (userRequestError && teamRequestError) { this.notifyError(userRequestError, query); debug('User mention request fails. ', userRequestError); debug('Team mention request fails. ', teamRequestError); } return [2 /*return*/]; } }); }); }; TeamMentionResource.prototype.notify = function (searchTime, mentionResult, query) { if (searchTime > this.lastReturnedSearchTeam) { this.lastReturnedSearchTeam = searchTime; this._notifyListeners(mentionResult, { teamMentionDuration: Date.now() - searchTime, }); } else { var date = new Date(searchTime).toISOString().substr(17, 6); debug('Stale search result, skipping', date, query); // eslint-disable-line no-console, max-len } this._notifyAllResultsListeners(mentionResult); }; TeamMentionResource.prototype.getQueryParamsOfTeamMentionConfig = function (contextIdentifier) { var configParams = {}; if (this.teamMentionConfig.containerId) { configParams['containerId'] = this.teamMentionConfig.containerId; } if (this.teamMentionConfig.productId) { configParams['productIdentifier'] = this.teamMentionConfig.productId; } // if contextParams exist then it will override configParams for containerId return tslib_1.__assign({}, configParams, contextIdentifier); }; TeamMentionResource.prototype.remoteUserSearch = function (query, contextIdentifier) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { return [2 /*return*/, _super.prototype.remoteSearch.call(this, query, contextIdentifier)]; }); }); }; TeamMentionResource.prototype.remoteTeamSearch = function (query, contextIdentifier) { return tslib_1.__awaiter(this, void 0, void 0, function () { var options, teamResult; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: options = { path: 'search', queryParams: tslib_1.__assign({ query: query, limit: MAX_QUERY_TEAMS }, this.getQueryParamsOfTeamMentionConfig(contextIdentifier)), }; return [4 /*yield*/, serviceUtils.requestService(this.teamMentionConfig, options)]; case 1: teamResult = _a.sent(); return [2 /*return*/, this.convertTeamResultToMentionResult(teamResult, query)]; } }); }); }; TeamMentionResource.prototype.convertTeamResultToMentionResult = function (result, query) { var _this = this; var mentions = result.map(function (team) { return { id: _this.trimTeamARI(team.id), avatarUrl: team.smallAvatarImageUrl, name: team.displayName, accessLevel: UserAccessLevel[UserAccessLevel.CONTAINER], userType: UserType[UserType.TEAM], highlight: team.highlight, context: { members: team.members, includesYou: team.includesYou, memberCount: team.memberCount, }, }; }); return { mentions: mentions, query: query }; }; TeamMentionResource.prototype.trimTeamARI = function (teamId) { if (teamId === void 0) { teamId = ''; } var TEAM_ARI_PREFIX = 'ari:cloud:teams::team/'; return teamId.replace(TEAM_ARI_PREFIX, ''); }; TeamMentionResource.prototype.recordSelection = function (mention, contextIdentifier) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { // TODO: should we record a team selection _super.prototype.recordSelection.call(this, mention, contextIdentifier); return [2 /*return*/]; }); }); }; return TeamMentionResource; }(MentionResource)); export default TeamMentionResource; //# sourceMappingURL=TeamMentionResource.js.map