UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

315 lines (314 loc) 11.9 kB
/** * @jsxRuntime classic * @jsx jsx */ import { useCallback, useMemo, useRef, useState } from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports import { css, jsx } from '@emotion/react'; import { FormattedMessage } from 'react-intl'; import { linkToolbarMessages, cardMessages as messages } from '@atlaskit/editor-common/messages'; import { FloatingToolbarButton as Button, FloatingToolbarSeparator as Separator } from '@atlaskit/editor-common/ui'; import { ArrowKeyNavigationType, DropdownContainer as UiDropdown } from '@atlaskit/editor-common/ui-menu'; import ChevronDownIcon from '@atlaskit/icon/core/chevron-down'; import { useSmartLinkContext } from '@atlaskit/link-provider'; import { ButtonItem } from '@atlaskit/menu'; import { Flex } from '@atlaskit/primitives/compiled'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import { focusEditorView, isDatasourceConfigEditable } from '../../pm-plugins/utils'; import { editDatasource } from '../editDatasourceAction'; import { useFetchDatasourceDataInfo } from '../useFetchDatasourceDataInfo'; import { useFetchDatasourceInfo } from '../useFetchDatasourceInfo'; import EditToolbarButtonPresentation from './EditToolbarButtonPresentation'; const dropdownExpandContainer = css({ margin: `0px ${"var(--ds-space-negative-050, -4px)"}` }); const EditToolbarButtonWithCardContext = props => { var _response$datasourceI; const { cardContext, currentAppearance, editorAnalyticsApi, editorView, intl, onLinkEditClick, url, areAnyNewToolbarFlagsEnabled } = props; const { extensionKey, ...response } = useFetchDatasourceInfo({ isRegularCardNode: true, url, cardContext }); const datasourceId = (_response$datasourceI = response.datasourceId) !== null && _response$datasourceI !== void 0 ? _response$datasourceI : props.datasourceId; const [isOpen, setIsOpen] = useState(false); const containerRef = useRef(); const toggleOpen = () => setIsOpen(open => !open); const onClose = () => setIsOpen(false); const onEditLink = useCallback(() => { if (editorView) { onLinkEditClick(editorView.state, editorView.dispatch); focusEditorView(editorView); } }, [editorView, onLinkEditClick]); const editVariant = useMemo(() => { const hasUrl = url !== null && url !== undefined; if (!datasourceId || !isDatasourceConfigEditable(datasourceId)) { if (hasUrl) { return 'edit-link'; } return 'none'; } if (hasUrl) { var _cardContext$store, _urlState$error; const urlState = cardContext === null || cardContext === void 0 ? void 0 : (_cardContext$store = cardContext.store) === null || _cardContext$store === void 0 ? void 0 : _cardContext$store.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 'edit-link'; } return 'edit-dropdown'; } else { return 'edit-datasource'; } }, [cardContext === null || cardContext === void 0 ? void 0 : cardContext.store, datasourceId, url]); const onEditDatasource = useCallback(() => { if (editorView && datasourceId) { editDatasource(datasourceId, editorAnalyticsApi, currentAppearance, extensionKey)(editorView.state, editorView.dispatch); focusEditorView(editorView); } }, [currentAppearance, datasourceId, editorAnalyticsApi, editorView, extensionKey]); switch (editVariant) { case 'edit-link': { return jsx(Flex, { gap: "space.050" }, jsx(Button, { testId: "edit-link", onClick: onEditLink, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }, jsx(FormattedMessage // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading , linkToolbarMessages.editLink)), !editorExperiment('platform_editor_controls', 'variant1') && jsx(Separator, { areAnyNewToolbarFlagsEnabled: false })); } case 'edit-datasource': { return jsx(Flex, { gap: "space.050" }, jsx(Button, { testId: "edit-datasource", tooltipContent: intl.formatMessage(linkToolbarMessages.editDatasourceStandaloneTooltip), onClick: onEditDatasource, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }, jsx(FormattedMessage // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading , linkToolbarMessages.editDatasourceStandalone)), !editorExperiment('platform_editor_controls', 'variant1') && jsx(Separator, { areAnyNewToolbarFlagsEnabled: false })); } case 'edit-dropdown': { const trigger = jsx(Flex, { gap: "space.050" }, jsx(Button, { testId: "edit-dropdown-trigger", iconAfter: jsx("span", { css: dropdownExpandContainer }, jsx(ChevronDownIcon, { label: intl.formatMessage(messages.editDropdownTriggerTitle), size: "small" })), onClick: toggleOpen, selected: isOpen, disabled: false, ariaHasPopup: true, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }, jsx(FormattedMessage // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading , messages.editDropdownTriggerTitle)), !editorExperiment('platform_editor_controls', 'variant1') && jsx(Separator, { areAnyNewToolbarFlagsEnabled: false })); return jsx(Flex, { ref: containerRef }, jsx(UiDropdown, { mountTo: containerRef.current, isOpen: isOpen, handleClickOutside: onClose, handleEscapeKeydown: onClose, trigger: trigger, scrollableElement: containerRef.current // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , arrowKeyNavigationProviderOptions: { type: ArrowKeyNavigationType.MENU } }, jsx(ButtonItem, { key: "edit.link", onClick: onEditLink, testId: "edit-dropdown-edit-link-item" }, jsx(FormattedMessage // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading , messages.editDropdownEditLinkTitle)), jsx(ButtonItem, { key: "edit.datasource", onClick: onEditDatasource, testId: "edit-dropdown-edit-datasource-item" }, jsx(FormattedMessage // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading , messages.editDropdownEditDatasourceTitle)))); } case 'none': default: return null; } }; const EditToolbarButtonWithUrl = props => { const { cardContext, currentAppearance, datasourceId: datasourceIdFromAdf, editorAnalyticsApi, editorView, intl, onLinkEditClick, url, areAnyNewToolbarFlagsEnabled } = props; const { extensionKey, datasourceId: datasourceIdFromUrl } = useFetchDatasourceInfo({ isRegularCardNode: true, url, cardContext }); const datasourceId = datasourceIdFromUrl !== null && datasourceIdFromUrl !== void 0 ? datasourceIdFromUrl : datasourceIdFromAdf; const editVariant = useMemo(() => { var _cardContext$store2, _urlState$error2; if (!datasourceId || !isDatasourceConfigEditable(datasourceId)) { return 'edit-link'; } const urlState = cardContext === null || cardContext === void 0 ? void 0 : (_cardContext$store2 = cardContext.store) === null || _cardContext$store2 === void 0 ? void 0 : _cardContext$store2.getState()[url]; if ((urlState === null || urlState === void 0 ? void 0 : (_urlState$error2 = urlState.error) === null || _urlState$error2 === void 0 ? void 0 : _urlState$error2.kind) === 'fatal') { return 'edit-link'; } return 'edit-dropdown'; }, [cardContext === null || cardContext === void 0 ? void 0 : cardContext.store, datasourceId, url]); return jsx(EditToolbarButtonPresentation, { datasourceId: datasourceId, currentAppearance: currentAppearance, editorAnalyticsApi: editorAnalyticsApi, editVariant: editVariant, editorView: editorView, extensionKey: extensionKey, onLinkEditClick: onLinkEditClick, intl: intl, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }); }; const EditToolbarButtonWithDatasourceId = props => { const { currentAppearance, editorAnalyticsApi, editorView, intl, onLinkEditClick, datasourceId, node, areAnyNewToolbarFlagsEnabled } = props; const fetchData = useMemo(() => { try { var _attrs$datasource$vie, _attrs$datasource$vie2; const attrs = node.attrs; const parameters = attrs.datasource.parameters; const visibleColumnKeys = (_attrs$datasource$vie = attrs.datasource.views[0]) === null || _attrs$datasource$vie === void 0 ? void 0 : (_attrs$datasource$vie2 = _attrs$datasource$vie.properties) === null || _attrs$datasource$vie2 === void 0 ? void 0 : _attrs$datasource$vie2.columns.map(c => c.key); return { parameters, visibleColumnKeys }; } catch (e) { // eslint-disable-next-line no-console console.error(e); } }, [node.attrs]); const { extensionKey } = useFetchDatasourceDataInfo({ datasourceId, parameters: fetchData === null || fetchData === void 0 ? void 0 : fetchData.parameters, visibleColumnKeys: fetchData === null || fetchData === void 0 ? void 0 : fetchData.visibleColumnKeys }); const editVariant = useMemo(() => { if (!datasourceId || !isDatasourceConfigEditable(datasourceId)) { return 'none'; } return 'edit-datasource'; }, [datasourceId]); return jsx(EditToolbarButtonPresentation, { datasourceId: datasourceId, currentAppearance: currentAppearance, editorAnalyticsApi: editorAnalyticsApi, editVariant: editVariant, editorView: editorView, extensionKey: extensionKey, onLinkEditClick: onLinkEditClick, intl: intl, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }); }; export const EditToolbarButton = props => { const { currentAppearance, datasourceId, editorAnalyticsApi, editorView, intl, onLinkEditClick, url, areAnyNewToolbarFlagsEnabled } = props; const cardContext = useSmartLinkContext(); if (props.url) { return jsx(EditToolbarButtonWithUrl, { datasourceId: datasourceId, url: props.url, intl: intl, editorAnalyticsApi: editorAnalyticsApi, editorView: editorView, cardContext: cardContext, onLinkEditClick: onLinkEditClick, currentAppearance: currentAppearance, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }); } if (props.datasourceId && props.node) { return jsx(EditToolbarButtonWithDatasourceId, { datasourceId: props.datasourceId, node: props.node, intl: intl, editorAnalyticsApi: editorAnalyticsApi, editorView: editorView, onLinkEditClick: onLinkEditClick, currentAppearance: currentAppearance, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }); } return jsx(EditToolbarButtonWithCardContext, { datasourceId: datasourceId, url: url, intl: intl, editorAnalyticsApi: editorAnalyticsApi, editorView: editorView, cardContext: cardContext, onLinkEditClick: onLinkEditClick, currentAppearance: currentAppearance, areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled }); };