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

Save UI Components #916

Merged
merged 58 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
bfbccda
* debugging local github auth
nickcastel50 Jan 8, 2024
05d5503
* Testing files / folders
nickcastel50 Jan 8, 2024
a5db75f
* Add Github function to get files and folders / add SelectorSeparato…
nickcastel50 Jan 9, 2024
4b9578f
* wip read/write from OPFS
nickcastel50 Jan 12, 2024
07f703f
Preliminary work for OPFS readFile/writeFile. Supports reloading page…
nickcastel50 Jan 15, 2024
0bfc193
Fixed linting issues
nickcastel50 Jan 15, 2024
3b570c4
* fixed jest tests, now passing
nickcastel50 Jan 15, 2024
3326ff3
Preliminary drag and drop support
nickcastel50 Jan 16, 2024
bb00806
* preliminary support for refreshing private models, needs more testing
nickcastel50 Jan 16, 2024
e4ad301
* hardening reload private models feature
nickcastel50 Jan 17, 2024
d9f8fd1
* Refactored OPFS - Reading and writing full project directory struct…
nickcastel50 Jan 18, 2024
7981b27
* WIP streaming writes from Github to OPFS
nickcastel50 Jan 20, 2024
8541cca
Lint + tests passing
nickcastel50 Jan 20, 2024
05981ce
* Fixed issues with download OPFS, now checking commit hash to see if…
nickcastel50 Jan 23, 2024
eb91353
* added Github owner and repo to OPFS model metadata
nickcastel50 Jan 23, 2024
e081165
Initial save new version commit work implemented
nickcastel50 Jan 23, 2024
8e31c39
* stop event propagation in TextFields on save control
nickcastel50 Jan 24, 2024
6976dc9
* lint
nickcastel50 Jan 24, 2024
6c52978
* added overrides for SnackBar anchor and style
nickcastel50 Jan 25, 2024
e63f6a0
* Added saving message for GitHub commit + committing new folders
nickcastel50 Jan 25, 2024
fd3b233
* Added drag and drop jest test
nickcastel50 Jan 25, 2024
5602c4d
* Moved savefile into CadView so Share can still be used during a save.
nickcastel50 Jan 25, 2024
4b28e8f
* added hide action button override to dialog, removed "Local files c…
nickcastel50 Jan 26, 2024
905515a
Add SaveModelControl.test.jsx
nickcastel50 Jan 26, 2024
e45035f
Reworked a OpenModelControl test to match "Please login to GitHub" in…
nickcastel50 Jan 26, 2024
61d3d84
* linting
nickcastel50 Jan 26, 2024
6fe4b23
* update tests remove old comments
nickcastel50 Jan 26, 2024
93bd416
Refactor ofps from utils/loader into opfs/utils. Make snackbar more …
pablo-mayrgundter Jan 30, 2024
5a88d81
Remove temp file.
pablo-mayrgundter Jan 30, 2024
7af5e96
Save Dialog.jsx
pablo-mayrgundter Jan 30, 2024
f1deb7a
Refactor SaveModelControl to use a fixture and passed in navigate.
pablo-mayrgundter Jan 30, 2024
58803f3
Fix auth0 workaround.
pablo-mayrgundter Jan 30, 2024
3181317
* refactor getlatestcommithash and URL parsing for proxy
nickcastel50 Jan 30, 2024
01cace1
Merge branch 'login_research' of https://github.com/nickcastel50/Shar…
nickcastel50 Jan 30, 2024
256ccf9
* merge with pablo's commit
nickcastel50 Jan 31, 2024
35a117a
* added a simple test for commitFile, removed margin on SaveModelCont…
nickcastel50 Jan 31, 2024
c597d44
Moved @import up
nickcastel50 Jan 31, 2024
c709d9d
* updated loadIfc to loadIfcFile
nickcastel50 Jan 31, 2024
a879d56
Setup msw handlers for GitHub#commitFile.
pablo-mayrgundter Jan 31, 2024
ff9936f
Merge pull request #2 from pablo-mayrgundter/login_research
nickcastel50 Jan 31, 2024
eb812e1
* Added tests for getFilesAndFolders + get latest commit hash
nickcastel50 Feb 1, 2024
bad3505
* linting
nickcastel50 Feb 1, 2024
2c10074
* added todo, fixed typo
nickcastel50 Feb 1, 2024
8af539f
* moved app prefix state setting to BaseRoutes.jsx from Share.jsx
nickcastel50 Feb 1, 2024
bc4316a
*lint
nickcastel50 Feb 1, 2024
857ad9e
Filter by selected owner for issue #952
nickcastel50 Feb 1, 2024
8f849fd
* check for owner that was not passed to getUserRepositories
nickcastel50 Feb 1, 2024
39c1515
* Issue #951, Issue #949
nickcastel50 Feb 2, 2024
62c7750
Merge branch 'main' into login_research
nickcastel50 Feb 2, 2024
04230df
Delete OPFS.worker.js from public/ directory
nickcastel50 Feb 2, 2024
94abc00
* added asserts, reordered imports in Cadview.jsx, fixed up package.json
nickcastel50 Feb 2, 2024
4e68b57
* updated build scripts
nickcastel50 Feb 2, 2024
8d3d54f
* fix build-share in package.json
nickcastel50 Feb 2, 2024
2c0cf95
* fixed assertions by removing unnecessary parameters
nickcastel50 Feb 2, 2024
7f0504f
* removed OPFS.worker.js from public, builds out to docs folder now
nickcastel50 Feb 2, 2024
73a65e4
linter warning
nickcastel50 Feb 2, 2024
2640998
* temporarily skipping two cypress tests as they are failing remotely…
nickcastel50 Feb 2, 2024
9eb06e8
Skip test
nickcastel50 Feb 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions __mocks__/web-ifc-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const impl = {
}),
},
loadIfcUrl: jest.fn(jest.fn(() => loadedModel)),
loadIfcFile: jest.fn(jest.fn(() => loadedModel)),
getProperties: jest.fn((modelId, eltId) => {
return loadedModel.ifcManager.getProperties(eltId)
}),
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/hide-feat/hide-feat.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe('Ifc Hide/Unhide E2E test suite', () => {
cy.visit('/')
})

