UNPKG

@atlaskit/editor-plugin-tasks-and-decisions

Version:

Tasks and decisions plugin for @atlaskit/editor-core

170 lines (165 loc) 6.83 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import { bindAll } from 'bind-event-listener'; import { SetAttrsStep } from '@atlaskit/adf-schema/steps'; import { tasksAndDecisionsMessages } from '@atlaskit/editor-common/messages'; import { DOMSerializer } from '@atlaskit/editor-prosemirror/model'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { openRequestEditPopupAt } from '../pm-plugins/helpers'; import { taskItemToDom } from './taskItemNodeSpec'; import { isContentEmpty } from './utils'; export class TaskItemNodeView { constructor(node, view, getPos, { api, placeholder, intl }) { _defineProperty(this, "handleOnClick", event => { var _this$api, _this$api$taskDecisio, _this$api$taskDecisio2; if (!((_this$api = this.api) !== null && _this$api !== void 0 && (_this$api$taskDecisio = _this$api.taskDecision) !== null && _this$api$taskDecisio !== void 0 && (_this$api$taskDecisio2 = _this$api$taskDecisio.sharedState.currentState()) !== null && _this$api$taskDecisio2 !== void 0 && _this$api$taskDecisio2.hasEditPermission)) { event.stopImmediatePropagation(); event.preventDefault(); const pos = this.getPos(); if (typeof pos === 'number') { openRequestEditPopupAt(this.view, pos); } return; } }); _defineProperty(this, "handleOnChange", () => { var _this$api2; const { tr } = this.view.state; const nodePos = this.getPos(); if (typeof nodePos !== 'number') { return; } const { localId, state } = this.node.attrs; const isDone = state === 'DONE'; const nextState = isDone ? 'TODO' : 'DONE'; const currentTaskDecisionState = (_this$api2 = this.api) === null || _this$api2 === void 0 ? void 0 : _this$api2.taskDecision.sharedState.currentState(); // logic is inspired from packages/elements/task-decision/src/components/ResourcedTaskItem.tsx const objectAri = this.getObjectAri(); if (currentTaskDecisionState !== null && currentTaskDecisionState !== void 0 && currentTaskDecisionState.taskDecisionProvider && objectAri) { currentTaskDecisionState.taskDecisionProvider.toggleTask({ localId, objectAri }, nextState); } // SetAttrsStep should be used to prevent task updates from being dropped when mapping task ticks // from a previous version of the document, such as a published page. tr.step(new SetAttrsStep(nodePos, { state: nextState, localId: localId })); tr.setMeta('scrollIntoView', false); const taskItemInfoMeta = { checkState: nextState, from: nodePos, to: nodePos + this.node.nodeSize }; tr.setMeta('taskItemInfo', taskItemInfoMeta); this.view.dispatch(tr); }); this.node = node; this.view = view; this.getPos = getPos; this.intl = intl; this.api = api; this.view = view; const domPlaceholder = placeholder !== null && placeholder !== void 0 ? placeholder : this.intl.formatMessage(tasksAndDecisionsMessages.taskPlaceholder); const { dom, contentDOM } = DOMSerializer.renderSpec(document, taskItemToDom(node, domPlaceholder, intl)); this.dom = dom; this.contentDOM = contentDOM; this.domElement = this.dom instanceof HTMLElement ? this.dom : undefined; if (this.domElement) { this.input = this.domElement.querySelector('input[type="checkbox"]'); this.unbindInputDom = bindAll(this.input, [{ type: 'click', listener: this.handleOnClick }, { type: 'change', listener: this.handleOnChange }]); } } getContextIdentifierProvider() { var _this$api3, _this$api3$contextIde, _this$api3$contextIde2; return (_this$api3 = this.api) === null || _this$api3 === void 0 ? void 0 : (_this$api3$contextIde = _this$api3.contextIdentifier) === null || _this$api3$contextIde === void 0 ? void 0 : (_this$api3$contextIde2 = _this$api3$contextIde.sharedState.currentState()) === null || _this$api3$contextIde2 === void 0 ? void 0 : _this$api3$contextIde2.contextIdentifierProvider; } getObjectAri() { const provider = this.getContextIdentifierProvider(); if (provider) { return provider.objectId; } return undefined; } isContentEmpty(node) { return node.content.childCount === 0; } // Update the placeholder visibility based on content updatePlaceholder(node) { let currentIsContentEmpty = this.isContentEmpty(node); if (expValEquals('platform_editor_blocktaskitem_node_tenantid', 'isEnabled', true)) { currentIsContentEmpty = isContentEmpty(node); } if (currentIsContentEmpty !== this.emptyContent) { var _this$contentDOM; this.emptyContent = currentIsContentEmpty; (_this$contentDOM = this.contentDOM) === null || _this$contentDOM === void 0 ? void 0 : _this$contentDOM.toggleAttribute('data-empty', currentIsContentEmpty); } } update(node) { if (!expValEquals('platform_editor_prevent_taskitem_remount', 'isEnabled', true)) { const isValidUpdate = node.type === this.node.type && !!(node.attrs.state === this.node.attrs.state); if (!isValidUpdate) { return false; } } // Only return false if this is a completely different task if (this.node.attrs.localId !== node.attrs.localId) { return false; } if (expValEquals('platform_editor_prevent_taskitem_remount', 'isEnabled', true)) { if (node.type !== this.node.type) { return false; } const stateChanged = node.type === this.node.type && !!(node.attrs.state !== this.node.attrs.state); // Update task checkbox state to match document state. // It's possible the state may have changed from a collab edit and not from a checkbox click // so we need to update the checkbox to match. if (stateChanged && this.input) { this.input.checked = node.attrs.state === 'DONE'; } } this.updatePlaceholder(node); if (this.domElement && !node.sameMarkup(this.node)) { this.domElement.setAttribute('data-task-state', node.attrs.state); this.domElement.setAttribute('data-task-local-id', node.attrs.localId); this.domElement.setAttribute('state', node.attrs.state); } this.node = node; return true; } ignoreMutation(mutation) { if (!this.contentDOM) { return true; } return !this.contentDOM.contains(mutation.target) && mutation.type !== 'selection'; } destroy() { if (this.unbindInputDom) { this.unbindInputDom(); } this.contentDOM = undefined; this.input = undefined; this.emptyContent = undefined; this.api = undefined; } }