Skip to content
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

CodeMirror implementation of GraphNodeComment #11585

Open
wants to merge 23 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
62d8bdd
Render tables in documentation.
kazcw Nov 6, 2024
40875ef
CHANGELOG, prettier
kazcw Nov 15, 2024
6bd2b95
Apply @farmaazon review.
kazcw Nov 15, 2024
c6432d0
Fix
kazcw Nov 15, 2024
be9bdd3
Lint
kazcw Nov 15, 2024
3d75871
Cleanup
kazcw Nov 15, 2024
e654dfd
Integration tests for GraphNodeComment
kazcw Nov 15, 2024
f317637
Merge remote-tracking branch 'origin/develop' into wip/kw/doc-tables
kazcw Nov 18, 2024
7431384
Workaround stuck CI
kazcw Nov 18, 2024
58adff3
Merge branch 'wip/kw/node-comment-tests' into staging
kazcw Nov 18, 2024
621be55
Merge branch 'wip/kw/doc-tables' into staging
kazcw Nov 18, 2024
89cf8df
CodeMirror implementation of GraphNodeComment
kazcw Nov 15, 2024
caaa01a
Revert "Workaround stuck CI"
kazcw Nov 18, 2024
4606f2b
Merge branch 'develop' into wip/kw/node-comment-tests
mergify[bot] Nov 18, 2024
4f8c80f
Merge branch 'develop' into wip/kw/doc-tables
mergify[bot] Nov 18, 2024
fcac2fd
Revert "Workaround stuck CI"
kazcw Nov 18, 2024
ae2b93f
Merge remote-tracking branch 'origin/wip/kw/node-comment-tests' into …
kazcw Nov 19, 2024
c58c8b7
Merge remote-tracking branch 'origin/develop' into wip/kw/doc-tables
kazcw Nov 19, 2024
fb396d8
Merge branch 'wip/kw/doc-tables' into wip/kw/cm-comments
kazcw Nov 19, 2024
b7549bc
Merge remote-tracking branch 'origin/develop' into wip/kw/doc-tables
kazcw Nov 19, 2024
f11dcce
Fix merge
kazcw Nov 19, 2024
2583a10
Merge branch 'wip/kw/doc-tables' into wip/kw/cm-comments
kazcw Nov 19, 2024
e80de7b
LINKABLE_URL_REGEX: Remove a Lexical special case
kazcw Nov 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
clipboard or by drag'n'dropping image files.
- ["Write" button in component menu allows to evaluate it separately from the
rest of the workflow][11523].
- [The documentation editor can now display tables][11564]

[11151]: https://github.com/enso-org/enso/pull/11151
[11271]: https://github.com/enso-org/enso/pull/11271
Expand All @@ -46,6 +47,7 @@
[11469]: https://github.com/enso-org/enso/pull/11469
[11547]: https://github.com/enso-org/enso/pull/11547
[11523]: https://github.com/enso-org/enso/pull/11523
[11564]: https://github.com/enso-org/enso/pull/11564

#### Enso Standard Library

Expand Down
7 changes: 7 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,10 @@
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.

---

This project includes components that are licensed under the MIT license. The
full text of the MIT license and its copyright notice can be found in the
`app/licenses/` directory.

1 change: 1 addition & 0 deletions app/gui/e2e/project-view/locate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export const componentBrowser = componentLocator('.ComponentBrowser')
export const nodeOutputPort = componentLocator('.outputPortHoverArea')
export const smallPlusButton = componentLocator('.SmallPlusButton')
export const editorRoot = componentLocator('.EditorRoot')
export const nodeComment = componentLocator('.GraphNodeComment div[contentEditable]')