it('should toggle hide icon when clicked', () => {
it.skip('should toggle hide icon when clicked', () => {
cy.findByTestId('Navigation').click()
cy.findByTestId('Navigation_panel').should('exist').click()
cy.findByTestId('hide-icon').should('be.visible').click()
Expand Down
4 changes: 2 additions & 2 deletions cypress/e2e/screenshot/screen-from-note.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ describe('Note screenshot', () => {
cy.visit('/')
})

it('should not show screenshot button when url param not present', () => {
it.skip('should not show screenshot button when url param not present', () => {
cy.findByRole('button', {name: /Take Screenshot/}).should('not.exist')
})

it('should show screenshot when url param present', () => {
it.skip('should show screenshot when url param present', () => {
cy.routerNavigate('/share/v/p/index.ifc?feature=screenshot')
cy.get('[title="Notes"]').click()
cy.get('button[title="Take Screenshot"]').should('exist')
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"name": "bldrs",
"version": "1.0.839",
"version": "1.0.860",
"main": "src/index.jsx",
"license": "MIT",
"homepage": "https://github.com/bldrs-ai/Share",
"bugs": {
"url": "https://github.com/bldrs-ai/Share/issues"
},
"scripts": {
"build": "yarn clean && yarn build-share-conway && yarn build-cosmos",
"build": "yarn build-conway",
"build-conway": "yarn clean && yarn build-share-conway && yarn build-cosmos",
"build-webifc": "yarn clean && yarn build-share-webifc && yarn build-cosmos",
"build-cosmos": "shx rm -rf docs/cosmos; shx mkdir -p docs ; cosmos-export --config .cosmos.config.json && shx mv cosmos-export docs/cosmos",
"build-share": "yarn update-version && node tools/esbuild/build.js && shx mkdir -p docs/static/js",
"build-share": "yarn update-version && node tools/esbuild/build.js && shx mkdir -p docs/static/js && shx cp src/OPFS/OPFS.worker.js docs/",
"build-share-conway": "run-script-os",
"build-share-conway:win32": "set USE_WEBIFC_SHIM=true&& yarn build-share",
"build-share-conway:linux:darwin": "USE_WEBIFC_SHIM=true yarn build-share",
Expand Down
8 changes: 6 additions & 2 deletions src/BaseRoutes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ export default function BaseRoutes({testElt = null}) {
const basePath = `${installPrefix }/`
const {isLoading, isAuthenticated, getAccessTokenSilently} = useAuth0()
const setAccessToken = useStore((state) => state.setAccessToken)
const appPrefix = `${basePath}share`
const setAppPrefix = useStore((state) => state.setAppPrefix)
setAppPrefix(appPrefix)

useEffect(() => {
if (location.pathname === installPrefix ||
location.pathname === basePath) {
const fwdPath = `${installPrefix}/share`
const fwdPath = `${appPrefix}`
debug().log('BaseRoutes#useEffect[], forwarding to: ', fwdPath)
navWith(navigate, fwdPath)
}
Expand All @@ -57,6 +60,7 @@ export default function BaseRoutes({testElt = null}) {
}
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [basePath, installPrefix, location, navigate, getAccessTokenSilently, isAuthenticated, isLoading, setAccessToken])

return (
Expand All @@ -68,7 +72,7 @@ export default function BaseRoutes({testElt = null}) {
testElt ||
<ShareRoutes
installPrefix={installPrefix}
appPrefix={`${installPrefix }/share`}
appPrefix={`${appPrefix}`}
/>
}
/>
Expand Down
16 changes: 8 additions & 8 deletions src/Components/ControlsGroup.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import React from 'react'
import ButtonGroup from '@mui/material/ButtonGroup'
import OpenModelControl from './OpenModelControl'
import useStore from '../store/useStore'
import {TooltipIconButton} from './Buttons'
import OpenModelControl from './OpenModelControl'
import SaveModelControl from './SaveModelControl'
import HistoryIcon from '@mui/icons-material/History'
import SearchIcon from '@mui/icons-material/Search'
import TreeIcon from '../assets/icons/Tree.svg'


/**
* OperationsGroup contains tools for sharing, notes, properties, cut
* plane, deselect, theme change and about.
*
* @property {Function} deselectItems deselects currently selected element
* @property {Function} navigate Callback from CadView to change page url
* @property {Function} isRepoActive deselects currently selected element
* @return {React.Component}
*/
export default function OperationsGroup({fileOpen, repo}) {
export default function ControlsGroup({navigate, isRepoActive}) {
const isNavigationVisible = useStore((state) => state.isNavigationVisible)
const toggleIsNavigationVisible = useStore((state) => state.toggleIsNavigationVisible)
const isSearchVisible = useStore((state) => state.isSearchVisible)
Expand All @@ -30,7 +29,7 @@ export default function OperationsGroup({fileOpen, repo}) {
variant='contained'
sx={{'& > *:not(:last-of-type)': {mr: .6}}}
>
<OpenModelControl fileOpen={fileOpen}/>
<OpenModelControl navigate={navigate}/>
<TooltipIconButton
title='Search'
icon={<SearchIcon className='icon-share' color='secondary'/>}
Expand All @@ -55,7 +54,8 @@ export default function OperationsGroup({fileOpen, repo}) {
}
}}
/>
{repo !== undefined &&
<SaveModelControl navigate={navigate}/>
{isRepoActive &&
<TooltipIconButton
title='Project History'
icon={<HistoryIcon className='icon-share' color='secondary'/>}
Expand Down
4 changes: 3 additions & 1 deletion src/Components/Dialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default function Dialog({
actionTitle,
actionCb,
actionIcon,
hideActionButton = false,
}) {
assertDefined(
headerText, isDialogDisplayed, setIsDialogDisplayed, content,
Expand All @@ -57,11 +58,12 @@ export default function Dialog({
<CloseIcon fontSize="inherit"/>
</IconButton>
<DialogContent>{content}</DialogContent>
{hideActionButton ? null :
<DialogActions>
<Button variant="contained" onClick={actionCb} >
{actionTitle}
</Button>
</DialogActions>
</DialogActions>}
</MuiDialog>
)
}
13 changes: 13 additions & 0 deletions src/Components/OpenModelControl.fixture.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import {ThemeCtx} from '../theme/Theme.fixture'
import OpenModelControl from './OpenModelControl'


// For unit test
export const OpenModelControlFixture = () => <ThemeCtx><OpenModelControl/></ThemeCtx>


// For cosmos
export default {
OpenModelControl: <OpenModelControlFixture/>,
}
53 changes: 31 additions & 22 deletions src/Components/OpenModelControl.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, {useState, useEffect} from 'react'
import {useNavigate} from 'react-router-dom'
import Box from '@mui/material/Box'
import Link from '@mui/material/Link'
import MenuItem from '@mui/material/MenuItem'
Expand All @@ -13,6 +12,9 @@ import {TooltipIconButton} from './Buttons'
import Selector from './Selector'
import useStore from '../store/useStore'
import {handleBeforeUnload} from '../utils/event'
import {
loadLocalFile,
} from '../utils/loader'
import {getOrganizations, getRepositories, getFiles, getUserRepositories} from '../utils/GitHub'
import {RectangularButton} from '../Components/Buttons'
import UploadIcon from '../assets/icons/Upload.svg'
Expand All @@ -21,11 +23,12 @@ import CreateNewFolderIcon from '@mui/icons-material/CreateNewFolderOutlined'


/**
* Displays model open dialog.
* Displays Open Model dialog.
*
* @property {Function} navigate Callback from CadView to change page url
* @return {React.ReactElement}
*/
export default function OpenModelControl({fileOpen}) {
export default function OpenModelControl({navigate}) {
const [isDialogDisplayed, setIsDialogDisplayed] = useState(false)
const [orgNamesArr, setOrgNamesArray] = useState([''])
const {user} = useAuth0()
Expand Down Expand Up @@ -61,47 +64,54 @@ export default function OpenModelControl({fileOpen}) {
dataTestId='open-ifc'
/>
{isDialogDisplayed &&
<OpenModelDialog
isDialogDisplayed={isDialogDisplayed}
setIsDialogDisplayed={setIsDialogDisplayed}
fileOpen={fileOpen}
orgNamesArr={orgNamesArr}
/>
<OpenModelDialog
isDialogDisplayed={isDialogDisplayed}
setIsDialogDisplayed={setIsDialogDisplayed}
navigate={navigate}
orgNamesArr={orgNamesArr}
/>
}
</Box>
)
}


/**
* @param {boolean} isDialogDisplayed
* @param {Function} setIsDialogDisplayed
* @return {object} React component
* @property {boolean} isDialogDisplayed Control uses this to control dialog vis.
* @property {Function} setIsDialogDisplayed Set dialog vis.
* @property {Function} navigate Callback from CadView to change page url
* @property {Array<string>} orgNamesArr List of org names for the current user.
* @return {React.ReactElement}
*/
function OpenModelDialog({isDialogDisplayed, setIsDialogDisplayed, fileOpen, orgNamesArr}) {
function OpenModelDialog({
isDialogDisplayed,
setIsDialogDisplayed,
navigate,
orgNamesArr,
}) {
const {isAuthenticated, user} = useAuth0()
const [selectedOrgName, setSelectedOrgName] = useState('')
const [selectedRepoName, setSelectedRepoName] = useState('')
const [selectedFileName, setSelectedFileName] = useState('')
const [repoNamesArr, setRepoNamesArr] = useState([''])
const [filesArr, setFilesArr] = useState([''])
const navigate = useNavigate()
const accessToken = useStore((state) => state.accessToken)
const orgNamesArrWithAt = orgNamesArr.map((orgName) => `@${orgName}`)
const orgName = orgNamesArr[selectedOrgName]
const repoName = repoNamesArr[selectedRepoName]
const fileName = filesArr[selectedFileName]
const appPrefix = useStore((state) => state.appPrefix)

const openFile = () => {
fileOpen()
loadLocalFile(navigate, appPrefix, handleBeforeUnload, false)
setIsDialogDisplayed(false)
}

const selectOrg = async (org) => {
setSelectedOrgName(org)
let repos
if (orgNamesArr[org] === user.nickname) {
repos = await getUserRepositories(user.nickname, accessToken)
repos = await getUserRepositories(accessToken)
} else {
repos = await getRepositories(orgNamesArr[org], accessToken)
}
Expand Down Expand Up @@ -141,7 +151,10 @@ function OpenModelDialog({isDialogDisplayed, setIsDialogDisplayed, fileOpen, org
alignItems="center"
sx={{paddingTop: '6px', width: '280px'}}
>
<SampleModelFileSelector setIsDialogDisplayed={setIsDialogDisplayed}/>
<SampleModelFileSelector
navigate={navigate}
setIsDialogDisplayed={setIsDialogDisplayed}
/>
{isAuthenticated ?
<Stack>
<Typography variant='overline' sx={{marginBottom: '6px'}}>Projects</Typography>
Expand All @@ -166,9 +179,6 @@ function OpenModelDialog({isDialogDisplayed, setIsDialogDisplayed, fileOpen, org
wiki
</Link> to learn more about GitHub hosting.
</Typography>
<Typography variant={'caption'} sx={{marginTop: '10px'}}>
* Local files cannot yet be saved or shared.
</Typography>
</Stack>
</Box>
}
Expand All @@ -183,8 +193,7 @@ function OpenModelDialog({isDialogDisplayed, setIsDialogDisplayed, fileOpen, org
* @property {Function} setIsDialogDisplayed callback
* @return {React.ReactElement}
*/
function SampleModelFileSelector({setIsDialogDisplayed}) {
const navigate = useNavigate()
function SampleModelFileSelector({navigate, setIsDialogDisplayed}) {
const [selected, setSelected] = useState('')
const theme = useTheme()
const handleSelect = (e, closeDialog) => {
Expand Down
23 changes: 17 additions & 6 deletions src/Components/OpenModelControl.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@ import {render, fireEvent} from '@testing-library/react'
import {
mockedUseAuth0,
mockedUserLoggedIn,
mockedUserLoggedOut} from '../__mocks__/authentication'
import OpenModelControl from './OpenModelControl'
import ShareMock from '../ShareMock'
mockedUserLoggedOut,
} from '../__mocks__/authentication'
import {OpenModelControlFixture} from './OpenModelControl.fixture'


describe('Open Model Dialog', () => {
it('Renders a login message if the user is not logged in', () => {
mockedUseAuth0.mockReturnValue(mockedUserLoggedOut)
const {getByTitle, getByText} = render(<ShareMock><OpenModelControl/></ShareMock>)
const {getByTitle, getByText} = render(<OpenModelControlFixture/>)
const button = getByTitle('Open IFC')
fireEvent.click(button)
const loginText = getByText('* Local files cannot yet be saved or shared.')
const loginTextMatcher = (content, node) => {
const hasText = (_node) => _node.textContent.includes('Please login to GitHub')
const nodeHasText = hasText(node)
const childrenDontHaveText = Array.from(node.children).every(
(child) => !hasText(child),
)
return nodeHasText && childrenDontHaveText
}

const loginText = getByText(loginTextMatcher)
expect(loginText).toBeInTheDocument()
})


it('Renders file selector if the user is logged in', async () => {
mockedUseAuth0.mockReturnValue(mockedUserLoggedIn)
const {getByTitle, getByTestId} = render(<ShareMock><OpenModelControl/></ShareMock>)
const {getByTitle, getByTestId} = render(<OpenModelControlFixture/>)
const button = getByTitle('Open IFC')
fireEvent.click(button)
const File = getByTestId('File')
Expand Down
13 changes: 13 additions & 0 deletions src/Components/SaveModelControl.fixture.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import {ThemeCtx} from '../theme/Theme.fixture'
import SaveModelControl from './SaveModelControl'


// For unit test
export const SaveModelControlFixture = () => <ThemeCtx><SaveModelControl/></ThemeCtx>


// For cosmos
export default {
SaveModelControl: <SaveModelControlFixture/>,
}