mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-21 23:48:47 +00:00
This commit is contained in:
parent
bd4071bd64
commit
a1e2b27f39
@ -10,7 +10,7 @@
|
||||
"updatedAt": 1647046363996,
|
||||
"updatedBy": "anonymous",
|
||||
"resolved": false,
|
||||
"message": "Added **tags**: `Tier.Tier2`",
|
||||
"message": "Updated **columns** : <span class=\"diff-added\">account_category_code, </span>account_type_code, account_type_desc, <span class=\"diff-removed\">account_category_code</span><span class=\"diff-added\">account_type_desc_eng</span>, <span class=\"diff-removed\">eca_ind</span><span class=\"diff-added\">ban_type_desc</span>, <span class=\"diff-removed\">bill_production_ind</span><span class=\"diff-added\">ban_type_key</span>, <span class=\"diff-removed\">collection_waive_ind</span><span class=\"diff-added\">bill_production_ind</span>, <span class=\"diff-removed\">vip_status</span><span class=\"diff-added\">business_type</span>, <span class=\"diff-removed\">ban_type_desc</span><span class=\"diff-added\">check_in_crm</span>, <span class=\"diff-removed\">non_commercial_ind</span><span class=\"diff-added\">collection_waive_ind</span>, <span class=\"diff-removed\">legacy_account_category, </span>corporate_category, <span class=\"diff-removed\">ban_type_key</span><span class=\"diff-added\">currency_key</span>, <span class=\"diff-removed\">segment_key</span><span class=\"diff-added\">eca_ind</span>, <span class=\"diff-removed\">check_in_crm</span><span class=\"diff-added\">legacy_account_category</span>, <span class=\"diff-removed\">currency_key</span><span class=\"diff-added\">legal_person_ind</span>, <span class=\"diff-removed\">legal_person_ind</span><span class=\"diff-added\">non_commercial_ind</span>, <span class=\"diff-removed\">account_type_desc_eng</span><span class=\"diff-added\">segment_key</span>, <span class=\"diff-removed\">business_type</span><span class=\"diff-added\">vip_status</span>",
|
||||
"postsCount": 0,
|
||||
"posts": []
|
||||
},
|
||||
@ -701,4 +701,4 @@
|
||||
"posts": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,6 @@
|
||||
"immutable": "^4.0.0-rc.14",
|
||||
"jquery": "^3.5.0",
|
||||
"markdown-draft-js": "^2.3.0",
|
||||
"markdown-to-jsx": "^7.1.6",
|
||||
"mobx": "6.0.1",
|
||||
"mobx-react": "6.1.4",
|
||||
"moment": "^2.29.1",
|
||||
@ -65,6 +64,7 @@
|
||||
"react-flow-renderer": "^9.6.8",
|
||||
"react-google-login": "^5.2.2",
|
||||
"react-js-pagination": "^3.0.3",
|
||||
"react-markdown": "^8.0.2",
|
||||
"react-oidc": "^1.0.3",
|
||||
"react-quill": "^1.3.5",
|
||||
"react-router-dom": "^5.2.0",
|
||||
@ -74,6 +74,8 @@
|
||||
"react-tippy": "^1.4.0",
|
||||
"reactjs-localstorage": "^1.0.1",
|
||||
"recharts": "^1.8.5",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"resolve": "1.15.0",
|
||||
"resolve-url-loader": "3.1.1",
|
||||
"slick-carousel": "^1.8.1",
|
||||
|
@ -28,6 +28,10 @@ jest.mock('../../auth-provider/AuthProvider', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||
});
|
||||
|
||||
jest.mock('../../axiosAPIs/glossaryAPI', () => ({
|
||||
addGlossaries: jest.fn().mockImplementation(() => Promise.resolve()),
|
||||
}));
|
||||
|
@ -36,6 +36,10 @@ jest.mock('../../axiosAPIs/glossaryAPI', () => ({
|
||||
addGlossaries: jest.fn().mockImplementation(() => Promise.resolve()),
|
||||
}));
|
||||
|
||||
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||
});
|
||||
|
||||
const mockOnCancel = jest.fn();
|
||||
const mockOnSave = jest.fn();
|
||||
|
||||
|
@ -46,6 +46,10 @@ jest.mock('../../auth-provider/AuthProvider', () => {
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||
});
|
||||
|
||||
const mockUserTeam = [
|
||||
{
|
||||
description: 'description',
|
||||
|
@ -30,6 +30,10 @@ window.ResizeObserver = jest.fn().mockImplementation(() => ({
|
||||
disconnect: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||
});
|
||||
|
||||
const mockLineageData = {
|
||||
entity: {
|
||||
id: 'efcc334a-41c8-483e-b779-464a88a7ece3',
|
||||
|
@ -627,8 +627,7 @@
|
||||
padding: 2px 4px;
|
||||
}
|
||||
.ql-snow .ql-editor pre.ql-syntax {
|
||||
background-color: #23241f;
|
||||
color: #f8f8f2;
|
||||
background-color: #ebeef1;
|
||||
overflow: visible;
|
||||
}
|
||||
.ql-snow .ql-editor img {
|
||||
|
@ -51,6 +51,10 @@ jest.mock('../../components/common/non-admin-action/NonAdminAction', () => {
|
||||
));
|
||||
});
|
||||
|
||||
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||
});
|
||||
|
||||
const mockProps = {
|
||||
glossary: mockedGlossaries[0],
|
||||
isHasAccess: true,
|
||||
|
@ -54,6 +54,10 @@ jest.mock('../../components/common/non-admin-action/NonAdminAction', () => {
|
||||
));
|
||||
});
|
||||
|
||||
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||
});
|
||||
|
||||
const mockProps = {
|
||||
assetData: mockedAssetData,
|
||||
isHasAccess: true,
|
||||
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2021 Collate
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
findByTestId,
|
||||
fireEvent,
|
||||
queryByTestId,
|
||||
render,
|
||||
} from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { BlurLayout } from './BlurLayout';
|
||||
|
||||
const markdown =
|
||||
// eslint-disable-next-line max-len
|
||||
'Updated **columns** : <span class="diff-added">account_category_code, </span>account_type_code, account_type_desc, <span class="diff-removed">account_category_code</span><span class="diff-added">account_type_desc_eng</span>, <span class="diff-removed">eca_ind</span><span class="diff-added">ban_type_desc</span>, <span class="diff-removed">bill_production_ind</span><span class="diff-added">ban_type_key</span>, <span class="diff-removed">collection_waive_ind</span><span class="diff-added">bill_production_ind</span>, <span class="diff-removed">vip_status</span><span class="diff-added">business_type</span>, <span class="diff-removed">ban_type_desc</span><span class="diff-added">check_in_crm</span>, <span class="diff-removed">non_commercial_ind</span><span class="diff-added">collection_waive_ind</span>, <span class="diff-removed">legacy_account_category, </span>corporate_category, <span class="diff-removed">ban_type_key</span><span class="diff-added">currency_key</span>, <span class="diff-removed">segment_key</span><span class="diff-added">eca_ind</span>, <span class="diff-removed">check_in_crm</span><span class="diff-added">legacy_account_category</span>, <span class="diff-removed">currency_key</span><span class="diff-added">legal_person_ind</span>, <span class="diff-removed">legal_person_ind</span><span class="diff-added">non_commercial_ind</span>, <span class="diff-removed">account_type_desc_eng</span><span class="diff-added">segment_key</span>, <span class="diff-removed">business_type</span><span class="diff-added">vip_status</span>';
|
||||
|
||||
const displayMoreHandler = jest.fn();
|
||||
|
||||
const mockProp = {
|
||||
enableSeeMoreVariant: true,
|
||||
markdown,
|
||||
displayMoreText: true,
|
||||
blurClasses: '',
|
||||
displayMoreHandler,
|
||||
};
|
||||
|
||||
jest.mock('./RichTextEditorPreviewer', () => ({
|
||||
MAX_LENGTH: 300,
|
||||
}));
|
||||
|
||||
describe('Test BlurLayout Component', () => {
|
||||
it('Should render the Layout Component', async () => {
|
||||
const { container } = render(<BlurLayout {...mockProp} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
|
||||
const blurLayout = await findByTestId(container, 'blur-layout');
|
||||
|
||||
const displayButton = await findByTestId(container, 'display-button');
|
||||
|
||||
expect(blurLayout).toBeInTheDocument();
|
||||
|
||||
expect(displayButton).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should not render the Layout Component if markdown length is less that MAX_LENGTH', async () => {
|
||||
const { container } = render(<BlurLayout {...mockProp} markdown="" />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
|
||||
const blurLayout = queryByTestId(container, 'blur-layout');
|
||||
|
||||
const displayButton = queryByTestId(container, 'display-button');
|
||||
|
||||
expect(blurLayout).not.toBeInTheDocument();
|
||||
|
||||
expect(displayButton).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should not render the Layout Component if enableSeeMoreVariant is false', async () => {
|
||||
const { container } = render(
|
||||
<BlurLayout {...mockProp} enableSeeMoreVariant={false} />,
|
||||
{
|
||||
wrapper: MemoryRouter,
|
||||
}
|
||||
);
|
||||
|
||||
const blurLayout = queryByTestId(container, 'blur-layout');
|
||||
|
||||
const displayButton = queryByTestId(container, 'display-button');
|
||||
|
||||
expect(blurLayout).not.toBeInTheDocument();
|
||||
|
||||
expect(displayButton).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Should call displayMoreHandler on display button click', async () => {
|
||||
const { container } = render(<BlurLayout {...mockProp} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
|
||||
const blurLayout = await findByTestId(container, 'blur-layout');
|
||||
|
||||
const displayButton = await findByTestId(container, 'display-button');
|
||||
|
||||
expect(blurLayout).toBeInTheDocument();
|
||||
|
||||
expect(displayButton).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(displayButton);
|
||||
|
||||
expect(displayMoreHandler).toBeCalled();
|
||||
});
|
||||
});
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2021 Collate
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
import React, { FC } from 'react';
|
||||
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
|
||||
import { MAX_LENGTH } from './RichTextEditorPreviewer';
|
||||
|
||||
interface BlurLayoutProp {
|
||||
markdown: string;
|
||||
enableSeeMoreVariant: boolean;
|
||||
displayMoreText: boolean;
|
||||
blurClasses: string;
|
||||
displayMoreHandler: () => void;
|
||||
}
|
||||
|
||||
export const BlurLayout: FC<BlurLayoutProp> = ({
|
||||
enableSeeMoreVariant,
|
||||
markdown,
|
||||
displayMoreText,
|
||||
blurClasses,
|
||||
displayMoreHandler,
|
||||
}: BlurLayoutProp) => {
|
||||
const getBlurClass = () => {
|
||||
return !displayMoreText ? blurClasses : '';
|
||||
};
|
||||
|
||||
return enableSeeMoreVariant && markdown.length > MAX_LENGTH ? (
|
||||
<div
|
||||
className={classNames(
|
||||
'tw-absolute tw-flex tw-h-full tw-w-full tw-inset-x-0 tw-pointer-events-none',
|
||||
getBlurClass(),
|
||||
{
|
||||
'tw-top-0 tw-bottom-0': !displayMoreText,
|
||||
' tw--bottom-4': displayMoreText,
|
||||
}
|
||||
)}
|
||||
data-testid="blur-layout">
|
||||
<p
|
||||
className="tw-cursor-pointer tw-self-end tw-pointer-events-auto tw-text-primary tw-mx-auto"
|
||||
data-testid="display-button"
|
||||
onClick={displayMoreHandler}>
|
||||
<span className="tw-flex tw-items-center tw-gap-2">
|
||||
<SVGIcons
|
||||
alt="expand-collapse"
|
||||
className={classNames({ 'rotate-inverse': displayMoreText })}
|
||||
icon={Icons.CHEVRON_DOWN}
|
||||
width="32"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
) : null;
|
||||
};
|
@ -11,7 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Attributes, HtmlHTMLAttributes, ReactNode } from 'react';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
export type editorRef = ReactNode | HTMLElement | string;
|
||||
export enum Format {
|
||||
@ -27,8 +27,11 @@ export type EditorProp = {
|
||||
customOptions?: ReactNode[];
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export interface ElementProp extends HtmlHTMLAttributes<any>, Attributes {
|
||||
class: string;
|
||||
className: string;
|
||||
export interface PreviewerProp {
|
||||
markdown: string;
|
||||
className?: string;
|
||||
blurClasses?: string;
|
||||
maxHtClass?: string;
|
||||
maxLen?: number;
|
||||
enableSeeMoreVariant?: boolean;
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2021 Collate
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { findByTestId, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import RichTextEditorPreviewer from './RichTextEditorPreviewer';
|
||||
|
||||
const mockProp = {
|
||||
markdown: '',
|
||||
className: '',
|
||||
blurClasses: 'see-more-blur',
|
||||
maxHtClass: 'tw-h-24',
|
||||
maxLen: 300,
|
||||
enableSeeMoreVariant: true,
|
||||
};
|
||||
|
||||
jest.mock('react-markdown', () => {
|
||||
return jest.fn().mockImplementation(() => {
|
||||
return <p data-testid="markdown-parser">markdown parser</p>;
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('rehype-raw', () => {
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
jest.mock('remark-gfm', () => {
|
||||
return jest.fn();
|
||||
});
|
||||
|
||||
describe('Test RichTextEditor Previewer Component', () => {
|
||||
it('Should render RichTextEditorViewer Component', async () => {
|
||||
const { container } = render(<RichTextEditorPreviewer {...mockProp} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
|
||||
const viewerContainer = await findByTestId(container, 'viewer-container');
|
||||
|
||||
expect(viewerContainer).toBeInTheDocument();
|
||||
|
||||
const markdownParser = await findByTestId(container, 'markdown-parser');
|
||||
|
||||
expect(markdownParser).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -12,13 +12,15 @@
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
import Markdown from 'markdown-to-jsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Paragraph, UnOrderedList } from '../../../utils/MarkdownUtils';
|
||||
import SVGIcons, { Icons } from '../../../utils/SvgUtils';
|
||||
import { ElementProp } from './RichTextEditor.interface';
|
||||
// Markdown Parser and plugin imports
|
||||
import MarkdownParser from 'react-markdown';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import { BlurLayout } from './BlurLayout';
|
||||
import { PreviewerProp } from './RichTextEditor.interface';
|
||||
|
||||
const MAX_LENGTH = 300;
|
||||
export const MAX_LENGTH = 300;
|
||||
|
||||
const RichTextEditorPreviewer = ({
|
||||
markdown = '',
|
||||
@ -27,21 +29,23 @@ const RichTextEditorPreviewer = ({
|
||||
maxHtClass = 'tw-h-24',
|
||||
maxLen = MAX_LENGTH,
|
||||
enableSeeMoreVariant = true,
|
||||
}: {
|
||||
markdown: string;
|
||||
className?: string;
|
||||
blurClasses?: string;
|
||||
maxHtClass?: string;
|
||||
maxLen?: number;
|
||||
enableSeeMoreVariant?: boolean;
|
||||
}) => {
|
||||
}: PreviewerProp) => {
|
||||
const [content, setContent] = useState<string>('');
|
||||
const [displayMoreText, setDisplayMoreText] = useState(false);
|
||||
useEffect(() => {
|
||||
const modifiedContent = markdown
|
||||
.replaceAll('<', '<')
|
||||
.replaceAll('>', '>');
|
||||
|
||||
const setModifiedContent = (markdownValue: string) => {
|
||||
const modifiedContent = markdownValue
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
setContent(modifiedContent);
|
||||
};
|
||||
|
||||
const displayMoreHandler = () => {
|
||||
setDisplayMoreText((pre) => !pre);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setModifiedContent(markdown);
|
||||
}, [markdown]);
|
||||
|
||||
return (
|
||||
@ -55,90 +59,55 @@ const RichTextEditorPreviewer = ({
|
||||
{
|
||||
'tw-mb-5': displayMoreText,
|
||||
}
|
||||
)}>
|
||||
<Markdown
|
||||
options={{
|
||||
overrides: {
|
||||
h1: {
|
||||
component: Paragraph,
|
||||
},
|
||||
h2: {
|
||||
component: Paragraph,
|
||||
},
|
||||
h3: {
|
||||
component: Paragraph,
|
||||
},
|
||||
h4: {
|
||||
component: Paragraph,
|
||||
},
|
||||
h5: {
|
||||
component: Paragraph,
|
||||
},
|
||||
h6: {
|
||||
component: Paragraph,
|
||||
},
|
||||
ul: {
|
||||
component: UnOrderedList,
|
||||
props: {
|
||||
className: 'tw-ml-3',
|
||||
},
|
||||
},
|
||||
},
|
||||
/**
|
||||
* Custom React CreateElement Implementation
|
||||
* @param type - Element type
|
||||
* @param props - Element Props
|
||||
* @param children - Elemeny children
|
||||
* @returns React element of {type} with {props} and {children}
|
||||
*/
|
||||
createElement(type, props, children) {
|
||||
const {
|
||||
className,
|
||||
/** disabling eslint rule because class is reserverd keyword
|
||||
* and here we have to give alias that is classes */
|
||||
// eslint-disable-next-line react/prop-types
|
||||
class: classes,
|
||||
...restProps
|
||||
} = props as ElementProp;
|
||||
const modifiedProps = {
|
||||
...restProps,
|
||||
/** react does not accept class attribute,
|
||||
* hence we need to escape class and pass className attribute
|
||||
*/
|
||||
className: `${className ? className : ''} ${
|
||||
classes ? classes : ''
|
||||
}`,
|
||||
};
|
||||
|
||||
return React.createElement(type, modifiedProps, children);
|
||||
},
|
||||
}}>
|
||||
{content}
|
||||
</Markdown>
|
||||
{enableSeeMoreVariant && markdown.length > MAX_LENGTH && (
|
||||
<div
|
||||
className={classNames(
|
||||
'tw-absolute tw-flex tw-h-full tw-w-full tw-inset-x-0 tw-pointer-events-none',
|
||||
!displayMoreText ? blurClasses : null,
|
||||
{
|
||||
'tw-top-0 tw-bottom-0': !displayMoreText,
|
||||
' tw--bottom-4': displayMoreText,
|
||||
}
|
||||
)}>
|
||||
<p
|
||||
className="tw-cursor-pointer tw-self-end tw-pointer-events-auto tw-text-primary tw-mx-auto"
|
||||
onClick={() => setDisplayMoreText((pre) => !pre)}>
|
||||
<span className="tw-flex tw-items-center tw-gap-2">
|
||||
<SVGIcons
|
||||
alt="expand-collapse"
|
||||
className={classNames({ 'rotate-inverse': displayMoreText })}
|
||||
icon={Icons.CHEVRON_DOWN}
|
||||
width="32"
|
||||
/>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
data-testid="viewer-container">
|
||||
<MarkdownParser
|
||||
sourcePos
|
||||
components={{
|
||||
h1: 'p',
|
||||
h2: 'p',
|
||||
ul: ({ children, ...props }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { ordered, ...rest } = props;
|
||||
|
||||
return (
|
||||
<ul className="tw-ml-3" {...rest}>
|
||||
{children}
|
||||
</ul>
|
||||
);
|
||||
},
|
||||
ol: ({ children, ...props }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { ordered, ...rest } = props;
|
||||
|
||||
return (
|
||||
<ol className="tw-ml-3" {...rest} style={{ listStyle: 'auto' }}>
|
||||
{children}
|
||||
</ol>
|
||||
);
|
||||
},
|
||||
code: ({ children, ...props }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { inline, ...rest } = props;
|
||||
|
||||
return (
|
||||
<code {...rest} className="tw-my">
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
},
|
||||
}}
|
||||
rehypePlugins={[rehypeRaw]}
|
||||
remarkPlugins={[remarkGfm]}>
|
||||
{content}
|
||||
</MarkdownParser>
|
||||
<BlurLayout
|
||||
blurClasses={blurClasses}
|
||||
displayMoreHandler={displayMoreHandler}
|
||||
displayMoreText={displayMoreText}
|
||||
enableSeeMoreVariant={enableSeeMoreVariant}
|
||||
markdown={content}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -31,6 +31,10 @@ const tagsWithTerm = [
|
||||
{ tagFQN: `tags:term`, source: 'Glossary' },
|
||||
];
|
||||
|
||||
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||
});
|
||||
|
||||
describe('Test TagsViewer Component', () => {
|
||||
it('Component should render', () => {
|
||||
const { container } = render(<TagsViewer sizeCap={-1} tags={tags} />);
|
||||
|
@ -898,7 +898,8 @@ body .profiler-graph .recharts-active-dot circle {
|
||||
.entity-feed-list {
|
||||
grid-template-columns: 200px auto 200px;
|
||||
}
|
||||
.activity-feed-card-text code {
|
||||
|
||||
code {
|
||||
padding: 2px 3px;
|
||||
border-radius: 4px;
|
||||
background: #ebeef1;
|
||||
|
@ -14,10 +14,13 @@
|
||||
import classNames from 'classnames';
|
||||
import { diffArrays, diffWordsWithSpace } from 'diff';
|
||||
import { isEmpty, isUndefined, uniqueId } from 'lodash';
|
||||
import Markdown from 'markdown-to-jsx';
|
||||
import React, { Fragment } from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
// Markdown Parser and plugin imports
|
||||
import MarkdownParser from 'react-markdown';
|
||||
import { Link } from 'react-router-dom';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import { FQN_SEPARATOR_CHAR } from '../constants/char.constants';
|
||||
import { DESCRIPTIONLENGTH, getTeamDetailsPath } from '../constants/constants';
|
||||
import { ChangeType } from '../enums/entity.enum';
|
||||
@ -27,7 +30,6 @@ import {
|
||||
FieldChange,
|
||||
} from '../generated/entity/services/databaseService';
|
||||
import { TagLabel } from '../generated/type/tagLabel';
|
||||
import { Paragraph, Span, UnOrderedList } from './MarkdownUtils';
|
||||
import { isValidJSONString } from './StringsUtils';
|
||||
import { getEntityLink, getOwnerFromId } from './TableUtils';
|
||||
|
||||
@ -38,49 +40,62 @@ const parseMarkdown = (
|
||||
_isNewLine: boolean
|
||||
) => {
|
||||
return (
|
||||
<Markdown
|
||||
options={{
|
||||
overrides: {
|
||||
h1: {
|
||||
component: Paragraph,
|
||||
<Fragment>
|
||||
<MarkdownParser
|
||||
sourcePos
|
||||
components={{
|
||||
h1: 'p',
|
||||
h2: 'p',
|
||||
ul: ({ children, ...props }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { ordered, ...rest } = props;
|
||||
|
||||
return (
|
||||
<ul className={classNames('tw-ml-3', className)} {...rest}>
|
||||
{children}
|
||||
</ul>
|
||||
);
|
||||
},
|
||||
h2: {
|
||||
component: Paragraph,
|
||||
ol: ({ children, ...props }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { ordered, ...rest } = props;
|
||||
|
||||
return (
|
||||
<ol className="tw-ml-3" {...rest} style={{ listStyle: 'auto' }}>
|
||||
{children}
|
||||
</ol>
|
||||
);
|
||||
},
|
||||
h3: {
|
||||
component: Paragraph,
|
||||
code: ({ children, ...props }) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { inline, ...rest } = props;
|
||||
|
||||
return (
|
||||
<code {...rest} className="tw-my">
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
},
|
||||
h4: {
|
||||
component: Paragraph,
|
||||
p: ({ children, ...props }) => {
|
||||
return (
|
||||
<p className={className} {...props}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
},
|
||||
h5: {
|
||||
component: Paragraph,
|
||||
span: ({ children, ...props }) => {
|
||||
return (
|
||||
<span className={className} {...props}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
h6: {
|
||||
component: Paragraph,
|
||||
},
|
||||
ul: {
|
||||
component: UnOrderedList,
|
||||
props: {
|
||||
className: `${className} tw-ml-3`,
|
||||
},
|
||||
},
|
||||
p: {
|
||||
component: Paragraph,
|
||||
props: {
|
||||
className: `${className}`,
|
||||
},
|
||||
},
|
||||
span: {
|
||||
component: Span,
|
||||
props: {
|
||||
className: `${className}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
}}>
|
||||
{content}
|
||||
</Markdown>
|
||||
}}
|
||||
rehypePlugins={[rehypeRaw]}
|
||||
remarkPlugins={[remarkGfm]}>
|
||||
{content}
|
||||
</MarkdownParser>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,15 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
},
|
||||
// .mjs files to be handled
|
||||
{
|
||||
test: /\.m?js/,
|
||||
include: path.resolve(__dirname, 'node_modules/kleur'),
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
|
||||
// .ts and .tsx files to be handled by ts-loader
|
||||
{
|
||||
test: /\.(ts|tsx)$/,
|
||||
|
@ -52,6 +52,15 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
},
|
||||
// .mjs files to be handled
|
||||
{
|
||||
test: /\.m?js/,
|
||||
include: path.resolve(__dirname, 'node_modules/kleur'),
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
|
||||
// .ts and .tsx files to be handled by ts-loader
|
||||
{
|
||||
test: /\.(ts|tsx)$/,
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user