-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(editor): improve documentation editor using Remirror #6631
Changes from all commits
f3ae52d
a8b7121
2632e9f
1d7d6f7
a755b5e
7b33748
5cc7d04
cee082d
58a1ad4
48c1226
a255acc
9864842
808e655
fe13b60
071081a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,8 +5,6 @@ import { useLocation } from 'react-router-dom'; | |
import styled from 'styled-components'; | ||
import { Button, Divider, Typography } from 'antd'; | ||
import { EditOutlined } from '@ant-design/icons'; | ||
import MDEditor from '@uiw/react-md-editor'; | ||
import DOMPurify from 'dompurify'; | ||
|
||
import TabToolbar from '../../components/styled/TabToolbar'; | ||
import { AddLinkModal } from '../../components/styled/AddLinkModal'; | ||
|
@@ -16,12 +14,12 @@ import { LinkList } from './components/LinkList'; | |
|
||
import { useEntityData, useRefetch, useRouteToTab } from '../../EntityContext'; | ||
import { EDITED_DESCRIPTIONS_CACHE_NAME } from '../../utils'; | ||
import { Editor } from './components/editor/Editor'; | ||
|
||
const DocumentationContainer = styled.div` | ||
margin: 0 auto; | ||
margin: 0 32px; | ||
padding: 40px 0; | ||
max-width: calc(100% - 10px); | ||
margin: 0 32px; | ||
`; | ||
|
||
interface Props { | ||
|
@@ -33,7 +31,6 @@ export const DocumentationTab = ({ properties }: { properties?: Props }) => { | |
const { urn, entityData } = useEntityData(); | ||
const refetch = useRefetch(); | ||
const description = entityData?.editableProperties?.description || entityData?.properties?.description || ''; | ||
const sanitizedDescription = DOMPurify.sanitize(description); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. even if remirror also handles this, do you think it's a problem to sanitize here as well? just in case anything ever changes with remirror I really want to avoid any unsafe scripts or anything getting into documentation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same idea with sanitizing below before sending to the BE There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I remembered the double sanitisation did throw out some unwanted syntax in the output. Let me take a look at it again. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. okay if that's the case I don't think it's a problem as long as we feel good about remirror being able to handle this for us |
||
const links = entityData?.institutionalMemory?.elements || []; | ||
const localStorageDictionary = localStorage.getItem(EDITED_DESCRIPTIONS_CACHE_NAME); | ||
|
||
|
@@ -53,7 +50,7 @@ export const DocumentationTab = ({ properties }: { properties?: Props }) => { | |
</> | ||
) : ( | ||
<> | ||
{sanitizedDescription || links.length ? ( | ||
{description || links.length ? ( | ||
<> | ||
<TabToolbar> | ||
<div> | ||
|
@@ -66,15 +63,19 @@ export const DocumentationTab = ({ properties }: { properties?: Props }) => { | |
{!hideLinksButton && <AddLinkModal buttonProps={{ type: 'text' }} refetch={refetch} />} | ||
</div> | ||
</TabToolbar> | ||
<DocumentationContainer> | ||
{sanitizedDescription ? ( | ||
<MDEditor.Markdown style={{ fontWeight: 400 }} source={sanitizedDescription} /> | ||
<div> | ||
{description ? ( | ||
<Editor content={description} readOnly /> | ||
) : ( | ||
<Typography.Text type="secondary">No documentation added yet.</Typography.Text> | ||
<DocumentationContainer> | ||
<Typography.Text type="secondary">No documentation added yet.</Typography.Text> | ||
</DocumentationContainer> | ||
)} | ||
<Divider /> | ||
{!hideLinksButton && <LinkList refetch={refetch} />} | ||
</DocumentationContainer> | ||
<DocumentationContainer> | ||
{!hideLinksButton && <LinkList refetch={refetch} />} | ||
</DocumentationContainer> | ||
</div> | ||
</> | ||
) : ( | ||
<EmptyTab tab="documentation"> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { htmlToMarkdown } from '../../../../components/editor/extensions/htmlToMarkdown'; | ||
|
||
const cases = [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thank you! |
||
['strike', '<strike>Lorem ipsum</strike>', '~Lorem ipsum~'], | ||
['s', '<s>Lorem ipsum</s>', '~Lorem ipsum~'], | ||
['del', '<del>Lorem ipsum</del>', '~Lorem ipsum~'], | ||
[ | ||
'should replace blank nodes in table', | ||
'<table><thead><tr><th>Lorem ipsum</th></tr></thead><tbody><tr><td><p>Lorem</p><p>ipsum</p></td></tr></tbody></table>', | ||
'| Lorem ipsum |\n| --- |\n| Lorem<br />ipsum |', | ||
], | ||
['should replace empty p tags to line breaks', '<p>Lorem</p><p></p><p>ipsum</p>', 'Lorem\n\n \n\nipsum'], | ||
[ | ||
'should parse image if it does not have a width attribute', | ||
'<img src="/my-image.png" style="width: 100%; min-width: 50px; object-fit: contain;" alt="my image">', | ||
'![my image](/my-image.png)', | ||
], | ||
|
||
[ | ||
'should highlight code block with html', | ||
'<pre><code class="language language-html"><<span class="pl-ent">p</span>>Hello world</<span class="pl-ent">p</span>></code></pre>', | ||
'```html\n<p>Hello world</p>\n```', | ||
], | ||
[ | ||
'should highlight code block with js', | ||
'<pre><code class="lang lang-js">;(<span class="pl-k">function</span> () {})()</code></pre>', | ||
'```js\n;(function () {})()\n```', | ||
], | ||
[ | ||
'should highlighted remirror code block', | ||
'<pre><code data-code-block-language="ts">;(<span class="pl-k">function</span> () {})()</code></pre>', | ||
'```ts\n;(function () {})()\n```', | ||
], | ||
[ | ||
'should parse without language code block', | ||
'<pre><code>;(<span class="pl-k">function</span> () {})()</code></pre>', | ||
'```\n;(function () {})()\n```', | ||
], | ||
[ | ||
'should parse datahub mention', | ||
'<span class="mentions" data-datahub-mention-urn="urn:li:dataset:(urn:li:dataPlatform:hive,SampleHiveDataset,PROD)">@SampleHiveDataset</span>', | ||
'[@SampleHiveDataset](urn:li:dataset:(urn:li:dataPlatform:hive,SampleHiveDataset,PROD))', | ||
], | ||
]; | ||
|
||
const skipParseCases = [ | ||
[ | ||
'table if ul or li is present', | ||
'<table><thead><tr><th>Lorem ipsum</th></tr></thead><tbody><tr><td><ul><li>Lorem</li><li>ipsum</li></ul></td></tr></tbody></table>', | ||
], | ||
[ | ||
'table if present', | ||
'<table><thead><tr><th>Lorem ipsum</th></tr></thead><tbody><tr><td><ul><li>Lorem</li><li>ipsum</li></ul></td></tr></tbody></table>', | ||
], | ||
[ | ||
'image if it has a width attribute', | ||
'<img src="/my-image.png" style="width: 100%; min-width: 50px; object-fit: contain;" alt="my image" width="200">', | ||
], | ||
]; | ||
|
||
describe('htmlToMarkdown', () => { | ||
it.each(cases)('%s', (_, input, expected) => { | ||
expect(htmlToMarkdown(input)).toBe(expected); | ||
}); | ||
|
||
it.each(skipParseCases)('should skip parsing %s', (_, input) => { | ||
expect(htmlToMarkdown(input)).toBe(input); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { markdownToHtml } from '../../../../components/editor/extensions/markdownToHtml'; | ||
|
||
const cases = [ | ||
[ | ||
'should parse datahub mentions', | ||
'Lorem [@SampleHiveDataset](urn:li:dataset:(urn:li:dataPlatform:hive,SampleHiveDataset,PROD)) ipsum', | ||
'<p>Lorem <span data-datahub-mention-urn="urn:li:dataset:(urn:li:dataPlatform:hive,SampleHiveDataset,PROD)">@SampleHiveDataset</span> ipsum</p>\n', | ||
], | ||
['should not parse github mentions', 'Lorem @githubuser ipsum', '<p>Lorem @githubuser ipsum</p>\n'], | ||
[ | ||
'should parse invalid mentions as links', | ||
'Lorem [@Some link](/lorem-ipsum) ipsum', | ||
'<p>Lorem <a href="/lorem-ipsum">@Some link</a> ipsum</p>\n', | ||
], | ||
]; | ||
|
||
describe('markdownToHtml', () => { | ||
it.each(cases)('%s', (_, input, expected) => { | ||
expect(markdownToHtml(input)).toBe(expected); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this change necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh it's to resolve the failing build that was caused by
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory.
in https://github.com/datahub-project/datahub/actions/runs/3804191769/jobs/6471221050. This line simply increases the memory limit allocated to node. If there are other solutions please feel free to make changes to the PR too!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like this failure is still happening :( do you know if we need to put this type of change elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another initiative we've discussed is removing the unneeded dependencies from our package.json - unsure how many things we can remove but if we can shrink our dependencies this may help solve this problem! it's something i'm looking into and will see if it helps here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, the latest build passed though: https://github.com/datahub-project/datahub/actions/runs/3805789729/jobs/6559405831. The only pipeline that's failing is https://github.com/datahub-project/datahub/actions/runs/3805789729/jobs/6559407548 which looks unrelated to the documentation, probably a flaky test (but I can't rereun it :x)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also let me know if you need help looking into shrinking the dependencies 🗡️ !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah so it looks like it's fixed in the Docker, Build, Scan, Test runs, but i'm still seeing the error in the logs on the general build & test / build job (https://github.com/datahub-project/datahub/actions/runs/3805789734/jobs/6521531814) - you'll have to search for it cuz that's a huge log lol
also it seems that that's timing out after 60 minutes, my hunch is that it's related to this build failing or even that something is taking much longer for some reason.