@atlaskit/editor-plugin-card
Version:
Card plugin for @atlaskit/editor-core
167 lines (166 loc) • 8.05 kB
JavaScript
import React from 'react';
import { ACTION, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
import { appearancePropsMap, commandWithMetadata, getDropdownOption } from '@atlaskit/editor-common/card';
import { cardMessages as messages, linkToolbarMessages } from '@atlaskit/editor-common/messages';
import { isSupportedInParent } from '@atlaskit/editor-common/utils';
import { Fragment } from '@atlaskit/editor-prosemirror/model';
import { useSmartCardContext } from '@atlaskit/link-provider';
import { ButtonItem, LinkItem, MenuGroup, Section } from '@atlaskit/menu';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { changeSelectedCardToLink, setSelectedCardAppearance } from '../pm-plugins/doc';
import { DatasourceDropdownOption, datasourceDisplayInformation } from './DatasourceDropdownOption';
import { getUnavailableMessage } from './LinkToolbarAppearance';
export const LinkAppearanceMenu = ({
url,
intl,
currentAppearance,
editorState,
allowEmbeds,
allowBlockCards = true,
allowDatasource,
editorAnalyticsApi,
isDatasourceView,
dispatchCommand,
settingsConfig
}) => {
var _cardContext$value, _setSelectedCardAppea, _setSelectedCardAppea2, _changeSelectedCardTo, _setSelectedCardAppea3;
const cardContext = useSmartCardContext();
const preview = allowEmbeds && cardContext && url && ((_cardContext$value = cardContext.value) === null || _cardContext$value === void 0 ? void 0 : _cardContext$value.extractors.getPreview(url, 'web'));
const defaultCommand = () => false;
if (url) {
var _cardContext$value2, _cardContext$value2$s, _urlState$error;
const urlState = (_cardContext$value2 = cardContext.value) === null || _cardContext$value2 === void 0 ? void 0 : (_cardContext$value2$s = _cardContext$value2.store) === null || _cardContext$value2$s === void 0 ? void 0 : _cardContext$value2$s.getState()[url];
if ((urlState === null || urlState === void 0 ? void 0 : (_urlState$error = urlState.error) === null || _urlState$error === void 0 ? void 0 : _urlState$error.kind) === 'fatal') {
return null;
}
}
const isBlockCardLinkSupportedInParent = allowBlockCards ? isSupportedInParent(editorState, Fragment.from(editorState.schema.nodes.blockCard.createChecked({})), currentAppearance) : false;
const isEmbedCardLinkSupportedInParent = allowEmbeds ? isSupportedInParent(editorState, Fragment.from(editorState.schema.nodes.embedCard.createChecked({})), currentAppearance) : false;
const embedOption = allowEmbeds && preview && {
appearance: 'embed',
title: intl.formatMessage(messages.embed),
onClick: (_setSelectedCardAppea = setSelectedCardAppearance('embed', editorAnalyticsApi)) !== null && _setSelectedCardAppea !== void 0 ? _setSelectedCardAppea : defaultCommand,
selected: currentAppearance === 'embed',
hidden: false,
testId: 'embed-appearance',
disabled: !isEmbedCardLinkSupportedInParent,
tooltip: isEmbedCardLinkSupportedInParent ? undefined : getUnavailableMessage(editorState, intl),
description: editorExperiment('platform_editor_preview_panel_responsiveness', true, {
exposure: true
}) ? intl.formatMessage(messages.embedToBlockCardWarning) : undefined
};
const blockCardOption = allowBlockCards && {
appearance: 'block',
title: intl.formatMessage(messages.block),
onClick: (_setSelectedCardAppea2 = setSelectedCardAppearance('block', editorAnalyticsApi)) !== null && _setSelectedCardAppea2 !== void 0 ? _setSelectedCardAppea2 : defaultCommand,
selected: currentAppearance === 'block' && !isDatasourceView,
testId: 'block-appearance',
disabled: !isBlockCardLinkSupportedInParent,
tooltip: isBlockCardLinkSupportedInParent ? undefined : getUnavailableMessage(editorState, intl)
};
const options = [{
title: intl.formatMessage(messages.url),
onClick: commandWithMetadata((_changeSelectedCardTo = changeSelectedCardToLink(url, url, true, undefined, undefined, editorAnalyticsApi)) !== null && _changeSelectedCardTo !== void 0 ? _changeSelectedCardTo : defaultCommand, {
action: ACTION.CHANGED_TYPE
}),
selected: !currentAppearance && !isDatasourceView,
testId: 'url-appearance'
}, {
appearance: 'inline',
title: intl.formatMessage(messages.inline),
onClick: (_setSelectedCardAppea3 = setSelectedCardAppearance('inline', editorAnalyticsApi)) !== null && _setSelectedCardAppea3 !== void 0 ? _setSelectedCardAppea3 : defaultCommand,
selected: currentAppearance === 'inline',
testId: 'inline-appearance'
}];
if (blockCardOption) {
options.push(blockCardOption);
}
if (embedOption) {
options.push(embedOption);
}
const finalOptions = options.map(option => getDropdownOption(intl, dispatchCommand, {
...option,
onClick: commandWithMetadata(option.onClick, {
inputMethod: INPUT_METHOD.FLOATING_TB
})
}));
let Icon;
if ('icon' in settingsConfig && settingsConfig.icon !== undefined) {
Icon = settingsConfig.icon;
}
// TODO: ED-26961 - packages/editor/editor-plugin-card/src/ui/LinkToolbarAppearance.tsx supports change boarding via pulse
// this implementation doesn't
return /*#__PURE__*/React.createElement(MenuGroup, null, /*#__PURE__*/React.createElement(Section, null, finalOptions.map(option => {
return /*#__PURE__*/React.createElement(ButtonItem, {
key: option.title,
iconBefore: option.icon
// eslint-disable-next-line @atlassian/perf-linting/detect-unnecessary-rerenders, @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onClick: () => option.onClick(),
isSelected: option.selected,
description: option.description,
shouldDescriptionWrap: true
}, option.title);
}), /*#__PURE__*/React.createElement(DatasourceDropdownOption, {
allowDatasource: allowDatasource,
intl: intl,
url: url !== null && url !== void 0 ? url : '',
selected: Boolean(isDatasourceView),
inputMethod: INPUT_METHOD.FLOATING_TB,
dispatchCommand: dispatchCommand
})), 'href' in settingsConfig && settingsConfig.href && /*#__PURE__*/React.createElement(Section, {
hasSeparator: true
}, /*#__PURE__*/React.createElement(LinkItem, {
iconBefore: Icon && /*#__PURE__*/React.createElement(Icon, {
label: "Settings"
}),
href: settingsConfig.href,
target: 'target' in settingsConfig ? settingsConfig.target : undefined
}, intl.formatMessage(linkToolbarMessages.preferencesLink))));
};
export const getLinkAppearanceDropdown = ({
url,
intl,
currentAppearance,
editorState,
allowEmbeds,
allowBlockCards = true,
allowDatasource,
editorAnalyticsApi,
showUpgradeDiscoverability = true,
isDatasourceView,
settingsConfig,
areAnyNewToolbarFlagsEnabled
}) => {
const alignmentItemOptions = {
render: props => {
return /*#__PURE__*/React.createElement(LinkAppearanceMenu, {
url: url,
intl: intl,
currentAppearance: currentAppearance,
editorState: editorState,
allowEmbeds: allowEmbeds,
allowBlockCards: allowBlockCards,
editorAnalyticsApi: editorAnalyticsApi,
showUpgradeDiscoverability: showUpgradeDiscoverability,
isDatasourceView: isDatasourceView,
allowDatasource: allowDatasource,
dispatchCommand: props.dispatchCommand,
settingsConfig: settingsConfig,
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
});
},
width: 200,
height: 400
};
const currentAppearanceDisplayInformation = isDatasourceView ? datasourceDisplayInformation : appearancePropsMap[currentAppearance !== null && currentAppearance !== void 0 ? currentAppearance : 'url'];
const alignmentToolbarItem = {
id: 'card-appearance',
testId: 'card-appearance-dropdown',
type: 'dropdown',
options: alignmentItemOptions,
title: intl.formatMessage(currentAppearanceDisplayInformation.title),
iconBefore: currentAppearanceDisplayInformation.icon
};
return alignmentToolbarItem;
};