@atlaskit/editor-plugin-card
Version:
Card plugin for @atlaskit/editor-core
131 lines (130 loc) • 4.28 kB
JavaScript
import React, { useCallback } from 'react';
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
import { hideDatasourceModal } from '../../pm-plugins/actions';
import { insertDatasource, updateCardViaDatasource } from '../../pm-plugins/doc';
import { useFetchDatasourceInfo } from '../useFetchDatasourceInfo';
export const DatasourceModal = ({
view,
cardContext,
datasourceId: defaultDatasourceId,
componentType: Component
}) => {
var _existingNode$attrs, _existingNode$attrs2;
const {
state
} = view;
const existingNode = getExistingNode(state);
const {
dispatch,
state: {
tr: transaction
}
} = view;
const onClose = useCallback(() => {
dispatch(hideDatasourceModal(transaction));
}, [dispatch, transaction]);
const updateAdf = useUpdateAdf(view, existingNode);
const isRegularCardNode = !!(existingNode && !(existingNode !== null && existingNode !== void 0 && (_existingNode$attrs = existingNode.attrs) !== null && _existingNode$attrs !== void 0 && _existingNode$attrs.datasource));
const {
id: datasourceId = defaultDatasourceId,
views = [],
parameters: nodeParameters
} = (existingNode === null || existingNode === void 0 ? void 0 : (_existingNode$attrs2 = existingNode.attrs) === null || _existingNode$attrs2 === void 0 ? void 0 : _existingNode$attrs2.datasource) || {};
const {
visibleColumnKeys,
wrappedColumnKeys,
columnCustomSizes
} = resolveColumnsConfig(views);
const {
parameters,
ready
} = useFetchDatasourceInfo({
isRegularCardNode,
url: existingNode === null || existingNode === void 0 ? void 0 : existingNode.attrs.url,
cardContext,
nodeParameters
});
if (!ready) {
return null;
}
return /*#__PURE__*/React.createElement(Component, {
datasourceId: datasourceId,
viewMode: isRegularCardNode ? 'inline' : 'table' // Want non-datasource cards to open in inline view since they are in table view
,
parameters: parameters,
url: existingNode === null || existingNode === void 0 ? void 0 : existingNode.attrs.url,
visibleColumnKeys: visibleColumnKeys,
columnCustomSizes: columnCustomSizes,
wrappedColumnKeys: wrappedColumnKeys,
onCancel: onClose,
onInsert: updateAdf
});
};
const useUpdateAdf = (view, existingNode) => {
return useCallback((newAdf, analyticEvent) => {
if (analyticEvent) {
analyticEvent.update(payload => ({
...payload,
attributes: {
...payload.attributes,
inputMethod: 'datasource_config'
}
}));
}
if (existingNode) {
updateCardViaDatasource({
state: view.state,
node: existingNode,
newAdf,
view,
sourceEvent: analyticEvent
});
} else {
insertDatasource(view.state, newAdf, view, analyticEvent);
}
}, [existingNode, view]);
};
const getExistingNode = state => {
const {
selection
} = state;
let existingNode;
// Check if the selection contains a link mark
const isLinkMark = state.doc.resolve(selection.from).marks().some(mark => mark.type === state.schema.marks.link);
// When selection is a TextNode and a link Mark is present return that node
if (selection instanceof NodeSelection) {
existingNode = selection.node;
} else if (isLinkMark) {
var _state$doc$nodeAt;
existingNode = (_state$doc$nodeAt = state.doc.nodeAt(selection.from)) !== null && _state$doc$nodeAt !== void 0 ? _state$doc$nodeAt : undefined;
}
return existingNode;
};
const resolveColumnsConfig = views => {
var _tableView$properties;
const [tableView] = views;
const visibleColumnKeys = [];
const wrappedColumnKeys = [];
const columnCustomSizes = {};
const columns = tableView === null || tableView === void 0 ? void 0 : (_tableView$properties = tableView.properties) === null || _tableView$properties === void 0 ? void 0 : _tableView$properties.columns;
if (columns) {
for (const {
key,
width,
isWrapped
} of columns) {
visibleColumnKeys.push(key);
if (width) {
columnCustomSizes[key] = width;
}
if (isWrapped) {
wrappedColumnKeys.push(key);
}
}
}
return {
visibleColumnKeys,
wrappedColumnKeys,
columnCustomSizes
};
};