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

Clear element path on unselect #374

Merged
merged 7 commits into from
Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
5 changes: 3 additions & 2 deletions src/Components/CutPlaneMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ import {addHashParams, getHashParams, removeHashParams} from '../utils/location'
* @param {Array} listOfOptions Title for the drawer
* @return {object} ItemPropertiesDrawer react component
*/
export default function CutPlaneMenu({listOfOptions, icon, title}) {
export default function CutPlaneMenu() {
const [anchorEl, setAnchorEl] = useState(null)
const [cutPlaneDirection, setCutPlaneDirection] = useState('')
const open = Boolean(anchorEl)
const model = useStore((state) => state.modelStore)
const PLANE_PREFIX = 'p'
Expand All @@ -33,6 +32,8 @@ export default function CutPlaneMenu({listOfOptions, icon, title}) {
setAnchorEl(null)
}
const viewer = useStore((state) => state.viewerStore)
const cutPlaneDirection = useStore((state) => state.cutPlaneDirection)
const setCutPlaneDirection = useStore((state) => state.setCutPlaneDirection)
const location = useLocation()

const createPlane = (normalDirection) => {
Expand Down
29 changes: 2 additions & 27 deletions src/Components/NavPanel.jsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
import React from 'react'
import Paper from '@mui/material/Paper'
import Tooltip from '@mui/material/Tooltip'
import TreeView from '@mui/lab/TreeView'
import IconButton from '@mui/material/IconButton'
import {makeStyles} from '@mui/styles'
import NavTree from './NavTree'
import {assertDefined} from '../utils/assert'
import NodeClosed from '../assets/2D_Icons/NodeClosed.svg'
import NodeOpen from '../assets/2D_Icons/NodeOpened.svg'
import Hamburger from '../assets/2D_Icons/Menu.svg'
import useStore from '../store/useStore'


/**
pablo-mayrgundter marked this conversation as resolved.
Show resolved Hide resolved
* Navigation panel control is a button that toggles the visibility of nav panel
*
* @param {number} topOffset global offset defined in the cad view
* @param {Function} onClickMenuCb callback passed from cad view
* @return {object} The button react component
*/
export function NavPanelControl({topOffset, onClickMenuCb}) {
const classes = useStyles({topOffset: topOffset})
return (
<div className={classes.toggleButton}>
<Tooltip title="Model Navigation" placement="bottom">
<IconButton onClick={() => {
onClickMenuCb()
}}
>
<Hamburger className={classes.treeIcon}/>
</IconButton>
</Tooltip>
</div>
)
}

/**
* @param {object} model
* @param {object} element
Expand All @@ -47,14 +22,14 @@ export function NavPanelControl({topOffset, onClickMenuCb}) {
export default function NavPanel({
model,
element,
selectedElements,
defaultExpandedElements,
expandedElements,
setExpandedElements,
pathPrefix,
}) {
assertDefined(...arguments)
const classes = useStyles()
const selectedElements = useStore((state) => state.selectedElements)
// TODO(pablo): the defaultExpanded array can contain bogus IDs with
// no error. Not sure of a better way to pre-open the first few
// nodes besides hardcoding.
Expand Down
10 changes: 7 additions & 3 deletions src/Containers/CadView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export default function CadView({
const [rootElement, setRootElement] = useState({})
const [elementsById] = useState({})
const [defaultExpandedElements, setDefaultExpandedElements] = useState([])
const [selectedElements, setSelectedElements] = useState([])
const [expandedElements, setExpandedElements] = useState([])

// UI elts
Expand All @@ -76,6 +75,8 @@ export default function CadView({

const setViewerStore = useStore((state) => state.setViewerStore)
const snackMessage = useStore((state) => state.snackMessage)
const setSelectedElements = useStore((state) => state.setSelectedElements)
const setCutPlaneDirection = useStore((state) => state.setCutPlaneDirection)


/* eslint-disable react-hooks/exhaustive-deps */
Expand Down Expand Up @@ -341,9 +342,13 @@ export default function CadView({

/** Unpick active scene elts and remove clip planes. */
function unSelectItems() {
setSelectedElement({})
setSelectedElement(null)
viewer.IFC.unpickIfcItems()
viewer.clipper.deleteAllPlanes()
setSelectedElements(null)
setCutPlaneDirection(null)
const repoFilePath = modelPath.gitpath ? modelPath.getRepoPath() : modelPath.filepath
navigate(`${pathPrefix}${repoFilePath}`)
}


Expand Down Expand Up @@ -455,7 +460,6 @@ export default function CadView({
<NavPanel
model={model}
element={rootElement}
selectedElements={selectedElements}
defaultExpandedElements={defaultExpandedElements}
expandedElements={expandedElements}
setExpandedElements={setExpandedElements}
Expand Down
42 changes: 39 additions & 3 deletions src/Containers/CadView.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useState} from 'react'
import {render, renderHook, screen, waitFor} from '@testing-library/react'
import {render, renderHook, act, fireEvent, screen, waitFor} from '@testing-library/react'
import useStore from '../store/useStore'
import CadView from './CadView'
import ShareMock from '../ShareMock'
import {actAsyncFlush} from '../utils/tests'
Expand All @@ -12,7 +13,6 @@ describe('CadView', () => {
jest.clearAllMocks()
})


it('renders with mock IfcViewerAPI', async () => {
const modelPath = {
filepath: `index.ifc`,
Expand Down Expand Up @@ -66,5 +66,41 @@ describe('CadView', () => {
expect(getPropsCalls[1][1]).toBe(targetEltId) // call 2, arg 2
await actAsyncFlush()
})
})

it('clear elements and planes on unselect', async () => {
pablo-mayrgundter marked this conversation as resolved.
Show resolved Hide resolved
const testTree = makeTestTree()
const targetEltId = testTree.children[0].expressID
const modelPath = {
filepath: `index.ifc/${targetEltId}`,
gitpath: undefined,
}
const viewer = __getIfcViewerAPIMockSingleton()
viewer._loadedModel.ifcManager.getSpatialStructure.mockReturnValueOnce(testTree)
const {result} = renderHook(() => useStore((state) => state))
await act(() => {
// result.current.setSelectedElement(targetEltId)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These seem like good ones to add. Still WIP?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep totally - forgot to turn it on

// result.current.setSelectedElements([targetEltId])
result.current.setCutPlaneDirection('y')
})
const {getByTitle} = render(
<ShareMock>
<CadView
installPrefix={'/'}
appPrefix={'/'}
pathPrefix={'/'}
modelPath={modelPath}
/>
</ShareMock>)
expect(getByTitle('Section')).toBeInTheDocument()
const clearSelection = getByTitle('Clear selection')
act(() => {
fireEvent.click(clearSelection)
})
const callDeletePlanes = viewer.clipper.deleteAllPlanes.mock.calls
expect(callDeletePlanes.length).toBe(1)
expect(result.current.selectedElements).toBe(null)
expect(result.current.selectedElement).toBe(null)
expect(result.current.cutPlaneDirection).toBe(null)
await actAsyncFlush()
})
})
2 changes: 2 additions & 0 deletions src/store/IFCSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ export default function createIFCSlice(set, get) {
modelPath: null,
modelStore: null,
selectedElement: null,
selectedElements: [],
cameraControls: null,
setViewerStore: (viewer) => set(() => ({viewerStore: viewer})),
setModelPath: (modelPath) => set(() => ({modelPath: modelPath})),
setModelStore: (model) => set(() => ({modelStore: model})),
setSelectedElement: (element) => set(() => ({selectedElement: element})),
setSelectedElements: (elements) => set(() => ({selectedElements: elements})),
setCameraControls: (cameraControls) => set(() => ({cameraControls: cameraControls})),
}
}
2 changes: 2 additions & 0 deletions src/store/UISlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ export default function createUISlice(set, get) {
isPropertiesOn: false,
isCommentsOn: false,
snackMessage: null,
cutPlaneDirection: null,
openDrawer: () => set(() => ({isDrawerOpen: true})),
closeDrawer: () => set(() => ({isDrawerOpen: false})),
toggleIsPropertiesOn: () => set((state) => ({isPropertiesOn: !state.isPropertiesOn})),
toggleIsCommentsOn: () => set((state) => ({isCommentsOn: !state.isCommentsOn})),
turnCommentsOn: () => set(() => ({isCommentsOn: true})),
turnCommentsOff: () => set(() => ({isCommentsOn: false})),
setSnackMessage: (message) => set(() => ({snackMessage: message})),
setCutPlaneDirection: (direction) => set(() => ({cutPlaneDirection: direction})),
}
}