UNPKG

@atlaskit/editor-plugin-extension

Version:

editor-plugin-extension plugin for @atlaskit/editor-core

152 lines (149 loc) 6.62 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import React, { useEffect, useState } from 'react'; import { bind } from 'bind-event-listener'; import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector'; import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import ConfigPanel from './ConfigPanel'; import { useStateFromPromise } from './use-state-from-promise'; var getFieldsDefinitionFn = function getFieldsDefinitionFn(extensionManifest, nodeKey) { if (extensionManifest && extensionManifest.modules.nodes && extensionManifest.modules.nodes[nodeKey] && extensionManifest.modules.nodes[nodeKey].getFieldsDefinition) { return extensionManifest.modules.nodes[nodeKey].getFieldsDefinition; } }; // having the default value in the props instead of a reference will cause excessive rerenders var defaultEmptyObject = {}; var FieldDefinitionsPromiseResolver = function FieldDefinitionsPromiseResolver(props) { var extensionManifest = props.extensionManifest, nodeKey = props.nodeKey, extensionParameters = props.extensionParameters, setErrorMessage = props.setErrorMessage; var _useState = useState(undefined), _useState2 = _slicedToArray(_useState, 2), fields = _useState2[0], setFields = _useState2[1]; // Event listener for Forge apps that have macro config. // When an app generates a new config schema, we need to force a re-render // of the config panel so that the UI reflects the new schema. // Otherwise the panel renders a stale schema. var _useState3 = useState(new Date()), _useState4 = _slicedToArray(_useState3, 2), forgeAppConfigLastUpdated = _useState4[0], setForgeAppConfigLastUpdated = _useState4[1]; useEffect(function () { if (extensionParameters !== null && extensionParameters !== void 0 && extensionParameters.extensionId && extensionParameters !== null && extensionParameters !== void 0 && extensionParameters.localId) { var extensionId = extensionParameters.extensionId, localId = extensionParameters.localId; var id = "".concat(extensionId, "-").concat(localId); var eventName = "forge.bridge.CONFIG_FORGE_DOC_UPDATED_".concat(id); var handleForgeConfigUpdated = function handleForgeConfigUpdated() { setForgeAppConfigLastUpdated(new Date()); }; var unbind = bind(window.document, { type: eventName, listener: handleForgeConfigUpdated }); return function () { unbind(); }; } }, [extensionParameters]); // Resolve the promise // useStateFromPromise() has an issue which isn't compatible with // DynamicFieldDefinitions when it returns a function as setState() // will immediately run the function returned and pass it the currentState. useEffect(function () { if (!extensionManifest) { return; } var promiseFn = getFieldsDefinitionFn(extensionManifest, nodeKey); if (typeof promiseFn !== 'function') { // eslint-disable-next-line @atlassian/perf-linting/no-chain-state-updates -- Ignored via go/ees017 (to be fixed) setFields(undefined); return; } promiseFn(extensionParameters).catch(function (err) { if (err && typeof err.message === 'string') { setErrorMessage(err.message); } setFields(undefined); }).then(function (value) { if (Array.isArray(value)) { // value: FieldDefinition[] setFields(value); } else if (typeof value === 'function') { try { // value: DynamicFieldDefinitions var dynamicFields = value(extensionParameters); setFields(dynamicFields); } catch (err) { if (err instanceof Error) { setErrorMessage(err.message); } setFields(undefined); } } else { // value: undefined setFields(undefined); } }); }, [extensionManifest, nodeKey, extensionParameters, setErrorMessage, forgeAppConfigLastUpdated]); return /*#__PURE__*/React.createElement(React.Fragment, null, props.children(fields)); }; export default function FieldsLoader(_ref) { var extensionType = _ref.extensionType, extensionKey = _ref.extensionKey, nodeKey = _ref.nodeKey, extensionProvider = _ref.extensionProvider, _ref$extensionParamet = _ref.extensionParameters, extensionParameters = _ref$extensionParamet === void 0 ? defaultEmptyObject : _ref$extensionParamet, _ref$parameters = _ref.parameters, parameters = _ref$parameters === void 0 ? defaultEmptyObject : _ref$parameters, autoSaveTrigger = _ref.autoSaveTrigger, autoSaveReject = _ref.autoSaveReject, closeOnEsc = _ref.closeOnEsc, showHeader = _ref.showHeader, featureFlags = _ref.featureFlags, onChange = _ref.onChange, onCancel = _ref.onCancel, api = _ref.api, usingObjectSidebarPanel = _ref.usingObjectSidebarPanel; var _useStateFromPromise = useStateFromPromise(function () { return extensionProvider.getExtension(extensionType, extensionKey); }, [extensionProvider, extensionType, extensionKey]), _useStateFromPromise2 = _slicedToArray(_useStateFromPromise, 1), extensionManifest = _useStateFromPromise2[0]; var _useState5 = useState(null), _useState6 = _slicedToArray(_useState5, 2), errorMessage = _useState6[0], setErrorMessage = _useState6[1]; var connectivityState = useSharedPluginStateSelector(api, 'connectivity.mode', { disabled: editorExperiment('platform_editor_offline_editing_web', false) }); return /*#__PURE__*/React.createElement(FieldDefinitionsPromiseResolver, { setErrorMessage: setErrorMessage, extensionManifest: extensionManifest, nodeKey: nodeKey, extensionParameters: extensionParameters }, function (fields) { return /*#__PURE__*/React.createElement(ConfigPanel, { api: api, extensionManifest: extensionManifest, isLoading: !extensionManifest || errorMessage === null && !fields, fields: fields, parameters: parameters, autoSaveTrigger: autoSaveTrigger, autoSaveReject: autoSaveReject, closeOnEsc: closeOnEsc, showHeader: showHeader, onChange: onChange, onCancel: onCancel, errorMessage: errorMessage, featureFlags: featureFlags // Remove below prop when cleaning platform_editor_ai_object_sidebar_injection FG , usingObjectSidebarPanel: usingObjectSidebarPanel, disableFields: isOfflineMode(connectivityState) }); }); }