diff --git a/app/components/container-picker.js b/app/components/container-picker.js
new file mode 100644
index 0000000000..40d642b65c
--- /dev/null
+++ b/app/components/container-picker.js
@@ -0,0 +1,11 @@
+import Component from '@ember/component';
+
+export default Component.extend({
+ containers: null,
+
+ actions: {
+ onSelect(containerId) {
+ this.sendAction('selectContainer', containerId);
+ }
+ }
+});
diff --git a/app/controllers/containers.js b/app/controllers/containers.js
new file mode 100644
index 0000000000..ba528c4853
--- /dev/null
+++ b/app/controllers/containers.js
@@ -0,0 +1,7 @@
+import Controller from '@ember/controller';
+import { sort } from '@ember/object/computed';
+
+export default Controller.extend({
+ sortProperties: ['container_type_id', 'container_instance_id'],
+ sorted: sort('model', 'sortProperties')
+});
diff --git a/app/router.js b/app/router.js
index eb2894c15a..124272f7cd 100644
--- a/app/router.js
+++ b/app/router.js
@@ -30,13 +30,16 @@ Router.map(function() {
});
this.route('render-tree', { resetNamespace: true });
- this.route('container-types', { resetNamespace: true }, function() {
- this.route('container-type', { path: '/:type_id', resetNamespace: true });
+ this.route('containers', { path: '/containers', resetNamespace: true }, function() {
+ this.route('container', { path: '/:container_type_id/instance/:container_instance_id' }, function() {
+ this.route('container-types', { path: '/type' }, function() {
+ this.route('container-type', { path: '/:type_id' });
+ });
+ });
});
this.route('deprecations', { resetNamespace: true });
});
-
});
export default Router;
diff --git a/app/routes/container-types/index.js b/app/routes/container-types/index.js
deleted file mode 100644
index 7490103e31..0000000000
--- a/app/routes/container-types/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import TabRoute from "ember-inspector/routes/tab";
-export default TabRoute;
diff --git a/app/routes/containers.js b/app/routes/containers.js
new file mode 100644
index 0000000000..3a3d0b8556
--- /dev/null
+++ b/app/routes/containers.js
@@ -0,0 +1,29 @@
+import TabRoute from "ember-inspector/routes/tab";
+
+export default TabRoute.extend({
+ model() {
+ const port = this.get('port');
+ return new Promise(resolve => {
+ port.one('container:all', function(message) {
+ let container_type_id, container_instance_id, containers;
+ containers = message.containers.map(function(containerRef) {
+ [container_type_id, container_instance_id] = containerRef.split(':');
+ return {
+ container_type_id,
+ container_instance_id
+ }
+ });
+ resolve(containers);
+ });
+ port.send('container:all');
+ });
+ },
+
+ actions: {
+ selectContainer(containerIndex) {
+ let containerRef;
+ containerRef = this.get('controller.model').objectAt(containerIndex);
+ this.transitionTo('containers.container', containerRef);
+ }
+ }
+});
diff --git a/app/routes/containers/container.js b/app/routes/containers/container.js
new file mode 100644
index 0000000000..6f5c7f18d8
--- /dev/null
+++ b/app/routes/containers/container.js
@@ -0,0 +1,7 @@
+import Route from '@ember/routing/route';
+
+export default Route.extend({
+ model(params) {
+ return params;
+ }
+});
diff --git a/app/routes/container-types.js b/app/routes/containers/container/container-types.js
similarity index 59%
rename from app/routes/container-types.js
rename to app/routes/containers/container/container-types.js
index 9307c188d0..11594b24ec 100644
--- a/app/routes/container-types.js
+++ b/app/routes/containers/container/container-types.js
@@ -2,13 +2,17 @@ import Route from '@ember/routing/route';
import { Promise } from 'rsvp';
export default Route.extend({
+ controllerName: 'container-types',
+
model() {
+ let containerRef = this.modelFor('containers.container');
const port = this.get('port');
return new Promise(resolve => {
port.one('container:types', function(message) {
resolve(message.types);
});
- port.send('container:getTypes');
+ containerRef = containerRef.container_type_id+':'+containerRef.container_instance_id;
+ port.send('container:getTypes', { containerRef });
});
},
actions: {
diff --git a/app/routes/container-type.js b/app/routes/containers/container/container-types/container-type.js
similarity index 62%
rename from app/routes/container-type.js
rename to app/routes/containers/container/container-types/container-type.js
index 970c6e87dc..af2c9e0a56 100644
--- a/app/routes/container-type.js
+++ b/app/routes/containers/container/container-types/container-type.js
@@ -1,8 +1,10 @@
import { Promise } from 'rsvp';
import { get } from '@ember/object';
-import TabRoute from "ember-inspector/routes/tab";
+import Route from '@ember/routing/route';
+
+export default Route.extend({
+ controllerName: 'container-type',
-export default TabRoute.extend({
setupController(controller) {
controller.setProperties({
search: '',
@@ -11,8 +13,9 @@ export default TabRoute.extend({
this._super(...arguments);
},
model(params) {
- const type = params.type_id;
+ const containerType = params.type_id;
const port = this.get('port');
+ let containerRef = this.modelFor('containers.container');
return new Promise((resolve, reject) => {
port.one('container:instances', message => {
if (message.status === 200) {
@@ -21,7 +24,8 @@ export default TabRoute.extend({
reject(message);
}
});
- port.send('container:getInstances', { containerType: type });
+ containerRef = containerRef.container_type_id+':'+containerRef.container_instance_id;
+ port.send('container:getInstances', { containerRef, containerType });
});
},
@@ -29,7 +33,7 @@ export default TabRoute.extend({
actions: {
error(err) {
if (err && err.status === 404) {
- this.transitionTo('container-types.index');
+ this.transitionTo('containers.container.containers-types.container-type.index');
return false;
}
},
diff --git a/app/routes/containers/container/container-types/index.js b/app/routes/containers/container/container-types/index.js
new file mode 100644
index 0000000000..64ddf589ad
--- /dev/null
+++ b/app/routes/containers/container/container-types/index.js
@@ -0,0 +1,8 @@
+import Route from '@ember/routing/route';
+
+export default Route.extend({
+ afterModel() {
+ let containerType = this.modelFor('containers.container.container-types').firstObject;
+ return this.transitionTo('containers.container.container-types.container-type', containerType.name);
+ }
+});
diff --git a/app/routes/containers/container/index.js b/app/routes/containers/container/index.js
new file mode 100644
index 0000000000..3bede5fdee
--- /dev/null
+++ b/app/routes/containers/container/index.js
@@ -0,0 +1,7 @@
+import Route from '@ember/routing/route';
+
+export default Route.extend({
+ beforeModel() {
+ this.transitionTo('containers.container.container-types');
+ }
+});
diff --git a/app/routes/containers/index.js b/app/routes/containers/index.js
new file mode 100644
index 0000000000..b94f0f28d9
--- /dev/null
+++ b/app/routes/containers/index.js
@@ -0,0 +1,11 @@
+import Route from '@ember/routing/route';
+
+export default Route.extend({
+ beforeModel() {
+ let containers = this.modelFor('containers');
+ if (containers) {
+ this.transitionTo('containers.container', containers[0]);
+ }
+ }
+});
+
diff --git a/app/templates/components/container-picker.hbs b/app/templates/components/container-picker.hbs
new file mode 100644
index 0000000000..c9e611b91c
--- /dev/null
+++ b/app/templates/components/container-picker.hbs
@@ -0,0 +1,8 @@
+
+
+ {{#each containers as |containerRef index|}}
+ {{containerRef.container_type_id}}:{{containerRef.container_instance_id}}
+ {{/each}}
+
+ {{svg-jar "dropdown-arrow" class="dropdown__arrow"}}
+
\ No newline at end of file
diff --git a/app/templates/components/item-types.hbs b/app/templates/components/item-types.hbs
index dd40b64493..1050e5b3f9 100644
--- a/app/templates/components/item-types.hbs
+++ b/app/templates/components/item-types.hbs
@@ -13,13 +13,14 @@
{{#each sorted as |itemType|}}
{{#link-to
- (if (eq type "model") "records" "container-type")
+ (if (eq type "model") "records" "containers.container.container-types.container-type")
(escape-url itemType.name)
}}
{{itemType.name}}
({{itemType.count}} )
+
{{/link-to}}
{{/each}}
diff --git a/app/templates/container-types/index-toolbar.hbs b/app/templates/containers-toolbar.hbs
similarity index 77%
rename from app/templates/container-types/index-toolbar.hbs
rename to app/templates/containers-toolbar.hbs
index cfe85a1470..6d96d2b189 100644
--- a/app/templates/container-types/index-toolbar.hbs
+++ b/app/templates/containers-toolbar.hbs
@@ -1,4 +1,6 @@
+ {{container-picker containers=sorted selectContainer='selectContainer'}}
+
{{reload-button
action="reload"
classNames="toolbar__icon-button js-reload-container-btn"
diff --git a/app/templates/containers.hbs b/app/templates/containers.hbs
new file mode 100644
index 0000000000..e2147cab02
--- /dev/null
+++ b/app/templates/containers.hbs
@@ -0,0 +1 @@
+{{outlet}}
\ No newline at end of file
diff --git a/app/templates/containers/container.hbs b/app/templates/containers/container.hbs
new file mode 100644
index 0000000000..e2147cab02
--- /dev/null
+++ b/app/templates/containers/container.hbs
@@ -0,0 +1 @@
+{{outlet}}
\ No newline at end of file
diff --git a/app/templates/container-types.hbs b/app/templates/containers/container/container-types.hbs
similarity index 100%
rename from app/templates/container-types.hbs
rename to app/templates/containers/container/container-types.hbs
diff --git a/app/templates/container-type.hbs b/app/templates/containers/container/container-types/container-type.hbs
similarity index 100%
rename from app/templates/container-type.hbs
rename to app/templates/containers/container/container-types/container-type.hbs
diff --git a/app/templates/nav.hbs b/app/templates/nav.hbs
index 6e2683eaac..f72482f512 100644
--- a/app/templates/nav.hbs
+++ b/app/templates/nav.hbs
@@ -47,7 +47,7 @@
{{/link-to}}
- {{#link-to "container-types"}}
+ {{#link-to "containers"}}
{{svg-jar "nav-container" width="20px" height="20px"}}
Container
{{/link-to}}
diff --git a/ember_debug/container-debug.js b/ember_debug/container-debug.js
index fe7cf6bd79..23f49db9ed 100644
--- a/ember_debug/container-debug.js
+++ b/ember_debug/container-debug.js
@@ -37,10 +37,34 @@ export default EmberObject.extend(PortMixin, {
return type[0] === '-' || this.get('TYPES_TO_SKIP').indexOf(type) !== -1;
},
- instancesByType() {
+ all() {
+ let containers = [
+ 'app:main'
+ ];
+
+ const router = this.get('container').lookup('router:main');
+ containers.pushObjects( Object.keys(router._engineInfoByRoute).map(function(key) {
+ return router._engineInfoByRoute[key].name + ':' + router._engineInfoByRoute[key].instanceId;}
+ ).uniq());
+
+ return containers;
+ },
+
+ getContainer(containerRef) {
+ if (containerRef === 'app:main') {
+ return this.get('container');
+ } else {
+ const router = this.get('container').lookup('router:main');
+ let container_type_id, container_instance_id;
+ [container_type_id, container_instance_id] = containerRef.split(':');
+ return router._engineInstances[container_type_id][container_instance_id].__container__;
+ }
+ },
+
+ instancesByType(container) {
let key;
let instancesByType = {};
- let cache = this.get('container').cache;
+ let cache = container.cache;
// Detect if InheritingDict (from Ember < 1.8)
if (typeof cache.dict !== 'undefined' && typeof cache.eachLocal !== 'undefined') {
cache = cache.dict;
@@ -59,18 +83,20 @@ export default EmberObject.extend(PortMixin, {
return instancesByType;
},
- getTypes() {
+ getTypes(containerRef) {
let key;
let types = [];
- const instancesByType = this.instancesByType();
+ const container = this.getContainer(containerRef);
+ const instancesByType = this.instancesByType(container);
for (key in instancesByType) {
types.push({ name: key, count: instancesByType[key].length });
}
return types;
},
- getInstances(type) {
- const instances = this.instancesByType()[type];
+ getInstances(containerRef, type) {
+ const container = this.getContainer(containerRef);
+ const instances = this.instancesByType(container)[type];
if (!instances) {
return null;
}
@@ -82,13 +108,19 @@ export default EmberObject.extend(PortMixin, {
},
messages: {
- getTypes() {
+ all() {
+ this.sendMessage('all', {
+ containers: this.all()
+ });
+ },
+
+ getTypes(message) {
this.sendMessage('types', {
- types: this.getTypes()
+ types: this.getTypes(message.containerRef)
});
},
getInstances(message) {
- let instances = this.getInstances(message.containerType);
+ let instances = this.getInstances(message.containerRef, message.containerType);
if (instances) {
this.sendMessage('instances', {
instances,
diff --git a/ember_debug/route-debug.js b/ember_debug/route-debug.js
index 0bace22f07..7ad56c517d 100644
--- a/ember_debug/route-debug.js
+++ b/ember_debug/route-debug.js
@@ -143,10 +143,18 @@ function buildSubTree(routeTree, route) {
const router = this.get('router');
const routerLib = router._routerMicrolib || router.router;
- routeHandler = routerLib.getHandler(handler);
- controllerName = routeHandler.get('controllerName') || routeHandler.get('routeName');
- controllerFactory = owner.factoryFor ? owner.factoryFor(`controller:${controllerName}`) : owner._lookupFactory(`controller:${controllerName}`);
- controllerClassName = this.getClassName(controllerName, 'controller');
+ let isWithinEngine = router._engineInfoByRoute[handler];
+ let hasBeenLoaded = router._seenHandlers[handler];
+ if (isWithinEngine && !hasBeenLoaded) {
+ controllerName = 'Unloaded controller name';
+ controllerFactory = true;
+ controllerClassName = 'Unloaded controller class name';
+ } else {
+ routeHandler = routerLib.getHandler(handler);
+ controllerName = routeHandler.get('controllerName') || routeHandler.get('routeName');
+ controllerFactory = owner.factoryFor ? owner.factoryFor(`controller:${controllerName}`) : owner._lookupFactory(`controller:${controllerName}`);
+ controllerClassName = this.getClassName(controllerName, 'controller');
+ }
templateName = this.getClassName(handler, 'template');
subTree[handler] = {
diff --git a/tests/integration/components/container-picker-test.js b/tests/integration/components/container-picker-test.js
new file mode 100644
index 0000000000..926bacc54e
--- /dev/null
+++ b/tests/integration/components/container-picker-test.js
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import hbs from 'htmlbars-inline-precompile';
+
+module('Integration | Component | container-picker', function(hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function(assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs`{{container-picker}}`);
+
+ assert.equal(this.element.textContent.trim(), '');
+
+ // Template block usage:
+ await render(hbs`
+ {{#container-picker}}
+ template block text
+ {{/container-picker}}
+ `);
+
+ assert.equal(this.element.textContent.trim(), 'template block text');
+ });
+});
diff --git a/tests/unit/routes/container-test.js b/tests/unit/routes/container-test.js
new file mode 100644
index 0000000000..f22641c3ba
--- /dev/null
+++ b/tests/unit/routes/container-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | container', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:container');
+ assert.ok(route);
+ });
+});
diff --git a/tests/unit/routes/containers-test.js b/tests/unit/routes/containers-test.js
new file mode 100644
index 0000000000..2dbe90393a
--- /dev/null
+++ b/tests/unit/routes/containers-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'ember-qunit';
+
+module('Unit | Route | containers', function(hooks) {
+ setupTest(hooks);
+
+ test('it exists', function(assert) {
+ let route = this.owner.lookup('route:containers');
+ assert.ok(route);
+ });
+});