diff --git a/ui-v2/app/components/consul-lock-session-list/README.mdx b/ui-v2/app/components/consul-lock-session-list/README.mdx new file mode 100644 index 0000000000..04afe202b9 --- /dev/null +++ b/ui-v2/app/components/consul-lock-session-list/README.mdx @@ -0,0 +1,24 @@ +## ConsulLockSessionList + +``` + +``` + +A presentational component for rendering Node Lock Sessions + +### Arguments + +| Argument/Attribute | Type | Default | Description | +| --- | --- | --- | --- | +| `items` | `array` | | An array of Node Lock Sessions | +| `onInvalidate` | `function` | | An action to confirm when the `Invalidate` action is clicked and confirmed | + +### See + +- [Component Source Code](./index.js) +- [Template Source Code](./index.hbs) + +--- diff --git a/ui-v2/app/components/consul-lock-session-list/index.hbs b/ui-v2/app/components/consul-lock-session-list/index.hbs new file mode 100644 index 0000000000..0076c5c321 --- /dev/null +++ b/ui-v2/app/components/consul-lock-session-list/index.hbs @@ -0,0 +1,74 @@ +{{#if (gt items.length 0)}} + + + {{item.Name}} + + +
+
+ +
+
{{item.ID}}
+
+
+
+ + Delay + +
+
{{format-time item.LockDelay}}
+
+
+
+ + TTL + +
+
{{item.TTL}}
+
+
+
+ + Behavior + +
+
{{item.Behavior}}
+
+
+
+ + Checks + +
+
+ {{#each item.Checks as |item|}} + {{item}} + {{/each}} +
+
+
+ + + + + + +

+ {{message}} +

+ + +
+
+
+
+{{/if}} \ No newline at end of file diff --git a/ui-v2/app/components/consul-lock-session-list/index.js b/ui-v2/app/components/consul-lock-session-list/index.js new file mode 100644 index 0000000000..4798652642 --- /dev/null +++ b/ui-v2/app/components/consul-lock-session-list/index.js @@ -0,0 +1,5 @@ +import Component from '@ember/component'; + +export default Component.extend({ + tagName: '', +}); diff --git a/ui-v2/app/helpers/format-time.js b/ui-v2/app/helpers/format-time.js new file mode 100644 index 0000000000..5f0fa8ddb1 --- /dev/null +++ b/ui-v2/app/helpers/format-time.js @@ -0,0 +1,29 @@ +import { helper } from '@ember/component/helper'; + +export default helper(function formatTime([params], hash) { + let day, hour, minute, seconds; + seconds = Math.floor(params / 1000); + minute = Math.floor(seconds / 60); + seconds = seconds % 60; + hour = Math.floor(minute / 60); + minute = minute % 60; + day = Math.floor(hour / 24); + hour = hour % 24; + const time = { + day: day, + hour: hour, + minute: minute, + seconds: seconds, + }; + + switch (true) { + case time.day !== 0: + return time.day + 'd'; + case time.hour !== 0: + return time.hour + 'h'; + case time.minute !== 0: + return time.minute + 'm'; + default: + return time.seconds + 's'; + } +}); diff --git a/ui-v2/app/styles/base/icons/base-variables.scss b/ui-v2/app/styles/base/icons/base-variables.scss index 8dd1eb6f64..d3e2e48d97 100644 --- a/ui-v2/app/styles/base/icons/base-variables.scss +++ b/ui-v2/app/styles/base/icons/base-variables.scss @@ -39,6 +39,7 @@ $consul-logo-color-svg: url('data:image/svg+xml;charset=UTF-8,'); $copy-success-svg: url('data:image/svg+xml;charset=UTF-8,'); $database-svg: url('data:image/svg+xml;charset=UTF-8,'); +$delay-svg: url('data:image/svg+xml;charset=UTF-8,'); $deny-alt-svg: url('data:image/svg+xml;charset=UTF-8,'); $deny-color-svg: url('data:image/svg+xml;charset=UTF-8,'); $deny-default-svg: url('data:image/svg+xml;charset=UTF-8,'); diff --git a/ui-v2/app/styles/base/icons/icon-placeholders.scss b/ui-v2/app/styles/base/icons/icon-placeholders.scss index bde82cc049..907ab91d63 100644 --- a/ui-v2/app/styles/base/icons/icon-placeholders.scss +++ b/ui-v2/app/styles/base/icons/icon-placeholders.scss @@ -398,6 +398,16 @@ mask-image: $database-svg; } +%with-delay-icon { + @extend %with-icon; + background-image: $delay-svg; +} +%with-delay-mask { + @extend %with-mask; + -webkit-mask-image: $delay-svg; + mask-image: $delay-svg; +} + %with-deny-alt-icon { @extend %with-icon; background-image: $deny-alt-svg; diff --git a/ui-v2/app/styles/components/composite-row.scss b/ui-v2/app/styles/components/composite-row.scss index 956141a8ec..7ffa997197 100644 --- a/ui-v2/app/styles/components/composite-row.scss +++ b/ui-v2/app/styles/components/composite-row.scss @@ -13,6 +13,9 @@ .consul-role-list > ul > li:not(:first-child) { @extend %with-composite-row-intent; } +.consul-lock-session-list ul > li:not(:first-child) { + @extend %with-one-action-row; +} /*TODO: This hides the icons-less dt's in the below lists as */ /* they don't have tooltips */ .consul-nspace-list > ul > li:not(:first-child) dt, diff --git a/ui-v2/app/styles/components/composite-row/layout.scss b/ui-v2/app/styles/components/composite-row/layout.scss index ae4f1b8ee3..2f08ea6021 100644 --- a/ui-v2/app/styles/components/composite-row/layout.scss +++ b/ui-v2/app/styles/components/composite-row/layout.scss @@ -12,6 +12,20 @@ /* whilst this isn't in the designs this makes our temporary rollover look better */ padding-left: 12px; } +%with-one-action-row { + display: grid; + grid-template-columns: 1fr auto; + grid-template-rows: 50% 50%; + + // only one action applies to these rows + grid-template-areas: + 'header actions' + 'detail actions'; + + padding-top: 10px; + padding-bottom: 10px; + padding-right: 12px; +} %composite-row-header { grid-area: header; align-self: start; diff --git a/ui-v2/app/styles/components/composite-row/skin.scss b/ui-v2/app/styles/components/composite-row/skin.scss index 51045dd419..6bf4f212bc 100644 --- a/ui-v2/app/styles/components/composite-row/skin.scss +++ b/ui-v2/app/styles/components/composite-row/skin.scss @@ -106,6 +106,22 @@ @extend %with-protocol-mask, %as-pseudo; background-color: $gray-500; } +%composite-row-detail dl.lock-delay dt::before { + @extend %with-delay-mask, %as-pseudo; + background-color: $gray-500; +} +%composite-row-detail dl.ttl dt::before { + @extend %with-history-mask, %as-pseudo; + background-color: $gray-500; +} +%composite-row-detail dl.behavior dt::before { + @extend %with-info-circle-outline-mask, %as-pseudo; + background-color: $gray-500; +} +%composite-row-detail dl.checks dt::before { + @extend %with-health-mask, %as-pseudo; + background-color: $gray-500; +} // In this case we do not need a background on the icon %composite-row .combined-address .copy-button button:hover, %composite-row-detail dt .copy-button button:hover { diff --git a/ui-v2/app/templates/dc/nodes/show/sessions.hbs b/ui-v2/app/templates/dc/nodes/show/sessions.hbs index 6a39b5e6e1..85ac9ae9c4 100644 --- a/ui-v2/app/templates/dc/nodes/show/sessions.hbs +++ b/ui-v2/app/templates/dc/nodes/show/sessions.hbs @@ -1,65 +1,15 @@
{{#if (gt sessions.length 0)}} - - - Name - ID - Delay - TTL - Behavior - Checks -   - - - - {{item.Name}} - - - {{item.ID}} - - - {{item.LockDelay}} - - - {{item.TTL}} - - - {{item.Behavior}} - - -{{#if (gt item.Checks.length 0)}} - {{ join ', ' item.Checks}} -{{/if}} - - - - - - - -

- {{message}} -

- - -
-
- -
-
+ {{else}} - - -

- There are no Lock Sessions for this Node. For more information, view our documentation -

-
-
+ + +

+ There are no Lock Sessions for this Node. For more information, view our documentation +

+
+
{{/if}}
diff --git a/ui-v2/tests/acceptance/dc/nodes/sessions/list.feature b/ui-v2/tests/acceptance/dc/nodes/sessions/list.feature index efcc9c1e4d..ba36a22056 100644 --- a/ui-v2/tests/acceptance/dc/nodes/sessions/list.feature +++ b/ui-v2/tests/acceptance/dc/nodes/sessions/list.feature @@ -26,3 +26,26 @@ Feature: dc / nodes / sessions / list: List Lock Sessions - 30s - 60m --- + Scenario: Given 2 session with LockDelay in milliseconds + Given 1 datacenter model with the value "dc1" + And 1 node model from yaml + --- + ID: node-0 + --- + And 2 session models from yaml + --- + - LockDelay: 120000 + - LockDelay: 18000000 + --- + When I visit the node page for yaml + --- + dc: dc1 + node: node-0 + --- + And I click lockSessions on the tabs + Then I see lockSessionsIsSelected on the tabs + Then I see delay on the sessions like yaml + --- + - 2m + - 5h + --- diff --git a/ui-v2/tests/integration/components/consul-lock-session-list-test.js b/ui-v2/tests/integration/components/consul-lock-session-list-test.js new file mode 100644 index 0000000000..ddc5057ebd --- /dev/null +++ b/ui-v2/tests/integration/components/consul-lock-session-list-test.js @@ -0,0 +1,26 @@ +import { module, skip } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | consul-lock-session-list', function(hooks) { + setupRenderingTest(hooks); + + skip('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``); + + assert.equal(this.element.textContent.trim(), ''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + assert.equal(this.element.textContent.trim(), 'template block text'); + }); +}); diff --git a/ui-v2/tests/integration/helpers/format-time-test.js b/ui-v2/tests/integration/helpers/format-time-test.js new file mode 100644 index 0000000000..127d89f21a --- /dev/null +++ b/ui-v2/tests/integration/helpers/format-time-test.js @@ -0,0 +1,17 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Helper | format-time', function(hooks) { + setupRenderingTest(hooks); + + // Replace this with your real tests. + test('it renders', async function(assert) { + this.set('inputValue', '7200000'); + + await render(hbs`{{format-time inputValue}}`); + + assert.equal(this.element.textContent.trim(), '2h'); + }); +}); diff --git a/ui-v2/tests/pages/dc/nodes/show.js b/ui-v2/tests/pages/dc/nodes/show.js index a5afb1c9f5..d3780143a5 100644 --- a/ui-v2/tests/pages/dc/nodes/show.js +++ b/ui-v2/tests/pages/dc/nodes/show.js @@ -16,12 +16,12 @@ export default function(visitable, deletable, clickable, attribute, collection, port: attribute('data-test-service-port', '[data-test-service-port]'), externalSource: attribute('data-test-external-source', '[data-test-external-source]'), }), - sessions: collection( - '#lock-sessions [data-test-tabular-row]', - deletable({ - TTL: attribute('data-test-session-ttl', '[data-test-session-ttl]'), - }) - ), + sessions: collection('.consul-lock-session-list [data-test-list-row]', { + TTL: attribute('data-test-session-ttl', '[data-test-session-ttl]'), + delay: text('[data-test-session-delay]'), + actions: clickable('label'), + ...deletable(), + }), metadata: collection('#metadata [data-test-tabular-row]', {}), }; }