diff --git a/app/adapters/application.js b/app/adapters/application.js index 1ec0aad10ed72c8bf4b826f233eeafbe6d1345b5..3e8a768ec2ab16f1af3c589c0b7e44fbc889d197 100644 --- a/app/adapters/application.js +++ b/app/adapters/application.js @@ -7,7 +7,7 @@ import UrlTemplates from "ember-data-url-templates"; * @return {Adapter} adapter that is used for all metamodel models */ export default BaseAdapter.extend(UrlTemplates, { - urlTemplate: '{+host}/{+namespace}/systems{/systemId}/{pathForType}/{/id}', + urlTemplate: '{+host}/{+namespace}/{pathForType}{/id}', findAllUrlTemplate: '{+host}/{+namespace}/systems{/systemId}/{pathForType}/{?query*}', urlSegments: { diff --git a/app/components/architecture-visualisation-cytoscape/component.js b/app/components/architecture-visualisation-cytoscape/component.js index e0de2b8743cf11642b0970fc625abdb8258624b7..f07e1506fb173002d294fa1388aee455bcfff283 100644 --- a/app/components/architecture-visualisation-cytoscape/component.js +++ b/app/components/architecture-visualisation-cytoscape/component.js @@ -9,8 +9,8 @@ import coseBilkent from 'npm:cytoscape-cose-bilkent'; coseBilkent(cytoscape); // register export default Ember.Component.extend({ - theme: null, - layoutAlgorithm: 'cose', + theme: null, // set by architecture-viewer + layoutAlgorithm: null, // set by architecture-viewer classNames: ['cytoscapeRenderingSpace'], init: function() { cycola( cytoscape, window.cola ); @@ -37,10 +37,10 @@ export default Ember.Component.extend({ layout: { name: this.get('layoutAlgorithm'), - maxSimulationTime: 1000, - padding: 6, - ungrabifyWhileSimulating: true, - infinite: false + // maxSimulationTime: 1000, + // padding: 6, + // ungrabifyWhileSimulating: true, + // infinite: false } }); diff --git a/app/components/entity-details.js b/app/components/entity-details.js new file mode 100644 index 0000000000000000000000000000000000000000..bd26aa6bbfa3ca677fd826a0fdcb3a4a73d4a953 --- /dev/null +++ b/app/components/entity-details.js @@ -0,0 +1,5 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + entity: null +}); diff --git a/app/router.js b/app/router.js index 7b6ee52098cc730579653149d620aa896645c608..211b13269183bfe32395e7eb19fb39a9c252544a 100644 --- a/app/router.js +++ b/app/router.js @@ -8,7 +8,9 @@ const Router = Ember.Router.extend({ Router.map(function() { this.route('home', {path: '/'}); this.route('architectures', function() { - this.route('single', {path: '/:systemId'}); + this.route('single', {path: '/:systemId'}, function() { + this.route('details', {path: '/:entityType/:entityId'}); // use model properties for automatic matching + }); }); }); diff --git a/app/routes/architectures/single.js b/app/routes/architectures/single.js index 606496cde55c7d37286c767af1485bc81ef8af40..b89ac00578ac47d9a8940b3b3d6c1a86a555f63e 100644 --- a/app/routes/architectures/single.js +++ b/app/routes/architectures/single.js @@ -28,5 +28,22 @@ export default Ember.Route.extend({ this.set('loading', false); return graph; }); + }, + actions: { + loadDetails(rawEntity) { + this.debug('loadDetails action', rawEntity); + const entityType = rawEntity.type.toLowerCase(); + const entityId = rawEntity.id; + + /* I would love to not generate the url first, but there seem to be unknown (to me) assumptions about + * passing object parameters to transitionTo which break with the current path variables. + */ + const url = this.router.generate('architectures.single.details', { + systemId: this.get('session.systemId'), + entityType, + entityId + }); + this.transitionTo(url); + } } }); diff --git a/app/routes/architectures/single/details.js b/app/routes/architectures/single/details.js new file mode 100644 index 0000000000000000000000000000000000000000..8ef736718125dcc37e3e1a18bfb5b43e375e4939 --- /dev/null +++ b/app/routes/architectures/single/details.js @@ -0,0 +1,7 @@ +import Ember from 'ember'; + +export default Ember.Route.extend({ + model(params) { + return this.store.findRecord(params.entityType.toLowerCase(), params.entityId); // TODO: match entity.type with model names + } +}); diff --git a/app/templates/architectures/single.hbs b/app/templates/architectures/single.hbs index c46db6911150dc6a7b68536aca7bc41433d8e788..46f98c443ab171dbc00c1d8f65c7a9f81244d394 100644 --- a/app/templates/architectures/single.hbs +++ b/app/templates/architectures/single.hbs @@ -1 +1,4 @@ -{{architecture-viewer graph=model}} \ No newline at end of file +{{#architecture-viewer graph=model}} + {{!-- show entity details in sidebar if subroute (details) is used --}} + {{outlet}} +{{/architecture-viewer}} \ No newline at end of file diff --git a/app/templates/architectures/single/details.hbs b/app/templates/architectures/single/details.hbs new file mode 100644 index 0000000000000000000000000000000000000000..f4b648a85bdddd471fd7e449de5d4f548ac23f0a --- /dev/null +++ b/app/templates/architectures/single/details.hbs @@ -0,0 +1,2 @@ +Hello Subroute! +{{entity-details entity=model}} \ No newline at end of file diff --git a/app/templates/components/architecture-viewer.hbs b/app/templates/components/architecture-viewer.hbs index f780a96394e94495402aba831099f3cf6f39e1a2..915841f3b7b997febf8a6488472d5eaa2af5bf2f 100644 --- a/app/templates/components/architecture-viewer.hbs +++ b/app/templates/components/architecture-viewer.hbs @@ -1,8 +1,8 @@ <div class="row"> <div class="col-md-10 visualisationContainer"> - {{architecture-visualisation-cytoscape graph=graph layoutAlgorithm=layoutAlgorithm theme=theme select=(action "graphClick")}} + {{architecture-visualisation-cytoscape graph=graph layoutAlgorithm=layoutAlgorithm theme=theme select=(route-action 'loadDetails')}} </div> - <div class="col-md-2 visualistaionSidebar"> + <div class="col-md-2 visualisationSidebar"> <div class="form-group"> <label for="layoutAlgorithm">Layout:</label> <select class="form-control" id="layoutAlgorithm" onchange={{action "selectLayoutAlgorithm" value="target.value"}}> @@ -20,10 +20,8 @@ </select> </div> - {{#if entityDetails}} - <h3>Details</h3> - {{entityDetails.type}} - {{/if}} + {{!-- this component can be used as a block, show content --}} + {{yield}} </div> </div> diff --git a/app/templates/components/entity-details.hbs b/app/templates/components/entity-details.hbs new file mode 100644 index 0000000000000000000000000000000000000000..541c63a0d49277e8f3861e17c5c3ed1736393a38 --- /dev/null +++ b/app/templates/components/entity-details.hbs @@ -0,0 +1,6 @@ +id: {{entity.id}} +name: {{entity.name}} +type: {{entity.type}} +systemId: {{entity.systemId}} + +{{log 'entity-details' entity}} diff --git a/package.json b/package.json index 7b621aa58a48e47c0a6b2bf3d9e7e24bf8330ff4..a5a27416380d3799e7fed660c7b3e7159d20e3cf 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "ember-export-application-global": "^1.0.4", "ember-load-initializers": "^0.5.0", "ember-resolver": "^2.0.3", + "ember-route-action-helper": "0.3.2", "loader.js": "^4.0.0", "lodash": "^4.11.1", "node-sass": "^3.8.0" diff --git a/tests/integration/components/entity-details-test.js b/tests/integration/components/entity-details-test.js new file mode 100644 index 0000000000000000000000000000000000000000..0b5314dcb3e2dac7576b05382b6f108c33c18598 --- /dev/null +++ b/tests/integration/components/entity-details-test.js @@ -0,0 +1,24 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('entity-details', 'Integration | Component | entity details', { + integration: true +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{entity-details}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#entity-details}} + template block text + {{/entity-details}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +});