Expose components needed for the ai plugin new interface (#24972)
* Export thread components * Exporting AdvancedCreateComment * Expose components needed for the ai plugin new interface * Exporting the placeholder for the plugin CreatePost component, and simplify the export * Fixing linter errors * Fixing type errors * Reverting typescript related changes * Cheating typescript to keep the changes as minimal as possible * Fix linter errors
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c67391f1db
Коммит
f8e8eca985
@@ -198,6 +198,7 @@ export type Props = {
|
|||||||
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[];
|
postEditorActions: PluginComponent[];
|
||||||
|
placeholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -1311,6 +1312,7 @@ class AdvancedCreateComment extends React.PureComponent<Props, State> {
|
|||||||
fileUploadRef={this.fileUploadRef}
|
fileUploadRef={this.fileUploadRef}
|
||||||
isThreadView={this.props.isThreadView}
|
isThreadView={this.props.isThreadView}
|
||||||
additionalControls={pluginItems.filter(Boolean)}
|
additionalControls={pluginItems.filter(Boolean)}
|
||||||
|
placeholder={this.props.placeholder}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ type Props = {
|
|||||||
additionalControls?: React.ReactNodeArray;
|
additionalControls?: React.ReactNodeArray;
|
||||||
labels?: React.ReactNode;
|
labels?: React.ReactNode;
|
||||||
disableSend?: boolean;
|
disableSend?: boolean;
|
||||||
|
placeholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AdvanceTextEditor = ({
|
const AdvanceTextEditor = ({
|
||||||
@@ -156,6 +157,7 @@ const AdvanceTextEditor = ({
|
|||||||
additionalControls,
|
additionalControls,
|
||||||
labels,
|
labels,
|
||||||
disableSend = false,
|
disableSend = false,
|
||||||
|
placeholder,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const readOnlyChannel = !canPost;
|
const readOnlyChannel = !canPost;
|
||||||
const {formatMessage} = useIntl();
|
const {formatMessage} = useIntl();
|
||||||
@@ -295,7 +297,9 @@ const AdvanceTextEditor = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
let createMessage;
|
let createMessage;
|
||||||
if (currentChannel && !readOnlyChannel) {
|
if (placeholder) {
|
||||||
|
createMessage = placeholder;
|
||||||
|
} else if (currentChannel && !readOnlyChannel) {
|
||||||
createMessage = formatMessage(
|
createMessage = formatMessage(
|
||||||
{
|
{
|
||||||
id: 'create_post.write',
|
id: 'create_post.write',
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export type Props = Attrs & {
|
|||||||
highlightedPostId?: Post['id'];
|
highlightedPostId?: Post['id'];
|
||||||
selectedPostFocusedAt?: number;
|
selectedPostFocusedAt?: number;
|
||||||
isThreadView?: boolean;
|
isThreadView?: boolean;
|
||||||
|
inputPlaceholder?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -212,6 +213,7 @@ export default class ThreadViewer extends React.PureComponent<Props, State> {
|
|||||||
<FileUploadOverlay overlayType='right'/>
|
<FileUploadOverlay overlayType='right'/>
|
||||||
{this.props.selected && (
|
{this.props.selected && (
|
||||||
<DeferredThreadViewerVirt
|
<DeferredThreadViewerVirt
|
||||||
|
inputPlaceholder={this.props.inputPlaceholder}
|
||||||
key={this.props.selected.id}
|
key={this.props.selected.id}
|
||||||
channel={this.props.channel}
|
channel={this.props.channel}
|
||||||
onCardClick={this.handleCardClick}
|
onCardClick={this.handleCardClick}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ type Props = {
|
|||||||
threadId: string;
|
threadId: string;
|
||||||
latestPostId: Post['id'];
|
latestPostId: Post['id'];
|
||||||
isThreadView?: boolean;
|
isThreadView?: boolean;
|
||||||
|
placeholder?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CreateComment = forwardRef<HTMLDivElement, Props>(({
|
const CreateComment = forwardRef<HTMLDivElement, Props>(({
|
||||||
@@ -34,6 +35,7 @@ const CreateComment = forwardRef<HTMLDivElement, Props>(({
|
|||||||
threadId,
|
threadId,
|
||||||
latestPostId,
|
latestPostId,
|
||||||
isThreadView,
|
isThreadView,
|
||||||
|
placeholder,
|
||||||
}: Props, ref) => {
|
}: Props, ref) => {
|
||||||
const getChannel = useMemo(makeGetChannel, []);
|
const getChannel = useMemo(makeGetChannel, []);
|
||||||
const rootPost = useSelector((state: GlobalState) => getPost(state, threadId));
|
const rootPost = useSelector((state: GlobalState) => getPost(state, threadId));
|
||||||
@@ -95,6 +97,7 @@ const CreateComment = forwardRef<HTMLDivElement, Props>(({
|
|||||||
data-testid='comment-create'
|
data-testid='comment-create'
|
||||||
>
|
>
|
||||||
<AdvancedCreateComment
|
<AdvancedCreateComment
|
||||||
|
placeholder={placeholder}
|
||||||
focusOnMount={focusOnMount}
|
focusOnMount={focusOnMount}
|
||||||
channelId={channel.id}
|
channelId={channel.id}
|
||||||
latestPostId={latestPostId}
|
latestPostId={latestPostId}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ type Props = {
|
|||||||
isThreadView: boolean;
|
isThreadView: boolean;
|
||||||
lastViewedAt: number;
|
lastViewedAt: number;
|
||||||
newMessagesSeparatorActions: PluginComponent[];
|
newMessagesSeparatorActions: PluginComponent[];
|
||||||
|
inputPlaceholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -355,6 +356,7 @@ class ThreadViewerVirtualized extends PureComponent<Props, State> {
|
|||||||
if (isCreateComment(itemId)) {
|
if (isCreateComment(itemId)) {
|
||||||
return (
|
return (
|
||||||
<CreateComment
|
<CreateComment
|
||||||
|
placeholder={this.props.inputPlaceholder}
|
||||||
focusOnMount={!this.props.isThreadView && (this.state.userScrolledToBottom || (!this.state.userScrolled && this.getInitialPostIndex() === 0))}
|
focusOnMount={!this.props.isThreadView && (this.state.userScrolledToBottom || (!this.state.userScrolled && this.getInitialPostIndex() === 0))}
|
||||||
isThreadView={this.props.isThreadView}
|
isThreadView={this.props.isThreadView}
|
||||||
latestPostId={this.props.lastPost.id}
|
latestPostId={this.props.lastPost.id}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {openPricingModal} from 'components/global_header/right_controls/plan_upg
|
|||||||
import {useNotifyAdmin} from 'components/notify_admin_cta/notify_admin_cta';
|
import {useNotifyAdmin} from 'components/notify_admin_cta/notify_admin_cta';
|
||||||
import PurchaseModal from 'components/purchase_modal';
|
import PurchaseModal from 'components/purchase_modal';
|
||||||
import StartTrialFormModal from 'components/start_trial_form_modal';
|
import StartTrialFormModal from 'components/start_trial_form_modal';
|
||||||
|
import ThreadViewer from 'components/threading/thread_viewer';
|
||||||
import Timestamp from 'components/timestamp';
|
import Timestamp from 'components/timestamp';
|
||||||
import BotTag from 'components/widgets/tag/bot_tag';
|
import BotTag from 'components/widgets/tag/bot_tag';
|
||||||
import Avatar from 'components/widgets/users/avatar';
|
import Avatar from 'components/widgets/users/avatar';
|
||||||
@@ -24,6 +25,7 @@ import {formatText} from 'utils/text_formatting';
|
|||||||
import {useWebSocket, useWebSocketClient, WebSocketContext} from 'utils/use_websocket';
|
import {useWebSocket, useWebSocketClient, WebSocketContext} from 'utils/use_websocket';
|
||||||
import {imageURLForUser} from 'utils/utils';
|
import {imageURLForUser} from 'utils/utils';
|
||||||
|
|
||||||
|
import CreatePost from './exported_create_post';
|
||||||
import {openInteractiveDialog} from './interactive_dialog'; // This import has intentional side effects. Do not remove without research.
|
import {openInteractiveDialog} from './interactive_dialog'; // This import has intentional side effects. Do not remove without research.
|
||||||
import Textbox from './textbox';
|
import Textbox from './textbox';
|
||||||
|
|
||||||
@@ -86,6 +88,8 @@ window.Components = {
|
|||||||
imageURLForUser,
|
imageURLForUser,
|
||||||
BotBadge: BotTag,
|
BotBadge: BotTag,
|
||||||
StartTrialFormModal,
|
StartTrialFormModal,
|
||||||
|
ThreadViewer,
|
||||||
|
CreatePost,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a prototype of the Product API for use by internal plugins only while we transition to the proper architecture
|
// This is a prototype of the Product API for use by internal plugins only while we transition to the proper architecture
|
||||||
|
|||||||
35
webapp/channels/src/plugins/exported_create_post.tsx
Обычный файл
35
webapp/channels/src/plugins/exported_create_post.tsx
Обычный файл
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import AdvancedCreateComment from 'components/advanced_create_comment';
|
||||||
|
|
||||||
|
import type {PostDraft} from 'types/store/draft';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
placeholder?: string;
|
||||||
|
onSubmit: (draft: PostDraft) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ExportedCreatePost = ({placeholder, onSubmit}: Props) => {
|
||||||
|
const Component = AdvancedCreateComment as any;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Component
|
||||||
|
placeholder={placeholder}
|
||||||
|
rootDeleted={false}
|
||||||
|
channelId={undefined}
|
||||||
|
rootId={undefined}
|
||||||
|
latestPostId={undefined}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
onUpdateCommentDraft={() => null}
|
||||||
|
updateCommentDraftWithRootId={() => null}
|
||||||
|
onMoveHistoryIndexBack={() => null}
|
||||||
|
onMoveHistoryIndexForward={() => null}
|
||||||
|
onEditLatestPost={() => ({data: true})}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ExportedCreatePost;
|
||||||
Ссылка в новой задаче
Block a user