UNPKG

@atlaskit/mention

Version:

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

476 lines (467 loc) 18.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.isResolvingMentionProvider = exports.default = exports.MentionResource = exports.HttpError = exports.AbstractResource = exports.AbstractMentionResource = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _utilServiceSupport = require("@atlaskit/util-service-support"); var _types = require("../types"); var _logger = _interopRequireDefault(require("../util/logger")); var _analytics = require("../util/analytics"); var _debounce = _interopRequireDefault(require("lodash/debounce")); 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; })(); } var MAX_QUERY_ITEMS = 100; var MAX_NOTIFIED_ITEMS = 20; // Re-exporting types to prevent breaking change // Re-exporting types to prevent breaking change /** * Support */ var emptySecurityProvider = function emptySecurityProvider() { return { params: {}, headers: {} }; }; var AbstractResource = exports.AbstractResource = /*#__PURE__*/function () { function AbstractResource() { (0, _classCallCheck2.default)(this, AbstractResource); this.changeListeners = new Map(); this.allResultsListeners = new Map(); this.errListeners = new Map(); this.infoListeners = new Map(); this.analyticsListeners = new Map(); } return (0, _createClass2.default)(AbstractResource, [{ key: "subscribe", value: function subscribe(key, callback, errCallback, infoCallback, allResultsCallback, analyticsListeners) { if (callback) { this.changeListeners.set(key, callback); } if (errCallback) { this.errListeners.set(key, errCallback); } if (infoCallback) { this.infoListeners.set(key, infoCallback); } if (allResultsCallback) { this.allResultsListeners.set(key, allResultsCallback); } if (analyticsListeners) { this.analyticsListeners.set(key, analyticsListeners); } } }, { key: "unsubscribe", value: function unsubscribe(key) { this.changeListeners.delete(key); this.errListeners.delete(key); this.infoListeners.delete(key); this.allResultsListeners.delete(key); this.analyticsListeners.delete(key); } }]); }(); var AbstractMentionResource = exports.AbstractMentionResource = /*#__PURE__*/function (_ref) { function AbstractMentionResource() { (0, _classCallCheck2.default)(this, AbstractMentionResource); return _callSuper(this, AbstractMentionResource, arguments); } (0, _inherits2.default)(AbstractMentionResource, _ref); return (0, _createClass2.default)(AbstractMentionResource, [{ key: "shouldHighlightMention", value: function shouldHighlightMention(_mention) { return false; } // eslint-disable-next-line class-methods-use-this }, { key: "filter", value: function filter(query) { throw new Error("not yet implemented.\nParams: query=".concat(query)); } // eslint-disable-next-line class-methods-use-this, no-unused-vars }, { key: "recordMentionSelection", value: function recordMentionSelection(_mention) { // Do nothing } }, { key: "isFiltering", value: function isFiltering(_query) { return false; } }, { key: "_notifyListeners", value: function _notifyListeners(mentionsResult, stats) { (0, _logger.default)('ak-mention-resource._notifyListeners', mentionsResult && mentionsResult.mentions && mentionsResult.mentions.length, this.changeListeners); this.changeListeners.forEach(function (listener, key) { try { listener(mentionsResult.mentions.slice(0, MAX_NOTIFIED_ITEMS), mentionsResult.query, stats); } catch (e) { // ignore error from listener (0, _logger.default)("error from listener '".concat(key, "', ignoring"), e); } }); } }, { key: "_notifyAllResultsListeners", value: function _notifyAllResultsListeners(mentionsResult) { (0, _logger.default)('ak-mention-resource._notifyAllResultsListeners', mentionsResult && mentionsResult.mentions && mentionsResult.mentions.length, this.changeListeners); this.allResultsListeners.forEach(function (listener, key) { try { listener(mentionsResult.mentions.slice(0, MAX_NOTIFIED_ITEMS), mentionsResult.query); } catch (e) { // ignore error from listener (0, _logger.default)("error from listener '".concat(key, "', ignoring"), e); } }); } }, { key: "_notifyErrorListeners", value: function _notifyErrorListeners(error, query) { this.errListeners.forEach(function (listener, key) { try { listener(error, query); } catch (e) { // ignore error from listener (0, _logger.default)("error from listener '".concat(key, "', ignoring"), e); } }); } }, { key: "_notifyInfoListeners", value: function _notifyInfoListeners(info) { this.infoListeners.forEach(function (listener, key) { try { listener(info); } catch (e) { // ignore error fromr listener (0, _logger.default)("error from listener '".concat(key, "', ignoring"), e); } }); } }, { key: "_notifyAnalyticsListeners", value: function _notifyAnalyticsListeners(event, actionSubject, action, attributes) { this.analyticsListeners.forEach(function (listener, key) { try { listener(event, actionSubject, action, attributes); } catch (e) { // ignore error from listener (0, _logger.default)("error from listener '".concat(key, "', ignoring"), e); } }); } }]); }(AbstractResource); /** * Provides a Javascript API */ var MentionResource = exports.MentionResource = /*#__PURE__*/function (_AbstractMentionResou) { function MentionResource(config) { var _this; (0, _classCallCheck2.default)(this, MentionResource); _this = _callSuper(this, MentionResource); _this.verifyMentionConfig(config); _this.config = config; _this.lastReturnedSearch = 0; _this.activeSearches = new Set(); _this.productName = config.productName; _this.shouldEnableInvite = !!config.shouldEnableInvite; _this.onInviteItemClick = config.onInviteItemClick; _this.inviteXProductUser = config.inviteXProductUser; _this.userRole = config.userRole || 'basic'; if (_this.config.debounceTime) { _this.filter = (0, _debounce.default)(_this.filter, _this.config.debounceTime); } return _this; } (0, _inherits2.default)(MentionResource, _AbstractMentionResou); return (0, _createClass2.default)(MentionResource, [{ key: "shouldHighlightMention", value: function shouldHighlightMention(mention) { if (this.config.shouldHighlightMention) { return this.config.shouldHighlightMention(mention); } return false; } }, { key: "notify", value: function notify(searchTime, mentionResult, query) { if (searchTime > this.lastReturnedSearch) { this.lastReturnedSearch = searchTime; this._notifyListeners(mentionResult, { duration: 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: "notifyError", value: function notifyError(error, query) { this._notifyErrorListeners(error, query); if (query) { this.activeSearches.delete(query); } } }, { key: "filter", value: function () { var _filter = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(query, contextIdentifier) { var searchTime, results, searchResponse; return _regenerator.default.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.prev = 0; searchTime = Date.now(); if (query) { _context.next = 8; break; } _context.next = 5; return this.initialState(contextIdentifier); case 5: results = _context.sent; _context.next = 13; break; case 8: this.activeSearches.add(query); searchResponse = this.search(query, contextIdentifier); _context.next = 12; return searchResponse.mentions; case 12: results = _context.sent; case 13: this.notify(searchTime, results, query); _context.next = 19; break; case 16: _context.prev = 16; _context.t0 = _context["catch"](0); this.notifyError(_context.t0, query); case 19: case "end": return _context.stop(); } }, _callee, this, [[0, 16]]); })); function filter(_x, _x2) { return _filter.apply(this, arguments); } return filter; }() }, { key: "isFiltering", value: function isFiltering(query) { return this.activeSearches.has(query); } }, { key: "resolveMentionName", value: function resolveMentionName(id) { if (!this.config.mentionNameResolver) { return { id: id, name: '', status: _types.MentionNameStatus.UNKNOWN }; } return this.config.mentionNameResolver.lookupName(id); } }, { key: "cacheMentionName", value: function cacheMentionName(id, mentionName) { if (!this.config.mentionNameResolver) { return; } this.config.mentionNameResolver.cacheName(id, mentionName); } }, { key: "supportsMentionNameResolving", value: function supportsMentionNameResolving() { return !!this.config.mentionNameResolver; } }, { key: "updateActiveSearches", value: function updateActiveSearches(query) { this.activeSearches.add(query); } }, { key: "verifyMentionConfig", value: function verifyMentionConfig(config) { if (!config.url) { throw new Error('config.url is a required parameter'); } if (!config.securityProvider) { config.securityProvider = emptySecurityProvider; } } }, { key: "initialState", value: function initialState(contextIdentifier) { return this.remoteInitialState(contextIdentifier); } /** * Clear a context object to generate query params by removing empty * strings, `undefined` and empty values. * * @param contextIdentifier the current context identifier * @returns a safe context for query encoding */ }, { key: "clearContext", value: function clearContext() { var contextIdentifier = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return Object.keys(contextIdentifier).filter(function (key) { return contextIdentifier[key]; }).reduce(function (context, key) { return _objectSpread((0, _defineProperty2.default)({}, key, contextIdentifier[key]), context); }, {}); } }, { key: "getQueryParams", value: function getQueryParams(contextIdentifier) { var configParams = {}; if (this.config.containerId) { configParams['containerId'] = this.config.containerId; } if (this.config.productId) { configParams['productIdentifier'] = this.config.productId; } // if contextParams exist then it will override configParams for containerId return _objectSpread(_objectSpread({}, configParams), this.clearContext(contextIdentifier)); } /** * Returns the initial mention display list before a search is performed for the specified * container. * * @param contextIdentifier * @returns Promise */ }, { key: "remoteInitialState", value: (function () { var _remoteInitialState = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(contextIdentifier) { var queryParams, options, result; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: queryParams = this.getQueryParams(contextIdentifier); options = { path: 'bootstrap', queryParams: queryParams }; _context2.prev = 2; _context2.next = 5; return _utilServiceSupport.utils.requestService(this.config, options); case 5: result = _context2.sent; this._notifyAnalyticsListeners(_analytics.SLI_EVENT_TYPE, _types.SliNames.INITIAL_STATE, _types.Actions.SUCCEEDED); return _context2.abrupt("return", this.transformServiceResponse(result, '')); case 10: _context2.prev = 10; _context2.t0 = _context2["catch"](2); this._notifyAnalyticsListeners(_analytics.SLI_EVENT_TYPE, _types.SliNames.INITIAL_STATE, _types.Actions.FAILED); throw _context2.t0; case 14: case "end": return _context2.stop(); } }, _callee2, this, [[2, 10]]); })); function remoteInitialState(_x3) { return _remoteInitialState.apply(this, arguments); } return remoteInitialState; }()) }, { key: "search", value: function search(query, contextIdentifier) { return { mentions: this.remoteSearch(query, contextIdentifier) }; } }, { key: "remoteSearch", value: function () { var _remoteSearch = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(query, contextIdentifier) { var options, result; 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_ITEMS }, this.getQueryParams(contextIdentifier)) }; _context3.prev = 1; _context3.next = 4; return _utilServiceSupport.utils.requestService(this.config, options); case 4: result = _context3.sent; this._notifyAnalyticsListeners(_analytics.SLI_EVENT_TYPE, _types.SliNames.SEARCH, _types.Actions.SUCCEEDED); return _context3.abrupt("return", this.transformServiceResponse(result, query)); case 9: _context3.prev = 9; _context3.t0 = _context3["catch"](1); this._notifyAnalyticsListeners(_analytics.SLI_EVENT_TYPE, _types.SliNames.SEARCH, _types.Actions.FAILED); throw _context3.t0; case 13: case "end": return _context3.stop(); } }, _callee3, this, [[1, 9]]); })); function remoteSearch(_x4, _x5) { return _remoteSearch.apply(this, arguments); } return remoteSearch; }() }, { key: "transformServiceResponse", value: function transformServiceResponse(result, query) { var mentions = result.mentions.map(function (mention) { var lozenge; if ((0, _types.isAppMention)(mention)) { lozenge = mention.userType; } else if ((0, _types.isTeamMention)(mention)) { lozenge = mention.userType; } return _objectSpread(_objectSpread({}, mention), {}, { lozenge: lozenge, query: query }); }); return _objectSpread(_objectSpread({}, result), {}, { mentions: mentions, query: result.query || query }); } }]); }(AbstractMentionResource); var HttpError = exports.HttpError = /*#__PURE__*/(0, _createClass2.default)(function HttpError(statusCode, statusMessage) { (0, _classCallCheck2.default)(this, HttpError); this.statusCode = statusCode; this.message = statusMessage; this.name = 'HttpError'; this.stack = new Error().stack; }); var isResolvingMentionProvider = exports.isResolvingMentionProvider = function isResolvingMentionProvider(p) { return !!(p && p.supportsMentionNameResolving && p.supportsMentionNameResolving()); }; var _default = exports.default = MentionResource;