UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

298 lines (293 loc) 15.5 kB
import _get from "@babel/runtime/helpers/get"; import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; } 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; } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(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; })(); } /** * @jsxRuntime classic * @jsx jsx */ import React from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports import { jsx } from '@emotion/react'; import ReactNodeView from '@atlaskit/editor-common/react-node-view'; import { DATASOURCE_INNER_CONTAINER_CLASSNAME, SmartCardSharedCssClassName } from '@atlaskit/editor-common/styles'; import { UnsupportedInline } from '@atlaskit/editor-common/ui'; import { calcBreakoutWidth } from '@atlaskit/editor-common/utils'; import { DatasourceTableView } from '@atlaskit/link-datasource'; import { EditorSmartCardProvider, EditorSmartCardProviderValueGuard } from '@atlaskit/link-provider'; import { DATASOURCE_DEFAULT_LAYOUT } from '@atlaskit/linking-common'; import { DatasourceErrorBoundary } from '../ui/datasourceErrorBoundary'; import { EditorAnalyticsContext } from '../ui/EditorAnalyticsContext'; var getPosSafely = function getPosSafely(pos) { if (!pos || typeof pos === 'boolean') { return; } try { return pos(); } catch (e) { // Can blow up in rare cases, when node has been removed. } }; // eslint-disable-next-line @repo/internal/react/no-class-components export var DatasourceComponent = /*#__PURE__*/function (_React$PureComponent) { function DatasourceComponent(props) { var _this; _classCallCheck(this, DatasourceComponent); _this = _callSuper(this, DatasourceComponent, [props]); _defineProperty(_this, "getDatasource", function () { return _this.props.node.attrs.datasource; }); _defineProperty(_this, "getTableView", function () { var views = _this.getDatasource().views; return views.find(function (view) { return view.type === 'table'; }) || undefined; }); _defineProperty(_this, "handleColumnChange", function (columnKeys) { var _this$getColumnsInfo = _this.getColumnsInfo(), _this$getColumnsInfo$ = _this$getColumnsInfo.wrappedColumnKeys, wrappedColumnKeys = _this$getColumnsInfo$ === void 0 ? [] : _this$getColumnsInfo$, _this$getColumnsInfo$2 = _this$getColumnsInfo.columnCustomSizes, columnCustomSizes = _this$getColumnsInfo$2 === void 0 ? {} : _this$getColumnsInfo$2; _this.updateTableProperties(columnKeys, columnCustomSizes, wrappedColumnKeys); }); _defineProperty(_this, "handleColumnResize", function (key, width) { var _this$getColumnsInfo2 = _this.getColumnsInfo(), _this$getColumnsInfo3 = _this$getColumnsInfo2.wrappedColumnKeys, wrappedColumnKeys = _this$getColumnsInfo3 === void 0 ? [] : _this$getColumnsInfo3, _this$getColumnsInfo4 = _this$getColumnsInfo2.columnCustomSizes, columnCustomSizes = _this$getColumnsInfo4 === void 0 ? {} : _this$getColumnsInfo4, _this$getColumnsInfo5 = _this$getColumnsInfo2.visibleColumnKeys, visibleColumnKeys = _this$getColumnsInfo5 === void 0 ? [] : _this$getColumnsInfo5; var newColumnCustomSizes = _objectSpread(_objectSpread({}, columnCustomSizes), {}, _defineProperty({}, key, width)); _this.updateTableProperties(visibleColumnKeys, newColumnCustomSizes, wrappedColumnKeys); }); _defineProperty(_this, "handleWrappedColumnChange", function (key, shouldWrap) { var _this$getColumnsInfo6 = _this.getColumnsInfo(), _this$getColumnsInfo7 = _this$getColumnsInfo6.wrappedColumnKeys, wrappedColumnKeys = _this$getColumnsInfo7 === void 0 ? [] : _this$getColumnsInfo7, _this$getColumnsInfo8 = _this$getColumnsInfo6.columnCustomSizes, columnCustomSizes = _this$getColumnsInfo8 === void 0 ? {} : _this$getColumnsInfo8, _this$getColumnsInfo9 = _this$getColumnsInfo6.visibleColumnKeys, visibleColumnKeys = _this$getColumnsInfo9 === void 0 ? [] : _this$getColumnsInfo9; var wrappedColumnKeysSet = new Set(wrappedColumnKeys); if (shouldWrap) { wrappedColumnKeysSet.add(key); } else { wrappedColumnKeysSet.delete(key); } _this.updateTableProperties(visibleColumnKeys, columnCustomSizes, Array.from(wrappedColumnKeysSet)); }); _defineProperty(_this, "onError", function (_ref) { var err = _ref.err; if (err) { throw err; } }); return _this; } _inherits(DatasourceComponent, _React$PureComponent); return _createClass(DatasourceComponent, [{ key: "updateTableProperties", value: function updateTableProperties(columnKeysArg, columnCustomSizes, wrappedColumnKeys) { var _this$props$view = this.props.view, state = _this$props$view.state, dispatch = _this$props$view.dispatch; var pos = getPosSafely(this.props.getPos); if (pos === undefined) { return; } // In case for some reason there are no visible keys stored in ADF, we take them // from incoming sets of attributes like column sizes and wrapped column keys // columnKeys are needed to update ADF ( // since attributes (like custom width and wrapped state) only make sense for a visible column ) // So this part effectively adds a visible column if it wasn't there but attributes were given. var columnKeys = columnKeysArg.length > 0 ? columnKeysArg : Array.from(new Set([].concat(_toConsumableArray(Object.keys(columnCustomSizes)), _toConsumableArray(wrappedColumnKeys)))); var views = [{ type: 'table', properties: { columns: columnKeys.map(function (key) { var width = columnCustomSizes[key]; var isWrapped = wrappedColumnKeys.includes(key); return _objectSpread(_objectSpread({ key: key }, width ? { width: width } : {}), isWrapped ? { isWrapped: isWrapped } : {}); }) } }]; var attrs = this.props.node.attrs; var tr = state.tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, attrs), {}, { datasource: _objectSpread(_objectSpread({}, attrs.datasource), {}, { views: views }) })); // Ensures dispatch does not contribute to undo history (otherwise user requires three undo's to revert table) tr.setMeta('addToHistory', false); tr.setMeta('scrollIntoView', false); dispatch(tr); } }, { key: "getColumnsInfo", value: function getColumnsInfo() { var _tableView$properties; var tableView = this.getTableView(); var columnsProp = tableView === null || tableView === void 0 || (_tableView$properties = tableView.properties) === null || _tableView$properties === void 0 ? void 0 : _tableView$properties.columns; var visibleColumnKeys = columnsProp === null || columnsProp === void 0 ? void 0 : columnsProp.map(function (_ref2) { var key = _ref2.key; return key; }); var columnCustomSizes; var columnsWithWidth = columnsProp === null || columnsProp === void 0 ? void 0 : columnsProp.filter(function (c) { return !!c.width; }); if (columnsWithWidth) { var keyWidthPairs = columnsWithWidth.map(function (c) { return [c.key, c.width]; }); columnCustomSizes = Object.fromEntries(keyWidthPairs); } var wrappedColumnKeys = columnsProp === null || columnsProp === void 0 ? void 0 : columnsProp.filter(function (c) { return c.isWrapped; }).map(function (c) { return c.key; }); return { visibleColumnKeys: visibleColumnKeys, columnCustomSizes: columnCustomSizes, wrappedColumnKeys: wrappedColumnKeys }; } }, { key: "render", value: function render() { var datasource = this.getDatasource(); var attrs = this.props.node.attrs; var tableView = this.getTableView(); if (tableView) { var _this$getColumnsInfo0 = this.getColumnsInfo(), visibleColumnKeys = _this$getColumnsInfo0.visibleColumnKeys, columnCustomSizes = _this$getColumnsInfo0.columnCustomSizes, wrappedColumnKeys = _this$getColumnsInfo0.wrappedColumnKeys; return jsx(EditorSmartCardProviderValueGuard, null, jsx(EditorAnalyticsContext, { editorView: this.props.view }, jsx(EditorSmartCardProvider, null, jsx(DatasourceTableView, { datasourceId: datasource.id, parameters: datasource.parameters, visibleColumnKeys: visibleColumnKeys, onVisibleColumnKeysChange: this.handleColumnChange, url: attrs === null || attrs === void 0 ? void 0 : attrs.url, onColumnResize: this.handleColumnResize, columnCustomSizes: columnCustomSizes, onWrappedColumnChange: this.handleWrappedColumnChange, wrappedColumnKeys: wrappedColumnKeys })))); } return null; } }]); }(React.PureComponent); export var Datasource = /*#__PURE__*/function (_ReactNodeView) { function Datasource(props) { var _props$pluginInjectio, _sharedState$currentS; var _this2; _classCallCheck(this, Datasource); _this2 = _callSuper(this, Datasource, [props.node, props.view, props.getPos, props.portalProviderAPI, props.eventDispatcher, props]); var sharedState = props === null || props === void 0 || (_props$pluginInjectio = props.pluginInjectionApi) === null || _props$pluginInjectio === void 0 || (_props$pluginInjectio = _props$pluginInjectio.width) === null || _props$pluginInjectio === void 0 ? void 0 : _props$pluginInjectio.sharedState; _this2.tableWidth = sharedState === null || sharedState === void 0 || (_sharedState$currentS = sharedState.currentState()) === null || _sharedState$currentS === void 0 ? void 0 : _sharedState$currentS.width; _this2.isNodeNested = props.isNodeNested; sharedState === null || sharedState === void 0 || sharedState.onChange(function (_ref3) { var nextSharedState = _ref3.nextSharedState; if (nextSharedState !== null && nextSharedState !== void 0 && nextSharedState.width && _this2.tableWidth !== (nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.width)) { _this2.tableWidth = nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.width; _this2.update(_this2.node, []); // required to update the width when page is resized. } }); return _this2; } // Need this function to check if the datasource attribute was added or not to a blockCard. // If not, we return false so we can get the node to re-render properly as a block node instead. // Otherwise, the node view will still consider the node as a Datasource and render a such. _inherits(Datasource, _ReactNodeView); return _createClass(Datasource, [{ key: "validUpdate", value: function validUpdate(_, newNode) { var _newNode$attrs; return !!((_newNode$attrs = newNode.attrs) !== null && _newNode$attrs !== void 0 && _newNode$attrs.datasource); } }, { key: "update", value: function update(node, decorations, _innerDecorations) { return _superPropGet(Datasource, "update", this, 3)([node, decorations, _innerDecorations, this.validUpdate]); } }, { key: "createDomRef", value: function createDomRef() { var domRef = document.createElement('div'); domRef.setAttribute('contenteditable', 'true'); domRef.classList.add(SmartCardSharedCssClassName.DATASOURCE_CONTAINER); return domRef; } /** * Node views may render interactive elements that should not have their events reach editor * * We should the stop editor from handling events from following elements: * - typing in input * - activating buttons via spacebar * * Can be used to prevent the editor view from trying to handle some or all DOM events that bubble up from the node view. * Events for which this returns true are not handled by the editor. * @see {@link https://prosemirror.net/docs/ref/#view.NodeView.stopEvent} */ }, { key: "stopEvent", value: function stopEvent(event) { var isFormElement = [HTMLButtonElement, HTMLInputElement].some(function (element) { return event.target instanceof element; }); if (isFormElement) { return true; } return false; } }, { key: "render", value: function render() { var _this$domRef, _attrs$datasource; var attrs = this.node.attrs; // EDM-10607: Workaround to remove datasource table draggable attribute // @ts-ignore TS2341: Property domRef is private (_this$domRef = this.domRef) === null || _this$domRef === void 0 || _this$domRef.setAttribute('draggable', 'false'); return jsx(DatasourceErrorBoundary, { unsupportedComponent: UnsupportedInline, view: this.view, url: attrs.url, datasourceId: attrs === null || attrs === void 0 || (_attrs$datasource = attrs.datasource) === null || _attrs$datasource === void 0 ? void 0 : _attrs$datasource.id }, jsx("div", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 className: DATASOURCE_INNER_CONTAINER_CLASSNAME, style: { minWidth: this.isNodeNested ? '100%' : // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 calcBreakoutWidth(attrs.layout || DATASOURCE_DEFAULT_LAYOUT, this.tableWidth) } }, jsx(DatasourceComponent, { node: this.node, view: this.view, getPos: this.getPos }))); } }]); }(ReactNodeView);