@atlaskit/editor-plugin-quick-insert 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +14 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +13 -0
- package/README.md +30 -0
- package/dist/cjs/commands.js +44 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/plugin-key.js +9 -0
- package/dist/cjs/plugin.js +188 -0
- package/dist/cjs/search.js +33 -0
- package/dist/cjs/ui/ModalElementBrowser/ModalElementBrowser.js +159 -0
- package/dist/cjs/ui/ModalElementBrowser/categories.js +100 -0
- package/dist/cjs/ui/ModalElementBrowser/index.js +61 -0
- package/dist/cjs/ui/ModalElementBrowser/messages.js +15 -0
- package/dist/es2019/commands.js +29 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/plugin-key.js +2 -0
- package/dist/es2019/plugin.js +150 -0
- package/dist/es2019/search.js +16 -0
- package/dist/es2019/ui/ModalElementBrowser/ModalElementBrowser.js +136 -0
- package/dist/es2019/ui/ModalElementBrowser/categories.js +94 -0
- package/dist/es2019/ui/ModalElementBrowser/index.js +51 -0
- package/dist/es2019/ui/ModalElementBrowser/messages.js +8 -0
- package/dist/esm/commands.js +35 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugin-key.js +2 -0
- package/dist/esm/plugin.js +180 -0
- package/dist/esm/search.js +25 -0
- package/dist/esm/ui/ModalElementBrowser/ModalElementBrowser.js +146 -0
- package/dist/esm/ui/ModalElementBrowser/categories.js +94 -0
- package/dist/esm/ui/ModalElementBrowser/index.js +50 -0
- package/dist/esm/ui/ModalElementBrowser/messages.js +8 -0
- package/dist/types/commands.d.ts +5 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/plugin-key.d.ts +3 -0
- package/dist/types/plugin.d.ts +15 -0
- package/dist/types/search.d.ts +5 -0
- package/dist/types/ui/ModalElementBrowser/ModalElementBrowser.d.ts +18 -0
- package/dist/types/ui/ModalElementBrowser/categories.d.ts +5 -0
- package/dist/types/ui/ModalElementBrowser/index.d.ts +11 -0
- package/dist/types/ui/ModalElementBrowser/messages.d.ts +7 -0
- package/dist/types-ts4.5/commands.d.ts +5 -0
- package/dist/types-ts4.5/index.d.ts +2 -0
- package/dist/types-ts4.5/plugin-key.d.ts +3 -0
- package/dist/types-ts4.5/plugin.d.ts +15 -0
- package/dist/types-ts4.5/search.d.ts +5 -0
- package/dist/types-ts4.5/ui/ModalElementBrowser/ModalElementBrowser.d.ts +18 -0
- package/dist/types-ts4.5/ui/ModalElementBrowser/categories.d.ts +5 -0
- package/dist/types-ts4.5/ui/ModalElementBrowser/index.d.ts +11 -0
- package/dist/types-ts4.5/ui/ModalElementBrowser/messages.d.ts +7 -0
- package/package.json +99 -0
- package/report.api.md +63 -0
- package/tmp/api-report-tmp.d.ts +33 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.messages = void 0;
|
|
7
|
+
var _reactIntlNext = require("react-intl-next");
|
|
8
|
+
var messages = (0, _reactIntlNext.defineMessages)({
|
|
9
|
+
help: {
|
|
10
|
+
id: 'fabric.editor.elementBrowser.help',
|
|
11
|
+
defaultMessage: 'Help',
|
|
12
|
+
description: 'Element browser help button label'
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
exports.messages = messages;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { insertSelectedItem } from '@atlaskit/editor-common/insert';
|
|
2
|
+
import { pluginKey } from './plugin-key';
|
|
3
|
+
export const openElementBrowserModal = ({
|
|
4
|
+
tr
|
|
5
|
+
}) => tr.setMeta(pluginKey, {
|
|
6
|
+
isElementBrowserModalOpen: true
|
|
7
|
+
});
|
|
8
|
+
export const closeElementBrowserModal = () => (state, dispatch) => {
|
|
9
|
+
if (dispatch) {
|
|
10
|
+
dispatch(state.tr.setMeta(pluginKey, {
|
|
11
|
+
isElementBrowserModalOpen: false
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// this method was adapted from the typeahead plugin so we respect the API for quick insert items
|
|
18
|
+
export const insertItem = item => (state, dispatch) => {
|
|
19
|
+
const insert = (maybeNode, opts = {}) => {
|
|
20
|
+
return insertSelectedItem(maybeNode, opts)(state, state.tr, state.selection.head);
|
|
21
|
+
};
|
|
22
|
+
const tr = item.action(insert, state);
|
|
23
|
+
|
|
24
|
+
/** @note There is no transaction when called without a search currently (different insert) */
|
|
25
|
+
if (tr && dispatch) {
|
|
26
|
+
dispatch(tr);
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { quickInsertPlugin } from './plugin';
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { memoProcessQuickInsertItems } from '@atlaskit/editor-common/quick-insert';
|
|
3
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
|
+
import { TypeAheadAvailableNodes } from '@atlaskit/editor-common/type-ahead';
|
|
5
|
+
import { insertItem, openElementBrowserModal } from './commands';
|
|
6
|
+
import { pluginKey } from './plugin-key';
|
|
7
|
+
import { getQuickInsertSuggestions } from './search';
|
|
8
|
+
import ModalElementBrowser from './ui/ModalElementBrowser';
|
|
9
|
+
export const quickInsertPlugin = ({
|
|
10
|
+
config: options,
|
|
11
|
+
api
|
|
12
|
+
}) => ({
|
|
13
|
+
name: 'quickInsert',
|
|
14
|
+
pmPlugins(defaultItems) {
|
|
15
|
+
return [{
|
|
16
|
+
name: 'quickInsert',
|
|
17
|
+
// It's important that this plugin is above TypeAheadPlugin
|
|
18
|
+
plugin: ({
|
|
19
|
+
providerFactory,
|
|
20
|
+
getIntl,
|
|
21
|
+
dispatch
|
|
22
|
+
}) => quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, options === null || options === void 0 ? void 0 : options.emptyStateHandler)
|
|
23
|
+
}];
|
|
24
|
+
},
|
|
25
|
+
pluginsOptions: {
|
|
26
|
+
typeAhead: {
|
|
27
|
+
id: TypeAheadAvailableNodes.QUICK_INSERT,
|
|
28
|
+
trigger: '/',
|
|
29
|
+
headless: options === null || options === void 0 ? void 0 : options.headless,
|
|
30
|
+
getItems({
|
|
31
|
+
query,
|
|
32
|
+
editorState
|
|
33
|
+
}) {
|
|
34
|
+
const quickInsertState = pluginKey.getState(editorState);
|
|
35
|
+
return Promise.resolve(getQuickInsertSuggestions({
|
|
36
|
+
query,
|
|
37
|
+
disableDefaultItems: options === null || options === void 0 ? void 0 : options.disableDefaultItems
|
|
38
|
+
}, quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.lazyDefaultItems, quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.providedItems));
|
|
39
|
+
},
|
|
40
|
+
selectItem: (state, item, insert) => {
|
|
41
|
+
return item.action(insert, state);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
contentComponent({
|
|
46
|
+
editorView
|
|
47
|
+
}) {
|
|
48
|
+
if (options !== null && options !== void 0 && options.enableElementBrowser) {
|
|
49
|
+
return /*#__PURE__*/React.createElement(ModalElementBrowser, {
|
|
50
|
+
editorView: editorView,
|
|
51
|
+
helpUrl: options === null || options === void 0 ? void 0 : options.elementBrowserHelpUrl,
|
|
52
|
+
pluginInjectionAPI: api
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
},
|
|
57
|
+
getSharedState(editorState) {
|
|
58
|
+
if (!editorState) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const quickInsertState = pluginKey.getState(editorState);
|
|
62
|
+
if (!quickInsertState) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
lazyDefaultItems: quickInsertState.lazyDefaultItems,
|
|
67
|
+
emptyStateHandler: quickInsertState.emptyStateHandler,
|
|
68
|
+
providedItems: quickInsertState.providedItems,
|
|
69
|
+
isElementBrowserModalOpen: quickInsertState.isElementBrowserModalOpen
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
actions: {
|
|
73
|
+
insertItem,
|
|
74
|
+
getSuggestions: searchOptions => {
|
|
75
|
+
var _api$quickInsert$shar;
|
|
76
|
+
const {
|
|
77
|
+
lazyDefaultItems,
|
|
78
|
+
providedItems
|
|
79
|
+
} = (_api$quickInsert$shar = api === null || api === void 0 ? void 0 : api.quickInsert.sharedState.currentState()) !== null && _api$quickInsert$shar !== void 0 ? _api$quickInsert$shar : {};
|
|
80
|
+
return getQuickInsertSuggestions(searchOptions, lazyDefaultItems, providedItems);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
commands: {
|
|
84
|
+
openElementBrowserModal
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const setProviderState = providerState => (state, dispatch) => {
|
|
88
|
+
if (dispatch) {
|
|
89
|
+
dispatch(state.tr.setMeta(pluginKey, providerState));
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
};
|
|
93
|
+
function quickInsertPluginFactory(defaultItems, providerFactory, getIntl, dispatch, emptyStateHandler) {
|
|
94
|
+
return new SafePlugin({
|
|
95
|
+
key: pluginKey,
|
|
96
|
+
state: {
|
|
97
|
+
init() {
|
|
98
|
+
return {
|
|
99
|
+
isElementBrowserModalOpen: false,
|
|
100
|
+
emptyStateHandler,
|
|
101
|
+
// lazy so it doesn't run on editor initialization
|
|
102
|
+
// memo here to avoid using a singleton cache, avoids editor
|
|
103
|
+
// getting confused when two editors exist within the same page.
|
|
104
|
+
lazyDefaultItems: () => memoProcessQuickInsertItems(defaultItems || [], getIntl())
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
apply(tr, pluginState) {
|
|
108
|
+
const meta = tr.getMeta(pluginKey);
|
|
109
|
+
if (meta) {
|
|
110
|
+
const keys = Object.keys(meta);
|
|
111
|
+
const changed = keys.some(key => {
|
|
112
|
+
return pluginState[key] !== meta[key];
|
|
113
|
+
});
|
|
114
|
+
if (changed) {
|
|
115
|
+
const newState = {
|
|
116
|
+
...pluginState,
|
|
117
|
+
...meta
|
|
118
|
+
};
|
|
119
|
+
dispatch(pluginKey, newState);
|
|
120
|
+
return newState;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return pluginState;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
view(editorView) {
|
|
127
|
+
const providerHandler = async (_name, providerPromise) => {
|
|
128
|
+
if (providerPromise) {
|
|
129
|
+
try {
|
|
130
|
+
const provider = await providerPromise;
|
|
131
|
+
const providedItems = await provider.getItems();
|
|
132
|
+
setProviderState({
|
|
133
|
+
provider,
|
|
134
|
+
providedItems
|
|
135
|
+
})(editorView.state, editorView.dispatch);
|
|
136
|
+
} catch (e) {
|
|
137
|
+
// eslint-disable-next-line no-console
|
|
138
|
+
console.error('Error getting items from quick insert provider', e);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
providerFactory.subscribe('quickInsertProvider', providerHandler);
|
|
143
|
+
return {
|
|
144
|
+
destroy() {
|
|
145
|
+
providerFactory.unsubscribe('quickInsertProvider', providerHandler);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { find } from '@atlaskit/editor-common/quick-insert';
|
|
2
|
+
import { dedupe } from '@atlaskit/editor-common/utils';
|
|
3
|
+
export const getQuickInsertSuggestions = (searchOptions, lazyDefaultItems = () => [], providedItems) => {
|
|
4
|
+
const {
|
|
5
|
+
query,
|
|
6
|
+
category,
|
|
7
|
+
disableDefaultItems,
|
|
8
|
+
featuredItems
|
|
9
|
+
} = searchOptions;
|
|
10
|
+
const defaultItems = disableDefaultItems ? [] : lazyDefaultItems();
|
|
11
|
+
const items = providedItems ? dedupe([...defaultItems, ...providedItems], item => item.title) : defaultItems;
|
|
12
|
+
if (featuredItems) {
|
|
13
|
+
return items.filter(item => item.featured);
|
|
14
|
+
}
|
|
15
|
+
return find(query || '', category === 'all' || !category ? items : items.filter(item => item.categories && item.categories.includes(category)));
|
|
16
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import React, { useCallback, useState } from 'react';
|
|
3
|
+
import { css, jsx } from '@emotion/react';
|
|
4
|
+
import { injectIntl } from 'react-intl-next';
|
|
5
|
+
import Button from '@atlaskit/button/custom-theme-button';
|
|
6
|
+
import { ElementBrowser } from '@atlaskit/editor-common/element-browser';
|
|
7
|
+
import QuestionCircleIcon from '@atlaskit/icon/glyph/question-circle';
|
|
8
|
+
import Modal, { ModalTransition, useModal } from '@atlaskit/modal-dialog';
|
|
9
|
+
import { DN50, N0 } from '@atlaskit/theme/colors';
|
|
10
|
+
import { themed } from '@atlaskit/theme/components';
|
|
11
|
+
import { borderRadius } from '@atlaskit/theme/constants';
|
|
12
|
+
import { getCategories } from './categories';
|
|
13
|
+
import { messages } from './messages';
|
|
14
|
+
export const MODAL_WRAPPER_PADDING = 16;
|
|
15
|
+
const actionsStyles = css({
|
|
16
|
+
display: 'inline-flex',
|
|
17
|
+
margin: `0 ${"var(--ds-space-negative-050, -4px)"}`
|
|
18
|
+
});
|
|
19
|
+
const actionItemStyles = css({
|
|
20
|
+
flex: '1 0 auto',
|
|
21
|
+
margin: `0 ${"var(--ds-space-050, 4px)"}`
|
|
22
|
+
});
|
|
23
|
+
const wrapperStyles = css({
|
|
24
|
+
display: 'flex',
|
|
25
|
+
flex: '1 1 auto',
|
|
26
|
+
boxSizing: 'border-box',
|
|
27
|
+
padding: `${"var(--ds-space-200, 16px)"} ${"var(--ds-space-200, 16px)"} 0 10px`,
|
|
28
|
+
overflow: 'hidden',
|
|
29
|
+
backgroundColor: `${themed({
|
|
30
|
+
light: `var(--ds-surface-overlay, ${N0})`,
|
|
31
|
+
dark: `var(--ds-surface-overlay, ${DN50})`
|
|
32
|
+
})()}`,
|
|
33
|
+
borderRadius: `${borderRadius()}px`
|
|
34
|
+
});
|
|
35
|
+
const modalFooterStyles = css({
|
|
36
|
+
display: 'flex',
|
|
37
|
+
padding: `${"var(--ds-space-200, 16px)"}`,
|
|
38
|
+
position: 'relative',
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
justifyContent: 'space-between'
|
|
41
|
+
});
|
|
42
|
+
const ModalElementBrowser = props => {
|
|
43
|
+
const [selectedItem, setSelectedItem] = useState();
|
|
44
|
+
const {
|
|
45
|
+
helpUrl,
|
|
46
|
+
intl,
|
|
47
|
+
onClose,
|
|
48
|
+
onInsertItem: onInsertItemFn
|
|
49
|
+
} = props;
|
|
50
|
+
const onSelectItem = useCallback(item => {
|
|
51
|
+
setSelectedItem(item);
|
|
52
|
+
}, [setSelectedItem]);
|
|
53
|
+
const onInsertItem = useCallback(item => {
|
|
54
|
+
onInsertItemFn(item);
|
|
55
|
+
}, [onInsertItemFn]);
|
|
56
|
+
const RenderFooter = useCallback(() => jsx(Footer, {
|
|
57
|
+
onInsert: () => onInsertItem(selectedItem),
|
|
58
|
+
beforeElement: helpUrl ? HelpLink(helpUrl, intl.formatMessage(messages.help)) : undefined
|
|
59
|
+
}), [onInsertItem, selectedItem, helpUrl, intl]);
|
|
60
|
+
|
|
61
|
+
// Since Modal uses stackIndex it's shouldCloseOnEscapePress prop doesn't work.
|
|
62
|
+
const onKeyDown = useCallback(e => {
|
|
63
|
+
if (e.key === 'Escape') {
|
|
64
|
+
onClose();
|
|
65
|
+
}
|
|
66
|
+
}, [onClose]);
|
|
67
|
+
const RenderBody = useCallback(() => jsx("div", {
|
|
68
|
+
css: wrapperStyles
|
|
69
|
+
}, jsx(ElementBrowser, {
|
|
70
|
+
categories: getCategories(props.intl),
|
|
71
|
+
getItems: props.getItems,
|
|
72
|
+
showSearch: true,
|
|
73
|
+
showCategories: true,
|
|
74
|
+
mode: "full",
|
|
75
|
+
onSelectItem: onSelectItem,
|
|
76
|
+
onInsertItem: onInsertItem,
|
|
77
|
+
emptyStateHandler: props.emptyStateHandler
|
|
78
|
+
})), [props.intl, props.getItems, onSelectItem, onInsertItem, props.emptyStateHandler]);
|
|
79
|
+
return jsx("div", {
|
|
80
|
+
"data-editor-popup": true,
|
|
81
|
+
onClick: onModalClick,
|
|
82
|
+
onKeyDown: onKeyDown
|
|
83
|
+
}, jsx(ModalTransition, null, props.isOpen && jsx(Modal, {
|
|
84
|
+
testId: "element-browser-modal-dialog",
|
|
85
|
+
stackIndex: 0,
|
|
86
|
+
key: "element-browser-modal",
|
|
87
|
+
onClose: props.onClose,
|
|
88
|
+
height: "664px",
|
|
89
|
+
width: "x-large",
|
|
90
|
+
autoFocus: false
|
|
91
|
+
// defaults to true and doesn't work along with stackIndex=1.
|
|
92
|
+
// packages/design-system/modal-dialog/src/components/Content.tsx Line 287
|
|
93
|
+
,
|
|
94
|
+
shouldCloseOnEscapePress: false
|
|
95
|
+
}, jsx(RenderBody, null), jsx(RenderFooter, null))));
|
|
96
|
+
};
|
|
97
|
+
ModalElementBrowser.displayName = 'ModalElementBrowser';
|
|
98
|
+
|
|
99
|
+
// Prevent ModalElementBrowser click propagation through to the editor.
|
|
100
|
+
const onModalClick = e => e.stopPropagation();
|
|
101
|
+
const Footer = ({
|
|
102
|
+
onInsert,
|
|
103
|
+
beforeElement
|
|
104
|
+
}) => {
|
|
105
|
+
const {
|
|
106
|
+
onClose
|
|
107
|
+
} = useModal();
|
|
108
|
+
return jsx("div", {
|
|
109
|
+
css: modalFooterStyles
|
|
110
|
+
}, beforeElement ? beforeElement : jsx("span", null), jsx("div", {
|
|
111
|
+
css: actionsStyles
|
|
112
|
+
}, jsx("div", {
|
|
113
|
+
css: actionItemStyles
|
|
114
|
+
}, jsx(Button, {
|
|
115
|
+
appearance: "primary",
|
|
116
|
+
onClick: onInsert,
|
|
117
|
+
testId: "ModalElementBrowser__insert-button"
|
|
118
|
+
}, "Insert")), jsx("div", {
|
|
119
|
+
css: actionItemStyles
|
|
120
|
+
}, jsx(Button, {
|
|
121
|
+
appearance: "subtle",
|
|
122
|
+
onClick: onClose,
|
|
123
|
+
testId: "ModalElementBrowser__close-button"
|
|
124
|
+
}, "Close"))));
|
|
125
|
+
};
|
|
126
|
+
const HelpLink = (url, helpText) => jsx(Button, {
|
|
127
|
+
iconBefore: jsx(QuestionCircleIcon, {
|
|
128
|
+
label: "",
|
|
129
|
+
size: "medium"
|
|
130
|
+
}),
|
|
131
|
+
appearance: "subtle-link",
|
|
132
|
+
href: url,
|
|
133
|
+
target: "_blank",
|
|
134
|
+
testId: "ModalElementBrowser__help-button"
|
|
135
|
+
}, helpText);
|
|
136
|
+
export default injectIntl(ModalElementBrowser);
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export function getCategories(intl) {
|
|
3
|
+
return [{
|
|
4
|
+
title: intl.formatMessage(messages.all),
|
|
5
|
+
name: 'all'
|
|
6
|
+
}, {
|
|
7
|
+
title: intl.formatMessage(messages.formatting),
|
|
8
|
+
name: 'formatting'
|
|
9
|
+
}, {
|
|
10
|
+
title: intl.formatMessage(messages['confluence-content']),
|
|
11
|
+
name: 'confluence-content'
|
|
12
|
+
}, {
|
|
13
|
+
title: intl.formatMessage(messages.media),
|
|
14
|
+
name: 'media'
|
|
15
|
+
}, {
|
|
16
|
+
title: intl.formatMessage(messages.visuals),
|
|
17
|
+
name: 'visuals'
|
|
18
|
+
}, {
|
|
19
|
+
title: intl.formatMessage(messages.navigation),
|
|
20
|
+
name: 'navigation'
|
|
21
|
+
}, {
|
|
22
|
+
title: intl.formatMessage(messages['external-content']),
|
|
23
|
+
name: 'external-content'
|
|
24
|
+
}, {
|
|
25
|
+
title: intl.formatMessage(messages.communication),
|
|
26
|
+
name: 'communication'
|
|
27
|
+
}, {
|
|
28
|
+
title: intl.formatMessage(messages.reporting),
|
|
29
|
+
name: 'reporting'
|
|
30
|
+
}, {
|
|
31
|
+
title: intl.formatMessage(messages.admin),
|
|
32
|
+
name: 'admin'
|
|
33
|
+
}, {
|
|
34
|
+
title: intl.formatMessage(messages.development),
|
|
35
|
+
name: 'development'
|
|
36
|
+
}];
|
|
37
|
+
}
|
|
38
|
+
const messages = defineMessages({
|
|
39
|
+
all: {
|
|
40
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-all',
|
|
41
|
+
defaultMessage: 'All',
|
|
42
|
+
description: 'all'
|
|
43
|
+
},
|
|
44
|
+
formatting: {
|
|
45
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-formatting',
|
|
46
|
+
defaultMessage: 'Formatting',
|
|
47
|
+
description: 'formatting'
|
|
48
|
+
},
|
|
49
|
+
'confluence-content': {
|
|
50
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-confluence-content',
|
|
51
|
+
defaultMessage: 'Confluence content',
|
|
52
|
+
description: 'confluence-content'
|
|
53
|
+
},
|
|
54
|
+
media: {
|
|
55
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-media',
|
|
56
|
+
defaultMessage: 'Media',
|
|
57
|
+
description: 'media'
|
|
58
|
+
},
|
|
59
|
+
visuals: {
|
|
60
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-visuals',
|
|
61
|
+
defaultMessage: 'Visuals & images',
|
|
62
|
+
description: 'visuals'
|
|
63
|
+
},
|
|
64
|
+
navigation: {
|
|
65
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-navigation',
|
|
66
|
+
defaultMessage: 'Navigation',
|
|
67
|
+
description: 'navigation'
|
|
68
|
+
},
|
|
69
|
+
'external-content': {
|
|
70
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-external-content',
|
|
71
|
+
defaultMessage: 'External content',
|
|
72
|
+
description: 'external-content'
|
|
73
|
+
},
|
|
74
|
+
communication: {
|
|
75
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-communication',
|
|
76
|
+
defaultMessage: 'Communication',
|
|
77
|
+
description: 'communication'
|
|
78
|
+
},
|
|
79
|
+
reporting: {
|
|
80
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-reporting',
|
|
81
|
+
defaultMessage: 'Reporting',
|
|
82
|
+
description: 'reporting'
|
|
83
|
+
},
|
|
84
|
+
admin: {
|
|
85
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-admin',
|
|
86
|
+
defaultMessage: 'Administration',
|
|
87
|
+
description: 'admin'
|
|
88
|
+
},
|
|
89
|
+
development: {
|
|
90
|
+
id: 'fabric.editor.elementbrowser.categorylist.category-development',
|
|
91
|
+
defaultMessage: 'Development',
|
|
92
|
+
description: 'development'
|
|
93
|
+
}
|
|
94
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
3
|
+
import { closeElementBrowserModal, insertItem } from '../../commands';
|
|
4
|
+
import { getQuickInsertSuggestions } from '../../search';
|
|
5
|
+
import ModalElementBrowser from './ModalElementBrowser';
|
|
6
|
+
const Modal = ({
|
|
7
|
+
quickInsertState,
|
|
8
|
+
editorView,
|
|
9
|
+
helpUrl
|
|
10
|
+
}) => {
|
|
11
|
+
const getItems = useCallback((query, category) => getQuickInsertSuggestions({
|
|
12
|
+
query,
|
|
13
|
+
category
|
|
14
|
+
}, quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.lazyDefaultItems, quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.providedItems), [quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.lazyDefaultItems, quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.providedItems]);
|
|
15
|
+
const focusInEditor = useCallback(() => {
|
|
16
|
+
if (!editorView.hasFocus()) {
|
|
17
|
+
editorView.focus();
|
|
18
|
+
}
|
|
19
|
+
}, [editorView]);
|
|
20
|
+
const onInsertItem = useCallback(item => {
|
|
21
|
+
closeElementBrowserModal()(editorView.state, editorView.dispatch);
|
|
22
|
+
focusInEditor();
|
|
23
|
+
insertItem(item)(editorView.state, editorView.dispatch);
|
|
24
|
+
}, [editorView, focusInEditor]);
|
|
25
|
+
const onClose = useCallback(() => {
|
|
26
|
+
closeElementBrowserModal()(editorView.state, editorView.dispatch);
|
|
27
|
+
focusInEditor();
|
|
28
|
+
}, [editorView, focusInEditor]);
|
|
29
|
+
return /*#__PURE__*/React.createElement(ModalElementBrowser, {
|
|
30
|
+
getItems: getItems,
|
|
31
|
+
onInsertItem: onInsertItem,
|
|
32
|
+
helpUrl: helpUrl,
|
|
33
|
+
isOpen: (quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.isElementBrowserModalOpen) || false,
|
|
34
|
+
emptyStateHandler: quickInsertState === null || quickInsertState === void 0 ? void 0 : quickInsertState.emptyStateHandler,
|
|
35
|
+
onClose: onClose
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export default (({
|
|
39
|
+
editorView,
|
|
40
|
+
helpUrl,
|
|
41
|
+
pluginInjectionAPI
|
|
42
|
+
}) => {
|
|
43
|
+
const {
|
|
44
|
+
quickInsertState
|
|
45
|
+
} = useSharedPluginState(pluginInjectionAPI, ['quickInsert']);
|
|
46
|
+
return /*#__PURE__*/React.createElement(Modal, {
|
|
47
|
+
quickInsertState: quickInsertState !== null && quickInsertState !== void 0 ? quickInsertState : undefined,
|
|
48
|
+
editorView: editorView,
|
|
49
|
+
helpUrl: helpUrl
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { insertSelectedItem } from '@atlaskit/editor-common/insert';
|
|
2
|
+
import { pluginKey } from './plugin-key';
|
|
3
|
+
export var openElementBrowserModal = function openElementBrowserModal(_ref) {
|
|
4
|
+
var tr = _ref.tr;
|
|
5
|
+
return tr.setMeta(pluginKey, {
|
|
6
|
+
isElementBrowserModalOpen: true
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
export var closeElementBrowserModal = function closeElementBrowserModal() {
|
|
10
|
+
return function (state, dispatch) {
|
|
11
|
+
if (dispatch) {
|
|
12
|
+
dispatch(state.tr.setMeta(pluginKey, {
|
|
13
|
+
isElementBrowserModalOpen: false
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// this method was adapted from the typeahead plugin so we respect the API for quick insert items
|
|
21
|
+
export var insertItem = function insertItem(item) {
|
|
22
|
+
return function (state, dispatch) {
|
|
23
|
+
var insert = function insert(maybeNode) {
|
|
24
|
+
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
25
|
+
return insertSelectedItem(maybeNode, opts)(state, state.tr, state.selection.head);
|
|
26
|
+
};
|
|
27
|
+
var tr = item.action(insert, state);
|
|
28
|
+
|
|
29
|
+
/** @note There is no transaction when called without a search currently (different insert) */
|
|
30
|
+
if (tr && dispatch) {
|
|
31
|
+
dispatch(tr);
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { quickInsertPlugin } from './plugin';
|