@atlaskit/editor-plugin-insert-block 1.12.0 → 1.14.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/CHANGELOG.md +28 -0
- package/dist/cjs/plugin.js +36 -5
- package/dist/cjs/ui/ElementBrowser/InsertMenu.js +47 -13
- package/dist/cjs/ui/ElementRail/index.js +186 -2
- package/dist/cjs/ui/ElementRail/useInsertMenuRailItems.js +63 -0
- package/dist/cjs/ui/templateOptions.js +128 -57
- package/dist/cjs/ui/templates.js +1130 -0
- package/dist/es2019/plugin.js +36 -5
- package/dist/es2019/ui/ElementBrowser/InsertMenu.js +61 -26
- package/dist/es2019/ui/ElementRail/index.js +189 -1
- package/dist/es2019/ui/ElementRail/useInsertMenuRailItems.js +54 -0
- package/dist/es2019/ui/templateOptions.js +78 -11
- package/dist/es2019/ui/templates.js +1118 -0
- package/dist/esm/plugin.js +36 -5
- package/dist/esm/ui/ElementBrowser/InsertMenu.js +47 -13
- package/dist/esm/ui/ElementRail/index.js +185 -2
- package/dist/esm/ui/ElementRail/useInsertMenuRailItems.js +56 -0
- package/dist/esm/ui/templateOptions.js +128 -57
- package/dist/esm/ui/templates.js +1124 -0
- package/dist/types/ui/ElementRail/index.d.ts +7 -4
- package/dist/types/ui/ElementRail/useInsertMenuRailItems.d.ts +4 -0
- package/dist/types/ui/ToolbarInsertBlock/create-items.d.ts +1 -1
- package/dist/types/ui/templateOptions.d.ts +3 -1
- package/dist/types/ui/templates.d.ts +522 -0
- package/dist/types-ts4.5/ui/ElementRail/index.d.ts +7 -4
- package/dist/types-ts4.5/ui/ElementRail/useInsertMenuRailItems.d.ts +4 -0
- package/dist/types-ts4.5/ui/ToolbarInsertBlock/create-items.d.ts +1 -1
- package/dist/types-ts4.5/ui/templateOptions.d.ts +3 -1
- package/dist/types-ts4.5/ui/templates.d.ts +522 -0
- package/package.json +14 -6
package/dist/es2019/plugin.js
CHANGED
|
@@ -4,9 +4,11 @@ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
|
4
4
|
import { contentAllowedInCodeBlock, shouldSplitSelectedNodeOnNodeInsertion } from '@atlaskit/editor-common/insert';
|
|
5
5
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
6
|
import { WithProviders } from '@atlaskit/editor-common/provider-factory';
|
|
7
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
7
8
|
import { ToolbarSize } from '@atlaskit/editor-common/types';
|
|
8
9
|
import { getWrappingOptions } from '@atlaskit/editor-common/utils';
|
|
9
10
|
import { BLOCK_QUOTE, CODE_BLOCK, PANEL } from '@atlaskit/editor-plugin-block-type/consts';
|
|
11
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
12
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
11
13
|
import SwitchIcon from './assets/switch';
|
|
12
14
|
import { elementBrowserPmKey, elementBrowserPmPlugin } from './pm-plugins/elementBrowser';
|
|
@@ -53,6 +55,9 @@ export const insertBlockPlugin = ({
|
|
|
53
55
|
const toggleDropdownMenuOptionsRef = {
|
|
54
56
|
current: null
|
|
55
57
|
};
|
|
58
|
+
const editorViewRef = {
|
|
59
|
+
current: null
|
|
60
|
+
};
|
|
56
61
|
const registerToggleDropdownMenuOptions = cb => {
|
|
57
62
|
toggleDropdownMenuOptionsRef.current = cb;
|
|
58
63
|
return () => {
|
|
@@ -119,6 +124,17 @@ export const insertBlockPlugin = ({
|
|
|
119
124
|
return [{
|
|
120
125
|
name: 'elementBrowserPmPlugin',
|
|
121
126
|
plugin: () => elementBrowserPmPlugin()
|
|
127
|
+
}, {
|
|
128
|
+
name: 'elementBrowserEditorViewRef',
|
|
129
|
+
plugin: () => {
|
|
130
|
+
return new SafePlugin({
|
|
131
|
+
view: editorView => {
|
|
132
|
+
// Workaround - need reference to editorView for contextPanel component
|
|
133
|
+
editorViewRef.current = editorView;
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
122
138
|
}];
|
|
123
139
|
},
|
|
124
140
|
pluginsOptions: {
|
|
@@ -188,10 +204,13 @@ export const insertBlockPlugin = ({
|
|
|
188
204
|
// If we decide to ship the feature, we will consider a separate plugin if needed.
|
|
189
205
|
// Experiment one-pager: https://hello.atlassian.net/wiki/spaces/ETM/pages/3983684902/Experiment+Drive+element+usage+via+element+templates
|
|
190
206
|
quickInsert: () => {
|
|
191
|
-
|
|
207
|
+
var _options$UNSAFE_edito;
|
|
208
|
+
if (
|
|
209
|
+
// @ts-ignore
|
|
210
|
+
['full-page', 'full-width'].includes((_options$UNSAFE_edito = options.UNSAFE_editorAppearance) !== null && _options$UNSAFE_edito !== void 0 ? _options$UNSAFE_edito : '') && editorExperiment('element-level-templates', true, {
|
|
192
211
|
exposure: true
|
|
193
212
|
})) {
|
|
194
|
-
return templateOptions;
|
|
213
|
+
return templateOptions(api);
|
|
195
214
|
}
|
|
196
215
|
return [];
|
|
197
216
|
}
|
|
@@ -210,8 +229,10 @@ export const insertBlockPlugin = ({
|
|
|
210
229
|
// api.getSharedState() will have an outdated reference to editorState on first mount of this component
|
|
211
230
|
// so instead just rely on plugin key as we don't need to be reactive to changes here
|
|
212
231
|
const pluginState = elementBrowserPmKey.getState(state);
|
|
213
|
-
if (pluginState !== null && pluginState !== void 0 && pluginState.menuBrowserOpen) {
|
|
232
|
+
if (pluginState !== null && pluginState !== void 0 && pluginState.menuBrowserOpen && editorViewRef.current) {
|
|
214
233
|
return /*#__PURE__*/React.createElement(InsertMenuRail, {
|
|
234
|
+
editorView: editorViewRef.current,
|
|
235
|
+
options: options,
|
|
215
236
|
api: api
|
|
216
237
|
});
|
|
217
238
|
}
|
|
@@ -249,6 +270,16 @@ function ToolbarInsertBlockWithInjectionApi({
|
|
|
249
270
|
typeAheadState,
|
|
250
271
|
placeholderTextState
|
|
251
272
|
} = useSharedPluginState(pluginInjectionApi, ['hyperlink', 'date', 'imageUpload', 'mention', 'emoji', 'blockType', 'media', 'typeAhead', 'placeholderText']);
|
|
273
|
+
const getEmojiProvider = () => {
|
|
274
|
+
if (fg('platform_editor_get_emoji_provider_from_config')) {
|
|
275
|
+
if (emojiState !== null && emojiState !== void 0 && emojiState.emojiProvider) {
|
|
276
|
+
return Promise.resolve(emojiState === null || emojiState === void 0 ? void 0 : emojiState.emojiProvider);
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
return providers.emojiProvider;
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
const emojiProvider = getEmojiProvider();
|
|
252
283
|
return /*#__PURE__*/React.createElement(ToolbarInsertBlock, {
|
|
253
284
|
pluginInjectionApi: pluginInjectionApi,
|
|
254
285
|
buttons: buttons,
|
|
@@ -275,8 +306,8 @@ function ToolbarInsertBlockWithInjectionApi({
|
|
|
275
306
|
availableWrapperBlockTypes: blockTypeState && blockTypeState.availableWrapperBlockTypes,
|
|
276
307
|
linkSupported: !!hyperlinkState,
|
|
277
308
|
linkDisabled: !hyperlinkState || !hyperlinkState.canInsertLink || !!hyperlinkState.activeLinkMark,
|
|
278
|
-
emojiDisabled: !emojiState || !
|
|
279
|
-
emojiProvider:
|
|
309
|
+
emojiDisabled: !emojiState || !emojiProvider,
|
|
310
|
+
emojiProvider: emojiProvider,
|
|
280
311
|
nativeStatusSupported: options.nativeStatusSupported,
|
|
281
312
|
horizontalRuleEnabled: options.horizontalRuleEnabled,
|
|
282
313
|
onInsertBlockType: handleInsertBlockType(pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c = pluginInjectionApi.codeBlock) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.actions.insertCodeBlock, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$p = pluginInjectionApi.panel) === null || _pluginInjectionApi$p === void 0 ? void 0 : _pluginInjectionApi$p.actions.insertPanel, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$b = pluginInjectionApi.blockType) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.insertBlockQuote),
|
|
@@ -16,6 +16,7 @@ import { withReactEditorViewOuterListeners as withOuterListeners } from '@atlask
|
|
|
16
16
|
// eslint-disable-next-line @atlassian/tangerine/import/entry-points
|
|
17
17
|
import { borderRadius } from '@atlaskit/theme';
|
|
18
18
|
import { N0, N30A, N60A } from '@atlaskit/theme/colors';
|
|
19
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
19
20
|
const InsertMenu = ({
|
|
20
21
|
editorView,
|
|
21
22
|
dropdownItems,
|
|
@@ -24,7 +25,7 @@ const InsertMenu = ({
|
|
|
24
25
|
toggleVisiblity,
|
|
25
26
|
pluginInjectionApi
|
|
26
27
|
}) => {
|
|
27
|
-
var _pluginInjectionApi$
|
|
28
|
+
var _pluginInjectionApi$q7, _pluginInjectionApi$q8, _pluginInjectionApi$q9;
|
|
28
29
|
const [itemCount, setItemCount] = useState(0);
|
|
29
30
|
const transform = useCallback(item => ({
|
|
30
31
|
title: item.content,
|
|
@@ -47,12 +48,19 @@ const InsertMenu = ({
|
|
|
47
48
|
const quickInsertDropdownItems = dropdownItems.map(transform);
|
|
48
49
|
const viewMoreItem = showElementBrowserLink ? quickInsertDropdownItems.pop() : undefined;
|
|
49
50
|
const onInsertItem = useCallback(item => {
|
|
50
|
-
var _pluginInjectionApi$q;
|
|
51
51
|
toggleVisiblity();
|
|
52
52
|
if (!editorView.hasFocus()) {
|
|
53
53
|
editorView.focus();
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
if (editorExperiment('insert-menu-in-right-rail', true)) {
|
|
56
|
+
var _pluginInjectionApi$q;
|
|
57
|
+
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q === void 0 ? void 0 : _pluginInjectionApi$q.actions.insertItem(item,
|
|
58
|
+
// @ts-expect-error
|
|
59
|
+
INPUT_METHOD.INSERT_MENU_RIGHT_RAIL)(editorView.state, editorView.dispatch);
|
|
60
|
+
} else {
|
|
61
|
+
var _pluginInjectionApi$q2;
|
|
62
|
+
pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q2 = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q2 === void 0 ? void 0 : _pluginInjectionApi$q2.actions.insertItem(item, INPUT_METHOD.TOOLBAR)(editorView.state, editorView.dispatch);
|
|
63
|
+
}
|
|
56
64
|
}, [editorView, toggleVisiblity, pluginInjectionApi]);
|
|
57
65
|
const getItems = useCallback((query, category) => {
|
|
58
66
|
let result;
|
|
@@ -63,23 +71,35 @@ const InsertMenu = ({
|
|
|
63
71
|
* @see above transform function for more details.
|
|
64
72
|
*/
|
|
65
73
|
if (query) {
|
|
66
|
-
var _pluginInjectionApi$
|
|
67
|
-
result = (_pluginInjectionApi$
|
|
74
|
+
var _pluginInjectionApi$q3, _pluginInjectionApi$q4;
|
|
75
|
+
result = (_pluginInjectionApi$q3 = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q4 = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q4 === void 0 ? void 0 : _pluginInjectionApi$q4.actions.getSuggestions({
|
|
68
76
|
query,
|
|
69
77
|
category
|
|
70
|
-
})) !== null && _pluginInjectionApi$
|
|
78
|
+
})) !== null && _pluginInjectionApi$q3 !== void 0 ? _pluginInjectionApi$q3 : [];
|
|
71
79
|
} else {
|
|
72
|
-
var _pluginInjectionApi$
|
|
73
|
-
const featuredQuickInsertSuggestions = (_pluginInjectionApi$
|
|
80
|
+
var _pluginInjectionApi$q5, _pluginInjectionApi$q6;
|
|
81
|
+
const featuredQuickInsertSuggestions = (_pluginInjectionApi$q5 = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q6 = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q6 === void 0 ? void 0 : _pluginInjectionApi$q6.actions.getSuggestions({
|
|
74
82
|
category,
|
|
75
|
-
featuredItems: true
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
featuredItems: true,
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
templateItems: editorExperiment('element-level-templates', true)
|
|
86
|
+
})) !== null && _pluginInjectionApi$q5 !== void 0 ? _pluginInjectionApi$q5 : [];
|
|
87
|
+
if (editorExperiment('element-level-templates', true)) {
|
|
88
|
+
// Make sure template options appear as top 5 items
|
|
89
|
+
featuredQuickInsertSuggestions.sort((a, b) => {
|
|
90
|
+
var _b$priority, _a$priority;
|
|
91
|
+
return ((_b$priority = b.priority) !== null && _b$priority !== void 0 ? _b$priority : 0) - ((_a$priority = a.priority) !== null && _a$priority !== void 0 ? _a$priority : 0);
|
|
92
|
+
});
|
|
93
|
+
const templateItems = featuredQuickInsertSuggestions.splice(0, 5);
|
|
94
|
+
result = [...templateItems, ...quickInsertDropdownItems, ...featuredQuickInsertSuggestions];
|
|
95
|
+
} else {
|
|
96
|
+
result = quickInsertDropdownItems.concat(featuredQuickInsertSuggestions);
|
|
97
|
+
}
|
|
78
98
|
}
|
|
79
99
|
setItemCount(result.length);
|
|
80
100
|
return result;
|
|
81
|
-
}, [pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$
|
|
82
|
-
const emptyStateHandler = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$
|
|
101
|
+
}, [pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q7 = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q7 === void 0 ? void 0 : _pluginInjectionApi$q7.actions, quickInsertDropdownItems]);
|
|
102
|
+
const emptyStateHandler = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$q8 = pluginInjectionApi.quickInsert) === null || _pluginInjectionApi$q8 === void 0 ? void 0 : (_pluginInjectionApi$q9 = _pluginInjectionApi$q8.sharedState.currentState()) === null || _pluginInjectionApi$q9 === void 0 ? void 0 : _pluginInjectionApi$q9.emptyStateHandler;
|
|
83
103
|
return (
|
|
84
104
|
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
|
|
85
105
|
jsx("div", {
|
|
@@ -129,21 +149,36 @@ const getInsertMenuHeight = ({
|
|
|
129
149
|
}
|
|
130
150
|
return 560; // For showing 6 Elements.
|
|
131
151
|
};
|
|
132
|
-
const insertMenuWrapper = itemCount =>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
152
|
+
const insertMenuWrapper = itemCount => {
|
|
153
|
+
if (editorExperiment('insert-menu-in-right-rail', true)) {
|
|
154
|
+
return css({
|
|
155
|
+
display: 'flex',
|
|
156
|
+
flexDirection: 'column',
|
|
157
|
+
width: '310px',
|
|
158
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
159
|
+
height: 'calc(100% - 32px)',
|
|
160
|
+
margin: `0 -10px`,
|
|
161
|
+
backgroundColor: `${`var(--ds-surface-overlay, ${N0})`}`,
|
|
162
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
163
|
+
borderRadius: `${borderRadius()}px`
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return css({
|
|
167
|
+
display: 'flex',
|
|
168
|
+
flexDirection: 'column',
|
|
169
|
+
width: '320px',
|
|
170
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
171
|
+
height: `${getInsertMenuHeight({
|
|
172
|
+
itemCount
|
|
173
|
+
})}px`,
|
|
174
|
+
backgroundColor: `${`var(--ds-surface-overlay, ${N0})`}`,
|
|
175
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
176
|
+
borderRadius: `${borderRadius()}px`,
|
|
177
|
+
boxShadow: `${`var(--ds-shadow-overlay, ${`0 0 0 1px ${N30A},
|
|
144
178
|
0 2px 1px ${N30A},
|
|
145
179
|
0 0 20px -6px ${N60A}`})`}`
|
|
146
|
-
});
|
|
180
|
+
});
|
|
181
|
+
};
|
|
147
182
|
const flexWrapperStyles = css({
|
|
148
183
|
display: 'flex',
|
|
149
184
|
flex: 1,
|
|
@@ -1,10 +1,198 @@
|
|
|
1
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
1
2
|
import React from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl-next';
|
|
4
|
+
import { IconButton } from '@atlaskit/button/new';
|
|
5
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
6
|
+
import { toolbarInsertBlockMessages } from '@atlaskit/editor-common/messages';
|
|
7
|
+
import Heading from '@atlaskit/heading';
|
|
8
|
+
import CrossIcon from '@atlaskit/icon/glyph/cross';
|
|
9
|
+
import { Box, xcss } from '@atlaskit/primitives';
|
|
10
|
+
import { toggleInsertMenuRightRail } from '../../pm-plugins/commands';
|
|
11
|
+
import InsertMenu from '../ElementBrowser/InsertMenu';
|
|
12
|
+
import { useInsertMenuRailItems } from './useInsertMenuRailItems';
|
|
13
|
+
const panelWrapper = xcss({
|
|
14
|
+
height: '100%'
|
|
15
|
+
});
|
|
16
|
+
const panelContentHeader = xcss({
|
|
17
|
+
height: '32px',
|
|
18
|
+
display: 'flex',
|
|
19
|
+
justifyContent: 'space-between',
|
|
20
|
+
alignItems: 'center'
|
|
21
|
+
});
|
|
22
|
+
|
|
2
23
|
/**
|
|
3
24
|
* For insert menu in right rail experiment
|
|
4
25
|
* - Clean up ticket ED-24801
|
|
5
26
|
*/
|
|
6
27
|
export const InsertMenuRail = ({
|
|
28
|
+
editorView,
|
|
29
|
+
options,
|
|
7
30
|
api
|
|
8
31
|
}) => {
|
|
9
|
-
|
|
32
|
+
const dropdownItems = useInsertMenuRailItems(editorView, options, api);
|
|
33
|
+
const {
|
|
34
|
+
formatMessage
|
|
35
|
+
} = useIntl();
|
|
36
|
+
const onInsert = ({
|
|
37
|
+
item
|
|
38
|
+
}) => {
|
|
39
|
+
var _api$core, _api$hyperlink, _api$imageUpload, _api$media, _api$mention, _api$emoji, _api$codeBlock, _api$blockType, _api$panel, _api$taskDecision, _api$taskDecision2, _api$rule, _api$core2, _api$quickInsert, _api$core3, _api$date, _api$date$commands, _api$placeholderText, _api$layout, _api$core4, _api$status, _api$status$commands;
|
|
40
|
+
const {
|
|
41
|
+
state,
|
|
42
|
+
dispatch
|
|
43
|
+
} = editorView;
|
|
44
|
+
let inputMethod = INPUT_METHOD.INSERT_MENU_RIGHT_RAIL;
|
|
45
|
+
if (!api) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (!editorView.hasFocus()) {
|
|
49
|
+
editorView.focus();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Below is duplicated from ToolbarInsertBlock/index.tsx - this function is only called
|
|
53
|
+
// for BlockMenuItem items, which are rendered in the insert menu when no search has been performed.
|
|
54
|
+
// When a search is performed, the list will be filled by QuickInsertItems, which handle their own insertion.
|
|
55
|
+
switch (item.value.name) {
|
|
56
|
+
case 'link':
|
|
57
|
+
// @ts-expect-error
|
|
58
|
+
(_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(api === null || api === void 0 ? void 0 : (_api$hyperlink = api.hyperlink) === null || _api$hyperlink === void 0 ? void 0 : _api$hyperlink.commands.showLinkToolbar(inputMethod));
|
|
59
|
+
break;
|
|
60
|
+
case 'table':
|
|
61
|
+
// workaround to solve race condition where cursor is not placed correctly inside table
|
|
62
|
+
queueMicrotask(() => {
|
|
63
|
+
var _api$table, _api$table$actions$in, _api$table$actions;
|
|
64
|
+
// @ts-expect-error
|
|
65
|
+
(_api$table = api.table) === null || _api$table === void 0 ? void 0 : (_api$table$actions$in = (_api$table$actions = _api$table.actions).insertTable) === null || _api$table$actions$in === void 0 ? void 0 : _api$table$actions$in.call(_api$table$actions, {
|
|
66
|
+
action: ACTION.INSERTED,
|
|
67
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
68
|
+
actionSubjectId: ACTION_SUBJECT_ID.TABLE,
|
|
69
|
+
attributes: {
|
|
70
|
+
inputMethod
|
|
71
|
+
},
|
|
72
|
+
eventType: EVENT_TYPE.TRACK
|
|
73
|
+
})(state, dispatch);
|
|
74
|
+
});
|
|
75
|
+
break;
|
|
76
|
+
case 'image upload':
|
|
77
|
+
(_api$imageUpload = api.imageUpload) === null || _api$imageUpload === void 0 ? void 0 : _api$imageUpload.actions.startUpload()(state, dispatch);
|
|
78
|
+
break;
|
|
79
|
+
case 'media':
|
|
80
|
+
const mediaState = (_api$media = api.media) === null || _api$media === void 0 ? void 0 : _api$media.sharedState.currentState();
|
|
81
|
+
if (mediaState) {
|
|
82
|
+
var _api$analytics;
|
|
83
|
+
mediaState.showMediaPicker();
|
|
84
|
+
// @ts-expect-error
|
|
85
|
+
(_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.attachAnalyticsEvent({
|
|
86
|
+
action: ACTION.OPENED,
|
|
87
|
+
actionSubject: ACTION_SUBJECT.PICKER,
|
|
88
|
+
actionSubjectId: ACTION_SUBJECT_ID.PICKER_CLOUD,
|
|
89
|
+
attributes: {
|
|
90
|
+
inputMethod
|
|
91
|
+
},
|
|
92
|
+
eventType: EVENT_TYPE.UI
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
case 'mention':
|
|
97
|
+
const pluginState = (_api$mention = api.mention) === null || _api$mention === void 0 ? void 0 : _api$mention.sharedState.currentState();
|
|
98
|
+
if (pluginState && pluginState.canInsertMention) {
|
|
99
|
+
var _api$mention2, _api$mention2$actions;
|
|
100
|
+
// @ts-expect-error
|
|
101
|
+
(_api$mention2 = api.mention) === null || _api$mention2 === void 0 ? void 0 : (_api$mention2$actions = _api$mention2.actions) === null || _api$mention2$actions === void 0 ? void 0 : _api$mention2$actions.openTypeAhead(inputMethod);
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
case 'emoji':
|
|
105
|
+
// @ts-expect-error
|
|
106
|
+
(_api$emoji = api.emoji) === null || _api$emoji === void 0 ? void 0 : _api$emoji.actions.openTypeAhead(inputMethod);
|
|
107
|
+
break;
|
|
108
|
+
case 'codeblock':
|
|
109
|
+
(_api$codeBlock = api.codeBlock) === null || _api$codeBlock === void 0 ? void 0 : _api$codeBlock.actions.insertCodeBlock(inputMethod);
|
|
110
|
+
break;
|
|
111
|
+
case 'blockquote':
|
|
112
|
+
// @ts-expect-error
|
|
113
|
+
(_api$blockType = api.blockType) === null || _api$blockType === void 0 ? void 0 : _api$blockType.actions.insertBlockQuote(inputMethod);
|
|
114
|
+
break;
|
|
115
|
+
case 'panel':
|
|
116
|
+
(_api$panel = api.panel) === null || _api$panel === void 0 ? void 0 : _api$panel.actions.insertPanel(inputMethod);
|
|
117
|
+
break;
|
|
118
|
+
case 'action':
|
|
119
|
+
// @ts-expect-error
|
|
120
|
+
(_api$taskDecision = api.taskDecision) === null || _api$taskDecision === void 0 ? void 0 : _api$taskDecision.actions.insertTaskDecision('taskList', inputMethod)(state, dispatch);
|
|
121
|
+
break;
|
|
122
|
+
case 'decision':
|
|
123
|
+
// @ts-expect-error
|
|
124
|
+
(_api$taskDecision2 = api.taskDecision) === null || _api$taskDecision2 === void 0 ? void 0 : _api$taskDecision2.actions.insertTaskDecision('decisionList', inputMethod)(state, dispatch);
|
|
125
|
+
break;
|
|
126
|
+
case 'horizontalrule':
|
|
127
|
+
// @ts-expect-error
|
|
128
|
+
(_api$rule = api.rule) === null || _api$rule === void 0 ? void 0 : _api$rule.actions.insertHorizontalRule(inputMethod)(state, dispatch);
|
|
129
|
+
break;
|
|
130
|
+
case 'macro':
|
|
131
|
+
(_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute((_api$quickInsert = api.quickInsert) === null || _api$quickInsert === void 0 ? void 0 : _api$quickInsert.commands.openElementBrowserModal);
|
|
132
|
+
break;
|
|
133
|
+
case 'date':
|
|
134
|
+
(_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute((_api$date = api.date) === null || _api$date === void 0 ? void 0 : (_api$date$commands = _api$date.commands) === null || _api$date$commands === void 0 ? void 0 : _api$date$commands.insertDate({
|
|
135
|
+
// @ts-expect-error
|
|
136
|
+
inputMethod
|
|
137
|
+
}));
|
|
138
|
+
break;
|
|
139
|
+
case 'placeholder text':
|
|
140
|
+
(_api$placeholderText = api.placeholderText) === null || _api$placeholderText === void 0 ? void 0 : _api$placeholderText.actions.showPlaceholderFloatingToolbar(editorView.state, editorView.dispatch);
|
|
141
|
+
break;
|
|
142
|
+
case 'layout':
|
|
143
|
+
// @ts-expect-error
|
|
144
|
+
(_api$layout = api.layout) === null || _api$layout === void 0 ? void 0 : _api$layout.actions.insertLayoutColumns(inputMethod)(editorView.state, editorView.dispatch);
|
|
145
|
+
break;
|
|
146
|
+
case 'status':
|
|
147
|
+
// @ts-expect-error
|
|
148
|
+
(_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute((_api$status = api.status) === null || _api$status === void 0 ? void 0 : (_api$status$commands = _api$status.commands) === null || _api$status$commands === void 0 ? void 0 : _api$status$commands.insertStatus(inputMethod));
|
|
149
|
+
break;
|
|
150
|
+
|
|
151
|
+
// https://product-fabric.atlassian.net/browse/ED-8053
|
|
152
|
+
// @ts-ignore: OK to fallthrough to default
|
|
153
|
+
case 'expand':
|
|
154
|
+
if (options.allowExpand) {
|
|
155
|
+
var _api$expand;
|
|
156
|
+
(_api$expand = api.expand) === null || _api$expand === void 0 ? void 0 : _api$expand.actions.insertExpand(state, dispatch);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// eslint-disable-next-line no-fallthrough
|
|
161
|
+
default:
|
|
162
|
+
// leaving this blank for now
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
166
|
+
xcss: panelWrapper
|
|
167
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
|
168
|
+
xcss: panelContentHeader
|
|
169
|
+
}, /*#__PURE__*/React.createElement(Heading, {
|
|
170
|
+
size: "small",
|
|
171
|
+
as: "h2"
|
|
172
|
+
}, formatMessage(toolbarInsertBlockMessages.insertRightRailTitle)), /*#__PURE__*/React.createElement(IconButton, {
|
|
173
|
+
appearance: "subtle",
|
|
174
|
+
testId: "right-rail-insert-menu-close-button",
|
|
175
|
+
label: formatMessage(toolbarInsertBlockMessages.closeInsertRightRail),
|
|
176
|
+
icon: CrossIcon,
|
|
177
|
+
onClick: () => {
|
|
178
|
+
if (!api) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
api.core.actions.execute(({
|
|
182
|
+
tr
|
|
183
|
+
}) => {
|
|
184
|
+
var _api$contextPanel;
|
|
185
|
+
toggleInsertMenuRightRail(tr);
|
|
186
|
+
(_api$contextPanel = api.contextPanel) === null || _api$contextPanel === void 0 ? void 0 : _api$contextPanel.actions.applyChange(tr);
|
|
187
|
+
return tr;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
})), /*#__PURE__*/React.createElement(InsertMenu, {
|
|
191
|
+
editorView: editorView,
|
|
192
|
+
dropdownItems: dropdownItems,
|
|
193
|
+
onInsert: onInsert,
|
|
194
|
+
toggleVisiblity: () => {},
|
|
195
|
+
showElementBrowserLink: true,
|
|
196
|
+
pluginInjectionApi: api
|
|
197
|
+
}));
|
|
10
198
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl-next';
|
|
3
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
4
|
+
import { createItems } from '../ToolbarInsertBlock/create-items';
|
|
5
|
+
export const useInsertMenuRailItems = (editorView, options, api) => {
|
|
6
|
+
const {
|
|
7
|
+
formatMessage
|
|
8
|
+
} = useIntl();
|
|
9
|
+
const {
|
|
10
|
+
dateState,
|
|
11
|
+
hyperlinkState,
|
|
12
|
+
imageUploadState,
|
|
13
|
+
mentionState,
|
|
14
|
+
emojiState,
|
|
15
|
+
blockTypeState,
|
|
16
|
+
mediaState,
|
|
17
|
+
typeAheadState,
|
|
18
|
+
placeholderTextState
|
|
19
|
+
} = useSharedPluginState(api, ['hyperlink', 'date', 'imageUpload', 'mention', 'emoji', 'blockType', 'media', 'typeAhead', 'placeholderText']);
|
|
20
|
+
const [_, dropdownItems] = useMemo(() => {
|
|
21
|
+
var _ref;
|
|
22
|
+
return createItems({
|
|
23
|
+
isTypeAheadAllowed: Boolean(typeAheadState === null || typeAheadState === void 0 ? void 0 : typeAheadState.isAllowed),
|
|
24
|
+
tableSupported: !!editorView.state.schema.nodes.table,
|
|
25
|
+
tableSelectorSupported: options.tableSelectorSupported && !!editorView.state.schema.nodes.table,
|
|
26
|
+
mediaUploadsEnabled: (_ref = mediaState && mediaState.allowsUploads) !== null && _ref !== void 0 ? _ref : undefined,
|
|
27
|
+
mediaSupported: !!mediaState,
|
|
28
|
+
imageUploadSupported: !!(api !== null && api !== void 0 && api.imageUpload),
|
|
29
|
+
imageUploadEnabled: imageUploadState === null || imageUploadState === void 0 ? void 0 : imageUploadState.enabled,
|
|
30
|
+
mentionsSupported: !!(mentionState && mentionState.mentionProvider),
|
|
31
|
+
mentionsDisabled: !!(mentionState && !mentionState.canInsertMention),
|
|
32
|
+
actionSupported: !!editorView.state.schema.nodes.taskItem,
|
|
33
|
+
decisionSupported: !!editorView.state.schema.nodes.decisionItem,
|
|
34
|
+
linkSupported: !!hyperlinkState,
|
|
35
|
+
linkDisabled: !hyperlinkState || !hyperlinkState.canInsertLink || !!hyperlinkState.activeLinkMark,
|
|
36
|
+
emojiDisabled: !emojiState || !emojiState.emojiProvider,
|
|
37
|
+
nativeStatusSupported: options.nativeStatusSupported,
|
|
38
|
+
dateEnabled: !!dateState,
|
|
39
|
+
placeholderTextEnabled: placeholderTextState && placeholderTextState.allowInserting,
|
|
40
|
+
horizontalRuleEnabled: options.horizontalRuleEnabled,
|
|
41
|
+
layoutSectionEnabled: Boolean(api === null || api === void 0 ? void 0 : api.layout),
|
|
42
|
+
expandEnabled: !!options.allowExpand,
|
|
43
|
+
showElementBrowserLink: options.showElementBrowserLink,
|
|
44
|
+
emojiProvider: emojiState === null || emojiState === void 0 ? void 0 : emojiState.emojiProvider,
|
|
45
|
+
availableWrapperBlockTypes: blockTypeState && blockTypeState.availableWrapperBlockTypes,
|
|
46
|
+
insertMenuItems: options.insertMenuItems,
|
|
47
|
+
schema: editorView.state.schema,
|
|
48
|
+
numberOfButtons: 10,
|
|
49
|
+
formatMessage,
|
|
50
|
+
isNewMenuEnabled: true
|
|
51
|
+
});
|
|
52
|
+
}, [api === null || api === void 0 ? void 0 : api.imageUpload, api === null || api === void 0 ? void 0 : api.layout, blockTypeState, dateState, editorView.state.schema, emojiState, formatMessage, hyperlinkState, imageUploadState === null || imageUploadState === void 0 ? void 0 : imageUploadState.enabled, mediaState, mentionState, options.allowExpand, options.horizontalRuleEnabled, options.insertMenuItems, options.nativeStatusSupported, options.showElementBrowserLink, options.tableSelectorSupported, placeholderTextState, typeAheadState === null || typeAheadState === void 0 ? void 0 : typeAheadState.isAllowed]);
|
|
53
|
+
return dropdownItems;
|
|
54
|
+
};
|
|
@@ -1,53 +1,120 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
4
|
import ActionListIcon from '../assets/action-list';
|
|
3
5
|
import ApprovalsTrackerIcon from '../assets/approvals-tracker';
|
|
4
6
|
import DecisionMatrixIcon from '../assets/decision-matrix';
|
|
5
7
|
import DiscussionNotesIcon from '../assets/discussion-notes';
|
|
6
8
|
import InstructionsOutlineIcon from '../assets/instructions-outline';
|
|
7
|
-
|
|
9
|
+
import { actionList, approvalsTracker, decisionMatrix, discussionNotes, instructionsOutline } from './templates';
|
|
10
|
+
const getTemplateInsertionPayload = (templateType, source) => ({
|
|
11
|
+
action: ACTION.INSERTED,
|
|
12
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
13
|
+
actionSubjectId: 'elementTemplate',
|
|
14
|
+
attributes: {
|
|
15
|
+
inputMethod: source !== null && source !== void 0 ? source : INPUT_METHOD.QUICK_INSERT,
|
|
16
|
+
templateType
|
|
17
|
+
},
|
|
18
|
+
eventType: EVENT_TYPE.TRACK
|
|
19
|
+
});
|
|
20
|
+
const getTableWidth = api => {
|
|
21
|
+
var _api$table, _api$table$sharedStat;
|
|
22
|
+
return api !== null && api !== void 0 && (_api$table = api.table) !== null && _api$table !== void 0 && (_api$table$sharedStat = _api$table.sharedState.currentState()) !== null && _api$table$sharedStat !== void 0 && _api$table$sharedStat.isFullWidthModeEnabled ? 1800 : 760;
|
|
23
|
+
};
|
|
24
|
+
export const templateOptions = api => [{
|
|
8
25
|
title: 'Discussion notes',
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
id: 'discussionNotes',
|
|
9
28
|
description: 'Record discussion points and action items',
|
|
10
29
|
keywords: ['decisions', 'summary', 'meeting', 'chat', 'debrief', 'track', 'keep track', 'tasks', 'outstanding items', 'owners'],
|
|
11
30
|
// Place templates right after AI item
|
|
12
31
|
priority: 99,
|
|
13
32
|
icon: () => /*#__PURE__*/React.createElement(DiscussionNotesIcon, null),
|
|
14
|
-
action: () => {
|
|
15
|
-
|
|
33
|
+
action: (insert, state, source) => {
|
|
34
|
+
var _api$analytics;
|
|
35
|
+
const tr = insert(Fragment.fromJSON(state.schema, discussionNotes(getTableWidth(api))), {
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
isTemplate: true
|
|
38
|
+
});
|
|
39
|
+
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.attachAnalyticsEvent(
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
getTemplateInsertionPayload('discussionNotes', source))(tr);
|
|
42
|
+
return tr;
|
|
16
43
|
}
|
|
17
44
|
}, {
|
|
18
45
|
title: 'Approvals tracker',
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
id: 'approvalsTracker',
|
|
19
48
|
description: 'Track reviewer approvals and dates',
|
|
20
49
|
keywords: ['reviews', 'requests', 'rejected requests', 'review dates', 'timeline', 'checklist', 'sme timeline', 'sme requests', 'sme check', 'table'],
|
|
21
50
|
priority: 99,
|
|
22
51
|
icon: () => /*#__PURE__*/React.createElement(ApprovalsTrackerIcon, null),
|
|
23
|
-
action: () => {
|
|
24
|
-
|
|
52
|
+
action: (insert, state, source) => {
|
|
53
|
+
var _api$analytics2;
|
|
54
|
+
const tr = insert(Fragment.fromJSON(state.schema, approvalsTracker(getTableWidth(api))), {
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
isTemplate: true
|
|
57
|
+
});
|
|
58
|
+
api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions.attachAnalyticsEvent(
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
getTemplateInsertionPayload('approvalsTracker', source))(tr);
|
|
61
|
+
return tr;
|
|
25
62
|
}
|
|
26
63
|
}, {
|
|
27
64
|
title: 'Decision matrix',
|
|
65
|
+
// @ts-ignore
|
|
66
|
+
id: 'decisionMatrix',
|
|
28
67
|
description: 'Compare options and make recommendations',
|
|
29
68
|
keywords: ['pros', 'cons', 'recommended', 'rationale', 'evaluation', 'options', 'choice', 'table'],
|
|
30
69
|
priority: 99,
|
|
31
70
|
icon: () => /*#__PURE__*/React.createElement(DecisionMatrixIcon, null),
|
|
32
|
-
action: () => {
|
|
33
|
-
|
|
71
|
+
action: (insert, state, source) => {
|
|
72
|
+
var _api$analytics3;
|
|
73
|
+
const tr = insert(Fragment.fromJSON(state.schema, decisionMatrix(getTableWidth(api))), {
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
isTemplate: true
|
|
76
|
+
});
|
|
77
|
+
api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions.attachAnalyticsEvent(
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
getTemplateInsertionPayload('decisionMatrix', source))(tr);
|
|
80
|
+
return tr;
|
|
34
81
|
}
|
|
35
82
|
}, {
|
|
36
83
|
title: 'List of actions',
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
id: 'actionList',
|
|
37
86
|
description: 'Track tasks, assignees and deadlines',
|
|
38
87
|
keywords: ['checklist', 'check', 'items', 'shopping list', 'jtbd', 'jobs to be done', 'due date', 'progress', 'task', 'tasks', 'prioritization', 'timeline', 'approvals', 'reviewers', 'review date'],
|
|
39
88
|
priority: 99,
|
|
40
89
|
icon: () => /*#__PURE__*/React.createElement(ActionListIcon, null),
|
|
41
|
-
action: () => {
|
|
42
|
-
|
|
90
|
+
action: (insert, state, source) => {
|
|
91
|
+
var _api$analytics4;
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
const tr = insert(Fragment.fromJSON(state.schema, actionList), {
|
|
94
|
+
isTemplate: true
|
|
95
|
+
});
|
|
96
|
+
api === null || api === void 0 ? void 0 : (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions.attachAnalyticsEvent(
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
getTemplateInsertionPayload('actionList', source))(tr);
|
|
99
|
+
return tr;
|
|
43
100
|
}
|
|
44
101
|
}, {
|
|
45
102
|
title: 'Instructions outline',
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
id: 'instructionsOutline',
|
|
46
105
|
description: 'Detailed steps for any process',
|
|
47
106
|
keywords: ['steps', 'manual', 'tasks', 'jobs to be done', 'jtbd', 'how-to', 'guide', 'journey', 'checklist', 'tutorial', 'map', 'brochure', 'columns', 'layout', 'help'],
|
|
48
107
|
priority: 99,
|
|
49
108
|
icon: () => /*#__PURE__*/React.createElement(InstructionsOutlineIcon, null),
|
|
50
|
-
action: () => {
|
|
51
|
-
|
|
109
|
+
action: (insert, state, source) => {
|
|
110
|
+
var _api$analytics5;
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
const tr = insert(Fragment.fromJSON(state.schema, instructionsOutline), {
|
|
113
|
+
isTemplate: true
|
|
114
|
+
});
|
|
115
|
+
api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions.attachAnalyticsEvent(
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
getTemplateInsertionPayload('instructionsOutline', source))(tr);
|
|
118
|
+
return tr;
|
|
52
119
|
}
|
|
53
120
|
}];
|