From b88e94b85bb9627067eb8cd596709a10f320ecb5 Mon Sep 17 00:00:00 2001
From: Chelsea Shaw
Date: Wed, 1 Jul 2020 12:50:02 -0500
Subject: [PATCH] Update TTL picker on add replication secondary (#9271)
* Update TTL picker on add replication secondary
This change updates the TTL picker to the new version to match most updated designs. The component also allows the default value to be more obvious
* Remove erroneous else
* Add changeOnInit param for TtlPicker2 and use it on add secondary page
* Update ttlPicker2 docs and add tests for new param
* Calculate value in unit provided on init for ttl-picker2, with tests
* Cleanup and make ttl-picker2 test more specific
---
ui/lib/core/addon/components/ttl-picker2.js | 31 +++++++++--
ui/lib/core/stories/ttl-picker2.md | 1 +
.../addon/controllers/mode/secondaries/add.js | 8 ++-
.../addon/templates/mode/secondaries/add.hbs | 15 +++--
.../components/ttl-picker2-test.js | 55 +++++++++++++++++--
5 files changed, 91 insertions(+), 19 deletions(-)
diff --git a/ui/lib/core/addon/components/ttl-picker2.js b/ui/lib/core/addon/components/ttl-picker2.js
index 808183d77b..622b255d81 100644
--- a/ui/lib/core/addon/components/ttl-picker2.js
+++ b/ui/lib/core/addon/components/ttl-picker2.js
@@ -18,6 +18,7 @@
* @param recalculationTimeout=5000 {Number} - This is the time, in milliseconds, that `recalculateSeconds` will be be true after time is updated
* @param initialValue=null {String} - This is the value set initially (particularly from a string like '30h')
* @param initialEnabled=null {Boolean} - Set this value if you want the toggle on when component is mounted
+ * @param changeOnInit=false {Boolean} - set this value if you'd like the passed onChange function to be called on component initialization
*/
import Ember from 'ember';
@@ -34,6 +35,7 @@ const secondsMap = {
h: 3600,
d: 86400,
};
+const validUnits = ['s', 'm', 'h', 'd'];
const convertToSeconds = (time, unit) => {
return time * secondsMap[unit];
};
@@ -52,37 +54,54 @@ export default Component.extend({
unit: 's',
recalculationTimeout: 5000,
initialValue: null,
+ changeOnInit: false,
init() {
this._super(...arguments);
const value = this.initialValue;
const enable = this.initialEnabled;
+ const changeOnInit = this.changeOnInit;
// if initial value is unset use params passed in as defaults
if (!value && value !== 0) {
return;
}
- let seconds = 30;
+ let time = 30;
+ let unit = 's';
let setEnable = this.enableTTL;
if (!!enable || typeOf(enable) === 'boolean') {
// This allows non-boolean values passed in to be evaluated for truthiness
setEnable = !!enable;
}
+
if (typeOf(value) === 'number') {
- seconds = value;
+ // if the passed value is a number, assume unit is seconds
+ time = value;
} else {
try {
- seconds = Duration.parse(value).seconds();
+ const seconds = Duration.parse(value).seconds();
+ const lastDigit = value.toString().substring(value.length - 1);
+ if (validUnits.indexOf(lastDigit) >= 0 && lastDigit !== 's') {
+ time = convertFromSeconds(seconds, lastDigit);
+ unit = lastDigit;
+ } else {
+ time = seconds;
+ }
} catch (e) {
console.error(e);
- // if parsing fails leave as default 30
+ // if parsing fails leave as default 30s
}
}
+
this.setProperties({
- time: seconds,
- unit: 's',
+ time,
+ unit,
enableTTL: setEnable,
});
+
+ if (changeOnInit) {
+ this.handleChange();
+ }
},
unitOptions: computed(function() {
diff --git a/ui/lib/core/stories/ttl-picker2.md b/ui/lib/core/stories/ttl-picker2.md
index eb12ce2650..a827de7c51 100644
--- a/ui/lib/core/stories/ttl-picker2.md
+++ b/ui/lib/core/stories/ttl-picker2.md
@@ -21,6 +21,7 @@ TtlPicker2 components are used to enable and select time to live values. Use thi
| recalculationTimeout | Number | 5000 | This is the time, in milliseconds, that `recalculateSeconds` will be be true after time is updated |
| initialValue | String | | This is the value set initially (particularly from a string like '30h') |
| initialEnabled | Boolean | | Set this value if you want the toggle on when component is mounted |
+| changeOnInit | Boolean | false | set this value if you'd like the passed onChange function to be called on component initialization |
**Example**
diff --git a/ui/lib/replication/addon/controllers/mode/secondaries/add.js b/ui/lib/replication/addon/controllers/mode/secondaries/add.js
index 6a80887200..09d290a793 100644
--- a/ui/lib/replication/addon/controllers/mode/secondaries/add.js
+++ b/ui/lib/replication/addon/controllers/mode/secondaries/add.js
@@ -1,3 +1,9 @@
import ReplicationController from 'replication/controllers/application';
-export default ReplicationController.extend();
+export default ReplicationController.extend({
+ actions: {
+ updateTtl: function(ttl) {
+ this.set('ttl', `${ttl.seconds}s`);
+ },
+ },
+});
diff --git a/ui/lib/replication/addon/templates/mode/secondaries/add.hbs b/ui/lib/replication/addon/templates/mode/secondaries/add.hbs
index c984ba44ee..2a46cc1bae 100644
--- a/ui/lib/replication/addon/templates/mode/secondaries/add.hbs
+++ b/ui/lib/replication/addon/templates/mode/secondaries/add.hbs
@@ -18,11 +18,14 @@
- {{!-- TODO fix so it defaults to 30s like in other places or replace with new TTL picker --}}
- {{ttl-picker onChange=(action (mut ttl)) initialValue="30m" class="is-marginless"}}
-
- This is the Time To Live for the generated secondary token. After this period, the generated token will no longer be valid.
-
+
{{#if (eq replicationMode "performance")}}
Generate token
-
+
{{#link-to "mode.secondaries" replicationMode class="button"}}
Cancel
diff --git a/ui/tests/integration/components/ttl-picker2-test.js b/ui/tests/integration/components/ttl-picker2-test.js
index c9b43955bc..e1455b5002 100644
--- a/ui/tests/integration/components/ttl-picker2-test.js
+++ b/ui/tests/integration/components/ttl-picker2-test.js
@@ -116,7 +116,7 @@ module('Integration | Component | ttl-picker2', function(hooks) {
);
});
- test('it sets default value to seconds of parsed value when set', async function(assert) {
+ test('it sets default value to time and unit passed', async function(assert) {
let changeSpy = sinon.spy();
this.set('onChange', changeSpy);
await render(hbs`
@@ -128,8 +128,27 @@ module('Integration | Component | ttl-picker2', function(hooks) {
@unit="d"
/>
`);
- assert.dom('[data-test-ttl-value]').hasValue('7200', 'time value is initialValue as seconds');
- assert.dom('[data-test-select="ttl-unit"]').hasValue('s', 'unit is seconds');
+ assert.dom('[data-test-ttl-value]').hasValue('2', 'time value is 2');
+ assert.dom('[data-test-select="ttl-unit"]').hasValue('h', 'unit is hours');
+ assert.ok(changeSpy.notCalled, 'it does not call onChange after render when changeOnInit is not set');
+ });
+
+ test('it is disabled on init if initialEnabled is false', async function(assert) {
+ let changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+ assert.dom('[data-test-ttl-value]').doesNotExist('Value is not shown on mount');
+ assert.dom('[data-test-ttl-unit]').doesNotExist('Unit is not shown on mount');
+ await click('[data-test-toggle-input="inittest"]');
+ assert.dom('[data-test-ttl-value]').hasValue('100', 'time after toggle is 100');
+ assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'Unit is minutes after toggle');
});
test('it is enabled on init if initialEnabled is true', async function(assert) {
@@ -143,8 +162,8 @@ module('Integration | Component | ttl-picker2', function(hooks) {
@initialEnabled={{true}}
/>
`);
- assert.dom('[data-test-ttl-value]').hasValue('6000', 'time value is initialValue as seconds');
- assert.dom('[data-test-ttl-unit]').exists('Unit is shown on mount');
+ assert.dom('[data-test-ttl-value]').hasValue('100', 'time is shown on mount');
+ assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'Unit is shown on mount');
await click('[data-test-toggle-input="inittest"]');
assert.dom('[data-test-ttl-value]').doesNotExist('Value no longer shows after toggle');
assert.dom('[data-test-ttl-unit]').doesNotExist('Unit no longer shows after toggle');
@@ -161,7 +180,31 @@ module('Integration | Component | ttl-picker2', function(hooks) {
@initialEnabled="true"
/>
`);
- assert.dom('[data-test-ttl-value]').hasValue('6000', 'time value is initialValue as seconds');
+ assert.dom('[data-test-ttl-value]').hasValue('100', 'time value is shown on mount');
assert.dom('[data-test-ttl-unit]').exists('Unit is shown on mount');
+ assert.dom('[data-test-select="ttl-unit"]').hasValue('m', 'Unit matches what is passed in');
+ });
+
+ test('it calls onChange on init when rendered if changeOnInit is true', async function(assert) {
+ let changeSpy = sinon.spy();
+ this.set('onChange', changeSpy);
+ await render(hbs`
+
+ `);
+ assert.ok(
+ changeSpy.calledWith({
+ enabled: true,
+ seconds: 6000,
+ timeString: '100m',
+ }),
+ 'Seconds value is recalculated based on time and unit'
+ );
+ assert.ok(changeSpy.calledOnce, 'it calls the passed onChange after render');
});
});