UNPKG

@atlaskit/mention

Version:

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

291 lines (285 loc) 14.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _analytics = require("./../util/analytics"); var _utilServiceSupport = require("@atlaskit/util-service-support"); var _types = require("../types"); var _MentionResource2 = _interopRequireDefault(require("./MentionResource")); var _logger = _interopRequireDefault(require("../util/logger")); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototypeOf2.default)(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } 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 = exports.default = /*#__PURE__*/function (_MentionResource) { function TeamMentionResource(userMentionConfig, teamMentionConfig) { var _this; (0, _classCallCheck2.default)(this, TeamMentionResource); _this = _callSuper(this, TeamMentionResource, [userMentionConfig]); (0, _defineProperty2.default)(_this, "lastSearchQuery", ''); _this.verifyMentionConfig(teamMentionConfig); _this.teamMentionConfig = teamMentionConfig; _this.lastReturnedSearchTeam = 0; return _this; } (0, _inherits2.default)(TeamMentionResource, _MentionResource); return (0, _createClass2.default)(TeamMentionResource, [{ key: "filter", value: function filter(query, contextIdentifier) { this.lastSearchQuery = query; if (!query) { return 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); return this.handleBothRequests(query, getUserPromise, getTeamsPromise); } } /** * Returns the initial mention display list before a search is performed for the specified * container. */ }, { key: "remoteInitialStateTeamAndUsers", value: (function () { var _remoteInitialStateTeamAndUsers = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(contextIdentifier) { var emptyQuery, getUserPromise, queryParams, options, getTeamsPromise; return _regenerator.default.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: emptyQuery = ''; getUserPromise = _superPropGet(TeamMentionResource, "remoteInitialState", this, 3)([contextIdentifier]); queryParams = this.getQueryParamsOfTeamMentionConfig(contextIdentifier); options = { path: 'bootstrap', queryParams: queryParams }; getTeamsPromise = _utilServiceSupport.utils.requestService(this.teamMentionConfig, options); this.handleBothRequests(emptyQuery, getUserPromise, getTeamsPromise); case 6: case "end": return _context.stop(); } }, _callee, this); })); function remoteInitialStateTeamAndUsers(_x) { return _remoteInitialStateTeamAndUsers.apply(this, arguments); } return remoteInitialStateTeamAndUsers; }() /** * 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 */ ) }, { key: "handleBothRequests", value: (function () { var _handleBothRequests = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(query, userRequest, teamRequest) { var _this2 = this; var searchTime, accumulatedResults, notifyWhenOneRequestDone, userResults, userRequestError, teamRequestError, teamsResult; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: searchTime = Date.now(); accumulatedResults = { mentions: [], query: query }; notifyWhenOneRequestDone = function notifyWhenOneRequestDone(results, hasTeamResults) { // just update UI for the last query string if (query !== _this2.lastSearchQuery) { return; } accumulatedResults = { mentions: [].concat((0, _toConsumableArray2.default)(accumulatedResults.mentions), (0, _toConsumableArray2.default)(results.mentions)), query: query }; // we need to calculate different `duration` for user and team request. if (hasTeamResults) { _this2.notify(searchTime, accumulatedResults, query); } else { _superPropGet(TeamMentionResource, "notify", _this2, 3)([searchTime, accumulatedResults, query]); } }; userRequestError = null; teamRequestError = null; _context2.prev = 5; _context2.next = 8; return userRequest; case 8: userResults = _context2.sent; notifyWhenOneRequestDone(userResults, false); _context2.next = 15; break; case 12: _context2.prev = 12; _context2.t0 = _context2["catch"](5); userRequestError = _context2.t0; case 15: _context2.prev = 15; _context2.next = 18; return teamRequest; case 18: teamsResult = _context2.sent; // update search time after team results returns notifyWhenOneRequestDone(Array.isArray(teamsResult) ? this.convertTeamResultToMentionResult(teamsResult, query) : teamsResult, true); _context2.next = 25; break; case 22: _context2.prev = 22; _context2.t1 = _context2["catch"](15); teamRequestError = _context2.t1; case 25: // both requests fail, show one of errors in UI if (userRequestError && teamRequestError) { this.notifyError(userRequestError, query); (0, _logger.default)('User mention request fails. ', userRequestError); (0, _logger.default)('Team mention request fails. ', teamRequestError); } case 26: case "end": return _context2.stop(); } }, _callee2, this, [[5, 12], [15, 22]]); })); function handleBothRequests(_x2, _x3, _x4) { return _handleBothRequests.apply(this, arguments); } return handleBothRequests; }()) }, { key: "notify", value: function notify(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); (0, _logger.default)('Stale search result, skipping', date, query); // eslint-disable-line no-console, max-len } this._notifyAllResultsListeners(mentionResult); } }, { key: "getQueryParamsOfTeamMentionConfig", value: function getQueryParamsOfTeamMentionConfig(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 _objectSpread(_objectSpread({}, configParams), contextIdentifier); } }, { key: "remoteUserSearch", value: function remoteUserSearch(query, contextIdentifier) { return _superPropGet(TeamMentionResource, "remoteSearch", this, 3)([query, contextIdentifier]); } }, { key: "remoteTeamSearch", value: function () { var _remoteTeamSearch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(query, contextIdentifier) { var options, teamResult; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: options = { path: 'search', queryParams: _objectSpread({ query: query, limit: MAX_QUERY_TEAMS }, this.getQueryParamsOfTeamMentionConfig(contextIdentifier)) }; _context3.prev = 1; _context3.next = 4; return _utilServiceSupport.utils.requestService(this.teamMentionConfig, options); case 4: teamResult = _context3.sent; this._notifyAnalyticsListeners(_analytics.SLI_EVENT_TYPE, _types.SliNames.SEARCH_TEAM, _types.Actions.SUCCEEDED); return _context3.abrupt("return", this.convertTeamResultToMentionResult(teamResult, query)); case 9: _context3.prev = 9; _context3.t0 = _context3["catch"](1); this._notifyAnalyticsListeners(_analytics.SLI_EVENT_TYPE, _types.SliNames.SEARCH_TEAM, _types.Actions.FAILED); throw _context3.t0; case 13: case "end": return _context3.stop(); } }, _callee3, this, [[1, 9]]); })); function remoteTeamSearch(_x5, _x6) { return _remoteTeamSearch.apply(this, arguments); } return remoteTeamSearch; }() }, { key: "convertTeamResultToMentionResult", value: function convertTeamResultToMentionResult(result, query) { var _this3 = this; var teamLinkResolver = this.teamMentionConfig.teamLinkResolver; var mentions = result.map(function (team) { var teamLink = ''; var defaultTeamLink = "".concat(window.location.origin, "/people/team/").concat(team.id); if (typeof teamLinkResolver === 'function') { teamLink = teamLinkResolver(team.id); } return { id: _this3.trimTeamARI(team.id), avatarUrl: team.smallAvatarImageUrl, name: team.displayName, accessLevel: _types.UserAccessLevel[_types.UserAccessLevel.CONTAINER], userType: _types.UserType[_types.UserType.TEAM], highlight: team.highlight, context: { members: team.members, includesYou: team.includesYou, memberCount: team.memberCount, teamLink: teamLink || defaultTeamLink } }; }); return { mentions: mentions, query: query }; } }, { key: "trimTeamARI", value: function trimTeamARI() { var teamId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; var TEAM_ARI_PREFIX = 'ari:cloud:teams::team/'; var IDENTITY_TEAM_ARI_PREFIX = 'ari:cloud:identity::team/'; return teamId.replace(TEAM_ARI_PREFIX, '').replace(IDENTITY_TEAM_ARI_PREFIX, ''); } }]); }(_MentionResource2.default);