From cfc05fb413c3e951f8c1d1298a96f5088ef54ac5 Mon Sep 17 00:00:00 2001 From: John Cowen Date: Mon, 4 Jun 2018 10:48:40 +0100 Subject: [PATCH] Make sure `didAppear` and therefore `resize` is called on change Tables need to calculate their sizing depending on other things in the DOM. When a table is in a tab panel, some of these things aren't visible and therefore some values are zero during `didInsertElement`. This commit ensures that the resize calc of the table is performed when it's parent tab is clicked (and therefore when the table 'appears') --- ui-v2/app/components/tabular-collection.js | 16 +++++++--------- ui-v2/app/controllers/dc/nodes/show.js | 16 ++++++++++++++++ ui-v2/app/templates/dc/nodes/show.hbs | 2 +- ui-v2/app/utils/get-component-factory.js | 9 +++++++++ ui-v2/app/utils/qsa-factory.js | 5 +++++ .../unit/utils/get-component-factory-test.js | 10 ++++++++++ ui-v2/tests/unit/utils/qsa-factory-test.js | 10 ++++++++++ 7 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 ui-v2/app/utils/get-component-factory.js create mode 100644 ui-v2/app/utils/qsa-factory.js create mode 100644 ui-v2/tests/unit/utils/get-component-factory-test.js create mode 100644 ui-v2/tests/unit/utils/qsa-factory-test.js diff --git a/ui-v2/app/components/tabular-collection.js b/ui-v2/app/components/tabular-collection.js index 06d7a2793..8facc6c71 100644 --- a/ui-v2/app/components/tabular-collection.js +++ b/ui-v2/app/components/tabular-collection.js @@ -4,6 +4,7 @@ import identity from 'ember-collection/utils/identity'; import Grid from 'ember-collection/layouts/grid'; import SlotsMixin from 'ember-block-slots'; import style from 'ember-computed-style'; +import qsaFactory from 'consul-ui/utils/qsa-factory'; import { computed, get, set } from '@ember/object'; /** @@ -18,11 +19,8 @@ import { computed, get, set } from '@ember/object'; * in the future */ -// basic DOM selecting utility, emeber doesn't like you using `$` -// hence `$$` -const $$ = function(sel, context = document) { - return context.querySelectorAll(sel); -}; +// ember doesn't like you using `$` hence `$$` +const $$ = qsaFactory(); // basic pseudo CustomEvent interface // TODO: use actual custom events once I've reminded // myself re: support/polyfills @@ -159,18 +157,18 @@ export default Component.extend(SlotsMixin, { // TODO: Consider moving all DOM lookups here // this seems to be the earliest place I can get them window.addEventListener('resize', this.handler); - this.handler(); + this.didAppear(); }, willDestroyElement: function() { window.removeEventListener('resize', this.handler); }, + didAppear: function() { + this.handler(); + }, resize: function(e) { const $tbody = [...$$('tbody', this.element)][0]; const $appContent = [...$$('main > div')][0]; if ($appContent) { - // TODO: This is zero if the tabular collection is in a tab - // need to make sure this also is calculated when - // things become visible const rect = $tbody.getBoundingClientRect(); const $footer = [...$$('footer[role="contentinfo"]')][0]; const space = rect.top + $footer.clientHeight; diff --git a/ui-v2/app/controllers/dc/nodes/show.js b/ui-v2/app/controllers/dc/nodes/show.js index 06c5c4004..0884b5848 100644 --- a/ui-v2/app/controllers/dc/nodes/show.js +++ b/ui-v2/app/controllers/dc/nodes/show.js @@ -1,7 +1,11 @@ import Controller from '@ember/controller'; import { get, set } from '@ember/object'; +import { getOwner } from '@ember/application'; import WithFiltering from 'consul-ui/mixins/with-filtering'; +import qsaFactory from 'consul-ui/utils/qsa-factory'; +import getComponentFactory from 'consul-ui/utils/get-component-factory'; +const $$ = qsaFactory(); export default Controller.extend(WithFiltering, { queryParams: { s: { @@ -26,6 +30,18 @@ export default Controller.extend(WithFiltering, { ); }, actions: { + change: function(e) { + set(this, 'selectedTab', e.target.value); + const getComponent = getComponentFactory(getOwner(this)); + // Ensure tabular-collections sizing is recalculated + // now it is visible in the DOM + [...$$('.tab-section input[type="radio"]:checked + div table')].forEach(function(item) { + const component = getComponent(item); + if (component && typeof component.didAppear === 'function') { + getComponent(item).didAppear(); + } + }); + }, sortChecksByImportance: function(a, b) { const statusA = get(a, 'Status'); const statusB = get(b, 'Status'); diff --git a/ui-v2/app/templates/dc/nodes/show.hbs b/ui-v2/app/templates/dc/nodes/show.hbs index 66764222c..78586c65e 100644 --- a/ui-v2/app/templates/dc/nodes/show.hbs +++ b/ui-v2/app/templates/dc/nodes/show.hbs @@ -45,7 +45,7 @@ ) ) as |panel| }} - {{#tab-section id=panel.id selected=(eq (if selectedTab selectedTab 'health-checks') panel.id) onchange=(action (mut selectedTab) value="target.value")}} + {{#tab-section id=panel.id selected=(eq (if selectedTab selectedTab 'health-checks') panel.id) onchange=(action "change")}} {{partial panel.partial}} {{/tab-section}} {{/each}} diff --git a/ui-v2/app/utils/get-component-factory.js b/ui-v2/app/utils/get-component-factory.js new file mode 100644 index 000000000..5ebc174ca --- /dev/null +++ b/ui-v2/app/utils/get-component-factory.js @@ -0,0 +1,9 @@ +export default function(owner, key = '-view-registry:main') { + const components = owner.lookup(key); + return function(el) { + const id = el.getAttribute('id'); + if (id) { + return components[id]; + } + }; +} diff --git a/ui-v2/app/utils/qsa-factory.js b/ui-v2/app/utils/qsa-factory.js new file mode 100644 index 000000000..ff5770a34 --- /dev/null +++ b/ui-v2/app/utils/qsa-factory.js @@ -0,0 +1,5 @@ +export default function(doc = document) { + return function(sel, context = doc) { + return context.querySelectorAll(sel); + }; +} diff --git a/ui-v2/tests/unit/utils/get-component-factory-test.js b/ui-v2/tests/unit/utils/get-component-factory-test.js new file mode 100644 index 000000000..ad39e3ae2 --- /dev/null +++ b/ui-v2/tests/unit/utils/get-component-factory-test.js @@ -0,0 +1,10 @@ +import getComponentFactory from 'consul-ui/utils/get-component-factory'; +import { module, test } from 'qunit'; + +module('Unit | Utility | get component factory'); + +// Replace this with your real tests. +test('it works', function(assert) { + let result = getComponentFactory({ lookup: function() {} }); + assert.ok(result); +}); diff --git a/ui-v2/tests/unit/utils/qsa-factory-test.js b/ui-v2/tests/unit/utils/qsa-factory-test.js new file mode 100644 index 000000000..76ed1ea14 --- /dev/null +++ b/ui-v2/tests/unit/utils/qsa-factory-test.js @@ -0,0 +1,10 @@ +import qsaFactory from 'consul-ui/utils/qsa-factory'; +import { module, test } from 'qunit'; + +module('Unit | Utility | qsa factory'); + +// Replace this with your real tests. +test('it works', function(assert) { + let result = qsaFactory(); + assert.ok(result); +});