@atlaskit/editor-plugin-mentions
Version:
Mentions plugin for @atlaskit/editor-core
189 lines (188 loc) • 10.5 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
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) { _defineProperty(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; }
import React from 'react';
import { bind } from 'bind-event-listener';
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
import uuid from 'uuid/v4';
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
import { findChildrenByAttr } from '@atlaskit/editor-prosemirror/utils';
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
import { fg } from '@atlaskit/platform-feature-flags/fg';
import { navigateToTeamsApp } from '@atlaskit/teams-app-config/navigation';
import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
import { getAgentMentionParentContext } from '../pm-plugins/agent-mention-context';
import { isAgentMentionType, ProfileCardComponent } from '../ui/ProfileCardComponent';
export var profileCardRenderer = function profileCardRenderer(_ref) {
var dom = _ref.dom,
options = _ref.options,
portalProviderAPI = _ref.portalProviderAPI,
node = _ref.node,
api = _ref.api,
editorView = _ref.editorView;
// Keep a mutable reference to the latest node so the click handler always
// reads up-to-date attrs
var currentNode = node;
var renderingProfileCard = false;
var navigatingToProfile = false;
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
var key = uuid();
var cleanupSelection;
var removeProfileCard = function removeProfileCard() {
var _cleanupSelection;
if (dom instanceof HTMLElement) {
dom.setAttribute('aria-expanded', 'false');
}
portalProviderAPI.remove(key);
renderingProfileCard = false;
(_cleanupSelection = cleanupSelection) === null || _cleanupSelection === void 0 || _cleanupSelection();
};
var renderProfileCardPopup = function renderProfileCardPopup(renderProfileCard) {
var _api$selection;
if (!(dom instanceof HTMLElement) || renderingProfileCard) {
return;
}
var referenceElement = dom;
referenceElement.setAttribute('aria-expanded', 'true');
renderingProfileCard = true;
portalProviderAPI.render(function () {
return renderProfileCard(referenceElement);
}, referenceElement, key);
cleanupSelection = api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 ? void 0 : _api$selection.sharedState.onChange(function (_ref2) {
var nextSharedState = _ref2.nextSharedState;
var selection = nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.selection;
if (selection instanceof NodeSelection ? expVal('platform_editor_reduced_agent_profile_cards', 'isEnabled', false) ? selection.node.sameMarkup(currentNode) : selection.node === node : false) {
return;
}
removeProfileCard === null || removeProfileCard === void 0 || removeProfileCard();
});
};
var renderEditorProfileCard = function renderEditorProfileCard() {
var isReducedProfileCards = expVal('platform_editor_reduced_agent_profile_cards', 'isEnabled', false);
var clickedNode = isReducedProfileCards ? currentNode : node;
var activeMention = isReducedProfileCards ? function (_ref3, _currentNode, _currentNode2, _currentNode3) {
// Avatar mentions keep their resolved display name in the nested text span.
// Control mentions preserve the legacy attrs-first fallback.
var mentionTextElement = dom instanceof HTMLElement ? dom.querySelector('.editor-mention-text') : undefined;
var primitiveText = (_ref3 = mentionTextElement !== null && mentionTextElement !== void 0 ? mentionTextElement : dom instanceof HTMLElement ? dom.querySelector('.editor-mention-primitive') : undefined) === null || _ref3 === void 0 || (_ref3 = _ref3.textContent) === null || _ref3 === void 0 ? void 0 : _ref3.trim();
var resolvedText = primitiveText && !primitiveText.startsWith('@') ? "@".concat(primitiveText) : primitiveText;
return {
attrs: _objectSpread(_objectSpread({}, (_currentNode = currentNode) === null || _currentNode === void 0 ? void 0 : _currentNode.attrs), {}, {
text: mentionTextElement ? resolvedText || ((_currentNode2 = currentNode) === null || _currentNode2 === void 0 || (_currentNode2 = _currentNode2.attrs) === null || _currentNode2 === void 0 ? void 0 : _currentNode2.text) || undefined : ((_currentNode3 = currentNode) === null || _currentNode3 === void 0 || (_currentNode3 = _currentNode3.attrs) === null || _currentNode3 === void 0 ? void 0 : _currentNode3.text) || primitiveText || undefined
})
};
}() : {
attrs: node.attrs
};
// Build agent mention context at click time by finding the parent block of this mention
// in the live document.
var agentMentionContext;
if (options !== null && options !== void 0 && options.onAgentMentionChatClick && editorView && fg('platform_editor_agent_mentions_drop_one_fixes')) {
var _clickedNode$attrs;
var localId = (_clickedNode$attrs = clickedNode.attrs) === null || _clickedNode$attrs === void 0 ? void 0 : _clickedNode$attrs.localId;
if (localId) {
var found = findChildrenByAttr(editorView.state.doc, function (attrs) {
return (attrs === null || attrs === void 0 ? void 0 : attrs.localId) === localId;
})[0];
if (found) {
var parentBlock = editorView.state.doc.resolve(found.pos).parent;
agentMentionContext = getAgentMentionParentContext(parentBlock, localId);
}
}
}
renderProfileCardPopup(function (referenceElement) {
return /*#__PURE__*/React.createElement(ProfileCardComponent, {
activeMention: activeMention,
profilecardProvider: options === null || options === void 0 ? void 0 : options.profilecardProvider,
onAgentMentionChatClick: options !== null && options !== void 0 && options.onAgentMentionChatClick && fg('platform_editor_agent_mentions_drop_one_fixes') ? function (agentId) {
var _options$onAgentMenti;
return (_options$onAgentMenti = options.onAgentMentionChatClick) === null || _options$onAgentMenti === void 0 ? void 0 : _options$onAgentMenti.call(options, agentId, agentMentionContext);
} : undefined,
dom: referenceElement,
closeComponent: removeProfileCard
});
});
};
var renderUserProfileCard = function renderUserProfileCard(_ref4) {
var userId = _ref4.userId,
cloudId = _ref4.cloudId,
renderUserMentionCard = _ref4.renderUserMentionCard;
if (!renderUserMentionCard) {
return false;
}
renderProfileCardPopup(function (referenceElement) {
return /*#__PURE__*/React.createElement(React.Fragment, null, renderUserMentionCard({
userId: userId,
cloudId: cloudId,
children: null,
referenceElement: referenceElement
}));
});
return true;
};
var navigateToProfile = function navigateToProfile(userId, cloudId) {
if (navigatingToProfile) {
return;
}
navigatingToProfile = true;
var _navigateToTeamsApp = navigateToTeamsApp({
type: 'USER',
payload: {
userId: userId
},
cloudId: cloudId
}),
href = _navigateToTeamsApp.href,
target = _navigateToTeamsApp.target;
window.open(href, target, 'noopener,noreferrer');
};
var renderDefaultProfileCard = function renderDefaultProfileCard(userId, provider) {
if (renderUserProfileCard({
userId: userId,
cloudId: provider.cloudId,
renderUserMentionCard: provider.renderUserMentionCard
})) {
return;
}
navigateToProfile(userId, provider.cloudId);
};
var listenerCleanup = bind(dom, {
type: 'click',
listener: function listener() {
if (fg('people-teams_migrate-user-profile-card') || isExperimentEnabled('pt_user_profile_card_migration_exp')) {
var _currentNode$attrs, _node$attrs, _options$profilecardP;
var userId = expVal('platform_editor_reduced_agent_profile_cards', 'isEnabled', false) ? (_currentNode$attrs = currentNode.attrs) === null || _currentNode$attrs === void 0 ? void 0 : _currentNode$attrs.id : (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.id;
if (!userId) {
return;
}
navigatingToProfile = false;
options === null || options === void 0 || (_options$profilecardP = options.profilecardProvider) === null || _options$profilecardP === void 0 || _options$profilecardP.then(function (provider) {
var _currentNode$attrs2, _node$attrs2;
if (!expVal('platform_editor_agent_mentions', 'isEnabled', false)) {
renderDefaultProfileCard(userId, provider);
return;
}
if (isAgentMentionType(expVal('platform_editor_reduced_agent_profile_cards', 'isEnabled', false) ? (_currentNode$attrs2 = currentNode.attrs) === null || _currentNode$attrs2 === void 0 ? void 0 : _currentNode$attrs2.userType : (_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.userType)) {
renderEditorProfileCard();
} else {
renderDefaultProfileCard(userId, provider);
}
});
return;
}
if (options !== null && options !== void 0 && options.profilecardProvider) {
renderEditorProfileCard();
}
}
});
return {
destroyProfileCard: function destroyProfileCard() {
listenerCleanup();
removeProfileCard === null || removeProfileCard === void 0 || removeProfileCard();
},
removeProfileCard: removeProfileCard,
updateNode: function updateNode(nextNode) {
currentNode = nextNode;
}
};
};