/**
* A not-selected variant of Component Browser Entry.
Expand Down
12 changes: 6 additions & 6 deletions app/gui/e2e/project-view/nodeClipboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ test('Copy node with comment', async ({ page }) => {

// Check state before operation.
const originalNodes = await locate.graphNode(page).count()
await expect(page.locator('.GraphNodeComment')).toExist()
const originalNodeComments = await page.locator('.GraphNodeComment').count()
await expect(locate.nodeComment(page)).toExist()
const originalNodeComments = await locate.nodeComment(page).count()

// Select a node.
const nodeToCopy = locate.graphNodeByBinding(page, 'final')
Expand All @@ -48,16 +48,16 @@ test('Copy node with comment', async ({ page }) => {

// Node and comment have been copied.
await expect(locate.graphNode(page)).toHaveCount(originalNodes + 1)
await expect(page.locator('.GraphNodeComment')).toHaveCount(originalNodeComments + 1)
await expect(locate.nodeComment(page)).toHaveCount(originalNodeComments + 1)
})

test('Copy multiple nodes', async ({ page }) => {
await actions.goToGraph(page)

// Check state before operation.
const originalNodes = await locate.graphNode(page).count()
await expect(page.locator('.GraphNodeComment')).toExist()
const originalNodeComments = await page.locator('.GraphNodeComment').count()
await expect(locate.nodeComment(page)).toExist()
const originalNodeComments = await locate.nodeComment(page).count()

// Select some nodes.
const node1 = locate.graphNodeByBinding(page, 'final')
Expand All @@ -76,7 +76,7 @@ test('Copy multiple nodes', async ({ page }) => {
// Nodes and comment have been copied.
await expect(locate.graphNode(page)).toHaveCount(originalNodes + 2)
// `final` node has a comment.
await expect(page.locator('.GraphNodeComment')).toHaveCount(originalNodeComments + 1)
await expect(locate.nodeComment(page)).toHaveCount(originalNodeComments + 1)
// Check that two copied nodes are isolated, i.e. connected to each other, not original nodes.
await expect(locate.graphNodeByBinding(page, 'prod1')).toBeVisible()
await expect(locate.graphNodeByBinding(page, 'final1')).toBeVisible()
Expand Down
75 changes: 75 additions & 0 deletions app/gui/e2e/project-view/nodeComments.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import test from 'playwright/test'
import * as actions from './actions'
import { expect } from './customExpect'
import { CONTROL_KEY } from './keyboard'
import * as locate from './locate'

test('Edit comment by click', async ({ page }) => {
await actions.goToGraph(page)
const nodeComment = locate.nodeComment(locate.graphNodeByBinding(page, 'final'))
await expect(nodeComment).toHaveText('This node can be entered')

await nodeComment.click()
await page.keyboard.press(`${CONTROL_KEY}+A`)
const NEW_COMMENT = 'New comment text'
await nodeComment.fill(NEW_COMMENT)
await page.keyboard.press(`Enter`)
await expect(nodeComment).not.toBeFocused()
await expect(nodeComment).toHaveText(NEW_COMMENT)
})

test('Start editing comment via menu', async ({ page }) => {
await actions.goToGraph(page)
const node = locate.graphNodeByBinding(page, 'final')
await node.click()
await locate.circularMenu(node).getByRole('button', { name: 'More' }).click()
await locate.circularMenu(node).getByRole('button', { name: 'Comment' }).click()
await expect(locate.nodeComment(node)).toBeFocused()
})

test('Add new comment via menu', async ({ page }) => {
await actions.goToGraph(page)
const INITIAL_NODE_COMMENTS = 1
await expect(locate.nodeComment(page)).toHaveCount(INITIAL_NODE_COMMENTS)
const node = locate.graphNodeByBinding(page, 'data')
const nodeComment = locate.nodeComment(node)

await node.click()
await locate.circularMenu(node).getByRole('button', { name: 'More' }).click()
await locate.circularMenu(node).getByRole('button', { name: 'Comment' }).click()
await expect(locate.nodeComment(node)).toBeFocused()
const NEW_COMMENT = 'New comment text'
await nodeComment.fill(NEW_COMMENT)
await page.keyboard.press(`Enter`)
await expect(nodeComment).not.toBeFocused()
await expect(nodeComment).toHaveText(NEW_COMMENT)
await expect(locate.nodeComment(page)).toHaveCount(INITIAL_NODE_COMMENTS + 1)
})

test('Delete comment by clearing text', async ({ page }) => {
await actions.goToGraph(page)
const nodeComment = locate.nodeComment(locate.graphNodeByBinding(page, 'final'))
await expect(nodeComment).toHaveText('This node can be entered')

await nodeComment.click()
await page.keyboard.press(`${CONTROL_KEY}+A`)
await page.keyboard.press(`Delete`)
await page.keyboard.press(`Enter`)
await expect(nodeComment).not.toExist()
})

test('URL added to comment is rendered as link', async ({ page }) => {
await actions.goToGraph(page)
const nodeComment = locate.nodeComment(locate.graphNodeByBinding(page, 'final'))
await expect(nodeComment).toHaveText('This node can be entered')
await expect(nodeComment.locator('a')).not.toExist()

await nodeComment.click()
await page.keyboard.press(`${CONTROL_KEY}+A`)
const NEW_COMMENT = "Here's a URL: https://example.com"
await nodeComment.fill(NEW_COMMENT)
await page.keyboard.press(`Enter`)
await expect(nodeComment).not.toBeFocused()
await expect(nodeComment).toHaveText(NEW_COMMENT)
await expect(nodeComment.locator('a')).toHaveCount(1)
})
3 changes: 2 additions & 1 deletion app/gui/e2e/project-view/undoRedo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ test('Removing node', async ({ page }) => {
await page.keyboard.press(`${CONTROL_KEY}+Z`)
await expect(locate.graphNode(page)).toHaveCount(nodesCount)
await expect(deletedNode.locator('.WidgetToken')).toHaveText(['Main', '.', 'func1', 'prod'])
await expect(deletedNode.locator('.GraphNodeComment')).toHaveText('This node can be entered')
await expect(locate.nodeComment(deletedNode)).toHaveText('This node can be entered')

const restoredBBox = await deletedNode.boundingBox()
expect(restoredBBox).toEqual(deletedNodeBBox)

Expand Down
8 changes: 1 addition & 7 deletions app/gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"build-cloud": "cross-env CLOUD_BUILD=true corepack pnpm run build",
"preview": "vite preview",
"//": "max-warnings set to 41 to match the amount of warnings introduced by the new react compiler. Eventual goal is to remove all the warnings.",
"lint": "eslint . --max-warnings=41",
"lint": "eslint . --max-warnings=39",
"format": "prettier --version && prettier --write src/ && eslint . --fix",
"dev:vite": "vite",
"test": "corepack pnpm run /^^^^test:.*/",
Expand Down Expand Up @@ -90,11 +90,7 @@
"@codemirror/view": "^6.28.3",
"@fast-check/vitest": "^0.0.8",
"@floating-ui/vue": "^1.0.6",
"@lexical/link": "^0.16.0",
"@lexical/plain-text": "^0.16.0",
"@lexical/utils": "^0.16.0",
"@lezer/common": "^1.1.0",
"@lezer/markdown": "^1.3.1",
"@lezer/highlight": "^1.1.6",
"@noble/hashes": "^1.4.0",
"@vueuse/core": "^10.4.1",
Expand All @@ -108,7 +104,6 @@
"hash-sum": "^2.0.0",
"install": "^0.13.0",
"isomorphic-ws": "^5.0.0",
"lexical": "^0.16.0",
"lib0": "^0.2.85",
"magic-string": "^0.30.3",
"murmurhash": "^2.0.1",
Expand All @@ -118,7 +113,6 @@
"veaury": "^2.3.18",
"vue": "^3.5.2",
"vue-component-type-helpers": "^2.0.29",
"y-codemirror.next": "^0.3.2",
"y-protocols": "^1.0.5",
"y-textarea": "^1.0.0",
"y-websocket": "^1.5.0",
Expand Down
3 changes: 2 additions & 1 deletion app/gui/src/dashboard/layouts/AssetDocs/AssetDocs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AssetType } from '#/services/Backend'
import { useSuspenseQuery } from '@tanstack/react-query'
import { useCallback } from 'react'
import * as ast from 'ydoc-shared/ast'
import { normalizedMarkdownToStandard } from 'ydoc-shared/ast/documentation'
import { splitFileContents } from 'ydoc-shared/ensoFile'
import { versionContentQueryOptions } from '../AssetDiffView/useFetchVersionContent'

Expand Down Expand Up @@ -48,7 +49,7 @@ export function AssetDocsContent(props: AssetDocsContentProps) {

for (const statement of module.statements()) {
if (statement instanceof ast.MutableFunctionDef && statement.name.code() === 'main') {
return statement.documentationText() ?? ''
return normalizedMarkdownToStandard(statement.mutableDocumentationMarkdown().toJSON())
}
}

Expand Down
Loading
Loading