Skip to content

Commit

Permalink
Variables Menu - Right Pane (#4569)
Browse files Browse the repository at this point in the history
* feat(editor): right pane

* feature(collaboration) Handle imports and exports correctly in collaboration. (#4565)

- Added `UPDATE_EXPORTS_DETAIL_FROM_COLLABORATION_UPDATE` and
  `UPDATE_IMPORTS_FROM_COLLABORATION_UPDATE` editor actions.
- `addHookForProjectChanges` now collates potentially many actions to
  dispatch at once.
- Reworked `ArrayChanges` as it didn't work very well in its original form.
- Refactored `updateEntireProjectContents` to produce a multitude of
  editor actions and dispatch all at once.
- Created `updateEditorWithArrayChanges` and `updateEditorWithMapChanges`
  utility functions.
- Implemented `updateTopLevelElementsOfFile`, `updateExportsDetailOfFile`
  and `updateImportsOfFile` to carry changes from the yjs types into the
  editor.
- `calculateArrayChanges` now produces step by step changes.
- Implemented `syncArrayChanges` and `syncMapChanges` utility functions.
- `synchroniseParseSuccesToCollabFile` now much more simplified than the
  original implementations.
- Reworked `updateEntireProjectContents` to handle key changes
  instead of using the `currentTarget` value so that file deletions
  are handled correctly.
- Strip source maps from the outgoing top level elements. (#4566)

* Make comment popups/indicators ignore zoom (#4568)

* right pane

* variables menu

* right pane

* right pane

* icons

* insert first-level values of objects

* insert first-level values of objects

* insert first-level values of objects

* insert first-level values of objects

* insert first-level values of objects

* fix tests

* fix tests

* tests

---------

Co-authored-by: Sean Parsons <[email protected]>
Co-authored-by: Federico Ruggi <[email protected]>
  • Loading branch information
3 people authored Nov 28, 2023
1 parent 75de236 commit b29c247
Show file tree
Hide file tree
Showing 10 changed files with 741 additions and 17 deletions.
11 changes: 11 additions & 0 deletions editor/src/components/canvas/design-panel-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { CanvasStrategyInspector } from './canvas-strategies/canvas-strategy-ins
import { getQueryParam } from '../../common/env-vars'
import { when } from '../../utils/react-conditionals'
import { InsertMenuPane } from '../navigator/insert-menu-pane'
import { VariablesMenuPane } from '../navigator/variables-menu-pane'
import { useDispatch } from '../editor/store/dispatch-context'
import { GridPanelsContainer } from './grid-panels-container'
import { TitleBarCode, TitleBarUserProfile } from '../titlebar/title-bar'
Expand Down Expand Up @@ -212,6 +213,10 @@ export const RightPane = React.memo<ResizableRightPaneProps>((props) => {
onClickTab(RightMenuTab.Insert)
}, [onClickTab])

const onClickVariablesTab = React.useCallback(() => {
onClickTab(RightMenuTab.Variables)
}, [onClickTab])

const onClickCommentsTab = React.useCallback(() => {
onClickTab(RightMenuTab.Comments)
}, [onClickTab])
Expand Down Expand Up @@ -253,6 +258,11 @@ export const RightPane = React.memo<ResizableRightPaneProps>((props) => {
selected={selectedTab === RightMenuTab.Insert}
onClick={onClickInsertTab}
/>
<MenuTab
label={'Variables'}
selected={selectedTab === RightMenuTab.Variables}
onClick={onClickVariablesTab}
/>
{when(
isFeatureEnabled('Commenting'),
<MenuTab
Expand Down Expand Up @@ -281,6 +291,7 @@ export const RightPane = React.memo<ResizableRightPaneProps>((props) => {
}}
>
{when(selectedTab === RightMenuTab.Insert, <InsertMenuPane />)}
{when(selectedTab === RightMenuTab.Variables, <VariablesMenuPane />)}
{when(selectedTab === RightMenuTab.Inspector, <InspectorEntryPoint />)}
{when(selectedTab === RightMenuTab.Settings, <SettingsPane />)}
{when(selectedTab === RightMenuTab.Comments, <CommentsPane />)}
Expand Down
3 changes: 3 additions & 0 deletions editor/src/components/common/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type LeftMenuPanel =
| 'genericExternalResources'
| 'googleFontsResources'
| 'insertmenu'
| 'variablesmenu'
| 'projectsettings'
| 'githuboptions'

Expand Down Expand Up @@ -43,6 +44,8 @@ export function paneForPanel(panel: EditorPanel | null): EditorPane | null {
return 'leftmenu'
case 'insertmenu':
return 'rightmenu'
case 'variablesmenu':
return 'rightmenu'
case 'projectsettings':
return 'leftmenu'
case 'navigator':
Expand Down
2 changes: 2 additions & 0 deletions editor/src/components/editor/actions/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2653,6 +2653,7 @@ export const UPDATE_FNS = {
case 'canvas':
case 'center':
case 'insertmenu':
case 'variablesmenu':
case 'projectsettings':
case 'githuboptions':
return editor
Expand Down Expand Up @@ -2759,6 +2760,7 @@ export const UPDATE_FNS = {
case 'misccodeeditor':
case 'center':
case 'insertmenu':
case 'variablesmenu':
case 'githuboptions':
return editor
default:
Expand Down
4 changes: 2 additions & 2 deletions editor/src/components/editor/canvas-toolbar.spec.browser2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ describe('canvas toolbar', () => {

FOR_TESTS_setNextGeneratedUids(['reserved', 'sample-text'])

await insertViaAddElementPopup(editor, 'myObj')
await insertViaAddElementPopup(editor, 'myObj.test')

expect(getPrintedUiJsCode(editor.getEditorState())).toEqual(
makeTestProjectCodeWithComponentInnards(`
Expand All @@ -567,7 +567,7 @@ describe('canvas toolbar', () => {
data-uid='container'
>
<div data-uid='a3d' />
<span style={{ width: 100, height: 100, top: 0, left: 0, position: 'absolute' }} data-uid='sample-text'>{JSON.stringify(myObj)}</span>
<span style={{ width: 100, height: 100, top: 0, left: 0, position: 'absolute' }} data-uid='sample-text'>{myObj.test}</span>
</div>
)`),
)
Expand Down
1 change: 1 addition & 0 deletions editor/src/components/editor/store/editor-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ export enum RightMenuTab {
Inspector = 'inspector',
Settings = 'settings',
Comments = 'comments',
Variables = 'variables',
}

// TODO: this should just contain an NpmDependency and a status
Expand Down
227 changes: 227 additions & 0 deletions editor/src/components/editor/variablesmenu.spec.browser2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
import { act, fireEvent, screen } from '@testing-library/react'
import type { EditorRenderResult } from '../canvas/ui-jsx.test-utils'
import {
TestAppUID,
TestSceneUID,
getPrintedUiJsCode,
makeTestProjectCodeWithComponentInnards,
makeTestProjectCodeWithSnippet,
renderTestEditorWithCode,
} from '../canvas/ui-jsx.test-utils'
import * as EP from '../../core/shared/element-path'
import { setPanelVisibility, setRightMenuTab } from './actions/action-creators'
import { RightMenuTab } from './store/editor-state'
import { selectComponentsForTest } from '../../utils/utils.test-utils'
import { BakedInStoryboardUID } from '../../core/model/scene-utils'
import { forceNotNull } from '../../core/shared/optional-utils'
import { InsertMenuFilterTestId } from './insertmenu'

function getInsertItems() {
return screen.queryAllByTestId(/^insert-item-/gi)
}

function openVariablesMenu(renderResult: EditorRenderResult) {
return renderResult.dispatch(
[setPanelVisibility('rightmenu', true), setRightMenuTab(RightMenuTab.Variables)],
true,
)
}

describe('variables menu', () => {
describe('filter search', () => {
it('can filter by variable name', async () => {
const editor = await renderTestEditorWithCode(
makeTestProjectCodeWithComponentInnards(`
const myObj = { test: 'test', num: 5, image: 'img.png' }
return (
<div
style={{
backgroundColor: '#aaaaaa33',
position: 'absolute',
left: 57,
top: 168,
width: 247,
height: 402,
}}
data-uid='container'
>
<div data-uid='a3d' />
</div>
)`),
'await-first-dom-report',
)

await selectComponentsForTest(editor, [
EP.fromString(`${BakedInStoryboardUID}/${TestSceneUID}/${TestAppUID}:container`),
])

await openVariablesMenu(editor)

expect(getInsertItems().length).toEqual(3)

document.execCommand('insertText', false, 'myObj.im')

expect(getInsertItems().length).toEqual(1)
expect(getInsertItems()[0].innerText).toEqual('myObj.image')
})

describe('no match', () => {
it('shows all elements', async () => {
const renderResult = await renderTestEditorWithCode(
makeTestProjectCodeWithSnippet(`<div />`),
'await-first-dom-report',
)

await openVariablesMenu(renderResult)

expect(getInsertItems().length).toEqual(0)
})
})

it('does not show insertables that cannot be inserted', async () => {
const editor = await renderTestEditorWithCode(
makeTestProjectCodeWithComponentInnards(`
const myObj = { test: 'test', num: 5, image: 'img.png' }
return (
<div
style={{
backgroundColor: '#aaaaaa33',
position: 'absolute',
left: 57,
top: 168,
width: 247,
height: 402,
}}
data-uid='container'
>
<div data-uid='a3d' />
</div>
)`),
'await-first-dom-report',
)

await openVariablesMenu(editor)

expect(getInsertItems().length).toEqual(0)
})
})

describe('insertion', () => {
it('inserts an image from within an object', async () => {
const editor = await renderTestEditorWithCode(
makeTestProjectCodeWithComponentInnards(`
const myObj = { test: 'test', num: 5, image: 'img.png' }
return (
<div
style={{
backgroundColor: '#aaaaaa33',
position: 'absolute',
left: 57,
top: 168,
width: 247,
height: 402,
}}
data-uid='container'
>
<div data-uid='a3d' />
</div>
)`),
'await-first-dom-report',
)

await selectComponentsForTest(editor, [
EP.fromString(`${BakedInStoryboardUID}/${TestSceneUID}/${TestAppUID}:container`),
])

await openVariablesMenu(editor)

document.execCommand('insertText', false, 'myObj.image')

const filterBox = await screen.findByTestId(InsertMenuFilterTestId)
forceNotNull('the filter box must not be null', filterBox)

await act(async () => {
fireEvent.keyDown(filterBox, { key: 'Enter', keycode: 13 })
})

expect(getPrintedUiJsCode(editor.getEditorState())).toEqual(
makeTestProjectCodeWithComponentInnards(`
const myObj = { test: 'test', num: 5, image: 'img.png' }
return (
<div
style={{
backgroundColor: '#aaaaaa33',
position: 'absolute',
left: 57,
top: 168,
width: 247,
height: 402,
}}
data-uid='container'
>
<div data-uid='a3d' />
<img src={myObj.image} style={{width: 100, height: 100, top:0, left: 0, position: 'absolute'}} data-uid='ele'/>
</div>
)`),
)
})
it('inserts a text', async () => {
const editor = await renderTestEditorWithCode(
makeTestProjectCodeWithComponentInnards(`
const myText = ''
return (
<div
style={{
backgroundColor: '#aaaaaa33',
position: 'absolute',
left: 57,
top: 168,
width: 247,
height: 402,
}}
data-uid='container'
>
<div data-uid='a3d' />
</div>
)`),
'await-first-dom-report',
)

await selectComponentsForTest(editor, [
EP.fromString(`${BakedInStoryboardUID}/${TestSceneUID}/${TestAppUID}:container`),
])

await openVariablesMenu(editor)

document.execCommand('insertText', false, 'myText')

const filterBox = await screen.findByTestId(InsertMenuFilterTestId)
forceNotNull('the filter box must not be null', filterBox)

await act(async () => {
fireEvent.keyDown(filterBox, { key: 'Enter', keycode: 13 })
})

expect(getPrintedUiJsCode(editor.getEditorState())).toEqual(
makeTestProjectCodeWithComponentInnards(`
const myText = ''
return (
<div
style={{
backgroundColor: '#aaaaaa33',
position: 'absolute',
left: 57,
top: 168,
width: 247,
height: 402,
}}
data-uid='container'
>
<div data-uid='a3d' />
<span style={{ width: 100, height: 100, top: 0, left: 0, position: 'absolute' }} data-uid='ele'>{myText}</span>
</div>
)`),
)
})
})
})
Loading

0 comments on commit b29c247

Please sign in to comment.