@atlaskit/editor-plugin-tasks-and-decisions
Version:
Tasks and decisions plugin for @atlaskit/editor-core
321 lines (320 loc) • 15 kB
JavaScript
/* tasksAndDecisionsPlugin.tsx generated by @compiled/babel-plugin v0.39.1 */
import "./tasksAndDecisionsPlugin.compiled.css";
import * as React from 'react';
import { ax, ix } from "@compiled/react/runtime";
import { decisionList, taskList } from '@atlaskit/adf-schema';
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { TRANSFORM_STRUCTURE_MENU_SECTION, TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM, TRANSFORM_STRUCTURE_MENU_SECTION_RANK, TRANSFORM_STRUCTURE_DECISION_MENU_ITEM } from '@atlaskit/editor-common/block-menu';
import { MAX_INDENTATION_LEVEL } from '@atlaskit/editor-common/indentation';
import { toolbarInsertBlockMessages as insertBlockMessages } from '@atlaskit/editor-common/messages';
import { IconAction, IconDecision } from '@atlaskit/editor-common/quick-insert';
import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { taskItemNodeSpec, blockTaskItemNodeSpec } from './nodeviews/taskItemNodeSpec';
import { decisionItemSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/decisionItem';
import { closeRequestEditPopupAt, getCurrentIndentLevel, getTaskItemIndex, isInsideTask } from './pm-plugins/helpers';
// Ignored via go/ees005
// eslint-disable-next-line import/no-named-as-default
import inputRulePlugin from './pm-plugins/input-rules';
import { getListTypes, insertTaskDecisionAction, insertTaskDecisionCommand, setProvider } from './pm-plugins/insert-commands';
import keymap, { getIndentCommand, getUnindentCommand } from './pm-plugins/keymaps';
import { createPlugin } from './pm-plugins/main';
import { stateKey as taskPluginKey } from './pm-plugins/plugin-key';
import { toggleTaskList } from './pm-plugins/toggle-tasklist-commands';
import { DecisionListBlockMenuItem } from './ui/DecisionListBlockMenuItem/DecisionListBlockMenuItem';
import { RequestToEditPopup } from './ui/Task/RequestToEditPopup';
import { TaskListBlockMenuItem } from './ui/TaskListBlockMenuItem/TaskListBlockMenuItem';
import { getTasksAndDecisionsToolbarComponents } from './ui/toolbar-components';
import ToolbarDecision from './ui/ToolbarDecision';
import ToolbarTask from './ui/ToolbarTask';
const taskDecisionToolbarGroupStyles = null;
const TASK_LIST_NODE_NAME = 'taskList';
const DECISION_LIST_NODE_NAME = 'decisionList';
const addItem = (insert, listType, schema) => ({
listLocalId,
itemLocalId
}) => {
const {
list,
item
} = getListTypes(listType, schema);
return insert(list.createChecked({
localId: listLocalId
}, item.createChecked({
localId: itemLocalId
})));
};
function ContentComponent({
editorView,
popupsMountPoint,
popupsBoundariesElement,
popupsScrollableElement,
dependencyApi
}) {
const openRequestToEditPopupAt = useSharedPluginStateSelector(dependencyApi, 'taskDecision.openRequestToEditPopupAt');
const hasEditPermission = useSharedPluginStateSelector(dependencyApi, 'taskDecision.hasEditPermission');
if (!editorView || hasEditPermission || !openRequestToEditPopupAt) {
return null;
}
const domAtPos = editorView.domAtPos.bind(editorView);
// eslint-disable-next-line @atlaskit/editor/no-as-casting
const element = findDomRefAtPos(openRequestToEditPopupAt, domAtPos);
const handleOnClose = () => {
closeRequestEditPopupAt(editorView);
editorView.focus();
};
return /*#__PURE__*/React.createElement(RequestToEditPopup, {
key: openRequestToEditPopupAt,
api: dependencyApi,
editorView: editorView,
mountTo: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
scrollableElement: popupsScrollableElement,
element: element,
onClose: handleOnClose
});
}
export const tasksAndDecisionsPlugin = ({
config: {
allowNestedTasks,
consumeTabs,
useLongPressSelection,
hasEditPermission = true,
hasRequestedEditPermission,
quickInsertActionDescription,
requestToEditContent,
taskDecisionProvider,
taskPlaceholder,
allowBlockTaskItem
} = {},
api
}) => {
var _api$analytics2, _api$analytics3, _api$analytics4;
const getIdentifierProvider = () => {
var _api$contextIdentifie, _api$contextIdentifie2;
return api === null || api === void 0 ? void 0 : (_api$contextIdentifie = api.contextIdentifier) === null || _api$contextIdentifie === void 0 ? void 0 : (_api$contextIdentifie2 = _api$contextIdentifie.sharedState.currentState()) === null || _api$contextIdentifie2 === void 0 ? void 0 : _api$contextIdentifie2.contextIdentifierProvider;
};
let previousTaskAndDecisionProvider;
const isToolbarAIFCEnabled = Boolean(api === null || api === void 0 ? void 0 : api.toolbar);
if (isToolbarAIFCEnabled) {
var _api$toolbar;
api === null || api === void 0 ? void 0 : (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 ? void 0 : _api$toolbar.actions.registerComponents(getTasksAndDecisionsToolbarComponents({
api
}));
}
if (taskDecisionProvider) {
taskDecisionProvider.then(provider => {
api === null || api === void 0 ? void 0 : api.core.actions.execute(({
tr
}) => setProvider(provider)(tr));
});
}
if (editorExperiment('platform_editor_block_menu', true)) {
var _api$blockMenu;
api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.registerBlockMenuComponents([{
type: 'block-menu-item',
key: TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key,
parent: {
type: 'block-menu-section',
key: TRANSFORM_STRUCTURE_MENU_SECTION.key,
rank: TRANSFORM_STRUCTURE_MENU_SECTION_RANK[TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key]
},
component: () => {
return /*#__PURE__*/React.createElement(TaskListBlockMenuItem, {
api: api
});
},
isHidden: () => {
var _api$blockMenu2;
return Boolean(api === null || api === void 0 ? void 0 : (_api$blockMenu2 = api.blockMenu) === null || _api$blockMenu2 === void 0 ? void 0 : _api$blockMenu2.actions.isTransformOptionDisabled(TASK_LIST_NODE_NAME));
}
}, {
type: 'block-menu-item',
key: TRANSFORM_STRUCTURE_DECISION_MENU_ITEM.key,
parent: {
type: 'block-menu-section',
key: TRANSFORM_STRUCTURE_MENU_SECTION.key,
rank: TRANSFORM_STRUCTURE_MENU_SECTION_RANK[TRANSFORM_STRUCTURE_DECISION_MENU_ITEM.key]
},
component: () => {
return /*#__PURE__*/React.createElement(DecisionListBlockMenuItem, {
api: api
});
},
isHidden: () => {
var _api$blockMenu3;
return Boolean(api === null || api === void 0 ? void 0 : (_api$blockMenu3 = api.blockMenu) === null || _api$blockMenu3 === void 0 ? void 0 : _api$blockMenu3.actions.isTransformOptionDisabled(DECISION_LIST_NODE_NAME));
}
}]);
}
return {
name: 'taskDecision',
nodes() {
return [{
name: 'decisionList',
node: decisionList
}, {
name: 'decisionItem',
node: decisionItemSpecWithFixedToDOM()
}, {
name: 'taskList',
node: taskList
}, {
name: 'taskItem',
node: taskItemNodeSpec()
}, ...(expValEquals('platform_editor_blocktaskitem_node_tenantid', 'isEnabled', true) && allowBlockTaskItem ? [{
name: 'blockTaskItem',
node: blockTaskItemNodeSpec()
}] : [])];
},
getSharedState(editorState) {
if (!editorState) {
return undefined;
}
const pluginState = taskPluginKey.getState(editorState);
const indentLevel = getCurrentIndentLevel(editorState.selection) || 0;
const itemIndex = getTaskItemIndex(editorState);
return {
focusedTaskItemLocalId: (pluginState === null || pluginState === void 0 ? void 0 : pluginState.focusedTaskItemLocalId) || null,
isInsideTask: isInsideTask(editorState),
indentDisabled: itemIndex === 0 || indentLevel >= MAX_INDENTATION_LEVEL,
outdentDisabled: indentLevel <= 1,
// hasEditPermission is assumed to be true if pluginState.hasEditPermission is undefined
// this allows the default plugin state to initialise as true if the extra configuration is not provided
hasEditPermission: (pluginState === null || pluginState === void 0 ? void 0 : pluginState.hasEditPermission) !== undefined ? pluginState === null || pluginState === void 0 ? void 0 : pluginState.hasEditPermission : true,
requestToEditContent: pluginState === null || pluginState === void 0 ? void 0 : pluginState.requestToEditContent,
hasRequestedEditPermission: pluginState === null || pluginState === void 0 ? void 0 : pluginState.hasRequestedEditPermission,
taskDecisionProvider: pluginState === null || pluginState === void 0 ? void 0 : pluginState.taskDecisionProvider,
openRequestToEditPopupAt: pluginState === null || pluginState === void 0 ? void 0 : pluginState.openRequestToEditPopupAt
};
},
commands: {
toggleTaskList: targetType => {
var _api$analytics;
return toggleTaskList(api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions)(targetType);
},
updateEditPermission: hasEditPermission => ({
tr
}) => tr.setMeta(taskPluginKey, {
hasEditPermission
}),
updateHasRequestedEditPermission: hasRequestedEditPermission => ({
tr
}) => tr.setMeta(taskPluginKey, {
hasRequestedEditPermission
})
},
actions: {
insertTaskDecision: insertTaskDecisionCommand(api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, getIdentifierProvider),
indentTaskList: getIndentCommand(api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions),
outdentTaskList: getUnindentCommand(api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions),
setProvider: async providerPromise => {
var _api$core$actions$exe;
const provider = await providerPromise;
// Prevent someone trying to set the exact same provider twice for performance reasons+
if (previousTaskAndDecisionProvider === provider || taskDecisionProvider === providerPromise) {
return false;
}
previousTaskAndDecisionProvider = provider;
return (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(({
tr
}) => setProvider(provider)(tr))) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false;
}
},
pmPlugins() {
return [{
name: 'tasksAndDecisions',
plugin: ({
portalProviderAPI,
eventDispatcher,
dispatch,
getIntl
}) => {
return createPlugin(portalProviderAPI, eventDispatcher, dispatch, api, getIntl, useLongPressSelection, hasEditPermission, hasRequestedEditPermission, requestToEditContent, taskPlaceholder);
}
}, {
name: 'tasksAndDecisionsInputRule',
plugin: ({
schema,
featureFlags
}) => {
var _api$analytics5;
return inputRulePlugin(api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions, getIdentifierProvider)(schema, featureFlags);
}
}, {
name: 'tasksAndDecisionsKeyMap',
plugin: ({
schema
}) => keymap(schema, api, allowNestedTasks, consumeTabs)
} // Needs to be after "save-on-enter"
];
},
secondaryToolbarComponent({
editorView,
disabled
}) {
return /*#__PURE__*/React.createElement("div", {
className: ax(["_1e0c1txw"])
}, /*#__PURE__*/React.createElement(ToolbarDecision, {
editorView: editorView,
isDisabled: disabled,
isReducedSpacing: true,
editorAPI: api
}), /*#__PURE__*/React.createElement(ToolbarTask, {
editorView: editorView,
isDisabled: disabled,
isReducedSpacing: true,
editorAPI: api
}));
},
contentComponent({
editorView,
dispatchAnalyticsEvent,
popupsMountPoint,
popupsBoundariesElement,
popupsScrollableElement
}) {
if (!editorView) {
return null;
}
return /*#__PURE__*/React.createElement(ContentComponent, {
dependencyApi: api,
editorView: editorView,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
popupsMountPoint: popupsMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement
});
},
pluginsOptions: {
quickInsert: ({
formatMessage
}) => [{
id: 'action',
title: formatMessage(insertBlockMessages.action),
description: quickInsertActionDescription !== null && quickInsertActionDescription !== void 0 ? quickInsertActionDescription : formatMessage(insertBlockMessages.actionDescription),
priority: 100,
keywords: ['checkbox', 'task', 'todo'],
keyshortcut: '[]',
icon: () => /*#__PURE__*/React.createElement(IconAction, null),
action(insert, state, source) {
var _api$analytics6;
return insertTaskDecisionAction(api === null || api === void 0 ? void 0 : (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions, getIdentifierProvider)(state, 'taskList', source !== null && source !== void 0 ? source : INPUT_METHOD.QUICK_INSERT, addItem(insert, 'taskList', state.schema));
}
}, {
id: 'decision',
title: formatMessage(insertBlockMessages.decision),
description: formatMessage(insertBlockMessages.decisionDescription),
priority: 900,
keyshortcut: '<>',
icon: () => /*#__PURE__*/React.createElement(IconDecision, null),
action(insert, state, source) {
var _api$analytics7;
return insertTaskDecisionAction(api === null || api === void 0 ? void 0 : (_api$analytics7 = api.analytics) === null || _api$analytics7 === void 0 ? void 0 : _api$analytics7.actions, getIdentifierProvider)(state, 'decisionList', source !== null && source !== void 0 ? source : INPUT_METHOD.QUICK_INSERT, addItem(insert, 'decisionList', state.schema));
}
}]
}
};
};