mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Adding PostAction plugin hook (#24102)
* Adding PostAction plugin hook * Adding missing doc string * WIP * Simplifying it * Adding support for selected text * fixing linter errors * Adding support for the plugin editor action in the thread view * Fixing ci check-types * Addressing PR review comments * Fix linter error in CI * Fixing tests
This commit is contained in:
parent
60fb112a27
commit
e1c6ae7d85
@ -5,6 +5,7 @@ exports[`components/AdvancedCreateComment should match snapshot when cannot post
|
|||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
>
|
>
|
||||||
<AdvanceTextEditor
|
<AdvanceTextEditor
|
||||||
|
additionalControls={Array []}
|
||||||
applyMarkdown={[Function]}
|
applyMarkdown={[Function]}
|
||||||
badConnection={false}
|
badConnection={false}
|
||||||
canPost={false}
|
canPost={false}
|
||||||
@ -77,6 +78,7 @@ exports[`components/AdvancedCreateComment should match snapshot, comment with me
|
|||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
>
|
>
|
||||||
<AdvanceTextEditor
|
<AdvanceTextEditor
|
||||||
|
additionalControls={Array []}
|
||||||
applyMarkdown={[Function]}
|
applyMarkdown={[Function]}
|
||||||
badConnection={false}
|
badConnection={false}
|
||||||
canPost={true}
|
canPost={true}
|
||||||
@ -144,6 +146,7 @@ exports[`components/AdvancedCreateComment should match snapshot, emoji picker di
|
|||||||
>
|
>
|
||||||
<FileLimitStickyBanner />
|
<FileLimitStickyBanner />
|
||||||
<AdvanceTextEditor
|
<AdvanceTextEditor
|
||||||
|
additionalControls={Array []}
|
||||||
applyMarkdown={[Function]}
|
applyMarkdown={[Function]}
|
||||||
badConnection={false}
|
badConnection={false}
|
||||||
canPost={true}
|
canPost={true}
|
||||||
@ -216,6 +219,7 @@ exports[`components/AdvancedCreateComment should match snapshot, empty comment 1
|
|||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
>
|
>
|
||||||
<AdvanceTextEditor
|
<AdvanceTextEditor
|
||||||
|
additionalControls={Array []}
|
||||||
applyMarkdown={[Function]}
|
applyMarkdown={[Function]}
|
||||||
badConnection={false}
|
badConnection={false}
|
||||||
canPost={true}
|
canPost={true}
|
||||||
@ -283,6 +287,7 @@ exports[`components/AdvancedCreateComment should match snapshot, non-empty messa
|
|||||||
>
|
>
|
||||||
<FileLimitStickyBanner />
|
<FileLimitStickyBanner />
|
||||||
<AdvanceTextEditor
|
<AdvanceTextEditor
|
||||||
|
additionalControls={Array []}
|
||||||
applyMarkdown={[Function]}
|
applyMarkdown={[Function]}
|
||||||
badConnection={false}
|
badConnection={false}
|
||||||
canPost={true}
|
canPost={true}
|
||||||
|
@ -80,6 +80,7 @@ describe('components/AdvancedCreateComment', () => {
|
|||||||
useLDAPGroupMentions: true,
|
useLDAPGroupMentions: true,
|
||||||
useCustomGroupMentions: true,
|
useCustomGroupMentions: true,
|
||||||
openModal: jest.fn(),
|
openModal: jest.fn(),
|
||||||
|
postEditorActions: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const emptyDraft = {
|
const emptyDraft = {
|
||||||
|
@ -19,6 +19,7 @@ import {sortFileInfos} from 'mattermost-redux/utils/file_utils';
|
|||||||
import * as GlobalActions from 'actions/global_actions';
|
import * as GlobalActions from 'actions/global_actions';
|
||||||
|
|
||||||
import {PostDraft} from 'types/store/draft';
|
import {PostDraft} from 'types/store/draft';
|
||||||
|
import {PluginComponent} from 'types/store/plugins';
|
||||||
import {ModalData} from 'types/actions';
|
import {ModalData} from 'types/actions';
|
||||||
|
|
||||||
import Constants, {AdvancedTextEditor as AdvancedTextEditorConst, Locations, ModalIdentifiers, Preferences} from 'utils/constants';
|
import Constants, {AdvancedTextEditor as AdvancedTextEditorConst, Locations, ModalIdentifiers, Preferences} from 'utils/constants';
|
||||||
@ -193,6 +194,7 @@ type Props = {
|
|||||||
useCustomGroupMentions: boolean;
|
useCustomGroupMentions: boolean;
|
||||||
isFormattingBarHidden: boolean;
|
isFormattingBarHidden: boolean;
|
||||||
searchAssociatedGroupsForReference: (prefix: string, teamId: string, channelId: string | undefined) => Promise<{ data: any }>;
|
searchAssociatedGroupsForReference: (prefix: string, teamId: string, channelId: string | undefined) => Promise<{ data: any }>;
|
||||||
|
postEditorActions: PluginComponent[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@ -1198,6 +1200,41 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const draft = this.state.draft!;
|
const draft = this.state.draft!;
|
||||||
|
|
||||||
|
const pluginItems = this.props.postEditorActions?.
|
||||||
|
map((item) => {
|
||||||
|
if (!item.component) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Component = item.component as any;
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
key={item.id}
|
||||||
|
draft={draft}
|
||||||
|
getSelectedText={() => {
|
||||||
|
const input = this.textboxRef.current?.getInputBox();
|
||||||
|
|
||||||
|
return {
|
||||||
|
start: input.selectionStart,
|
||||||
|
end: input.selectionEnd,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
updateText={(message: string) => {
|
||||||
|
const draft = this.state.draft!;
|
||||||
|
const modifiedDraft = {
|
||||||
|
...draft,
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
this.handleDraftChange(modifiedDraft);
|
||||||
|
this.setState({
|
||||||
|
draft: modifiedDraft,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={this.handleSubmit}>
|
<form onSubmit={this.handleSubmit}>
|
||||||
{
|
{
|
||||||
@ -1251,6 +1288,7 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
|||||||
getFileUploadTarget={this.getFileUploadTarget}
|
getFileUploadTarget={this.getFileUploadTarget}
|
||||||
fileUploadRef={this.fileUploadRef}
|
fileUploadRef={this.fileUploadRef}
|
||||||
isThreadView={this.props.isThreadView}
|
isThreadView={this.props.isThreadView}
|
||||||
|
additionalControls={pluginItems.filter(Boolean)}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
@ -87,6 +87,7 @@ function makeMapStateToProps() {
|
|||||||
const groupsWithAllowReference = useLDAPGroupMentions || useCustomGroupMentions ? getAssociatedGroupsForReferenceByMention(state, channel.team_id, channel.id) : null;
|
const groupsWithAllowReference = useLDAPGroupMentions || useCustomGroupMentions ? getAssociatedGroupsForReferenceByMention(state, channel.team_id, channel.id) : null;
|
||||||
const isFormattingBarHidden = getBool(state, Constants.Preferences.ADVANCED_TEXT_EDITOR, AdvancedTextEditor.COMMENT);
|
const isFormattingBarHidden = getBool(state, Constants.Preferences.ADVANCED_TEXT_EDITOR, AdvancedTextEditor.COMMENT);
|
||||||
const currentTeamId = getCurrentTeamId(state);
|
const currentTeamId = getCurrentTeamId(state);
|
||||||
|
const postEditorActions = state.plugins.components.PostEditorAction;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentTeamId,
|
currentTeamId,
|
||||||
@ -116,6 +117,7 @@ function makeMapStateToProps() {
|
|||||||
channelMemberCountsByGroup,
|
channelMemberCountsByGroup,
|
||||||
useCustomGroupMentions,
|
useCustomGroupMentions,
|
||||||
canUploadFiles: canUploadFiles(config),
|
canUploadFiles: canUploadFiles(config),
|
||||||
|
postEditorActions,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import {CommandArgs} from '@mattermost/types/integrations';
|
|||||||
import {Group, GroupSource} from '@mattermost/types/groups';
|
import {Group, GroupSource} from '@mattermost/types/groups';
|
||||||
import {FileInfo} from '@mattermost/types/files';
|
import {FileInfo} from '@mattermost/types/files';
|
||||||
import {Emoji} from '@mattermost/types/emojis';
|
import {Emoji} from '@mattermost/types/emojis';
|
||||||
|
import {PluginComponent} from 'types/store/plugins';
|
||||||
|
|
||||||
import * as GlobalActions from 'actions/global_actions';
|
import * as GlobalActions from 'actions/global_actions';
|
||||||
import Constants, {
|
import Constants, {
|
||||||
@ -234,6 +235,7 @@ type Props = {
|
|||||||
channelMemberCountsByGroup: ChannelMemberCountsByGroup;
|
channelMemberCountsByGroup: ChannelMemberCountsByGroup;
|
||||||
useLDAPGroupMentions: boolean;
|
useLDAPGroupMentions: boolean;
|
||||||
useCustomGroupMentions: boolean;
|
useCustomGroupMentions: boolean;
|
||||||
|
postEditorActions: PluginComponent[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@ -1398,7 +1400,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
this.setState({showEmojiPicker: false});
|
this.setState({showEmojiPicker: false});
|
||||||
};
|
};
|
||||||
|
|
||||||
setMessageAndCaretPostion = (newMessage: string, newCaretPosition: number) => {
|
setMessageAndCaretPosition = (newMessage: string, newCaretPosition: number) => {
|
||||||
const textbox = this.textboxRef.current?.getInputBox();
|
const textbox = this.textboxRef.current?.getInputBox();
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -1417,7 +1419,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
prefillMessage = (message: string, shouldFocus?: boolean) => {
|
prefillMessage = (message: string, shouldFocus?: boolean) => {
|
||||||
this.setMessageAndCaretPostion(message, message.length);
|
this.setMessageAndCaretPosition(message, message.length);
|
||||||
|
|
||||||
if (shouldFocus) {
|
if (shouldFocus) {
|
||||||
const inputBox = this.textboxRef.current?.getInputBox();
|
const inputBox = this.textboxRef.current?.getInputBox();
|
||||||
@ -1439,7 +1441,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
if (this.state.message === '') {
|
if (this.state.message === '') {
|
||||||
const newMessage = ':' + emojiAlias + ': ';
|
const newMessage = ':' + emojiAlias + ': ';
|
||||||
this.setMessageAndCaretPostion(newMessage, newMessage.length);
|
this.setMessageAndCaretPosition(newMessage, newMessage.length);
|
||||||
} else {
|
} else {
|
||||||
const {message} = this.state;
|
const {message} = this.state;
|
||||||
const {firstPiece, lastPiece} = splitMessageBasedOnCaretPosition(this.state.caretPosition, message);
|
const {firstPiece, lastPiece} = splitMessageBasedOnCaretPosition(this.state.caretPosition, message);
|
||||||
@ -1450,7 +1452,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
const newCaretPosition =
|
const newCaretPosition =
|
||||||
firstPiece === '' ? `:${emojiAlias}: `.length : `${firstPiece} :${emojiAlias}: `.length;
|
firstPiece === '' ? `:${emojiAlias}: `.length : `${firstPiece} :${emojiAlias}: `.length;
|
||||||
this.setMessageAndCaretPostion(newMessage, newCaretPosition);
|
this.setMessageAndCaretPosition(newMessage, newCaretPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleEmojiClose();
|
this.handleEmojiClose();
|
||||||
@ -1560,6 +1562,38 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
render() {
|
render() {
|
||||||
const {draft, canPost} = this.props;
|
const {draft, canPost} = this.props;
|
||||||
|
|
||||||
|
const pluginItems = this.props.postEditorActions?.
|
||||||
|
map((item) => {
|
||||||
|
if (!item.component) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Component = item.component as any;
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
key={item.id}
|
||||||
|
draft={draft}
|
||||||
|
getSelectedText={() => {
|
||||||
|
const input = this.textboxRef.current?.getInputBox();
|
||||||
|
|
||||||
|
return {
|
||||||
|
start: input.selectionStart,
|
||||||
|
end: input.selectionEnd,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
updateText={(message: string) => {
|
||||||
|
this.setState({
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
this.handleDraftChange({
|
||||||
|
...this.props.draft,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
let centerClass = '';
|
let centerClass = '';
|
||||||
if (!this.props.fullWidthTextBox) {
|
if (!this.props.fullWidthTextBox) {
|
||||||
centerClass = 'center';
|
centerClass = 'center';
|
||||||
@ -1649,6 +1683,7 @@ class AdvancedCreatePost extends React.PureComponent<Props, State> {
|
|||||||
disabled={this.props.shouldShowPreview}
|
disabled={this.props.shouldShowPreview}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
...(pluginItems || []),
|
||||||
].filter(Boolean)}
|
].filter(Boolean)}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
@ -104,6 +104,7 @@ function makeMapStateToProps() {
|
|||||||
const tourStep = isGuestUser ? OnboardingTourStepsForGuestUsers.SEND_MESSAGE : OnboardingTourSteps.SEND_MESSAGE;
|
const tourStep = isGuestUser ? OnboardingTourStepsForGuestUsers.SEND_MESSAGE : OnboardingTourSteps.SEND_MESSAGE;
|
||||||
const showSendTutorialTip = enableTutorial && tutorialStep === tourStep;
|
const showSendTutorialTip = enableTutorial && tutorialStep === tourStep;
|
||||||
const isFormattingBarHidden = getBool(state, Preferences.ADVANCED_TEXT_EDITOR, AdvancedTextEditor.POST);
|
const isFormattingBarHidden = getBool(state, Preferences.ADVANCED_TEXT_EDITOR, AdvancedTextEditor.POST);
|
||||||
|
const postEditorActions = state.plugins.components.PostEditorAction;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentTeamId,
|
currentTeamId,
|
||||||
@ -143,6 +144,7 @@ function makeMapStateToProps() {
|
|||||||
isLDAPEnabled,
|
isLDAPEnabled,
|
||||||
useCustomGroupMentions,
|
useCustomGroupMentions,
|
||||||
isPostPriorityEnabled: isPostPriorityEnabled(state),
|
isPostPriorityEnabled: isPostPriorityEnabled(state),
|
||||||
|
postEditorActions,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,6 @@ function makeMapStateToProps() {
|
|||||||
postEditTimeLimit: config.PostEditTimeLimit,
|
postEditTimeLimit: config.PostEditTimeLimit,
|
||||||
isLicensed: license.IsLicensed === 'true',
|
isLicensed: license.IsLicensed === 'true',
|
||||||
teamId: getCurrentTeamId(state),
|
teamId: getCurrentTeamId(state),
|
||||||
pluginMenuItems: state.plugins.components.PostDropdownMenu,
|
|
||||||
canEdit: PostUtils.canEditPost(state, post, license, config, channel, userId),
|
canEdit: PostUtils.canEditPost(state, post, license, config, channel, userId),
|
||||||
canDelete: PostUtils.canDeletePost(state, post, channel),
|
canDelete: PostUtils.canDeletePost(state, post, channel),
|
||||||
teamUrl,
|
teamUrl,
|
||||||
|
@ -213,6 +213,7 @@ function makeMapStateToProps() {
|
|||||||
isCardOpen: selectedCard && selectedCard.id === post.id,
|
isCardOpen: selectedCard && selectedCard.id === post.id,
|
||||||
shouldShowDotMenu: shouldShowDotMenu(state, post, channel),
|
shouldShowDotMenu: shouldShowDotMenu(state, post, channel),
|
||||||
canDelete: canDeletePost(state, post, channel),
|
canDelete: canDeletePost(state, post, channel),
|
||||||
|
pluginActions: state.plugins.components.PostAction,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ describe('PostComponent', () => {
|
|||||||
recentEmojis: [],
|
recentEmojis: [],
|
||||||
replyCount: 0,
|
replyCount: 0,
|
||||||
team: currentTeam,
|
team: currentTeam,
|
||||||
|
pluginActions: [],
|
||||||
actions: {
|
actions: {
|
||||||
markPostAsUnread: jest.fn(),
|
markPostAsUnread: jest.fn(),
|
||||||
emitShortcutReactToLastPostFrom: jest.fn(),
|
emitShortcutReactToLastPostFrom: jest.fn(),
|
||||||
|
@ -14,7 +14,7 @@ import Constants, {A11yCustomEventTypes, A11yFocusEventDetail, AppEvents, Locati
|
|||||||
|
|
||||||
import * as PostUtils from 'utils/post_utils';
|
import * as PostUtils from 'utils/post_utils';
|
||||||
|
|
||||||
import {PostPluginComponent} from 'types/store/plugins';
|
import {PostPluginComponent, PluginComponent} from 'types/store/plugins';
|
||||||
|
|
||||||
import FileAttachmentListContainer from 'components/file_attachment_list';
|
import FileAttachmentListContainer from 'components/file_attachment_list';
|
||||||
import DateSeparator from 'components/post_view/date_separator';
|
import DateSeparator from 'components/post_view/date_separator';
|
||||||
@ -118,6 +118,7 @@ export type Props = {
|
|||||||
isPostPriorityEnabled: boolean;
|
isPostPriorityEnabled: boolean;
|
||||||
isCardOpen?: boolean;
|
isCardOpen?: boolean;
|
||||||
canDelete?: boolean;
|
canDelete?: boolean;
|
||||||
|
pluginActions: PluginComponent[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const PostComponent = (props: Props): JSX.Element => {
|
const PostComponent = (props: Props): JSX.Element => {
|
||||||
|
@ -16,6 +16,7 @@ import PostFlagIcon from 'components/post_view/post_flag_icon';
|
|||||||
import PostRecentReactions from 'components/post_view/post_recent_reactions';
|
import PostRecentReactions from 'components/post_view/post_recent_reactions';
|
||||||
import PostReaction from 'components/post_view/post_reaction';
|
import PostReaction from 'components/post_view/post_reaction';
|
||||||
import CommentIcon from 'components/common/comment_icon';
|
import CommentIcon from 'components/common/comment_icon';
|
||||||
|
import {PluginComponent} from 'types/store/plugins';
|
||||||
|
|
||||||
import {Emoji} from '@mattermost/types/emojis';
|
import {Emoji} from '@mattermost/types/emojis';
|
||||||
import {Post} from '@mattermost/types/posts';
|
import {Post} from '@mattermost/types/posts';
|
||||||
@ -49,6 +50,7 @@ type Props = {
|
|||||||
isPostHeaderVisible?: boolean | null;
|
isPostHeaderVisible?: boolean | null;
|
||||||
isPostBeingEdited?: boolean;
|
isPostBeingEdited?: boolean;
|
||||||
canDelete?: boolean;
|
canDelete?: boolean;
|
||||||
|
pluginActions: PluginComponent[];
|
||||||
actions: {
|
actions: {
|
||||||
emitShortcutReactToLastPostFrom: (emittedFrom: 'CENTER' | 'RHS_ROOT' | 'NO_WHERE') => void;
|
emitShortcutReactToLastPostFrom: (emittedFrom: 'CENTER' | 'RHS_ROOT' | 'NO_WHERE') => void;
|
||||||
};
|
};
|
||||||
@ -175,6 +177,24 @@ const PostOptions = (props: Props): JSX.Element => {
|
|||||||
isMenuOpen={showActionsMenu}
|
isMenuOpen={showActionsMenu}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let pluginItems: ReactNode = null;
|
||||||
|
if ((!isEphemeral && !post.failed && !systemMessage) && hoverLocal) {
|
||||||
|
pluginItems = props.pluginActions?.
|
||||||
|
map((item) => {
|
||||||
|
if (item.component) {
|
||||||
|
const Component = item.component as any;
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
post={props.post}
|
||||||
|
key={item.id}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}) || [];
|
||||||
|
}
|
||||||
|
|
||||||
const dotMenu = (
|
const dotMenu = (
|
||||||
<DotMenu
|
<DotMenu
|
||||||
post={props.post}
|
post={props.post}
|
||||||
@ -243,6 +263,7 @@ const PostOptions = (props: Props): JSX.Element => {
|
|||||||
{showRecentReactions}
|
{showRecentReactions}
|
||||||
{postReaction}
|
{postReaction}
|
||||||
{flagIcon}
|
{flagIcon}
|
||||||
|
{pluginItems}
|
||||||
{actionsMenu}
|
{actionsMenu}
|
||||||
{commentIcon}
|
{commentIcon}
|
||||||
{(collapsedThreadsEnabled || showRecentlyUsedReactions) && dotMenu}
|
{(collapsedThreadsEnabled || showRecentlyUsedReactions) && dotMenu}
|
||||||
|
@ -496,6 +496,18 @@ export default class PluginRegistry {
|
|||||||
return id;
|
return id;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Register a component to the add to the post message menu shown on hover.
|
||||||
|
// Accepts a React component. Returns a unique identifier.
|
||||||
|
registerPostActionComponent = reArg(['component'], ({component}: DPluginComponentProp) => {
|
||||||
|
return dispatchPluginComponentAction('PostAction', this.id, component);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register a component to the add to the post text editor menu.
|
||||||
|
// Accepts a React component. Returns a unique identifier.
|
||||||
|
registerPostEditorActionComponent = reArg(['component'], ({component}: DPluginComponentProp) => {
|
||||||
|
return dispatchPluginComponentAction('PostEditorAction', this.id, component);
|
||||||
|
});
|
||||||
|
|
||||||
// Register a post menu list item by providing some text and an action function.
|
// Register a post menu list item by providing some text and an action function.
|
||||||
// Accepts the following:
|
// Accepts the following:
|
||||||
// - text - A string or React element to display in the menu
|
// - text - A string or React element to display in the menu
|
||||||
|
@ -181,6 +181,8 @@ const initialComponents: PluginsState['components'] = {
|
|||||||
ChannelHeaderButton: [],
|
ChannelHeaderButton: [],
|
||||||
MobileChannelHeaderButton: [],
|
MobileChannelHeaderButton: [],
|
||||||
PostDropdownMenu: [],
|
PostDropdownMenu: [],
|
||||||
|
PostAction: [],
|
||||||
|
PostEditorAction: [],
|
||||||
Product: [],
|
Product: [],
|
||||||
RightHandSidebarComponent: [],
|
RightHandSidebarComponent: [],
|
||||||
UserGuideDropdownItem: [],
|
UserGuideDropdownItem: [],
|
||||||
|
@ -27,6 +27,8 @@ export type PluginsState = {
|
|||||||
Product: ProductComponent[];
|
Product: ProductComponent[];
|
||||||
CallButton: PluginComponent[];
|
CallButton: PluginComponent[];
|
||||||
PostDropdownMenu: PluginComponent[];
|
PostDropdownMenu: PluginComponent[];
|
||||||
|
PostAction: PluginComponent[];
|
||||||
|
PostEditorAction: PluginComponent[];
|
||||||
FilePreview: PluginComponent[];
|
FilePreview: PluginComponent[];
|
||||||
MainMenu: PluginComponent[];
|
MainMenu: PluginComponent[];
|
||||||
LinkTooltip: PluginComponent[];
|
LinkTooltip: PluginComponent[];
|
||||||
|
Loading…
Reference in New Issue
Block a user