@atlaskit/editor-plugin-annotation
Version:
Annotation plugin for @atlaskit/editor-core
208 lines (205 loc) • 10.6 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.shouldSuppressFloatingToolbar = exports.buildToolbar = exports.buildSuppressedToolbar = void 0;
var _react = _interopRequireDefault(require("react"));
var _analytics = require("@atlaskit/editor-common/analytics");
var _keymaps = require("@atlaskit/editor-common/keymaps");
var _mediaSingle = require("@atlaskit/editor-common/media-single");
var _messages = require("@atlaskit/editor-common/messages");
var _utils = require("@atlaskit/editor-common/utils");
var _editorPluginConnectivity = require("@atlaskit/editor-plugin-connectivity");
var _comment = _interopRequireDefault(require("@atlaskit/icon/core/comment"));
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
var _editorCommands = require("../editor-commands");
var _types = require("../types");
var _utils2 = require("./utils");
var getValidNodes = function getValidNodes(state) {
var schema = state.schema;
var annotation = schema.marks.annotation;
return Object.keys(schema.nodes).reduce(function (acc, current) {
var type = schema.nodes[current];
if (type.allowsMarkType(annotation)) {
acc.push(type);
}
return acc;
}, []);
};
/**
* Should suppress toolbars when the user is creating an inline comment
* This only applies when the selection range exactly matches the bookmark range
* which should be the case immediately after the comment button is clicked
* if the user creates a different selection range, the floating toolbar should still be shown
* @param root0
* @param root0.state
* @param root0.bookmark
* @example
*/
var shouldSuppressFloatingToolbar = exports.shouldSuppressFloatingToolbar = function shouldSuppressFloatingToolbar(_ref) {
var state = _ref.state,
bookmark = _ref.bookmark;
if (!bookmark) {
return false;
}
var tr = state.tr;
var resolvedBookmark = bookmark.resolve(tr.doc);
var isSelectionMatchingBookmark = resolvedBookmark.to === tr.selection.to && resolvedBookmark.from === tr.selection.from;
return isSelectionMatchingBookmark;
};
var buildSuppressedToolbar = exports.buildSuppressedToolbar = function buildSuppressedToolbar(state) {
return {
items: [],
nodeType: getValidNodes(state),
title: 'Annotation suppressed toolbar'
};
};
var buildToolbar = exports.buildToolbar = function buildToolbar(editorAnalyticsAPI) {
return function (_ref2) {
var _api$connectivity;
var state = _ref2.state,
intl = _ref2.intl,
_ref2$isToolbarAbove = _ref2.isToolbarAbove,
isToolbarAbove = _ref2$isToolbarAbove === void 0 ? false : _ref2$isToolbarAbove,
_ref2$_supportedNodes = _ref2._supportedNodes,
_supportedNodes = _ref2$_supportedNodes === void 0 ? [] : _ref2$_supportedNodes,
api = _ref2.api,
createCommentExperience = _ref2.createCommentExperience,
annotationManager = _ref2.annotationManager,
onCommentButtonMount = _ref2.onCommentButtonMount,
_ref2$getCanAddCommen = _ref2.getCanAddComments,
getCanAddComments = _ref2$getCanAddCommen === void 0 ? function () {
return true;
} : _ref2$getCanAddCommen,
contentType = _ref2.contentType;
var selectionValid = (0, _utils2.isSelectionValid)(state);
var isMediaSelected = (0, _mediaSingle.currentMediaNodeWithPos)(state);
// comments on media can only be added via media floating toolbar
if (isMediaSelected || selectionValid === _types.AnnotationSelectionType.INVALID) {
return undefined;
}
var createCommentMessage = intl.formatMessage(_messages.annotationMessages.createComment);
var commentDisabledMessage = intl.formatMessage((0, _platformFeatureFlags.fg)('editor_inline_comments_on_inline_nodes') ? _messages.annotationMessages.createCommentDisabled : _messages.annotationMessages.createCommentInvalid);
var canAddComments = getCanAddComments();
var isCommentButtonDisabled = !canAddComments || selectionValid === _types.AnnotationSelectionType.DISABLED;
var disabledTooltipContent = !canAddComments ? intl.formatMessage(_messages.annotationMessages.noPermissionToAddComment, {
contentType: contentType
}) : commentDisabledMessage;
var createComment = {
type: 'button',
showTitle: true,
disabled: isCommentButtonDisabled || (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity = api.connectivity) === null || _api$connectivity === void 0 || (_api$connectivity = _api$connectivity.sharedState) === null || _api$connectivity === void 0 || (_api$connectivity = _api$connectivity.currentState()) === null || _api$connectivity === void 0 ? void 0 : _api$connectivity.mode),
testId: _types.AnnotationTestIds.floatingToolbarCreateButton,
interactionName: 'start-inline-comment-action',
icon: _comment.default,
iconFallback: _comment.default,
tooltipContent: isCommentButtonDisabled ? disabledTooltipContent : /*#__PURE__*/_react.default.createElement(_keymaps.ToolTipContent, {
description: createCommentMessage,
keymap: _keymaps.addInlineComment
}),
title: createCommentMessage,
onMount: function onMount() {
var _getRangeInlineNodeNa;
if ((0, _platformFeatureFlags.fg)('confluence_frontend_preload_inline_comment_editor')) {
onCommentButtonMount && onCommentButtonMount();
}
// Check if the selection includes an non-text inline node
var inlineCommentPluginState = (0, _utils2.getPluginState)(state);
var inlineNodeNames = (_getRangeInlineNodeNa = (0, _utils.getRangeInlineNodeNames)({
doc: state.doc,
pos: (0, _utils2.resolveDraftBookmark)(state, inlineCommentPluginState === null || inlineCommentPluginState === void 0 ? void 0 : inlineCommentPluginState.bookmark)
})) !== null && _getRangeInlineNodeNa !== void 0 ? _getRangeInlineNodeNa : [];
var isNonTextInlineNodeInludedInComment = inlineNodeNames.filter(function (nodeName) {
return nodeName !== 'text';
}).length > 0;
if (editorAnalyticsAPI) {
editorAnalyticsAPI.fireAnalyticsEvent({
action: _analytics.ACTION.VIEWED,
actionSubject: _analytics.ACTION_SUBJECT.BUTTON,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
eventType: _analytics.EVENT_TYPE.UI,
attributes: {
isNonTextInlineNodeInludedInComment: isNonTextInlineNodeInludedInComment,
isDisabled: selectionValid === _types.AnnotationSelectionType.DISABLED,
inputMethod: _analytics.INPUT_METHOD.FLOATING_TB,
mode: _analytics.MODE.EDITOR
}
});
}
},
onClick: function onClick(state, dispatch) {
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.fireAnalyticsEvent({
action: _analytics.ACTION.CLICKED,
actionSubject: _analytics.ACTION_SUBJECT.BUTTON,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.CREATE_INLINE_COMMENT_FROM_HIGHLIGHT_ACTIONS_MENU,
eventType: _analytics.EVENT_TYPE.UI,
attributes: {
source: 'highlightActionsMenu',
pageMode: 'edit'
}
});
if (annotationManager) {
annotationManager.checkPreemptiveGate().then(function (canStartDraft) {
if (canStartDraft) {
createCommentExperience === null || createCommentExperience === void 0 || createCommentExperience.start({
attributes: {
pageClass: 'editor',
commentType: 'inline',
entryPoint: 'highlightActions'
}
});
createCommentExperience === null || createCommentExperience === void 0 || createCommentExperience.initExperience.start();
var result = annotationManager.startDraft();
if (!result.success) {
// Fire an analytics event to indicate that the user has clicked the button
// but the action was not completed, the result should contain a reason.
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.fireAnalyticsEvent({
action: _analytics.ACTION.ERROR,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
eventType: _analytics.EVENT_TYPE.OPERATIONAL,
attributes: {
errorReason: "toolbar-start-draft-failed/".concat(result.reason)
}
});
}
}
}).catch(function () {
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.fireAnalyticsEvent({
action: _analytics.ACTION.ERROR,
actionSubject: _analytics.ACTION_SUBJECT.ANNOTATION,
actionSubjectId: _analytics.ACTION_SUBJECT_ID.INLINE_COMMENT,
eventType: _analytics.EVENT_TYPE.OPERATIONAL,
attributes: {
errorReason: "toolbar-start-draft-preemptive-gate-error"
}
});
});
return true;
} else {
createCommentExperience === null || createCommentExperience === void 0 || createCommentExperience.start({
attributes: {
pageClass: 'editor',
commentType: 'inline',
entryPoint: 'highlightActions'
}
});
createCommentExperience === null || createCommentExperience === void 0 || createCommentExperience.initExperience.start();
return (0, _editorCommands.setInlineCommentDraftState)(editorAnalyticsAPI)(true)(state, dispatch);
}
},
supportsViewMode: true // TODO: MODES-3950 - Clean up this floating toolbar view mode logic,
};
var toolbarTitle = intl.formatMessage(_messages.annotationMessages.toolbar);
var calcToolbarPosition = isToolbarAbove ? _utils.calculateToolbarPositionAboveSelection : _utils.calculateToolbarPositionTrackHead;
var onPositionCalculated = calcToolbarPosition(toolbarTitle);
return {
title: toolbarTitle,
nodeType: getValidNodes(state),
items: [createComment],
onPositionCalculated: onPositionCalculated,
pluginName: 'annotation'
};
};
};