[MM-55339] Improve types for Markdown component (#25350)

Этот коммит содержится в:
M-ZubairAhmed
2023-11-09 14:17:22 +05:30
коммит произвёл GitHub
родитель ee6457c3df
Коммит cd58a5baaf
5 изменённых файлов: 134 добавлений и 180 удалений

Просмотреть файл

@@ -231,7 +231,6 @@ exports[`components/drafts/panel/panel_body should have called handleFormattedTe
} }
channelNamesMap={Object {}} channelNamesMap={Object {}}
dispatch={[Function]} dispatch={[Function]}
editedAt={0}
emojiMap={ emojiMap={
EmojiMap { EmojiMap {
"customEmojis": Map {}, "customEmojis": Map {},
@@ -240,7 +239,6 @@ exports[`components/drafts/panel/panel_body should have called handleFormattedTe
} }
enableFormatting={true} enableFormatting={true}
hasImageProxy={false} hasImageProxy={false}
imagesMetadata={Object {}}
managedResourcePaths={Array []} managedResourcePaths={Array []}
mentionKeys={Array []} mentionKeys={Array []}
message="message" message="message"
@@ -251,8 +249,6 @@ exports[`components/drafts/panel/panel_body should have called handleFormattedTe
"mentionHighlight": false, "mentionHighlight": false,
} }
} }
postId=""
proxyImages={true}
siteURL="http://localhost:8065" siteURL="http://localhost:8065"
team={ team={
Object { Object {
@@ -508,7 +504,6 @@ exports[`components/drafts/panel/panel_body should match snapshot 1`] = `
} }
channelNamesMap={Object {}} channelNamesMap={Object {}}
dispatch={[Function]} dispatch={[Function]}
editedAt={0}
emojiMap={ emojiMap={
EmojiMap { EmojiMap {
"customEmojis": Map {}, "customEmojis": Map {},
@@ -517,7 +512,6 @@ exports[`components/drafts/panel/panel_body should match snapshot 1`] = `
} }
enableFormatting={true} enableFormatting={true}
hasImageProxy={false} hasImageProxy={false}
imagesMetadata={Object {}}
managedResourcePaths={Array []} managedResourcePaths={Array []}
mentionKeys={Array []} mentionKeys={Array []}
message="message" message="message"
@@ -528,8 +522,6 @@ exports[`components/drafts/panel/panel_body should match snapshot 1`] = `
"mentionHighlight": false, "mentionHighlight": false,
} }
} }
postId=""
proxyImages={true}
siteURL="http://localhost:8065" siteURL="http://localhost:8065"
team={ team={
Object { Object {
@@ -853,7 +845,6 @@ exports[`components/drafts/panel/panel_body should match snapshot for priority 1
} }
channelNamesMap={Object {}} channelNamesMap={Object {}}
dispatch={[Function]} dispatch={[Function]}
editedAt={0}
emojiMap={ emojiMap={
EmojiMap { EmojiMap {
"customEmojis": Map {}, "customEmojis": Map {},
@@ -862,7 +853,6 @@ exports[`components/drafts/panel/panel_body should match snapshot for priority 1
} }
enableFormatting={true} enableFormatting={true}
hasImageProxy={false} hasImageProxy={false}
imagesMetadata={Object {}}
managedResourcePaths={Array []} managedResourcePaths={Array []}
mentionKeys={Array []} mentionKeys={Array []}
message="message" message="message"
@@ -873,8 +863,6 @@ exports[`components/drafts/panel/panel_body should match snapshot for priority 1
"mentionHighlight": false, "mentionHighlight": false,
} }
} }
postId=""
proxyImages={true}
siteURL="http://localhost:8065" siteURL="http://localhost:8065"
team={ team={
Object { Object {
@@ -1277,7 +1265,6 @@ exports[`components/drafts/panel/panel_body should match snapshot for requested_
} }
channelNamesMap={Object {}} channelNamesMap={Object {}}
dispatch={[Function]} dispatch={[Function]}
editedAt={0}
emojiMap={ emojiMap={
EmojiMap { EmojiMap {
"customEmojis": Map {}, "customEmojis": Map {},
@@ -1286,7 +1273,6 @@ exports[`components/drafts/panel/panel_body should match snapshot for requested_
} }
enableFormatting={true} enableFormatting={true}
hasImageProxy={false} hasImageProxy={false}
imagesMetadata={Object {}}
managedResourcePaths={Array []} managedResourcePaths={Array []}
mentionKeys={Array []} mentionKeys={Array []}
message="message" message="message"
@@ -1297,8 +1283,6 @@ exports[`components/drafts/panel/panel_body should match snapshot for requested_
"mentionHighlight": false, "mentionHighlight": false,
} }
} }
postId=""
proxyImages={true}
siteURL="http://localhost:8065" siteURL="http://localhost:8065"
team={ team={
Object { Object {

Просмотреть файл

@@ -1,30 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/Markdown should not render markdown when formatting is disabled 1`] = ` exports[`components/Markdown should not render markdown when formatting is disabled 1`] = `
<span> <div>
This _is_ some **Markdown** <p>
<Connect(PostEditedIndicator)
editedAt={0}
postId=""
/>
</span>
`;
exports[`components/Markdown should render properly 1`] = `
<p
key="0"
>
This This
<em <em>
key="1"
>
is is
</em> </em>
some some
<strong <strong>
key="3"
>
Markdown Markdown
</strong> </strong>
</p> </p>
</div>
`;
exports[`components/Markdown should render properly 1`] = `
<div>
<p>
This
<em>
is
</em>
some
<strong>
Markdown
</strong>
</p>
</div>
`; `;

Просмотреть файл

@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import {connect} from 'react-redux'; import {connect, type ConnectedProps} from 'react-redux';
import {Preferences} from 'mattermost-redux/constants'; import {Preferences} from 'mattermost-redux/constants';
import {createSelector} from 'mattermost-redux/selectors/create_selector'; import {createSelector} from 'mattermost-redux/selectors/create_selector';
@@ -14,24 +14,17 @@ import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
import {getEmojiMap} from 'selectors/emojis'; import {getEmojiMap} from 'selectors/emojis';
import type {ChannelNamesMap, MentionKey} from 'utils/text_formatting';
import {getSiteURL} from 'utils/url'; import {getSiteURL} from 'utils/url';
import type {GlobalState} from 'types/store'; import type {GlobalState} from 'types/store';
import Markdown from './markdown'; import Markdown, {type OwnProps} from './markdown';
type Props = {
channelNamesMap?: ChannelNamesMap;
mentionKeys?: MentionKey[];
postId?: string;
}
function makeGetChannelNamesMap() { function makeGetChannelNamesMap() {
return createSelector( return createSelector(
'makeGetChannelNamesMap', 'makeGetChannelNamesMap',
getChannelNameToDisplayNameMap, getChannelNameToDisplayNameMap,
(state: GlobalState, props: Props) => props && props.channelNamesMap, (state: GlobalState, props: OwnProps) => props && props.channelNamesMap,
(channelNamesMap, channelMentions) => { (channelNamesMap, channelMentions) => {
if (channelMentions) { if (channelMentions) {
return Object.assign({}, channelMentions, channelNamesMap); return Object.assign({}, channelMentions, channelNamesMap);
@@ -45,7 +38,7 @@ function makeGetChannelNamesMap() {
function makeMapStateToProps() { function makeMapStateToProps() {
const getChannelNamesMap = makeGetChannelNamesMap(); const getChannelNamesMap = makeGetChannelNamesMap();
return function mapStateToProps(state: GlobalState, ownProps: Props) { return function mapStateToProps(state: GlobalState, ownProps: OwnProps) {
const config = getConfig(state); const config = getConfig(state);
let channelId; let channelId;
@@ -69,4 +62,7 @@ function makeMapStateToProps() {
}; };
} }
export default connect(makeMapStateToProps)(Markdown); const connector = connect(makeMapStateToProps);
export type PropsFromRedux = ConnectedProps<typeof connector>;
export default connector(Markdown);

Просмотреть файл

@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import {shallow} from 'enzyme';
import React from 'react'; import React from 'react';
import type {TeamType} from '@mattermost/types/teams'; import type {TeamType} from '@mattermost/types/teams';
import Markdown from 'components/markdown/markdown'; import Markdown from 'components/markdown';
import {renderWithContext} from 'tests/react_testing_utils';
import EmojiMap from 'utils/emoji_map'; import EmojiMap from 'utils/emoji_map';
import {TestHelper} from 'utils/test_helper'; import {TestHelper} from 'utils/test_helper';
@@ -42,10 +42,8 @@ describe('components/Markdown', () => {
}; };
test('should render properly', () => { test('should render properly', () => {
const wrapper = shallow( const {container} = renderWithContext(<Markdown {...baseProps}/>);
<Markdown {...baseProps}/>, expect(container).toMatchSnapshot();
);
expect(wrapper).toMatchSnapshot();
}); });
test('should not render markdown when formatting is disabled', () => { test('should not render markdown when formatting is disabled', () => {
@@ -54,9 +52,7 @@ describe('components/Markdown', () => {
enableFormatting: false, enableFormatting: false,
}; };
const wrapper = shallow( const {container} = renderWithContext(<Markdown {...props}/>);
<Markdown {...props}/>, expect(container).toMatchSnapshot();
);
expect(wrapper).toMatchSnapshot();
}); });
}); });

Просмотреть файл

@@ -4,93 +4,35 @@
import React from 'react'; import React from 'react';
import type {PostImage, PostType} from '@mattermost/types/posts'; import type {PostImage, PostType} from '@mattermost/types/posts';
import type {Team} from '@mattermost/types/teams';
import PostEditedIndicator from 'components/post_view/post_edited_indicator'; import PostEditedIndicator from 'components/post_view/post_edited_indicator';
import type EmojiMap from 'utils/emoji_map'; import type EmojiMap from 'utils/emoji_map';
import messageHtmlToComponent from 'utils/message_html_to_component'; import messageHtmlToComponent from 'utils/message_html_to_component';
import type {ChannelNamesMap, MentionKey, TextFormattingOptions} from 'utils/text_formatting';
import {formatText} from 'utils/text_formatting'; import {formatText} from 'utils/text_formatting';
import type {ChannelNamesMap, TextFormattingOptions, MentionKey} from 'utils/text_formatting';
type Props = { import type {PropsFromRedux} from './index';
/* export type Props = PropsFromRedux & OwnProps;
* An object mapping channel names to channels for the current team
*/
channelNamesMap?: ChannelNamesMap;
/* export type OwnProps = {
* An array of URL schemes that should be turned into links. Anything that looks
* like a link will be turned into a link if this is not provided.
*/
autolinkedUrlSchemes?: string[];
/* /**
* Whether or not to do Markdown rendering
*/
enableFormatting?: boolean;
/*
* An array of paths on the server that are managed by another server
*/
managedResourcePaths?: string[];
/*
* An array of words that can be used to mention a user
*/
mentionKeys?: MentionKey[];
/*
* The text to be rendered
*/
message: string;
/*
* Any additional text formatting options to be used * Any additional text formatting options to be used
*/ */
options: Partial<TextFormattingOptions>; options?: Partial<TextFormattingOptions>;
/*
* The root Site URL for the page
*/
siteURL?: string;
/*
* The current team
*/
team?: Team;
/**
* If an image proxy is enabled.
*/
hasImageProxy?: boolean;
/**
* Minimum number of characters in a hashtag.
*/
minimumHashtagLength?: number;
/** /**
* Whether or not to proxy image URLs * Whether or not to proxy image URLs
*/ */
proxyImages?: boolean; proxyImages?: boolean;
/**
* Any extra props that should be passed into the image component
*/
imageProps?: object;
/** /**
* prop for passed down to image component for dimensions * prop for passed down to image component for dimensions
*/ */
imagesMetadata?: Record<string, PostImage>; imagesMetadata?: Record<string, PostImage>;
/**
* Whether or not to place the LinkTooltip component inside links
*/
hasPluginTooltips?: boolean;
/** /**
* Post id prop passed down to markdown image * Post id prop passed down to markdown image
*/ */
@@ -101,13 +43,34 @@ type Props = {
*/ */
editedAt?: number; editedAt?: number;
/*
* The text to be rendered
*/
message?: string;
channelNamesMap?: ChannelNamesMap;
/*
* An array of words that can be used to mention a user
*/
mentionKeys?: MentionKey[];
/**
* Any extra props that should be passed into the image component
*/
imageProps?: object;
/**
* Whether or not to place the LinkTooltip component inside links
*/
hasPluginTooltips?: boolean;
channelId?: string; channelId?: string;
/** /**
* Post id prop passed down to markdown image * Post id prop passed down to markdown image
*/ */
postType?: PostType; postType?: PostType;
emojiMap: EmojiMap; emojiMap?: EmojiMap;
/** /**
* Some components processed by messageHtmlToComponent e.g. AtSumOfMembersMention require to have a list of userIds * Some components processed by messageHtmlToComponent e.g. AtSumOfMembersMention require to have a list of userIds
@@ -120,17 +83,30 @@ type Props = {
messageMetadata?: Record<string, string>; messageMetadata?: Record<string, string>;
} }
export default class Markdown extends React.PureComponent<Props> { function Markdown({
static defaultProps: Partial<Props> = { options = {},
options: {}, proxyImages = true,
proxyImages: true, imagesMetadata = {},
imagesMetadata: {}, postId = '', // Needed to avoid proptypes console errors for cases like channel header, which doesn't have a proper value
postId: '', // Needed to avoid proptypes console errors for cases like channel header, which doesn't have a proper value editedAt = 0,
editedAt: 0, message = '',
}; channelNamesMap,
mentionKeys,
render() { imageProps,
const {postId, editedAt, message, enableFormatting} = this.props; channelId,
hasPluginTooltips,
postType,
emojiMap,
userIds,
messageMetadata,
enableFormatting,
autolinkedUrlSchemes,
siteURL,
hasImageProxy,
team,
minimumHashtagLength,
managedResourcePaths,
}: Props) {
if (message === '' || !enableFormatting) { if (message === '' || !enableFormatting) {
return ( return (
<span> <span>
@@ -143,36 +119,37 @@ export default class Markdown extends React.PureComponent<Props> {
); );
} }
const options = Object.assign({ const inputOptions = Object.assign({
autolinkedUrlSchemes: this.props.autolinkedUrlSchemes, autolinkedUrlSchemes,
siteURL: this.props.siteURL, siteURL,
mentionKeys: this.props.mentionKeys, mentionKeys,
atMentions: true, atMentions: true,
channelNamesMap: this.props.channelNamesMap, channelNamesMap,
proxyImages: this.props.hasImageProxy && this.props.proxyImages, proxyImages: hasImageProxy && proxyImages,
team: this.props.team, team,
minimumHashtagLength: this.props.minimumHashtagLength, minimumHashtagLength,
managedResourcePaths: this.props.managedResourcePaths, managedResourcePaths,
editedAt, editedAt,
postId, postId,
}, this.props.options); }, options);
const htmlFormattedText = formatText(message, options, this.props.emojiMap); const htmlFormattedText = formatText(message, inputOptions, emojiMap);
return messageHtmlToComponent(htmlFormattedText, { return messageHtmlToComponent(htmlFormattedText, {
imageProps: this.props.imageProps, imageProps,
imagesMetadata: this.props.imagesMetadata, imagesMetadata,
hasPluginTooltips: this.props.hasPluginTooltips, hasPluginTooltips,
postId: this.props.postId, postId,
userIds: this.props.userIds, userIds,
messageMetadata: this.props.messageMetadata, messageMetadata,
channelId: this.props.channelId, channelId,
postType: this.props.postType, postType,
mentionHighlight: this.props.options.mentionHighlight, mentionHighlight: options?.mentionHighlight,
disableGroupHighlight: this.props.options.disableGroupHighlight, disableGroupHighlight: options?.disableGroupHighlight,
editedAt, editedAt,
atSumOfMembersMentions: this.props.options.atSumOfMembersMentions, atSumOfMembersMentions: options?.atSumOfMembersMentions,
atPlanMentions: this.props.options.atPlanMentions, atPlanMentions: options?.atPlanMentions,
}); });
}
} }
export default Markdown;