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

VYZN: Viewer: UI configuration via Matrix config message #525

Merged
merged 42 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f843f07
fix: turn off the y-axis lock of the ifc clipper component
Dec 2, 2022
1915e28
Merge branch 'main' of https://github.com/Ibrahim5aad/Share
Dec 10, 2022
6a81e63
refactor: widget api event registery and add support for ui visibilit…
Dec 20, 2022
33994d6
widget api package and version lock added
Dec 20, 2022
729f199
wire up ui visibility controls to ui components + supporting changes
Dec 20, 2022
03ca1ca
test: tidy up e2e tests and add test for ui visibility msg
Dec 20, 2022
22f53d5
Merge branch 'main' of https://github.com/Ibrahim5aad/Share
Dec 20, 2022
67919ce
Merge pull request #1 from bldrs-ai/main
Ibrahim5aad Dec 21, 2022
2ef525a
guard againist non initialized viewer
Dec 21, 2022
344c8ea
Merge branch 'main' of https://github.com/Ibrahim5aad/Share
Dec 21, 2022
d8851c8
fix: cad view failing 'selects the element ID from URL' test
Dec 21, 2022
8e0ca55
fix: ui components visibility modified to be set per button group
Dec 26, 2022
b7b7dc7
fix: ui visibility e2e test
Dec 26, 2022
37fb1d8
Merge branch 'feat/ui-config' of https://github.com/Ibrahim5aad/Share…
Dec 26, 2022
8a6d575
fix: linter issue in ops. group component
Dec 26, 2022
9ad9524
Merge branch 'feat/ui-config' of https://github.com/Ibrahim5aad/Share…
Dec 29, 2022
69a28a4
remoe unused hook
Dec 29, 2022
6f0c227
linter linebreak style
Dec 29, 2022
754b2e6
fix conflicts
Dec 29, 2022
2afc91c
Merge branch 'feat/ui-config'
Dec 29, 2022
826bfb5
fix linter linebreak rule
Dec 29, 2022
817a1ba
Removing ApiSlice For debouncing
aozien Jan 6, 2023
02db30e
merging Selection/Deselction into one Event
aozien Jan 6, 2023
79ba390
Model Loaded Event
aozien Jan 6, 2023
2337d90
porting initial changes to the test files
aozien Jan 6, 2023
93f1fa7
fix linting problems
aozien Jan 7, 2023
089bbfc
fix linting issues
aozien Jan 7, 2023
544580c
fix: guards order in SelectElementsEventHandler
Jan 9, 2023
2ea7850
fix: remove debouncing state setters
Jan 9, 2023
616d4cf
Merge pull request #2 from aozien/main
Ibrahim5aad Jan 9, 2023
716f8ba
fix: yarn lock conflicts
Jan 9, 2023
7805b56
Merge branch 'main' of https://github.com/Ibrahim5aad/Share
Jan 9, 2023
6dd9ded
Merge branch 'main' into main
Ibrahim5aad Jan 9, 2023
0162901
update yarn file
Jan 9, 2023
0321be2
update packages
Jan 9, 2023
7f087ae
Merge branch 'main' of https://github.com/Ibrahim5aad/Share
Jan 9, 2023
5b3b117
fix linter issues
Jan 9, 2023
1987a77
Merge branch 'master'
Jan 28, 2023
9befdd0
package version fix
Jan 28, 2023
f0274f6
refactor: arrays are equal utility
Jan 31, 2023
85a6305
fix: remove momentum model from e2e tests, use minimal ifc to interce…
Jan 31, 2023
e8e7a9b
version update
Jan 31, 2023
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
8 changes: 7 additions & 1 deletion cypress/e2e/ifc-model/load-sample-model.cy.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
describe('sample models', () => {
const REMOTE_IFC_URL = '**/Momentum.ifc'
const REMOTE_IFC_FIXTURE = 'TestFixture.ifc'
const REQUEST_SUCCESS_CODE = 200

context('when no model is loaded', () => {
beforeEach(() => {
cy.setCookie('isFirstTime', 'false')
Expand All @@ -22,12 +26,14 @@ describe('sample models', () => {
it('should load the Momentum model when selected', () => {
cy.findByRole('button', {name: 'Open IFC', timeout: 300000}).realClick()
cy.findByLabelText('Sample Projects').realClick()
cy.intercept('GET', REMOTE_IFC_URL, {fixture: REMOTE_IFC_FIXTURE}).as('loadModel')
cy.findByRole('listbox', {timeout: 300000}).within(() => {
cy.findByRole('option', {name: 'Momentum', timeout: 300000}).realClick()
cy.wait('@loadModel').its('response.statusCode').should('eq', REQUEST_SUCCESS_CODE)
})
cy.findByRole('listbox', {timeout: 300000}).should('not.exist')
cy.findByRole('tree', {label: 'IFC Navigator', timeout: 300000})
cy.findByText('Momentum / KNIK v3', {timeout: 300000})
cy.findByText('Proxy with extruded box', {timeout: 300000})
})
})
})
67 changes: 49 additions & 18 deletions cypress/e2e/integration/bldrs-inside-iframe.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const path = require('path')
describe('bldrs inside iframe', () => {
const SYSTEM_UNDER_TEST = '/cypress/static/bldrs-inside-iframe.html'
const KEYCODE_ESC = 27
const REQUEST_SUCCESS_CODE = 200
const REMOTE_IFC_URL = '**/Momentum.ifc'
const REMOTE_IFC_FIXTURE = 'TestFixture.ifc'

/**
* Copy web page to target directory to make it accessible to cypress.
Expand All @@ -36,67 +39,95 @@ describe('bldrs inside iframe', () => {
})

it('should emit ready-messsage when page load completes', () => {
// cy.get('@iframe').find('[data-ifc-model="1"]')
cy.get('#cbxIsReady').should('exist').and('be.checked')
})

it('should load model when LoadModel-message emitted', () => {
const model = 'Swiss-Property-AG/Momentum-Public/main/Momentum.ifc'
const modelRootNodeName = 'Momentum / KNIK v3'
const modelRootNodeName = 'Proxy with extruded box'

// cy.get('@iframe').find('[data-ifc-model="1"]').should('exist')
// cy.get('#messagesCount').contains('1') //First loaded message

cy.get('#txtSendMessageType').clear().type('ai.bldrs-share.LoadModel')
const msg = {
githubIfcPath: model,
}
cy.get('#txtSendMessagePayload').clear().type(JSON.stringify(msg), {parseSpecialCharSequences: false})

cy.intercept('GET', REMOTE_IFC_URL, {fixture: REMOTE_IFC_FIXTURE}).as('loadModel')

cy.get('#txtSendMessagePayload').clear()
.type(JSON.stringify(msg), {parseSpecialCharSequences: false})
cy.get('#btnSendMessage').click()
cy.wait('@loadModel').its('response.statusCode').should('eq', REQUEST_SUCCESS_CODE)
// cy.get('@iframe').find('[data-ifc-model="1"]').should('exist')
cy.get('@iframe').contains('span', modelRootNodeName).should('exist')
// cy.get('#messagesCount').contains('2') //Second loaded message received
})

it('should select element when SelectElements-message emitted', () => {
cy.get('#lastMessageReceivedAction').contains(/ModelLoaded/i)
const globalId = '02uD5Qe8H3mek2PYnMWHk1'
const expectedExpressId = '621'
// cy.get('@iframe').find('[data-ifc-model="1"]').should('exist')
cy.get('#txtSendMessageType').clear().type('ai.bldrs-share.SelectElements')
const msg = {
globalIds: [globalId],
}
cy.get('#txtSendMessagePayload').clear().type(JSON.stringify(msg), {parseSpecialCharSequences: false})
cy.get('@iframe').find('[data-model-ready="true"]').should('exist')
cy.get('#btnSendMessage').click()
cy.get('@iframe').findByRole('button', {name: /Properties/}).click()
// Bldrs itemProperties dialog appears to slice the ID across different rows
// therefore we currently need to do it this way as a workaround:
cy.get('iframe').iframe().contains('span', expectedExpressId[0]).should('exist')
cy.get('iframe').iframe().contains('span', expectedExpressId[1]).should('exist')
cy.get('iframe').iframe().contains('span', expectedExpressId[2]).should('exist')
cy.get('@iframe').contains('span', /621/).should('exist')
})

it('should emit ElementsSelected-message when element was selected from panel', () => {
cy.get('@iframe').find('[data-model-ready="true"]').should('exist')
it('should emit SelectionChanged-message when element was selected through the menu and when cleared', () => {
const targetElementId = '3vMqyUfHj3tgritpIZS4iG'
cy.get('#lastMessageReceivedAction').contains(/ModelLoaded/i)
cy.get('@iframe').findByText(/bldrs/i).click()
cy.get('@iframe').findByText(/build/i).click()
cy.get('@iframe').findByText(/every/i).click()
cy.get('@iframe').findByText(/thing/i).click()
cy.get('@iframe').findAllByText(/together/i).first().click()

cy.get('#txtLastMsg').should(($txtLastMsg) => {
const msg = JSON.parse($txtLastMsg.val())
assert.equal(msg.api, 'fromWidget')
assert.equal(msg.widgetId, 'bldrs-share')
assert.exists(msg.requestId)
assert.equal(msg.action, 'ai.bldrs-share.ElementsSelected')
assert.exists(msg.data)
assert.equal(msg.action, 'ai.bldrs-share.SelectionChanged')
assert.equal(msg.data['current'][0], targetElementId)
})
})

it('should emit ElementsDeSelected-message when selection was cleared', () => {
cy.get('@iframe').find('[data-model-ready="true"]').should('exist')
cy.get('@iframe').findByText(/bldrs/i).click()
cy.get('@iframe').findByText(/build/i).click()
cy.get('@iframe').findAllByText(/together/i).last().click()
cy.get('#lastMessageReceivedAction').contains(/SelectionChanged/i)

cy.get('@iframe').findByRole('button', {name: /Clear/}).click()

cy.get('#txtLastMsg').should(($txtLastMsg) => {
const msg = JSON.parse($txtLastMsg.val())
assert.equal(msg.api, 'fromWidget')
assert.equal(msg.widgetId, 'bldrs-share')
assert.exists(msg.requestId)
assert.equal(msg.action, 'ai.bldrs-share.ElementsDeSelected')
assert.exists(msg.data)
assert.equal(msg.action, 'ai.bldrs-share.SelectionChanged')
assert.equal(msg.data['current'].length, 0)
})
})

it('should hide UI components when UIComponentsVisibility-message emitted', () => {
cy.get('#txtSendMessageType').clear().type('ai.bldrs-share.UIComponentsVisibility')
const msg = {
navigationPanel: false,
modelInteraction: false,
}
cy.get('#txtSendMessagePayload').clear().type(JSON.stringify(msg), {parseSpecialCharSequences: false})
cy.get('#btnSendMessage').click()

cy.findByRole('tree', {label: 'IFC Navigator'}).should('not.exist')
cy.get('@iframe').findByRole('button', {name: /Notes/}).should('not.exist')
cy.get('@iframe').findByRole('button', {name: /Properties/}).should('not.exist')
cy.get('@iframe').findByRole('button', {name: /Section/}).should('not.exist')
cy.get('@iframe').findByRole('button', {name: /Clear/}).should('not.exist')
})
})
23 changes: 23 additions & 0 deletions cypress/fixtures/TestFixture.ifc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('IFC4'),'2;1');
FILE_NAME('example.ifc','2018-08-8',(''),(''),'','','');
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
#100=IFCPROJECT('UUID-Project',$,'Proxy with extruded box',$,$,$,$,(#201),#301);
#201=IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.0E-5,$,$);
#202=IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#201,$,.MODEL_VIEW.,$);
#301=IFCUNITASSIGNMENT((#311));
#311=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
#500=IFCBUILDING('UUID-building',$,'Test Building',$,$,#511,$,$,.ELEMENT.,$,$,$);
#519=IFCRELAGGREGATES('UUID-RelAggregates',$,$,$,#100,(#500));
#1000=IFCBUILDINGELEMENTPROXY('UUID-Proxy',$,'Proxy','sample proxy',$,$,#1010,$,$);
#1010=IFCPRODUCTDEFINITIONSHAPE($,$,(#1020));
#1020=IFCSHAPEREPRESENTATION(#202,'Body','SweptSolid',(#1021));
#1021=IFCEXTRUDEDAREASOLID(#1022,$,#1034,1.);
#1022=IFCRECTANGLEPROFILEDEF(.AREA.,'1m x 1m rectangle',$,1.,1.);
#1034=IFCDIRECTION((0.,0.,1.));
#10000=IFCRELCONTAINEDINSPATIALSTRUCTURE('UUID-Spatial',$,'Physical model',$,(#1000),#500);
ENDSEC;
END-ISO-10303-21;
38 changes: 34 additions & 4 deletions cypress/fixtures/bldrs-inside-iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,29 @@
<!-- Flag is set once Matrix Widget API is ready -->
<input id="cbxIsReady" type="checkbox"></input>
<label for="cbxIsReady">Is Ready</label>
<br/>

<!-- Contains the last message received from the iframe through Matrix Widget API -->
<input id="txtLastMsg" type="text"></input>
<label for="txtLastMsg">Last Message Received</label>
<br/>

<!-- Sends a message to the iframe through Matrix Widget API -->
<input id="txtSendMessageType" type="text" placeholder="message type"></input>
<input id="txtSendMessagePayload" type="text" placeholder="message payload"></input>
<input id="btnSendMessage" type="button" value="Send"></input>
<div class="send-actions d-flex">
<input id="txtSendMessageType" type="text" placeholder="message type"></input>
<input id="txtSendMessagePayload" type="text" placeholder="message payload"></input>
<input id="btnSendMessage" type="button" value="Send"></input>
<!-- Last Message Received info -->
<div class="msg-info d-flex" >
<div>
Messages Count: <span id="messagesCount">0</span>
</div>
<div>
Last Action Type: <span id="lastMessageReceivedAction">-</span>
</div>
</div>
</div>



<!-- Contains Bldrs in an iframe, the URL is set later -->
<iframe
Expand All @@ -39,5 +51,23 @@
height="90%">
</iframe>

<style>

.d-flex{
display: flex;
}

.msg-info div {
padding:4px;
margin: 2px;
border-radius: 5px;
background-color: #c7c7c7;
}

.send-actions > * {
margin-right: 0.5rem;
}

</style>
</body>
</html>