From 4ace04de7ac099f1c8804ce2fe26d8db5a3b844a Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 5 May 2021 15:42:12 -0400 Subject: [PATCH 01/28] feat: Add condensed style to Rose::Table --- .../addon/components/rose/table/index.hbs | 2 +- .../addon/components/rose/table/row/index.hbs | 2 +- .../styles/rose/components/table/_table.scss | 15 ++ .../rose/tests/dummy/app/templates/index.hbs | 177 +++++++++--------- 4 files changed, 107 insertions(+), 89 deletions(-) diff --git a/addons/rose/addon/components/rose/table/index.hbs b/addons/rose/addon/components/rose/table/index.hbs index 655e7dbd4..643a14cfa 100644 --- a/addons/rose/addon/components/rose/table/index.hbs +++ b/addons/rose/addon/components/rose/table/index.hbs @@ -1,4 +1,4 @@ - +
{{#if @caption}} {{/if}} diff --git a/addons/rose/addon/components/rose/table/row/index.hbs b/addons/rose/addon/components/rose/table/row/index.hbs index e5bad550e..5267351c8 100644 --- a/addons/rose/addon/components/rose/table/row/index.hbs +++ b/addons/rose/addon/components/rose/table/row/index.hbs @@ -1,4 +1,4 @@ - + {{yield (hash cell=(component 'rose/anonymous' tagName='td' diff --git a/addons/rose/addon/styles/rose/components/table/_table.scss b/addons/rose/addon/styles/rose/components/table/_table.scss index 0c581393e..7460d2f4d 100644 --- a/addons/rose/addon/styles/rose/components/table/_table.scss +++ b/addons/rose/addon/styles/rose/components/table/_table.scss @@ -38,4 +38,19 @@ [class*='rose-button'] { margin-bottom: 0; } + + &.rose-table-condensed { + .rose-table-cell { + @include type.type(s); + $lineHeight: 36 / 14; + line-height: $lineHeight; + padding: (sizing.rems(s) / 2) sizing.rems(s); + } + } + + .rose-table-row-visually-hidden { + position: absolute; + top: -9999rem; + left: -9999rem; + } } diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 8bb8b116d..3c7b27e5c 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -1,93 +1,96 @@ - - +

Condensed Table

- - - Menu item - Menu item - danger - - Button menu item - + + + + Address + Host Set + Name + Description + + + + + 1.1.1.1 + host-set-1, host-set-2 + optional name + description + + + + + Footer + + + - Section - Section - +

Key/Value

+ + + Key + Value + + + Key + Value + + + Key + Value + - - - Menu item - Menu item - danger - Button - default - - Button - danger - - -
+ {{!-- In actual use, form fields should be yielded from an outer form component --}} + + + + Key + + + + + + Add + + + - - Menu item - Menu item - danger - + + + + Key + + + + + + Remove + + + - Button menu item - Button - danger - + - - Menu item - - - - - Menu item - Button menu item - - - - - -
    -
  • - - - -
  • -
  • - - - -
  • -
  • - - - -
  • -
-
-
-
- - - - <:header> -

Authentication Pending

- - <:body> -

Complete authentication in the newly-opened window.

-

Don't see the new window? Try again.

-

Cancel

- -
+

Table

+ + + + Address + Host Set + Name + Description + + + + + 1.1.1.1 + host-set-1, host-set-2 + optional name + description + + + + + Footer + + + \ No newline at end of file From 8e1e2b6b3628833e60a7c4678a8df7cef2272d08 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 5 May 2021 17:21:49 -0400 Subject: [PATCH 02/28] feat: Add Rose::Table::Row::Cell for cells to expand/shrink --- .../components/rose/table/row/cell/index.hbs | 1 + .../components/rose/table/row/cell/index.js | 17 +++ .../addon/components/rose/table/row/index.hbs | 13 ++- .../styles/rose/components/table/_table.scss | 7 ++ .../app/components/rose/table/row/cell.js | 1 + .../rose/tests/dummy/app/templates/index.hbs | 102 +++++++++++++++++- .../components/rose/table/row/cell-test.js | 26 +++++ 7 files changed, 162 insertions(+), 5 deletions(-) create mode 100644 addons/rose/addon/components/rose/table/row/cell/index.hbs create mode 100644 addons/rose/addon/components/rose/table/row/cell/index.js create mode 100644 addons/rose/app/components/rose/table/row/cell.js create mode 100644 addons/rose/tests/integration/components/rose/table/row/cell-test.js diff --git a/addons/rose/addon/components/rose/table/row/cell/index.hbs b/addons/rose/addon/components/rose/table/row/cell/index.hbs new file mode 100644 index 000000000..fb5c4b157 --- /dev/null +++ b/addons/rose/addon/components/rose/table/row/cell/index.hbs @@ -0,0 +1 @@ +{{yield}} \ No newline at end of file diff --git a/addons/rose/addon/components/rose/table/row/cell/index.js b/addons/rose/addon/components/rose/table/row/cell/index.js new file mode 100644 index 000000000..4a7572db7 --- /dev/null +++ b/addons/rose/addon/components/rose/table/row/cell/index.js @@ -0,0 +1,17 @@ +import Component from '@ember/component'; +import layout from './index'; +import { computed } from '@ember/object'; + +export default Component.extend({ + layout, + classNameBindings: [ + 'cellStyle', + 'cellSizeStyle', + ], + cellStyle: computed(function () { + return this.tagName.match('th') ? `rose-table-header-cell` : 'rose-table-cell'; + }), + cellSizeStyle: computed(function () { + return this.style ? `rose-table-cell-${this.style}` : ''; + }), +}); diff --git a/addons/rose/addon/components/rose/table/row/index.hbs b/addons/rose/addon/components/rose/table/row/index.hbs index 5267351c8..52d1f3ba9 100644 --- a/addons/rose/addon/components/rose/table/row/index.hbs +++ b/addons/rose/addon/components/rose/table/row/index.hbs @@ -1,12 +1,21 @@ + {{yield (hash + cell=(component 'rose/table/row/cell' tagName='td') + headerCell=(component 'rose/table/row/cell' tagName='th') + )}} + + + +{{!-- {{yield (hash cell=(component 'rose/anonymous' tagName='td' class='rose-table-cell' + classNames='{{style}} {{@style}}' ) headerCell=(component 'rose/anonymous' tagName='th' - class='rose-table-header-cell' + class='rose-table-header-cell @style {{if @style (concat "rose-table-cell-" @style)}}' ) )}} - + --}} diff --git a/addons/rose/addon/styles/rose/components/table/_table.scss b/addons/rose/addon/styles/rose/components/table/_table.scss index 7460d2f4d..0e3305a9a 100644 --- a/addons/rose/addon/styles/rose/components/table/_table.scss +++ b/addons/rose/addon/styles/rose/components/table/_table.scss @@ -13,6 +13,7 @@ .rose-table-cell, .rose-table-header-cell { vertical-align: middle; + white-space: nowrap; } .rose-table-header-cell { @@ -35,6 +36,12 @@ } } + // Grow to full available width + .rose-table-cell-expand { + width: 100%; + border: 1px solid red; + } + [class*='rose-button'] { margin-bottom: 0; } diff --git a/addons/rose/app/components/rose/table/row/cell.js b/addons/rose/app/components/rose/table/row/cell.js new file mode 100644 index 000000000..a6ca12293 --- /dev/null +++ b/addons/rose/app/components/rose/table/row/cell.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/table/row/cell'; \ No newline at end of file diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 3c7b27e5c..27c3bbeff 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -1,9 +1,8 @@

Condensed Table

- - - Address + + Address Host Set Name Description @@ -24,6 +23,103 @@ +

Condensed Table With Expanded Cells

+ + + + Address + Host Set + Name + Description + + + + + 1.1.1.1 + host-set-1, host-set-2 + + Remove + + description + + + + + Footer + + + + +

Condensed Table Key/Value Lookalike

+ + + + Key + Value + + + + + Key + Value + + + Key + Value + + + Key + Value + + + Key + + + {{!-- --}} + + Remove + {{!-- --}} + + + + + {{!-- Remove --}} + + + + + + + Footer + + + + +

Condensed Table With Visually Hidden Header & Footer

+ + + + Address + Host Set + Name + Description + + + + + 1.1.1.1 + host-set-1, host-set-2 + optional name + description + + + + + Footer + + + +

Key/Value

diff --git a/addons/rose/tests/integration/components/rose/table/row/cell-test.js b/addons/rose/tests/integration/components/rose/table/row/cell-test.js new file mode 100644 index 000000000..9279a81df --- /dev/null +++ b/addons/rose/tests/integration/components/rose/table/row/cell-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 'ember-cli-htmlbars'; + +module('Integration | Component | rose/table/row/cell', 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``); + + assert.equal(this.element.textContent.trim(), ''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + assert.equal(this.element.textContent.trim(), 'template block text'); + }); +}); From 3425dc89be53bc667161d3417bb8515c7b652d34 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 6 May 2021 10:00:16 -0400 Subject: [PATCH 03/28] chore: Setup Rose::Table cell alignment config --- .../styles/rose/components/table/_table.scss | 6 +++- .../rose/tests/dummy/app/templates/index.hbs | 34 ++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/addons/rose/addon/styles/rose/components/table/_table.scss b/addons/rose/addon/styles/rose/components/table/_table.scss index 0e3305a9a..6fc53e78e 100644 --- a/addons/rose/addon/styles/rose/components/table/_table.scss +++ b/addons/rose/addon/styles/rose/components/table/_table.scss @@ -39,7 +39,11 @@ // Grow to full available width .rose-table-cell-expand { width: 100%; - border: 1px solid red; + + & > * { + vertical-align: inherit; + margin: 0; + } } [class*='rose-button'] { diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 27c3bbeff..22d4f9e81 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -50,6 +50,31 @@ +

Condensed Table With Right and Center aligned cells

+ + + + Address + Host Set + Name + Description + + + + + 1.1.1.1 + host-set-1, host-set-2 + optional name + description + + + + + Footer + + + +

Condensed Table Key/Value Lookalike

@@ -75,15 +100,8 @@ Key - {{!-- --}} Remove - {{!-- --}} - - - - - {{!-- Remove --}} @@ -135,7 +153,6 @@ Value
- {{!-- In actual use, form fields should be yielded from an outer form component --}} @@ -163,7 +180,6 @@ -

Table

From cf40b53fd05042a456ac623fded54d1d175df792 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 6 May 2021 10:14:11 -0400 Subject: [PATCH 04/28] chore: Format newly added files in rose --- .../rose/addon/components/rose/table/row/cell/index.js | 9 ++++----- .../rose/addon/styles/rose/components/table/_table.scss | 2 +- addons/rose/app/components/rose/table/row/cell.js | 2 +- .../integration/components/rose/table/row/cell-test.js | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/addons/rose/addon/components/rose/table/row/cell/index.js b/addons/rose/addon/components/rose/table/row/cell/index.js index 4a7572db7..0fc901f10 100644 --- a/addons/rose/addon/components/rose/table/row/cell/index.js +++ b/addons/rose/addon/components/rose/table/row/cell/index.js @@ -4,12 +4,11 @@ import { computed } from '@ember/object'; export default Component.extend({ layout, - classNameBindings: [ - 'cellStyle', - 'cellSizeStyle', - ], + classNameBindings: ['cellStyle', 'cellSizeStyle'], cellStyle: computed(function () { - return this.tagName.match('th') ? `rose-table-header-cell` : 'rose-table-cell'; + return this.tagName.match('th') + ? `rose-table-header-cell` + : 'rose-table-cell'; }), cellSizeStyle: computed(function () { return this.style ? `rose-table-cell-${this.style}` : ''; diff --git a/addons/rose/addon/styles/rose/components/table/_table.scss b/addons/rose/addon/styles/rose/components/table/_table.scss index 6fc53e78e..997ef944a 100644 --- a/addons/rose/addon/styles/rose/components/table/_table.scss +++ b/addons/rose/addon/styles/rose/components/table/_table.scss @@ -43,7 +43,7 @@ & > * { vertical-align: inherit; margin: 0; - } + } } [class*='rose-button'] { diff --git a/addons/rose/app/components/rose/table/row/cell.js b/addons/rose/app/components/rose/table/row/cell.js index a6ca12293..50e7502b4 100644 --- a/addons/rose/app/components/rose/table/row/cell.js +++ b/addons/rose/app/components/rose/table/row/cell.js @@ -1 +1 @@ -export { default } from 'rose/components/rose/table/row/cell'; \ No newline at end of file +export { default } from 'rose/components/rose/table/row/cell'; diff --git a/addons/rose/tests/integration/components/rose/table/row/cell-test.js b/addons/rose/tests/integration/components/rose/table/row/cell-test.js index 9279a81df..c58c9096c 100644 --- a/addons/rose/tests/integration/components/rose/table/row/cell-test.js +++ b/addons/rose/tests/integration/components/rose/table/row/cell-test.js @@ -3,10 +3,10 @@ import { setupRenderingTest } from 'ember-qunit'; import { render } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; -module('Integration | Component | rose/table/row/cell', function(hooks) { +module('Integration | Component | rose/table/row/cell', function (hooks) { setupRenderingTest(hooks); - test('it renders', async function(assert) { + test('it renders', async function (assert) { // Set any properties with this.set('myProperty', 'value'); // Handle any actions with this.set('myAction', function(val) { ... }); From a909ba67df6f576c4a44ab48b25c47aace2f31d3 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 6 May 2021 14:27:46 -0400 Subject: [PATCH 05/28] chore: Minor cleanup in Rose::Table::Row template --- addons/rose/addon/components/rose/table/row/index.hbs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/rose/addon/components/rose/table/row/index.hbs b/addons/rose/addon/components/rose/table/row/index.hbs index 52d1f3ba9..5afc830e2 100644 --- a/addons/rose/addon/components/rose/table/row/index.hbs +++ b/addons/rose/addon/components/rose/table/row/index.hbs @@ -11,11 +11,10 @@ cell=(component 'rose/anonymous' tagName='td' class='rose-table-cell' - classNames='{{style}} {{@style}}' ) headerCell=(component 'rose/anonymous' tagName='th' - class='rose-table-header-cell @style {{if @style (concat "rose-table-cell-" @style)}}' + class='rose-table-header-cell' ) )}} --}} From 6b93032a78a3c6ee74e28901a0f0169e7455a5d0 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 6 May 2021 16:57:49 -0400 Subject: [PATCH 06/28] style: Update Rose::Table storybook --- .../components/rose/table/index.stories.mdx | 107 +++++++++++++++++- 1 file changed, 101 insertions(+), 6 deletions(-) diff --git a/addons/rose/addon/components/rose/table/index.stories.mdx b/addons/rose/addon/components/rose/table/index.stories.mdx index a720bd877..a6a840401 100644 --- a/addons/rose/addon/components/rose/table/index.stories.mdx +++ b/addons/rose/addon/components/rose/table/index.stories.mdx @@ -1,11 +1,14 @@ import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; import { hbs } from 'ember-cli-htmlbars'; +import { boolean, select } from '@storybook/addon-knobs'; # Table -A table component to display data in structure of rows and columns. It supports `header`, `body` and `footer` optional definitions. Each definition allows for a table `row` to be defined with either a `cell` or `headerCell` table element. +A table component to display data in structure of rows and columns. It supports `header`, `body` and `footer` optional definitions. Each definition allows for a table `row` to be defined with either a `cell` or `headerCell` table element. Rows can be visually hidden, cells can be expanded to fit full width, and center/right cell alignment is supported. + +Cell expansion style should be applied to only one cell in a row. ```htmlbars @@ -24,6 +27,18 @@ A table component to display data in structure of rows and columns. It supports optional name description + + 1.1.1.1 + host-set-2 + optional name + description + + + 1.1.1.1 + host-set-1 + optional name + description + @@ -36,11 +51,11 @@ A table component to display data in structure of rows and columns. It supports {{ template: hbs` - + - + Address - Host Set + Host Set Name Description @@ -48,7 +63,19 @@ A table component to display data in structure of rows and columns. It supports 1.1.1.1 - host-set-1, host-set-2 + host-set-1, host-set-2 + optional name + description + + + 1.1.1.1 + host-set-2 + optional name + description + + + 1.1.1.1 + host-set-1 optional name description @@ -60,6 +87,74 @@ A table component to display data in structure of rows and columns. It supports `, - context: {} + context: { + visuallyHideHeaderRow: boolean('visuallyHideHeaderRow', false), + cellStyle: select( + 'cellStyle', + { + default: '', + 'expand': 'expand' + } + ), + style: select( + 'style', + { + 'default': '', + 'condensed': 'condensed' + } + ) + }, + }} + + + + {{ + template: hbs` + + + + Key + Value + + + + + Key + Value + + + Key + Value + + + Key + Value + + + Key + + + + Add + + + + + Key + + + + Remove + + + + + + + Footer + + + + `, }} From 84051e4b7242a62e8defeddec4178b5d19993b4a Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 6 May 2021 17:06:01 -0400 Subject: [PATCH 07/28] chore: Refactor Rose::Table::Row visually-hidden to hidden --- .../components/rose/table/index.stories.mdx | 22 +++++++++---------- .../addon/components/rose/table/row/index.hbs | 2 +- .../rose/tests/dummy/app/templates/index.hbs | 8 +++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/addons/rose/addon/components/rose/table/index.stories.mdx b/addons/rose/addon/components/rose/table/index.stories.mdx index a6a840401..d2f56a5b8 100644 --- a/addons/rose/addon/components/rose/table/index.stories.mdx +++ b/addons/rose/addon/components/rose/table/index.stories.mdx @@ -10,12 +10,12 @@ A table component to display data in structure of rows and columns. It supports Cell expansion style should be applied to only one cell in a row. -```htmlbars - +```html + - + Address - Host Set + Host Set Name Description @@ -23,19 +23,19 @@ Cell expansion style should be applied to only one cell in a row. 1.1.1.1 - host-set-1, host-set-2 + host-set-1, host-set-2 optional name description 1.1.1.1 - host-set-2 + host-set-2 optional name description 1.1.1.1 - host-set-1 + host-set-1 optional name description @@ -53,7 +53,7 @@ Cell expansion style should be applied to only one cell in a row. template: hbs` - + Address Host Set Name @@ -88,7 +88,7 @@ Cell expansion style should be applied to only one cell in a row. `, context: { - visuallyHideHeaderRow: boolean('visuallyHideHeaderRow', false), + hideHeaderRow: boolean('hideHeaderRow', false), cellStyle: select( 'cellStyle', { @@ -112,7 +112,7 @@ Cell expansion style should be applied to only one cell in a row. template: hbs` - + Key Value @@ -150,7 +150,7 @@ Cell expansion style should be applied to only one cell in a row. - + Footer diff --git a/addons/rose/addon/components/rose/table/row/index.hbs b/addons/rose/addon/components/rose/table/row/index.hbs index 5afc830e2..7431132ea 100644 --- a/addons/rose/addon/components/rose/table/row/index.hbs +++ b/addons/rose/addon/components/rose/table/row/index.hbs @@ -1,4 +1,4 @@ - + {{yield (hash cell=(component 'rose/table/row/cell' tagName='td') headerCell=(component 'rose/table/row/cell' tagName='th') diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 22d4f9e81..eabd793cb 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -43,7 +43,7 @@ description - + Footer @@ -106,7 +106,7 @@ - + Footer @@ -116,7 +116,7 @@

Condensed Table With Visually Hidden Header & Footer

- + Address Host Set Name @@ -132,7 +132,7 @@ - + Footer From ec9d953bad2a65bd21828724b3573719d5e5f73a Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Thu, 6 May 2021 17:36:30 -0400 Subject: [PATCH 08/28] test: Add Rose::Table::Row::Cell tests --- .../components/rose/table/row/cell/index.js | 7 ++-- .../addon/components/rose/table/row/index.hbs | 2 +- .../integration/components/rose/table-test.js | 5 +++ .../components/rose/table/row-test.js | 5 +++ .../components/rose/table/row/cell-test.js | 40 ++++++++++++------- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/addons/rose/addon/components/rose/table/row/cell/index.js b/addons/rose/addon/components/rose/table/row/cell/index.js index 0fc901f10..01bcb5fd7 100644 --- a/addons/rose/addon/components/rose/table/row/cell/index.js +++ b/addons/rose/addon/components/rose/table/row/cell/index.js @@ -4,13 +4,14 @@ import { computed } from '@ember/object'; export default Component.extend({ layout, - classNameBindings: ['cellStyle', 'cellSizeStyle'], - cellStyle: computed(function () { + tagName: 'td', + classNameBindings: ['cellTypeStyle', 'cellStyle'], + cellTypeStyle: computed(function () { return this.tagName.match('th') ? `rose-table-header-cell` : 'rose-table-cell'; }), - cellSizeStyle: computed(function () { + cellStyle: computed(function () { return this.style ? `rose-table-cell-${this.style}` : ''; }), }); diff --git a/addons/rose/addon/components/rose/table/row/index.hbs b/addons/rose/addon/components/rose/table/row/index.hbs index 7431132ea..5183c0746 100644 --- a/addons/rose/addon/components/rose/table/row/index.hbs +++ b/addons/rose/addon/components/rose/table/row/index.hbs @@ -1,6 +1,6 @@
{{yield (hash - cell=(component 'rose/table/row/cell' tagName='td') + cell=(component 'rose/table/row/cell') headerCell=(component 'rose/table/row/cell' tagName='th') )}} diff --git a/addons/rose/tests/integration/components/rose/table-test.js b/addons/rose/tests/integration/components/rose/table-test.js index 06f2a5b8c..aa78b58eb 100644 --- a/addons/rose/tests/integration/components/rose/table-test.js +++ b/addons/rose/tests/integration/components/rose/table-test.js @@ -43,4 +43,9 @@ module('Integration | Component | rose/table', function (hooks) { `); assert.ok(find('tfoot')); }); + + test('it supports a style class', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-table-condensed')); + }); }); diff --git a/addons/rose/tests/integration/components/rose/table/row-test.js b/addons/rose/tests/integration/components/rose/table/row-test.js index 94c57cd08..7e0774504 100644 --- a/addons/rose/tests/integration/components/rose/table/row-test.js +++ b/addons/rose/tests/integration/components/rose/table/row-test.js @@ -32,4 +32,9 @@ module('Integration | Component | rose/table/row', function (hooks) { assert.ok(find('th')); assert.ok(find('.rose-table-header-cell')); }); + + test('it can be hidden', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-table-row-visually-hidden')); + }); }); diff --git a/addons/rose/tests/integration/components/rose/table/row/cell-test.js b/addons/rose/tests/integration/components/rose/table/row/cell-test.js index c58c9096c..48928d3d6 100644 --- a/addons/rose/tests/integration/components/rose/table/row/cell-test.js +++ b/addons/rose/tests/integration/components/rose/table/row/cell-test.js @@ -1,26 +1,38 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render } from '@ember/test-helpers'; -import { hbs } from 'ember-cli-htmlbars'; +import { render, find } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; module('Integration | Component | rose/table/row/cell', 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) { ... }); + assert.expect(2); + await render(hbs` + content + `); + assert.ok(find('td')); + assert.equal(find('.rose-table-cell').textContent.trim(), 'content'); + }); - await render(hbs``); + test('it renders with attributes', async function (assert) { + assert.expect(1); + await render(hbs``); + assert.ok(find('#cell')); + }); - assert.equal(this.element.textContent.trim(), ''); + test('it renders as header cell', async function (assert) { + assert.expect(4); + await render(hbs``); + assert.ok(find('th')); + assert.ok(find('.rose-table-header-cell')); + assert.notOk(find('td')); + assert.notOk(find('.rose-table-cell')); + }); - // Template block usage: - await render(hbs` - - template block text - - `); - - assert.equal(this.element.textContent.trim(), 'template block text'); + test('it adds a style class', async function (assert) { + assert.expect(1); + await render(hbs``); + assert.ok(find('.rose-table-cell-expand')); }); }); From 8feeaa47dc5874d7c6753d8fc919856d1c97328f Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Tue, 11 May 2021 15:06:04 -0700 Subject: [PATCH 09/28] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Refactor=20rose=20?= =?UTF-8?q?table=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We refactor the component adding a condensed variant of the table, refactor the hidden feature. We also provide different alignments for a cell. Updated tests and storybook page --- .../components/rose/table/index.stories.mdx | 32 ++++++++++--------- .../components/rose/table/row/cell/index.js | 11 ++++++- .../addon/components/rose/table/row/index.hbs | 14 -------- .../styles/rose/components/table/_table.scss | 4 +++ .../rose/tests/dummy/app/templates/index.hbs | 14 ++++---- .../components/rose/table/row/cell-test.js | 32 +++++++++++++++++++ 6 files changed, 70 insertions(+), 37 deletions(-) diff --git a/addons/rose/addon/components/rose/table/index.stories.mdx b/addons/rose/addon/components/rose/table/index.stories.mdx index d2f56a5b8..f11560e41 100644 --- a/addons/rose/addon/components/rose/table/index.stories.mdx +++ b/addons/rose/addon/components/rose/table/index.stories.mdx @@ -30,8 +30,8 @@ Cell expansion style should be applied to only one cell in a row. 1.1.1.1 host-set-2 - optional name - description + optional name + description 1.1.1.1 @@ -54,10 +54,10 @@ Cell expansion style should be applied to only one cell in a row. - Address - Host Set - Name - Description + Address + Host Set + Name + Description @@ -68,16 +68,16 @@ Cell expansion style should be applied to only one cell in a row. description - 1.1.1.1 - host-set-2 - optional name - description + 1.1.1.1 + host-set-2 + optional name + description - 1.1.1.1 - host-set-1 - optional name - description + 1.1.1.1 + host-set-1 + optional name + description @@ -102,7 +102,9 @@ Cell expansion style should be applied to only one cell in a row. 'default': '', 'condensed': 'condensed' } - ) + ), + cellAlignmentCenter: boolean('cellAlignmentCenter', false), + cellAlignmentRight: boolean('cellAlignmentRight', false), }, }} diff --git a/addons/rose/addon/components/rose/table/row/cell/index.js b/addons/rose/addon/components/rose/table/row/cell/index.js index 01bcb5fd7..09f5f53dc 100644 --- a/addons/rose/addon/components/rose/table/row/cell/index.js +++ b/addons/rose/addon/components/rose/table/row/cell/index.js @@ -5,7 +5,7 @@ import { computed } from '@ember/object'; export default Component.extend({ layout, tagName: 'td', - classNameBindings: ['cellTypeStyle', 'cellStyle'], + classNameBindings: ['cellTypeStyle', 'cellStyle', 'cellAlignmentStyle'], cellTypeStyle: computed(function () { return this.tagName.match('th') ? `rose-table-header-cell` @@ -14,4 +14,13 @@ export default Component.extend({ cellStyle: computed(function () { return this.style ? `rose-table-cell-${this.style}` : ''; }), + cellAlignmentStyle: computed(function () { + if (this.alignRight) { + return 'align-right'; + } + + if (this.alignCenter) { + return 'align-center'; + } + }) }); diff --git a/addons/rose/addon/components/rose/table/row/index.hbs b/addons/rose/addon/components/rose/table/row/index.hbs index 5183c0746..4b511d869 100644 --- a/addons/rose/addon/components/rose/table/row/index.hbs +++ b/addons/rose/addon/components/rose/table/row/index.hbs @@ -4,17 +4,3 @@ headerCell=(component 'rose/table/row/cell' tagName='th') )}} - - -{{!-- - {{yield (hash - cell=(component 'rose/anonymous' - tagName='td' - class='rose-table-cell' - ) - headerCell=(component 'rose/anonymous' - tagName='th' - class='rose-table-header-cell' - ) - )}} - --}} diff --git a/addons/rose/addon/styles/rose/components/table/_table.scss b/addons/rose/addon/styles/rose/components/table/_table.scss index 997ef944a..4f6ea31d8 100644 --- a/addons/rose/addon/styles/rose/components/table/_table.scss +++ b/addons/rose/addon/styles/rose/components/table/_table.scss @@ -14,6 +14,9 @@ .rose-table-header-cell { vertical-align: middle; white-space: nowrap; + + &.align-right { text-align: right; } + &.align-center { text-align: center; } } .rose-table-header-cell { @@ -57,6 +60,7 @@ line-height: $lineHeight; padding: (sizing.rems(s) / 2) sizing.rems(s); } + } .rose-table-row-visually-hidden { diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index eabd793cb..17cd6861b 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -43,7 +43,7 @@ description - + Footer @@ -63,9 +63,9 @@ 1.1.1.1 - host-set-1, host-set-2 - optional name - description + host-set-1, host-set-2 + optional name + description @@ -106,7 +106,7 @@ - + Footer @@ -116,7 +116,7 @@

Condensed Table With Visually Hidden Header & Footer

- + Address Host Set Name @@ -132,7 +132,7 @@ - + Footer diff --git a/addons/rose/tests/integration/components/rose/table/row/cell-test.js b/addons/rose/tests/integration/components/rose/table/row/cell-test.js index 48928d3d6..dcc93e33c 100644 --- a/addons/rose/tests/integration/components/rose/table/row/cell-test.js +++ b/addons/rose/tests/integration/components/rose/table/row/cell-test.js @@ -35,4 +35,36 @@ module('Integration | Component | rose/table/row/cell', function (hooks) { await render(hbs``); assert.ok(find('.rose-table-cell-expand')); }); + + test('it renders with align center in a header cell', async function (assert) { + assert.expect(2); + await render( + hbs`` + ); + assert.ok(find('.rose-table-header-cell')); + assert.ok(find('.align-center')); + }); + + test('it renders with align center in a body', async function (assert) { + assert.expect(2); + await render(hbs``); + assert.ok(find('.rose-table-cell')); + assert.ok(find('.align-center')); + }); + + test('it renders with align right in a header cell', async function (assert) { + assert.expect(2); + await render( + hbs`` + ); + assert.ok(find('.rose-table-header-cell')); + assert.ok(find('.align-right')); + }); + + test('it renders with align right', async function (assert) { + assert.expect(2); + await render(hbs``); + assert.ok(find('.rose-table-cell')); + assert.ok(find('.align-right')); + }); }); From ce7cdba0bc2a25133e982b1af2d98dde1c3c17cb Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 12 May 2021 12:27:16 -0400 Subject: [PATCH 10/28] feat: Prompt for quitting session on desktop quit --- ui/desktop/electron-app/src/index.js | 27 ++++++++++++++++++- .../electron-app/src/session/manager.js | 11 +++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ui/desktop/electron-app/src/index.js b/ui/desktop/electron-app/src/index.js index 3ff94bf64..e4db2c671 100644 --- a/ui/desktop/electron-app/src/index.js +++ b/ui/desktop/electron-app/src/index.js @@ -7,9 +7,9 @@ const { const { session, app, + dialog, protocol, BrowserWindow, - ipcMain, Menu, MenuItem, } = require('electron'); @@ -17,6 +17,7 @@ require('./ipc/handlers.js'); const origin = require('./origin/index.js'); const { generateCSPHeader } = require('./config/content-security-policy.js'); +const sessionManager = require('./session/manager.js'); const menu = require('./config/menu.js'); const appUpdater = require('./helpers/app-updater.js'); @@ -183,6 +184,30 @@ app.on('ready', async () => { }); }); +/** + * Prompt for closing spawned processes + */ +app.on('before-quit', (event) => { + if (sessionManager.hasActiveSessions) { + const dialogOpts = { + type: 'question', + buttons: ['Close & Quit', 'Ignore & Quit', 'Cancel'], + detail: 'Close sessions before quitting?', + }; + + dialog.showMessageBox(dialogOpts).then((returnValue) => { + switch (returnValue.response) { + case 0: + sessionManager.stopAll(); + break; + case 2: + event.preventDefault(); + break; + } + }); + } +}); + // Handle an unhandled error in the main thread // // Note that 'uncaughtException' is a crude mechanism for exception handling intended to diff --git a/ui/desktop/electron-app/src/session/manager.js b/ui/desktop/electron-app/src/session/manager.js index cb25bef93..63b3a8943 100644 --- a/ui/desktop/electron-app/src/session/manager.js +++ b/ui/desktop/electron-app/src/session/manager.js @@ -7,6 +7,14 @@ class SessionManager { this.#sessions = []; } + /** + * Checks for active sessions + * @returns {boolean} + */ + get hasActiveSessions() { + return Boolean(this.#sessions.find((session) => session.isActive)); + } + /** * Start a session and track it. * Returns session proxy details if successfully started. @@ -27,10 +35,11 @@ class SessionManager { */ async stopById(session_id) { const session = this.#sessions.find((session) => session.id === session_id); - return session.stop(); + return session && session.stop(); } stopAll() { + this.#sessions.forEach((session) => session.stop()); } } From 4b587d35fa831ece55d480d3bffd1c8bd289248d Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 12 May 2021 12:48:03 -0400 Subject: [PATCH 11/28] docs: Add feature note to changelog --- ui/desktop/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui/desktop/CHANGELOG.md b/ui/desktop/CHANGELOG.md index 614ad5f8a..93e8fb472 100644 --- a/ui/desktop/CHANGELOG.md +++ b/ui/desktop/CHANGELOG.md @@ -4,6 +4,10 @@ Canonical reference for changes, improvements, and bugfixes for Boundary Desktop ## Next +### New + +- Add prompt to close sessions when quitting client. ([PR](https://github.com/hashicorp/boundary-ui/pull/555)) + ### Bug Fixes - Close spawned boundary process on session cancel. ([PR](https://github.com/hashicorp/boundary-ui/pull/549)) From dcc77153bfc699077f6b608bc38ef38a669fa760 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 12 May 2021 14:27:01 -0400 Subject: [PATCH 12/28] feat: Do not allow desktop to quit without closing sessions --- ui/desktop/electron-app/src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/desktop/electron-app/src/index.js b/ui/desktop/electron-app/src/index.js index e4db2c671..07a9a32d2 100644 --- a/ui/desktop/electron-app/src/index.js +++ b/ui/desktop/electron-app/src/index.js @@ -191,7 +191,7 @@ app.on('before-quit', (event) => { if (sessionManager.hasActiveSessions) { const dialogOpts = { type: 'question', - buttons: ['Close & Quit', 'Ignore & Quit', 'Cancel'], + buttons: ['Close', 'Cancel'], detail: 'Close sessions before quitting?', }; @@ -200,7 +200,7 @@ app.on('before-quit', (event) => { case 0: sessionManager.stopAll(); break; - case 2: + case 1: event.preventDefault(); break; } From 542b469ad8deb769a16090f7270d79292e91c6f8 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 12 May 2021 15:46:40 -0400 Subject: [PATCH 13/28] chore: Reapply stopping all session in desktop after merge --- ui/desktop/electron-app/src/models/session-manager.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/desktop/electron-app/src/models/session-manager.js b/ui/desktop/electron-app/src/models/session-manager.js index dfcfd923a..3bcd7938f 100644 --- a/ui/desktop/electron-app/src/models/session-manager.js +++ b/ui/desktop/electron-app/src/models/session-manager.js @@ -3,6 +3,14 @@ const Session = require('./session.js'); class SessionManager { #sessions = []; + /** + * Checks for active sessions + * @returns {boolean} + */ + get hasActiveSessions() { + return Boolean(this.#sessions.find((session) => session.isActive)); + } + /** * Start a session and track it. * Returns session proxy details if successfully started. @@ -23,10 +31,11 @@ class SessionManager { */ stopById(session_id) { const session = this.#sessions.find((session) => session.id === session_id); - return session.stop(); + return session && session.stop(); } stopAll() { + this.#sessions.forEach((session) => session.stop()); } } From e91612b3136116890057dcd600b31660330552d6 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 12 May 2021 17:12:59 -0400 Subject: [PATCH 14/28] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20implement=20basic?= =?UTF-8?q?=20OIDC=20auth=20method=20attributes=20modeling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/models/auth-method.js | 22 +++++++++++++++++++ .../models/fragment-auth-method-attributes.js | 17 ++++++++++++++ .../models/fragment-auth-method-attributes.js | 1 + .../mirage/generated/factories/auth-method.js | 18 +++++++++++++++ .../fragment-auth-method-attributes-test.js | 13 +++++++++++ 5 files changed, 71 insertions(+) create mode 100644 addons/api/addon/models/fragment-auth-method-attributes.js create mode 100644 addons/api/app/models/fragment-auth-method-attributes.js create mode 100644 addons/api/tests/unit/models/fragment-auth-method-attributes-test.js diff --git a/addons/api/addon/models/auth-method.js b/addons/api/addon/models/auth-method.js index 7686c2783..2874b0a67 100644 --- a/addons/api/addon/models/auth-method.js +++ b/addons/api/addon/models/auth-method.js @@ -1,9 +1,31 @@ import GeneratedAuthMethodModel from '../generated/models/auth-method'; +import { fragment } from 'ember-data-model-fragments/attributes'; import { equal } from '@ember/object/computed'; +export const signingAlgorithms = [ + 'RS256', + 'RS384', + 'RS512', + 'ES256', + 'ES384', + 'ES512', + 'PS256', + 'PS384', + 'PS512', + 'EdDSA', +]; + +export const states = ['inactive', 'active-private', 'active-public']; + export default class AuthMethodModel extends GeneratedAuthMethodModel { // =attributes + /** + * Attributes of this resource, if any, represented as a JSON fragment. + * @type {FragmentAuthMethodAttributesModel} + */ + @fragment('fragment-auth-method-attributes', { defaultValue: {} }) attributes; + /** * @type {boolean} */ diff --git a/addons/api/addon/models/fragment-auth-method-attributes.js b/addons/api/addon/models/fragment-auth-method-attributes.js new file mode 100644 index 000000000..a8ba64af5 --- /dev/null +++ b/addons/api/addon/models/fragment-auth-method-attributes.js @@ -0,0 +1,17 @@ +import Fragment from 'ember-data-model-fragments/fragment'; +import { attr } from '@ember-data/model'; + +export default class FragmentAuthMethodAttributesModel extends Fragment { + // =attributes (OIDC) + + @attr('string', { readOnly: true }) state; + @attr('string') issuer; + @attr('string') client_id; + @attr('string') client_secret; + @attr('string') client_secret_hmac; + @attr('number') max_age; + @attr('string') api_url_prefix; + @attr('string') callback_url; + @attr('boolean') disable_discovered_config_validation; + @attr('boolean') dry_run; +} diff --git a/addons/api/app/models/fragment-auth-method-attributes.js b/addons/api/app/models/fragment-auth-method-attributes.js new file mode 100644 index 000000000..46bd1e0f2 --- /dev/null +++ b/addons/api/app/models/fragment-auth-method-attributes.js @@ -0,0 +1 @@ +export { default } from 'api/models/fragment-auth-method-attributes'; diff --git a/addons/api/mirage/generated/factories/auth-method.js b/addons/api/mirage/generated/factories/auth-method.js index 6ea181f58..8fd338a53 100644 --- a/addons/api/mirage/generated/factories/auth-method.js +++ b/addons/api/mirage/generated/factories/auth-method.js @@ -11,4 +11,22 @@ export default Factory.extend({ created_time: () => date.recent(), updated_time: () => date.recent(), disabled: () => datatype.boolean(), + + attributes: function () { + let attrs; + switch (this.type) { + case 'oidc': + attrs = { + api_url_prefix: 'http://127.0.0.1:9200', + callback_url: + 'http://127.0.0.1:9200/v1/auth-methods/oidc:authenticate:callback', + client_id: 'YTwdJBB55LpKnuXb9n65', + client_secret_hmac: 'GY7blb4ynM5TEPNi_qnphJ9aDWhW8FpmN3D-eP_L7Zk', + issuer: 'http://127.0.0.1:57070', + state: 'active-public', + }; + break; + } + return attrs; + }, }); diff --git a/addons/api/tests/unit/models/fragment-auth-method-attributes-test.js b/addons/api/tests/unit/models/fragment-auth-method-attributes-test.js new file mode 100644 index 000000000..4dd985316 --- /dev/null +++ b/addons/api/tests/unit/models/fragment-auth-method-attributes-test.js @@ -0,0 +1,13 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Model | fragment auth method attributes', function (hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord('fragment-auth-method-attributes', {}); + assert.ok(model); + }); +}); From 385ea34c98e86200bcd42be77f6e38c19533b944 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Thu, 13 May 2021 09:41:13 -0700 Subject: [PATCH 15/28] Swap @style='expand' to boolean @expand='true' --- .../components/rose/table/index.stories.mdx | 24 +++++++------------ .../components/rose/table/row/cell/index.js | 8 ++++--- .../rose/tests/dummy/app/templates/index.hbs | 10 ++++---- .../components/rose/table/row/cell-test.js | 10 ++++++-- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/addons/rose/addon/components/rose/table/index.stories.mdx b/addons/rose/addon/components/rose/table/index.stories.mdx index f11560e41..0a70f24e8 100644 --- a/addons/rose/addon/components/rose/table/index.stories.mdx +++ b/addons/rose/addon/components/rose/table/index.stories.mdx @@ -15,7 +15,7 @@ Cell expansion style should be applied to only one cell in a row. Address - Host Set + Host Set Name Description @@ -23,19 +23,19 @@ Cell expansion style should be applied to only one cell in a row. 1.1.1.1 - host-set-1, host-set-2 + host-set-1, host-set-2 optional name description 1.1.1.1 - host-set-2 + host-set-2 optional name description 1.1.1.1 - host-set-1 + host-set-1 optional name description @@ -55,7 +55,7 @@ Cell expansion style should be applied to only one cell in a row. Address - Host Set + Host Set Name Description @@ -63,19 +63,19 @@ Cell expansion style should be applied to only one cell in a row. 1.1.1.1 - host-set-1, host-set-2 + host-set-1, host-set-2 optional name description 1.1.1.1 - host-set-2 + host-set-2 optional name description 1.1.1.1 - host-set-1 + host-set-1 optional name description @@ -89,13 +89,7 @@ Cell expansion style should be applied to only one cell in a row. `, context: { hideHeaderRow: boolean('hideHeaderRow', false), - cellStyle: select( - 'cellStyle', - { - default: '', - 'expand': 'expand' - } - ), + cellExpand: boolean('cellExpand', false), style: select( 'style', { diff --git a/addons/rose/addon/components/rose/table/row/cell/index.js b/addons/rose/addon/components/rose/table/row/cell/index.js index 09f5f53dc..4d0a04897 100644 --- a/addons/rose/addon/components/rose/table/row/cell/index.js +++ b/addons/rose/addon/components/rose/table/row/cell/index.js @@ -5,14 +5,16 @@ import { computed } from '@ember/object'; export default Component.extend({ layout, tagName: 'td', - classNameBindings: ['cellTypeStyle', 'cellStyle', 'cellAlignmentStyle'], + classNameBindings: ['cellTypeStyle', 'cellExpand', 'cellAlignmentStyle'], cellTypeStyle: computed(function () { return this.tagName.match('th') ? `rose-table-header-cell` : 'rose-table-cell'; }), - cellStyle: computed(function () { - return this.style ? `rose-table-cell-${this.style}` : ''; + cellExpand: computed(function () { + if (this.expand) { + return 'rose-table-cell-expand' + } }), cellAlignmentStyle: computed(function () { if (this.alignRight) { diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 17cd6861b..c7c91cea6 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -30,7 +30,7 @@ Address Host Set Name - Description + Description @@ -40,7 +40,7 @@ Remove - description + description @@ -80,7 +80,7 @@ Key - Value + Value @@ -98,7 +98,7 @@ Key - + Remove @@ -120,7 +120,7 @@ Address Host Set Name - Description + Description diff --git a/addons/rose/tests/integration/components/rose/table/row/cell-test.js b/addons/rose/tests/integration/components/rose/table/row/cell-test.js index dcc93e33c..65fa7083f 100644 --- a/addons/rose/tests/integration/components/rose/table/row/cell-test.js +++ b/addons/rose/tests/integration/components/rose/table/row/cell-test.js @@ -30,12 +30,18 @@ module('Integration | Component | rose/table/row/cell', function (hooks) { assert.notOk(find('.rose-table-cell')); }); - test('it adds a style class', async function (assert) { + test('it adds expand style class', async function (assert) { assert.expect(1); - await render(hbs``); + await render(hbs``); assert.ok(find('.rose-table-cell-expand')); }); + test('it does not add expand style class', async function (assert) { + assert.expect(1); + await render(hbs``); + assert.notOk(find('.rose-table-cell-expand')); + }); + test('it renders with align center in a header cell', async function (assert) { assert.expect(2); await render( From 24e37d3faa6826468c3f7694202aa3989974e4c5 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Thu, 13 May 2021 14:10:37 -0400 Subject: [PATCH 16/28] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20OIDC=20chang?= =?UTF-8?q?e=20state=20custom=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/api/addon/models/auth-method.js | 25 ++++++++ addons/api/addon/serializers/auth-method.js | 57 +++++++++++++++++++ .../api/tests/unit/models/auth-method-test.js | 37 ++++++++++++ .../unit/serializers/auth-method-test.js | 50 +++++++++++++++- 4 files changed, 167 insertions(+), 2 deletions(-) diff --git a/addons/api/addon/models/auth-method.js b/addons/api/addon/models/auth-method.js index 2874b0a67..d213e5c51 100644 --- a/addons/api/addon/models/auth-method.js +++ b/addons/api/addon/models/auth-method.js @@ -44,4 +44,29 @@ export default class AuthMethodModel extends GeneratedAuthMethodModel { get isOIDC() { return this.type === 'oidc'; } + + // =methods + + /** + * Change the active and visibility state of an OIDC auth method + * given its ID. + * For OIDC auth methods only. + * @param {[string]} state + * @param {object} options + * @param {object} options.adapterOptions + * @return {Promise} + */ + changeState(state, options = { adapterOptions: {} }) { + const defaultAdapterOptions = { + method: 'change-state', + state, + }; + return this.save({ + ...options, + adapterOptions: { + ...defaultAdapterOptions, + ...options.adapterOptions, + }, + }); + } } diff --git a/addons/api/addon/serializers/auth-method.js b/addons/api/addon/serializers/auth-method.js index a8569c14d..e40285ce9 100644 --- a/addons/api/addon/serializers/auth-method.js +++ b/addons/api/addon/serializers/auth-method.js @@ -1,6 +1,63 @@ import ApplicationSerializer from './application'; export default class AuthMethodSerializer extends ApplicationSerializer { + // =methods + + /** + * Delegates to a type-specific serialization, or default. + * @override + * @param {Snapshot} snapshot + * @return {object} + */ + serialize(snapshot) { + switch (snapshot.record.type) { + case 'oidc': + return this.serializeOIDC(...arguments); + default: + return this.serializeDefault(...arguments); + } + } + + /** + * Default serialization omits `attributes`. + * @return {object} + */ + serializeDefault() { + let serialized = super.serialize(...arguments); + delete serialized.attributes; + return serialized; + } + + /** + * If `adapterOptions.state` is set, the serialization should + * include **only state** and version. Normally, this is not serialized. + * @param {Snapshot} snapshot + * @return {object} + */ + serializeOIDC(snapshot) { + let serialized = super.serialize(...arguments); + const state = snapshot?.adapterOptions?.state; + if (state) { + serialized = this.serializeOIDCWithState(snapshot, state); + } else { + delete serialized.attributes.state; + } + return serialized; + } + + /** + * Returns a payload containing only state and version. + * @param {Snapshot} snapshot + * @param {string} state + * @return {object} + */ + serializeOIDCWithState(snapshot, state) { + return { + version: snapshot.attr('version'), + attributes: { state }, + }; + } + /** * Sorts the array in order of "is_primary" such that the primary method * appears first. The "natural" order of auth methods places primary first. diff --git a/addons/api/tests/unit/models/auth-method-test.js b/addons/api/tests/unit/models/auth-method-test.js index 31ff3fca1..ff746e777 100644 --- a/addons/api/tests/unit/models/auth-method-test.js +++ b/addons/api/tests/unit/models/auth-method-test.js @@ -1,8 +1,10 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; module('Unit | Model | auth method', function (hooks) { setupTest(hooks); + setupMirage(hooks); // Replace this with your real tests. test('it exists', function (assert) { @@ -10,4 +12,39 @@ module('Unit | Model | auth method', function (hooks) { let model = store.createRecord('auth-method', {}); assert.ok(model); }); + + test('it has a `changeState` method that targets a specific POST API endpoint and serialization', async function (assert) { + assert.expect(1); + this.server.post( + '/v1/auth-methods/123abc:change-state', + (schema, request) => { + const body = JSON.parse(request.requestBody); + assert.deepEqual(body, { + attributes: { + state: 'foobar', + }, + version: 1, + }); + return { id: '123abc' }; + } + ); + const store = this.owner.lookup('service:store'); + store.push({ + data: { + id: '123abc', + type: 'auth-method', + attributes: { + type: 'oidc', + state: 'foobar', + version: 1, + scope: { + scope_id: 'o_1', + type: 'scope', + }, + }, + }, + }); + const model = store.peekRecord('auth-method', '123abc'); + await model.changeState('foobar'); + }); }); diff --git a/addons/api/tests/unit/serializers/auth-method-test.js b/addons/api/tests/unit/serializers/auth-method-test.js index cd7fcd396..54d10dede 100644 --- a/addons/api/tests/unit/serializers/auth-method-test.js +++ b/addons/api/tests/unit/serializers/auth-method-test.js @@ -12,13 +12,59 @@ module('Unit | Serializer | auth method', function (hooks) { assert.ok(serializer); }); - test('it serializes records', function (assert) { + test('it serializes password records', function (assert) { + assert.expect(2); let store = this.owner.lookup('service:store'); - let record = store.createRecord('auth-method', {}); + let record = store.createRecord('auth-method', { type: 'password' }); let serializedRecord = record.serialize(); assert.ok(serializedRecord); + assert.notOk( + serializedRecord.attributes, + 'Password should not have attributes' + ); + }); + + test('it serializes OIDC records without state', function (assert) { + assert.expect(3); + let store = this.owner.lookup('service:store'); + let record = store.createRecord('auth-method', { + type: 'oidc', + attributes: { + state: 'foo', + }, + }); + + let serializedRecord = record.serialize(); + + assert.ok(serializedRecord); + assert.ok(serializedRecord.attributes, 'OIDC should have attributes'); + assert.notOk(serializedRecord.attributes.state); + }); + + test('it serializes OIDC records with only state and version when `adapterOptions.state` is passed', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('auth-method'); + const record = store.createRecord('auth-method', { + type: 'oidc', + attributes: { + state: 'foo', + }, + version: 1, + }); + const snapshot = record._createSnapshot(); + snapshot.adapterOptions = { + state: 'bar', + }; + const serializedRecord = serializer.serialize(snapshot); + assert.deepEqual(serializedRecord, { + attributes: { + state: 'bar', + }, + version: 1, + }); }); test('it sorts primary first in normalizeArrayResponse', function (assert) { From dead74c825a39153be559b6f24f357a5fadfb490 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Fri, 14 May 2021 12:05:09 -0400 Subject: [PATCH 17/28] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20add=20OIDC=20accou?= =?UTF-8?q?nt=5Fclaim=5Fmaps=20modeling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...attributes-account-claim-map-serializer.js | 15 +++++++ addons/api/addon/models/auth-method.js | 37 ++++++++++------ ...uth-method-attributes-account-claim-map.js | 9 ++++ .../models/fragment-auth-method-attributes.js | 6 +++ addons/api/addon/serializers/auth-method.js | 16 +++++-- ...uth-method-attributes-account-claim-map.js | 30 +++++++++++++ ...attributes-account-claim-map-serializer.js | 4 ++ ...uth-method-attributes-account-claim-map.js | 1 + ...butes-account-claim-map-serializer-test.js | 35 +++++++++++++++ ...ethod-attributes-account-claim-map-test.js | 19 ++++++++ .../unit/serializers/auth-method-test.js | 44 +++++++++++++++++-- 11 files changed, 195 insertions(+), 21 deletions(-) create mode 100644 addons/api/addon/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js create mode 100644 addons/api/addon/models/fragment-auth-method-attributes-account-claim-map.js create mode 100644 addons/api/addon/serializers/fragment-auth-method-attributes-account-claim-map.js create mode 100644 addons/api/app/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js create mode 100644 addons/api/app/models/fragment-auth-method-attributes-account-claim-map.js create mode 100644 addons/api/tests/unit/initializers/fragment-auth-method-attributes-account-claim-map-serializer-test.js create mode 100644 addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js diff --git a/addons/api/addon/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js b/addons/api/addon/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js new file mode 100644 index 000000000..59387536f --- /dev/null +++ b/addons/api/addon/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js @@ -0,0 +1,15 @@ +// app/initializers/fragment-serializer.js +import FragmentAuthMethodAttributesAccountClaimMapSerializer from '../serializers/fragment-auth-method-attributes-account-claim-map'; + +export function initialize(application) { + application.register( + 'serializer:fragment-auth-method-attributes-account-claim-map', + FragmentAuthMethodAttributesAccountClaimMapSerializer + ); +} + +// Fragment serializers must be manually registered +export default { + name: 'fragment-auth-method-attributes-account-claim-map', + initialize: initialize, +}; diff --git a/addons/api/addon/models/auth-method.js b/addons/api/addon/models/auth-method.js index d213e5c51..699f5137e 100644 --- a/addons/api/addon/models/auth-method.js +++ b/addons/api/addon/models/auth-method.js @@ -2,20 +2,29 @@ import GeneratedAuthMethodModel from '../generated/models/auth-method'; import { fragment } from 'ember-data-model-fragments/attributes'; import { equal } from '@ember/object/computed'; -export const signingAlgorithms = [ - 'RS256', - 'RS384', - 'RS512', - 'ES256', - 'ES384', - 'ES512', - 'PS256', - 'PS384', - 'PS512', - 'EdDSA', -]; - -export const states = ['inactive', 'active-private', 'active-public']; +/** + * Enum ptions per auth method type and field. + */ +export const options = { + oidc: { + signing_algorithm: [ + 'RS256', + 'RS384', + 'RS512', + 'ES256', + 'ES384', + 'ES512', + 'PS256', + 'PS384', + 'PS512', + 'EdDSA', + ], + state: ['inactive', 'active-private', 'active-public'], + account_claim_maps: { + to: ['sub', 'name', 'email'], + }, + }, +}; export default class AuthMethodModel extends GeneratedAuthMethodModel { // =attributes diff --git a/addons/api/addon/models/fragment-auth-method-attributes-account-claim-map.js b/addons/api/addon/models/fragment-auth-method-attributes-account-claim-map.js new file mode 100644 index 000000000..c3e2aec21 --- /dev/null +++ b/addons/api/addon/models/fragment-auth-method-attributes-account-claim-map.js @@ -0,0 +1,9 @@ +import Fragment from 'ember-data-model-fragments/fragment'; +import { attr } from '@ember-data/model'; + +export default class FragmentAuthMethodAttributesAccountClaimMapModel extends Fragment { + // =attributes (OIDC) + + @attr('string') from; + @attr('string') to; +} diff --git a/addons/api/addon/models/fragment-auth-method-attributes.js b/addons/api/addon/models/fragment-auth-method-attributes.js index a8ba64af5..b023401f2 100644 --- a/addons/api/addon/models/fragment-auth-method-attributes.js +++ b/addons/api/addon/models/fragment-auth-method-attributes.js @@ -1,5 +1,6 @@ import Fragment from 'ember-data-model-fragments/fragment'; import { attr } from '@ember-data/model'; +import { fragmentArray } from 'ember-data-model-fragments/attributes'; export default class FragmentAuthMethodAttributesModel extends Fragment { // =attributes (OIDC) @@ -14,4 +15,9 @@ export default class FragmentAuthMethodAttributesModel extends Fragment { @attr('string') callback_url; @attr('boolean') disable_discovered_config_validation; @attr('boolean') dry_run; + + @fragmentArray('fragment-auth-method-attributes-account-claim-map', { + emptyArrayIfMissing: true, + }) + account_claim_maps; } diff --git a/addons/api/addon/serializers/auth-method.js b/addons/api/addon/serializers/auth-method.js index e40285ce9..6895cf512 100644 --- a/addons/api/addon/serializers/auth-method.js +++ b/addons/api/addon/serializers/auth-method.js @@ -1,4 +1,5 @@ import ApplicationSerializer from './application'; +import { copy } from 'ember-copy'; export default class AuthMethodSerializer extends ApplicationSerializer { // =methods @@ -80,10 +81,19 @@ export default class AuthMethodSerializer extends ApplicationSerializer { * * TODO: generalize this so that all zero values are reified. * @override - * @return {object} + * @see FragmentScope + * @param {Model} typeClass + * @param {Object} hash + * @return {Object} */ - normalize() { - const normalized = super.normalize(...arguments); + normalize(typeClass, hash, ...rest) { + let normalizedHash = copy(hash, true); + // switch (normalizedHash.type) { + // case 'oidc': + // normalizedHash = this.normalizeOIDC(normalizedHash); + // break; + // } + const normalized = super.normalize(typeClass, normalizedHash, ...rest); if (!normalized.data.attributes.is_primary) { normalized.data.attributes.is_primary = false; } diff --git a/addons/api/addon/serializers/fragment-auth-method-attributes-account-claim-map.js b/addons/api/addon/serializers/fragment-auth-method-attributes-account-claim-map.js new file mode 100644 index 000000000..5c5b4789e --- /dev/null +++ b/addons/api/addon/serializers/fragment-auth-method-attributes-account-claim-map.js @@ -0,0 +1,30 @@ +import JSONSerializer from '@ember-data/serializer/json'; + +export default class FragmentHostSetSerializer extends JSONSerializer { + // =methods + + /** + * Serializes an account claim to string. + * @param {Snapshot} snapshot + * @return {string} + */ + serialize(snapshot) { + const from = snapshot.attr('from'); + const to = snapshot.attr('to'); + return `${from}=${to}`; + } + + /** + * Normalizes account claim strings into JSON API objects. + * @param {Model} typeClass + * @param {string} value + * @return {object} + */ + normalize(typeClass, value) { + const normalizedHash = { + from: value.split('=')[0], + to: value.split('=')[1], + }; + return super.normalize(typeClass, normalizedHash); + } +} diff --git a/addons/api/app/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js b/addons/api/app/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js new file mode 100644 index 000000000..844980fbc --- /dev/null +++ b/addons/api/app/initializers/fragment-auth-method-attributes-account-claim-map-serializer.js @@ -0,0 +1,4 @@ +export { + default, + initialize, +} from 'api/initializers/fragment-auth-method-attributes-account-claim-map-serializer'; diff --git a/addons/api/app/models/fragment-auth-method-attributes-account-claim-map.js b/addons/api/app/models/fragment-auth-method-attributes-account-claim-map.js new file mode 100644 index 000000000..8d0f7b0c7 --- /dev/null +++ b/addons/api/app/models/fragment-auth-method-attributes-account-claim-map.js @@ -0,0 +1 @@ +export { default } from 'api/models/fragment-auth-method-attributes-account-claim-map'; diff --git a/addons/api/tests/unit/initializers/fragment-auth-method-attributes-account-claim-map-serializer-test.js b/addons/api/tests/unit/initializers/fragment-auth-method-attributes-account-claim-map-serializer-test.js new file mode 100644 index 000000000..caac46ee2 --- /dev/null +++ b/addons/api/tests/unit/initializers/fragment-auth-method-attributes-account-claim-map-serializer-test.js @@ -0,0 +1,35 @@ +import Application from '@ember/application'; + +import { initialize } from 'dummy/initializers/fragment-auth-method-attributes-account-claim-map-serializer'; +import { module, test } from 'qunit'; +import Resolver from 'ember-resolver'; +import { run } from '@ember/runloop'; + +module( + 'Unit | Initializer | fragment-auth-method-attributes-account-claim-map-serializer', + function (hooks) { + hooks.beforeEach(function () { + this.TestApplication = class TestApplication extends Application {}; + this.TestApplication.initializer({ + name: 'initializer under test', + initialize, + }); + + this.application = this.TestApplication.create({ + autoboot: false, + Resolver, + }); + }); + + hooks.afterEach(function () { + run(this.application, 'destroy'); + }); + + // TODO: Replace this with your real tests. + test('it works', async function (assert) { + await this.application.boot(); + + assert.ok(true); + }); + } +); diff --git a/addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js b/addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js new file mode 100644 index 000000000..ade04df8f --- /dev/null +++ b/addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js @@ -0,0 +1,19 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module( + 'Unit | Model | fragment auth method attributes account claim map', + function (hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let model = store.createRecord( + 'fragment-auth-method-attributes-account-claim-map', + {} + ); + assert.ok(model); + }); + } +); diff --git a/addons/api/tests/unit/serializers/auth-method-test.js b/addons/api/tests/unit/serializers/auth-method-test.js index 54d10dede..c9c7ec1bb 100644 --- a/addons/api/tests/unit/serializers/auth-method-test.js +++ b/addons/api/tests/unit/serializers/auth-method-test.js @@ -1,8 +1,10 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; +import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; module('Unit | Serializer | auth method', function (hooks) { setupTest(hooks); + setupMirage(hooks); // Replace this with your real tests. test('it exists', function (assert) { @@ -27,20 +29,36 @@ module('Unit | Serializer | auth method', function (hooks) { }); test('it serializes OIDC records without state', function (assert) { - assert.expect(3); + assert.expect(1); let store = this.owner.lookup('service:store'); let record = store.createRecord('auth-method', { type: 'oidc', + name: 'OIDC Auth Method', attributes: { state: 'foo', + account_claim_maps: [{ from: 'foo', to: 'bar' }], }, }); let serializedRecord = record.serialize(); - assert.ok(serializedRecord); - assert.ok(serializedRecord.attributes, 'OIDC should have attributes'); - assert.notOk(serializedRecord.attributes.state); + assert.deepEqual(serializedRecord, { + type: 'oidc', + name: 'OIDC Auth Method', + description: null, + attributes: { + account_claim_maps: ['foo=bar'], + api_url_prefix: null, + callback_url: null, + client_id: null, + client_secret: null, + client_secret_hmac: null, + disable_discovered_config_validation: false, + dry_run: false, + issuer: null, + max_age: null, + }, + }); }); test('it serializes OIDC records with only state and version when `adapterOptions.state` is passed', function (assert) { @@ -109,4 +127,22 @@ module('Unit | Serializer | auth method', function (hooks) { 'First normalized item is primary' ); }); + + test('it normalizes OIDC records', async function (assert) { + const store = this.owner.lookup('service:store'); + this.server.get('/v1/auth-methods/oidc123', () => ({ + attributes: { + account_claim_maps: ['from=to', 'foo=bar'], + }, + version: 1, + type: 'oidc', + id: 'oidc123', + })); + const record = await store.findRecord('auth-method', 'oidc123'); + const { account_claim_maps } = record.attributes; + assert.equal(account_claim_maps.firstObject.from, 'from'); + assert.equal(account_claim_maps.firstObject.to, 'to'); + assert.equal(account_claim_maps.lastObject.from, 'foo'); + assert.equal(account_claim_maps.lastObject.to, 'bar'); + }); }); From f2f5a46cdfc6d5eddcae098d092bb5cfa8ab3538 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 14 May 2021 15:08:06 -0400 Subject: [PATCH 18/28] refactor: Add conditional chaining to session-manager call --- ui/desktop/electron-app/src/index.js | 2 +- ui/desktop/electron-app/src/models/session-manager.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/desktop/electron-app/src/index.js b/ui/desktop/electron-app/src/index.js index 07a9a32d2..94508b0dd 100644 --- a/ui/desktop/electron-app/src/index.js +++ b/ui/desktop/electron-app/src/index.js @@ -200,7 +200,7 @@ app.on('before-quit', (event) => { case 0: sessionManager.stopAll(); break; - case 1: + default: event.preventDefault(); break; } diff --git a/ui/desktop/electron-app/src/models/session-manager.js b/ui/desktop/electron-app/src/models/session-manager.js index 3bcd7938f..b6e0d0939 100644 --- a/ui/desktop/electron-app/src/models/session-manager.js +++ b/ui/desktop/electron-app/src/models/session-manager.js @@ -31,7 +31,7 @@ class SessionManager { */ stopById(session_id) { const session = this.#sessions.find((session) => session.id === session_id); - return session && session.stop(); + return session?.stop?.(); } stopAll() { From ce9503fc5b2e652716206a58b30caec19aab747a Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Fri, 14 May 2021 15:40:18 -0700 Subject: [PATCH 19/28] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Refactor=20table?= =?UTF-8?q?=20component=20with=20PR=20suggestions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add shrink style to cells and deprecate expand. Add Key/value style for table rows. Refactor storybook table page with all the changes. Refactor styles for new feature and simplification. --- .../components/rose/table/index.stories.mdx | 75 +++++++++++-------- .../components/rose/table/row/cell/index.js | 8 +- .../addon/components/rose/table/row/index.hbs | 2 +- .../styles/rose/components/table/_table.scss | 31 +++++--- .../rose/tests/dummy/app/templates/index.hbs | 51 +++++++------ .../components/rose/table/row-test.js | 11 +++ .../components/rose/table/row/cell-test.js | 10 +-- 7 files changed, 116 insertions(+), 72 deletions(-) diff --git a/addons/rose/addon/components/rose/table/index.stories.mdx b/addons/rose/addon/components/rose/table/index.stories.mdx index 0a70f24e8..7c91f0de4 100644 --- a/addons/rose/addon/components/rose/table/index.stories.mdx +++ b/addons/rose/addon/components/rose/table/index.stories.mdx @@ -6,37 +6,39 @@ import { boolean, select } from '@storybook/addon-knobs'; # Table -A table component to display data in structure of rows and columns. It supports `header`, `body` and `footer` optional definitions. Each definition allows for a table `row` to be defined with either a `cell` or `headerCell` table element. Rows can be visually hidden, cells can be expanded to fit full width, and center/right cell alignment is supported. +A table component to display data in structure of rows and columns. It supports `header`, `body` and `footer` optional definitions. Each definition allows for a table `row` to be defined with either a `cell` or `headerCell` table element. Rows can be visually hidden, styled for a key/value visualization, cells can be shrinked to its content with, and center/right cell alignment is supported. -Cell expansion style should be applied to only one cell in a row. +Row `key/value` style should be applied per row. + +Cell shrink should be applied to all the cells in a row. Otherwise the bigger cell with shrink applied will determinate the width of the row. ```html Address - Host Set + Host Set Name - Description + Description 1.1.1.1 - host-set-1, host-set-2 - optional name - description + host-set-1, host-set-2 + optional name + description 1.1.1.1 - host-set-2 - optional name + host-set-2 + optional name description 1.1.1.1 - host-set-1 - optional name + host-set-1 + optional name description @@ -54,29 +56,29 @@ Cell expansion style should be applied to only one cell in a row. - Address - Host Set - Name + Address + Host Set + Name Description - 1.1.1.1 - host-set-1, host-set-2 - optional name + 1.1.1.1 + host-set-1, host-set-2 + optional name description - 1.1.1.1 - host-set-2 - optional name + 1.1.1.1 + host-set-2 + optional name description - 1.1.1.1 - host-set-1 - optional name + 1.1.1.1 + host-set-1 + optional name description @@ -89,7 +91,7 @@ Cell expansion style should be applied to only one cell in a row. `, context: { hideHeaderRow: boolean('hideHeaderRow', false), - cellExpand: boolean('cellExpand', false), + cellShrink: boolean('cellShrink', false), style: select( 'style', { @@ -110,34 +112,34 @@ Cell expansion style should be applied to only one cell in a row. Key - Value + Value - + Key Value - + Key Value - + Key Value - + Key - + Add - + Key - + Remove @@ -152,5 +154,14 @@ Cell expansion style should be applied to only one cell in a row. `, + context: { + style: select( + 'style', + { + 'default': '', + 'key-value': 'key-value' + } + ) + } }} diff --git a/addons/rose/addon/components/rose/table/row/cell/index.js b/addons/rose/addon/components/rose/table/row/cell/index.js index 4d0a04897..588c072cf 100644 --- a/addons/rose/addon/components/rose/table/row/cell/index.js +++ b/addons/rose/addon/components/rose/table/row/cell/index.js @@ -5,15 +5,15 @@ import { computed } from '@ember/object'; export default Component.extend({ layout, tagName: 'td', - classNameBindings: ['cellTypeStyle', 'cellExpand', 'cellAlignmentStyle'], + classNameBindings: ['cellTypeStyle', 'cellShrink', 'cellAlignmentStyle'], cellTypeStyle: computed(function () { return this.tagName.match('th') ? `rose-table-header-cell` : 'rose-table-cell'; }), - cellExpand: computed(function () { - if (this.expand) { - return 'rose-table-cell-expand' + cellShrink: computed(function () { + if (this.shrink) { + return 'rose-table-cell-shrink' } }), cellAlignmentStyle: computed(function () { diff --git a/addons/rose/addon/components/rose/table/row/index.hbs b/addons/rose/addon/components/rose/table/row/index.hbs index 4b511d869..65fb90e81 100644 --- a/addons/rose/addon/components/rose/table/row/index.hbs +++ b/addons/rose/addon/components/rose/table/row/index.hbs @@ -1,4 +1,4 @@ -
+ {{yield (hash cell=(component 'rose/table/row/cell') headerCell=(component 'rose/table/row/cell' tagName='th') diff --git a/addons/rose/addon/styles/rose/components/table/_table.scss b/addons/rose/addon/styles/rose/components/table/_table.scss index 4f6ea31d8..a3c3bfcdc 100644 --- a/addons/rose/addon/styles/rose/components/table/_table.scss +++ b/addons/rose/addon/styles/rose/components/table/_table.scss @@ -10,10 +10,20 @@ text-align: left; } + .rose-table-row-key-value { + td:nth-child(2) { + display: flex; + input { + width: 100%; + margin-right: sizing.rems(s); + } + button { margin-right: 0; } + } + } + .rose-table-cell, .rose-table-header-cell { vertical-align: middle; - white-space: nowrap; &.align-right { text-align: right; } &.align-center { text-align: center; } @@ -39,20 +49,23 @@ } } - // Grow to full available width - .rose-table-cell-expand { - width: 100%; - - & > * { - vertical-align: inherit; - margin: 0; - } + .rose-table-cell-shrink { + width: 1%; + white-space: nowrap; } [class*='rose-button'] { margin-bottom: 0; } + .rose-table-cell { + .rose-form-input-field { + margin: 0; + width: inherit; + vertical-align: inherit; + } + } + &.rose-table-condensed { .rose-table-cell { @include type.type(s); diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index c7c91cea6..f162f9948 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -23,24 +23,24 @@ -

Condensed Table With Expanded Cells

+

Condensed Table with Shrink Cells

- Address - Host Set - Name - Description + Address + Host Set + Name + Description 1.1.1.1 - host-set-1, host-set-2 - + host-set-1, host-set-2 + Remove - description + description @@ -50,12 +50,12 @@ -

Condensed Table With Right and Center aligned cells

+

Condensed Table with Right and Center aligned cells

- Address - Host Set + Address + Host Set Name Description @@ -79,29 +79,38 @@ - Key - Value + Key + Value - + Key Value - + Key Value - + Key Value - + Key - + - - Remove + + Remove + + + + + Key + + + + Add @@ -120,7 +129,7 @@ Address Host Set Name - Description + Description diff --git a/addons/rose/tests/integration/components/rose/table/row-test.js b/addons/rose/tests/integration/components/rose/table/row-test.js index 7e0774504..c61552778 100644 --- a/addons/rose/tests/integration/components/rose/table/row-test.js +++ b/addons/rose/tests/integration/components/rose/table/row-test.js @@ -7,17 +7,20 @@ module('Integration | Component | rose/table/row', function (hooks) { setupRenderingTest(hooks); test('it renders', async function (assert) { + assert.expect(2); await render(hbs``); assert.ok(find('tr')); assert.ok(find('.rose-table-row')); }); test('it renders with attributes', async function (assert) { + assert.expect(1); await render(hbs``); assert.ok(find('#row')); }); test('it renders a cell', async function (assert) { + assert.expect(2); await render(hbs` `); @@ -26,6 +29,7 @@ module('Integration | Component | rose/table/row', function (hooks) { }); test('it renders a header cell', async function (assert) { + assert.expect(2); await render(hbs` `); @@ -34,7 +38,14 @@ module('Integration | Component | rose/table/row', function (hooks) { }); test('it can be hidden', async function (assert) { + assert.expect(1); await render(hbs``); assert.ok(find('.rose-table-row-visually-hidden')); }); + + test('it can be key/value style', async function (assert) { + assert.expect(1); + await render(hbs``); + assert.ok(find('.rose-table-row-key-value')); + }); }); diff --git a/addons/rose/tests/integration/components/rose/table/row/cell-test.js b/addons/rose/tests/integration/components/rose/table/row/cell-test.js index 65fa7083f..4b8c3332d 100644 --- a/addons/rose/tests/integration/components/rose/table/row/cell-test.js +++ b/addons/rose/tests/integration/components/rose/table/row/cell-test.js @@ -30,16 +30,16 @@ module('Integration | Component | rose/table/row/cell', function (hooks) { assert.notOk(find('.rose-table-cell')); }); - test('it adds expand style class', async function (assert) { + test('it adds shrink style class', async function (assert) { assert.expect(1); - await render(hbs``); - assert.ok(find('.rose-table-cell-expand')); + await render(hbs``); + assert.ok(find('.rose-table-cell-shrink')); }); - test('it does not add expand style class', async function (assert) { + test('it does not add expand style class in default cells', async function (assert) { assert.expect(1); await render(hbs``); - assert.notOk(find('.rose-table-cell-expand')); + assert.notOk(find('.rose-table-cell-shrink')); }); test('it renders with align center in a header cell', async function (assert) { From ee29f3c5991dc57cc46ccabb1f8de531f5cc362b Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Mon, 17 May 2021 16:33:34 -0400 Subject: [PATCH 20/28] refactor: change isActive to isRunning and related language to reduce confusion with the API concept of session status "active" --- ui/desktop/electron-app/src/models/session-manager.js | 6 +++--- ui/desktop/electron-app/src/models/session.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/desktop/electron-app/src/models/session-manager.js b/ui/desktop/electron-app/src/models/session-manager.js index b6e0d0939..311d86899 100644 --- a/ui/desktop/electron-app/src/models/session-manager.js +++ b/ui/desktop/electron-app/src/models/session-manager.js @@ -4,11 +4,11 @@ class SessionManager { #sessions = []; /** - * Checks for active sessions + * Checks for running sessions * @returns {boolean} */ - get hasActiveSessions() { - return Boolean(this.#sessions.find((session) => session.isActive)); + get hasRunningSessions() { + return Boolean(this.#sessions.find((session) => session.isRunning)); } /** diff --git a/ui/desktop/electron-app/src/models/session.js b/ui/desktop/electron-app/src/models/session.js index 6ec9d3ce8..a59316f7f 100644 --- a/ui/desktop/electron-app/src/models/session.js +++ b/ui/desktop/electron-app/src/models/session.js @@ -36,7 +36,7 @@ class Session { /** * @return {boolean} */ - get isActive() { + get isRunning() { return !this.#process.killed; } @@ -60,12 +60,12 @@ class Session { */ stop() { return new Promise((resolve, reject) => { - if (this.isActive) { + if (this.isRunning) { this.#process.on('close', () => resolve()); this.#process.on('error', (e) => reject(e)); this.#process.kill(); } else { - // Do nothing when process isn't active + // Do nothing when process isn't running resolve(); } }); From 4fed7f3d94d75f28101d26d8ba7bd02e0217427f Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Mon, 17 May 2021 17:23:18 -0400 Subject: [PATCH 21/28] refactor: rename to "running" --- ui/desktop/electron-app/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/desktop/electron-app/src/index.js b/ui/desktop/electron-app/src/index.js index 3b0b79f0d..0de2bfb54 100644 --- a/ui/desktop/electron-app/src/index.js +++ b/ui/desktop/electron-app/src/index.js @@ -188,7 +188,7 @@ app.on('ready', async () => { * Prompt for closing spawned processes */ app.on('before-quit', (event) => { - if (sessionManager.hasActiveSessions) { + if (sessionManager.hasRunningSessions) { const dialogOpts = { type: 'question', buttons: ['Close', 'Cancel'], From 545e7d5a7f2d8c032d954fad84625189526c37cb Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 19 May 2021 09:45:07 -0400 Subject: [PATCH 22/28] fix: import session manager correctly and reconstruct origin URL without extra colons --- ui/desktop/electron-app/src/index.js | 2 +- ui/desktop/electron-app/src/utils/sanitizer.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/desktop/electron-app/src/index.js b/ui/desktop/electron-app/src/index.js index 0de2bfb54..1f220eb85 100644 --- a/ui/desktop/electron-app/src/index.js +++ b/ui/desktop/electron-app/src/index.js @@ -17,7 +17,7 @@ require('./ipc/handlers.js'); const runtimeSettings = require('./services/runtime-settings.js'); const { generateCSPHeader } = require('./config/content-security-policy.js'); -const sessionManager = require('./session/manager.js'); +const sessionManager = require('./services/session-manager.js'); const menu = require('./config/menu.js'); const appUpdater = require('./helpers/app-updater.js'); diff --git a/ui/desktop/electron-app/src/utils/sanitizer.js b/ui/desktop/electron-app/src/utils/sanitizer.js index 9e635b0d5..5dbc5efa9 100644 --- a/ui/desktop/electron-app/src/utils/sanitizer.js +++ b/ui/desktop/electron-app/src/utils/sanitizer.js @@ -21,7 +21,7 @@ module.exports = { urlValidate: (str) => { try { const url = new URL(str); - return `${url.protocol}://${url.host}`; + return `${url.protocol}//${url.host}`; } catch (e) { // Parse error throw new Error(`URL ${str} could not be validated.`); From e86a4fc27dc264aad56e19b977fdb897d470a703 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Wed, 19 May 2021 13:04:40 -0400 Subject: [PATCH 23/28] chore: bump CLI version and update changelog --- ui/desktop/CHANGELOG.md | 2 +- ui/desktop/electron-app/config/cli.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/desktop/CHANGELOG.md b/ui/desktop/CHANGELOG.md index 93e8fb472..42bd5a07d 100644 --- a/ui/desktop/CHANGELOG.md +++ b/ui/desktop/CHANGELOG.md @@ -2,7 +2,7 @@ Canonical reference for changes, improvements, and bugfixes for Boundary Desktop. -## Next +## v1.0.1 [CLI 0.2.2] (2021.05.19) ### New diff --git a/ui/desktop/electron-app/config/cli.js b/ui/desktop/electron-app/config/cli.js index 9ebc26ea7..6c7ecb6a4 100644 --- a/ui/desktop/electron-app/config/cli.js +++ b/ui/desktop/electron-app/config/cli.js @@ -4,7 +4,7 @@ const https = require('https'); const decompress = require('decompress'); const os = require('os'); -const artifactVersion = '0.2.0'; +const artifactVersion = '0.2.2'; const artifactDestination = path.resolve(__dirname, '..', 'cli'); const downloadArtifact = version => { From ab668d74eb717ca9d3c3a5d234d6690598e14457 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 19 May 2021 11:16:30 -0700 Subject: [PATCH 24/28] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Delete=20key-value?= =?UTF-8?q?=20row=20and=20other=20tweaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delete the recently introduced key-value class for rows, for they key-value lookalike, when editing we want to use 3 colums on the table rather than 2. Some style's tweaks to simplify --- .../components/rose/table/index.stories.mdx | 77 ++++++++----- .../styles/rose/components/table/_table.scss | 23 +--- .../rose/tests/dummy/app/templates/index.hbs | 109 +++++++----------- 3 files changed, 99 insertions(+), 110 deletions(-) diff --git a/addons/rose/addon/components/rose/table/index.stories.mdx b/addons/rose/addon/components/rose/table/index.stories.mdx index 7c91f0de4..444419be4 100644 --- a/addons/rose/addon/components/rose/table/index.stories.mdx +++ b/addons/rose/addon/components/rose/table/index.stories.mdx @@ -6,9 +6,7 @@ import { boolean, select } from '@storybook/addon-knobs'; # Table -A table component to display data in structure of rows and columns. It supports `header`, `body` and `footer` optional definitions. Each definition allows for a table `row` to be defined with either a `cell` or `headerCell` table element. Rows can be visually hidden, styled for a key/value visualization, cells can be shrinked to its content with, and center/right cell alignment is supported. - -Row `key/value` style should be applied per row. +A table component to display data in structure of rows and columns. It supports `header`, `body` and `footer` optional definitions. Each definition allows for a table `row` to be defined with either a `cell` or `headerCell` table element. Rows can be visually hidden, and cells can be shrinked to its content with, and center/right cell alignment is supported. Cell shrink should be applied to all the cells in a row. Otherwise the bigger cell with shrink applied will determinate the width of the row. @@ -108,48 +106,71 @@ Cell shrink should be applied to all the cells in a row. Otherwise the bigger ce {{ template: hbs` - + - - Key - Value + + Key + Value - - Key - Value - - - Key - Value - - - Key - Value - - + Key - Add + + Remove + - + + Key + + + + Choose an option + Value 1 + Value 2 + Value 3 + + + + + Add + + + Key - Remove + + Add + + + + Key + + + + + Add + - - - Footer + + + Footer @@ -158,8 +179,8 @@ Cell shrink should be applied to all the cells in a row. Otherwise the bigger ce style: select( 'style', { - 'default': '', - 'key-value': 'key-value' + 'condensed': 'condensed', + 'default': '' } ) } diff --git a/addons/rose/addon/styles/rose/components/table/_table.scss b/addons/rose/addon/styles/rose/components/table/_table.scss index a3c3bfcdc..f9b7b9daf 100644 --- a/addons/rose/addon/styles/rose/components/table/_table.scss +++ b/addons/rose/addon/styles/rose/components/table/_table.scss @@ -10,15 +10,12 @@ text-align: left; } - .rose-table-row-key-value { - td:nth-child(2) { - display: flex; - input { - width: 100%; - margin-right: sizing.rems(s); - } - button { margin-right: 0; } - } + // This styles are add to stop the input to apply extra margin (default on forms) + .rose-form-input-field, + .rose-form-select, + .rose-form-input { + margin: 0; + width: 100%; } .rose-table-cell, @@ -58,14 +55,6 @@ margin-bottom: 0; } - .rose-table-cell { - .rose-form-input-field { - margin: 0; - width: inherit; - vertical-align: inherit; - } - } - &.rose-table-condensed { .rose-table-cell { @include type.type(s); diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index f162f9948..e82d02286 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -75,49 +75,72 @@ -

Condensed Table Key/Value Lookalike

+

Condensed Table Key/Value Lookalike (edit mode)

Key - Value + Value - - Key - Value - - - Key - Value - - - Key - Value - - + Key - - Remove + + + Remove + - + + Key + + + + Choose an option + Value 1 + Value 2 + Value 3 + + + + + Add + + + Key - - Add + + + Add + + + + Key + + + + + Add + - Footer + Footer @@ -147,50 +170,6 @@
-

Key/Value

- - - Key - Value - - - Key - Value - - - Key - Value - - - - - - Key - - - - - - Add - - - - - - - - Key - - - - - - Remove - - - - -

Table

From 3133997e78408b6036afa8f05509877f8ad199f6 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Wed, 19 May 2021 13:15:04 -0700 Subject: [PATCH 25/28] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Deleting=20forgot?= =?UTF-8?q?=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deleting a test that is not need it anymore after last changes --- .../tests/integration/components/rose/table/row-test.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/addons/rose/tests/integration/components/rose/table/row-test.js b/addons/rose/tests/integration/components/rose/table/row-test.js index c61552778..2a0c1f758 100644 --- a/addons/rose/tests/integration/components/rose/table/row-test.js +++ b/addons/rose/tests/integration/components/rose/table/row-test.js @@ -42,10 +42,4 @@ module('Integration | Component | rose/table/row', function (hooks) { await render(hbs``); assert.ok(find('.rose-table-row-visually-hidden')); }); - - test('it can be key/value style', async function (assert) { - assert.expect(1); - await render(hbs``); - assert.ok(find('.rose-table-row-key-value')); - }); }); From 6159378a527547fd934c5e3c58a605b85c28d415 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Date: Fri, 21 May 2021 08:19:48 -0700 Subject: [PATCH 26/28] =?UTF-8?q?style:=20=F0=9F=92=84=20Clean=20default?= =?UTF-8?q?=20tests=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean the default test comment added when creating a new test file with ember-cli. --- addons/api/tests/unit/models/auth-method-test.js | 1 - addons/api/tests/unit/models/auth-token-test.js | 1 - .../fragment-auth-method-attributes-account-claim-map-test.js | 1 - .../tests/unit/models/fragment-auth-method-attributes-test.js | 1 - addons/api/tests/unit/models/fragment-host-set-test.js | 1 - addons/api/tests/unit/models/fragment-principal-test.js | 1 - addons/api/tests/unit/models/fragment-string-test.js | 1 - addons/api/tests/unit/models/host-test.js | 1 - addons/api/tests/unit/serializers/auth-method-test.js | 1 - addons/api/tests/unit/serializers/host-test.js | 1 - addons/api/tests/unit/serializers/session-test.js | 1 - ui/admin/tests/unit/controllers/application-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope-test.js | 1 - .../tests/unit/controllers/scopes/scope/auth-methods-test.js | 1 - .../controllers/scopes/scope/auth-methods/auth-method-test.js | 1 - .../scopes/scope/auth-methods/auth-method/accounts-test.js | 1 - .../scope/auth-methods/auth-method/accounts/account-test.js | 1 - .../scopes/scope/auth-methods/auth-method/accounts/new-test.js | 1 - .../tests/unit/controllers/scopes/scope/auth-methods/new-test.js | 1 - .../tests/unit/controllers/scopes/scope/authenticate-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/groups-test.js | 1 - .../tests/unit/controllers/scopes/scope/groups/group-test.js | 1 - .../controllers/scopes/scope/groups/group/add-members-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/groups/new-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/roles-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/roles/role-test.js | 1 - .../controllers/scopes/scope/roles/role/add-principals-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/users-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/users/new-test.js | 1 - ui/admin/tests/unit/controllers/scopes/scope/users/user-test.js | 1 - .../controllers/scopes/scope/users/user/add-accounts-test.js | 1 - 32 files changed, 32 deletions(-) diff --git a/addons/api/tests/unit/models/auth-method-test.js b/addons/api/tests/unit/models/auth-method-test.js index ff746e777..5e96526e3 100644 --- a/addons/api/tests/unit/models/auth-method-test.js +++ b/addons/api/tests/unit/models/auth-method-test.js @@ -6,7 +6,6 @@ module('Unit | Model | auth method', function (hooks) { setupTest(hooks); setupMirage(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord('auth-method', {}); diff --git a/addons/api/tests/unit/models/auth-token-test.js b/addons/api/tests/unit/models/auth-token-test.js index bf9809ee0..0900707df 100644 --- a/addons/api/tests/unit/models/auth-token-test.js +++ b/addons/api/tests/unit/models/auth-token-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Model | auth token', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord('auth-token', {}); diff --git a/addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js b/addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js index ade04df8f..7f87ebe7e 100644 --- a/addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js +++ b/addons/api/tests/unit/models/fragment-auth-method-attributes-account-claim-map-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord( diff --git a/addons/api/tests/unit/models/fragment-auth-method-attributes-test.js b/addons/api/tests/unit/models/fragment-auth-method-attributes-test.js index 4dd985316..433c2045d 100644 --- a/addons/api/tests/unit/models/fragment-auth-method-attributes-test.js +++ b/addons/api/tests/unit/models/fragment-auth-method-attributes-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Model | fragment auth method attributes', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord('fragment-auth-method-attributes', {}); diff --git a/addons/api/tests/unit/models/fragment-host-set-test.js b/addons/api/tests/unit/models/fragment-host-set-test.js index 9d9248f8b..3031c94f5 100644 --- a/addons/api/tests/unit/models/fragment-host-set-test.js +++ b/addons/api/tests/unit/models/fragment-host-set-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Model | fragment host set', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord('fragment-host-set', {}); diff --git a/addons/api/tests/unit/models/fragment-principal-test.js b/addons/api/tests/unit/models/fragment-principal-test.js index f6c243ede..c55fd56de 100644 --- a/addons/api/tests/unit/models/fragment-principal-test.js +++ b/addons/api/tests/unit/models/fragment-principal-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Model | fragment principal', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord('fragment-principal', {}); diff --git a/addons/api/tests/unit/models/fragment-string-test.js b/addons/api/tests/unit/models/fragment-string-test.js index 72f2c3eee..7d3c7dcb9 100644 --- a/addons/api/tests/unit/models/fragment-string-test.js +++ b/addons/api/tests/unit/models/fragment-string-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Model | fragment string', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord('fragment-string', {}); diff --git a/addons/api/tests/unit/models/host-test.js b/addons/api/tests/unit/models/host-test.js index 73e66b086..871551523 100644 --- a/addons/api/tests/unit/models/host-test.js +++ b/addons/api/tests/unit/models/host-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Model | host', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let model = store.createRecord('host', {}); diff --git a/addons/api/tests/unit/serializers/auth-method-test.js b/addons/api/tests/unit/serializers/auth-method-test.js index c9c7ec1bb..95706c401 100644 --- a/addons/api/tests/unit/serializers/auth-method-test.js +++ b/addons/api/tests/unit/serializers/auth-method-test.js @@ -6,7 +6,6 @@ module('Unit | Serializer | auth method', function (hooks) { setupTest(hooks); setupMirage(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let serializer = store.serializerFor('auth-method'); diff --git a/addons/api/tests/unit/serializers/host-test.js b/addons/api/tests/unit/serializers/host-test.js index 86c17fdd0..4c531ca82 100644 --- a/addons/api/tests/unit/serializers/host-test.js +++ b/addons/api/tests/unit/serializers/host-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Serializer | host', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let serializer = store.serializerFor('host'); diff --git a/addons/api/tests/unit/serializers/session-test.js b/addons/api/tests/unit/serializers/session-test.js index a5ae53586..8c674b1c9 100644 --- a/addons/api/tests/unit/serializers/session-test.js +++ b/addons/api/tests/unit/serializers/session-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Serializer | session', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let store = this.owner.lookup('service:store'); let serializer = store.serializerFor('session'); diff --git a/ui/admin/tests/unit/controllers/application-test.js b/ui/admin/tests/unit/controllers/application-test.js index eb120e471..ba85a8331 100644 --- a/ui/admin/tests/unit/controllers/application-test.js +++ b/ui/admin/tests/unit/controllers/application-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | application', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:application'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope-test.js b/ui/admin/tests/unit/controllers/scopes/scope-test.js index 1ac27e62b..491aad466 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods-test.js b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods-test.js index af2caa0e3..8b1297655 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/auth-methods', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/auth-methods'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method-test.js b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method-test.js index f1396eba0..7523b46d0 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/auth-methods/auth-method' diff --git a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts-test.js b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts-test.js index 7475cb779..f0706cc2e 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/auth-methods/auth-method/accounts' diff --git a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/account-test.js b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/account-test.js index d906d24de..dcd65f4bb 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/account-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/account-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/auth-methods/auth-method/accounts/account' diff --git a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/new-test.js b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/new-test.js index 1c8baec09..990775639 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/new-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/auth-method/accounts/new-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/auth-methods/auth-method/accounts/new' diff --git a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/new-test.js b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/new-test.js index a3d44a02a..048e103b5 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/new-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/auth-methods/new-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/auth-methods/new', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/auth-methods/new' diff --git a/ui/admin/tests/unit/controllers/scopes/scope/authenticate-test.js b/ui/admin/tests/unit/controllers/scopes/scope/authenticate-test.js index cd9b09503..04ab78eb5 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/authenticate-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/authenticate-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/authenticate', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/authenticate'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/groups-test.js b/ui/admin/tests/unit/controllers/scopes/scope/groups-test.js index 4f1a10f19..4cfb2bb56 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/groups-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/groups-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/groups', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/groups'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/groups/group-test.js b/ui/admin/tests/unit/controllers/scopes/scope/groups/group-test.js index bb3e8b7cc..ddae53937 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/groups/group-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/groups/group-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/groups/group', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/groups/group'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js b/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js index 263e690aa..b1dd91e25 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/groups/group/add-members-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/groups/group/add-members' diff --git a/ui/admin/tests/unit/controllers/scopes/scope/groups/new-test.js b/ui/admin/tests/unit/controllers/scopes/scope/groups/new-test.js index 56eaa6c76..ef0ff13af 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/groups/new-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/groups/new-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/groups/new', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/groups/new'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles-test.js index 1567c0d37..4bd0614e6 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/roles-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/roles', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/roles'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js index ee2595d36..f42c4638e 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/new-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/roles/new', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/roles/new'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/role-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/role-test.js index 4edaa508f..32e0058c3 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/roles/role-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/role-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/roles/role', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/roles/role'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js index 7eb851443..587884b96 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/roles/role/add-principals-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/roles/role/add-principals' diff --git a/ui/admin/tests/unit/controllers/scopes/scope/users-test.js b/ui/admin/tests/unit/controllers/scopes/scope/users-test.js index 25ced1669..a6ea8b7cb 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/users-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/users-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/users', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/users'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/users/new-test.js b/ui/admin/tests/unit/controllers/scopes/scope/users/new-test.js index 440b4523c..de3dce931 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/users/new-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/users/new-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/users/new', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/users/new'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/users/user-test.js b/ui/admin/tests/unit/controllers/scopes/scope/users/user-test.js index 17d292de0..6d985406e 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/users/user-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/users/user-test.js @@ -4,7 +4,6 @@ import { setupTest } from 'ember-qunit'; module('Unit | Controller | scopes/scope/users/user', function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup('controller:scopes/scope/users/user'); assert.ok(controller); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/users/user/add-accounts-test.js b/ui/admin/tests/unit/controllers/scopes/scope/users/user/add-accounts-test.js index 7971e808f..5cbf98f77 100644 --- a/ui/admin/tests/unit/controllers/scopes/scope/users/user/add-accounts-test.js +++ b/ui/admin/tests/unit/controllers/scopes/scope/users/user/add-accounts-test.js @@ -6,7 +6,6 @@ module( function (hooks) { setupTest(hooks); - // Replace this with your real tests. test('it exists', function (assert) { let controller = this.owner.lookup( 'controller:scopes/scope/users/user/add-accounts' From 47c453e979462c5fc8ee1d8e769b992c529e1091 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 May 2021 17:20:49 -0400 Subject: [PATCH 27/28] feat: Generate forge config file based on platform In addition, store release variables in forge config for display in "About" menu option --- .../electron-app/config/forge.config.js | 59 ------------- ui/desktop/electron-app/config/forge.js | 84 +++++++++++++++++++ ui/desktop/electron-app/package.json | 3 +- ui/desktop/electron-app/src/config/menu.js | 21 ++++- ui/desktop/package.json | 2 +- 5 files changed, 106 insertions(+), 63 deletions(-) delete mode 100644 ui/desktop/electron-app/config/forge.config.js create mode 100644 ui/desktop/electron-app/config/forge.js diff --git a/ui/desktop/electron-app/config/forge.config.js b/ui/desktop/electron-app/config/forge.config.js deleted file mode 100644 index c426f9aff..000000000 --- a/ui/desktop/electron-app/config/forge.config.js +++ /dev/null @@ -1,59 +0,0 @@ -const process = require('process'); -const { version } = require('../src/cli/index.js'); - -const formattedCLIVersion = version().formatted; - -const appVersion = process.env.RELEASE_VERSION - ? `Version: ${process.env.RELEASE_VERSION}\n` - : ''; -const appCommit = process.env.RELEASE_COMMIT - ? `Commit: ${process.env.RELEASE_COMMIT}\n` - : ''; - -const formattedAppVersion = `${appVersion}${appCommit}`; - -// Output version strings for debugging -console.log('\n\nVersion Env Vars:'); -console.log('RELEASE_VERSION ', process.env.RELEASE_VERSION); -console.log('RELEASE_COMMIT ', process.env.RELEASE_COMMIT); - -module.exports = { - releaseVersion: process.env.RELEASE_VERSION, - hooks: { - prePackage: () => { - if (!process.env.BOUNDARY_DESKTOP_SIGNING_IDENTITY) { - console.warn('\nWARNING: Could not find signing identity.'); - } - }, - }, - packagerConfig: { - ignore: ['/ember-test(/|$)', '/tests(/|$)'], - name: 'Boundary', - appBundleId: 'com.electron.boundary', - // TODO: where should the client version number come from? - appVersion: `${formattedAppVersion}${formattedCLIVersion}\n`, - appCopyright: 'Copyright © 2021 HashiCorp, Inc.', - icon: './config/macos/icon.icns', - osxSign: { - identity: process.env.BOUNDARY_DESKTOP_SIGNING_IDENTITY, - 'hardened-runtime': true, - entitlements: './config/macos/entitlements.plist', - 'entitlements-inherit': './config/macos/entitlements.plist', - 'signature-flags': 'library', - }, - }, - makers: [ - { - name: '@electron-forge/maker-dmg', - config: { - title: 'Boundary', - name: 'boundary', - icon: './config/macos/disk.icns', - background: './config/macos/background.png', - }, - }, - { - name: '@electron-forge/maker-zip', - }, - ], -}; diff --git a/ui/desktop/electron-app/config/forge.js b/ui/desktop/electron-app/config/forge.js new file mode 100644 index 000000000..1b6aab69f --- /dev/null +++ b/ui/desktop/electron-app/config/forge.js @@ -0,0 +1,84 @@ +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +const DEFAULT_CONFIG = { + packagerConfig: { + ignore: ['/ember-test(/|$)', '/tests(/|$)'], + name: 'Boundary', + version: '0.0.0', + appBundleId: 'com.electron.boundary', + appCopyright: 'Copyright © 2021 HashiCorp, Inc.', + }, + makers: [ + { + name: '@electron-forge/maker-zip', + }, + ], +} + +// Create forge config based on platform +const createConfig = () => { + const config = { ...DEFAULT_CONFIG }; + + // Store env vars in config + ['RELEASE_COMMIT', 'RELEASE_VERSION'].forEach((envVar) => { + if (process.env[envVar]) { + config[envVar] = process.env[envVar]; + console.log(`[forge-config] ${envVar} ${config[envVar]}`); + } + }); + + if (os.platform().match(/(darwin)/i)) { + config.packagerConfig.icon = './config/macos/icon.icns'; + config.packagerConfig.osxSign = { + 'hardened-runtime': true, + entitlements: './config/macos/entitlements.plist', + 'entitlements-inherit': './config/macos/entitlements.plist', + 'signature-flags': 'library', + }; + + // Version + if (config.RELEASE_VERSION) + config.packagerConfig.version = config.RELEASE_VERSION; + + // Signing identity + const signingIdentity = process.env.BOUNDARY_DESKTOP_SIGNING_IDENTITY; + if (signingIdentity) { + config.packagerConfig.osxSign.identity = signingIdentity; + } else { + console.warn( + '[forge-config] WARNING: Could not find signing identity. Proceeding without signing.' + ); + } + + // Generate DMG file + config.makers.push({ + name: '@electron-forge/maker-dmg', + config: { + title: 'Boundary', + name: 'boundary', + icon: './config/macos/disk.icns', + background: './config/macos/background.png', + }, + }); + } + + return config; +}; + +// Save forge config file +const saveConfig = (config, destination) => { + const configPath = `${destination}/forge.config.js`; + console.log(`[forge-config] ${configPath}`); + const content = `module.exports = ${JSON.stringify(config, null, 2)}`; + fs.writeFileSync(configPath, content); +}; + +module.exports = { + setup: () => { + const config = createConfig(); + const destination = path.resolve(__dirname); + saveConfig(config, destination); + }, +}; diff --git a/ui/desktop/electron-app/package.json b/ui/desktop/electron-app/package.json index d9df381c8..14502cdfc 100644 --- a/ui/desktop/electron-app/package.json +++ b/ui/desktop/electron-app/package.json @@ -9,9 +9,10 @@ "main": "src/index.js", "scripts": { "build:cli": "node -e 'require(\"./config/cli.js\").setup()'", + "build:config": "node -e 'require(\"./config/forge.js\").setup()'", "start": "electron-forge start", "package": "electron-forge package", - "premake": "yarn build:cli", + "premake": "yarn build:cli && yarn build:config", "make": "electron-forge make", "publish": "electron-forge publish", "lint": "echo \"No linting configured\"" diff --git a/ui/desktop/electron-app/src/config/menu.js b/ui/desktop/electron-app/src/config/menu.js index 5f669e4bb..4e72a2d0f 100644 --- a/ui/desktop/electron-app/src/config/menu.js +++ b/ui/desktop/electron-app/src/config/menu.js @@ -1,5 +1,7 @@ -const { shell } = require('electron'); +const { app, shell, dialog } = require('electron'); const appUpdater = require('../helpers/app-updater.js'); +const forgeConfig = require('../../config/forge.config.js'); +const { version } = require('../cli/index.js'); const generateMenuTemplate = () => { return [ @@ -7,7 +9,22 @@ const generateMenuTemplate = () => { { label: 'Boundary', submenu: [ - { role: 'about' }, + // { role: 'about' }, + { + label: `About ${app.getName()}`, + click: () => { + const appVersion = `Version: ${forgeConfig.RELEASE_VERSION}`; + const appCommit = `Commit: ${forgeConfig.RELEASE_COMMIT}`; + const cliVersion = version().formatted; + + const dialogOpts = { + type: 'none', + message: `${appVersion}\n${appCommit}`, + detail: cliVersion, + }; + dialog.showMessageBox(dialogOpts); + }, + }, { id: 'update', label: 'Check for Updates', diff --git a/ui/desktop/package.json b/ui/desktop/package.json index ad95f6b81..ba2dab71e 100644 --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -28,7 +28,7 @@ "format:sass": "prettier --write app/**/*.scss", "lint:js:fix": "eslint . --fix", "start": "ember serve", - "prestart:desktop": "cd electron-app && yarn build:cli", + "prestart:desktop": "cd electron-app && yarn premake", "start:desktop": "ember electron", "clean:coverage": "rm -rf coverage_*", "pretest": "yarn clean:coverage", From 5bb7d4190390943b54bfce8ae418f53cffe909e6 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Fri, 21 May 2021 17:38:26 -0400 Subject: [PATCH 28/28] feat: Add copyright info to 'About' menu option Ignore generated forge config file --- ui/desktop/electron-app/.gitignore | 3 +++ ui/desktop/electron-app/src/config/menu.js | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ui/desktop/electron-app/.gitignore b/ui/desktop/electron-app/.gitignore index 75a95bf75..bb7b930fa 100644 --- a/ui/desktop/electron-app/.gitignore +++ b/ui/desktop/electron-app/.gitignore @@ -88,6 +88,9 @@ typings/ # Electron-Forge out/ +# Electron-Forge config +config/forge.config.js + # Ember build ember-dist/ ember-test/ diff --git a/ui/desktop/electron-app/src/config/menu.js b/ui/desktop/electron-app/src/config/menu.js index 4e72a2d0f..d2a0b12c4 100644 --- a/ui/desktop/electron-app/src/config/menu.js +++ b/ui/desktop/electron-app/src/config/menu.js @@ -16,11 +16,12 @@ const generateMenuTemplate = () => { const appVersion = `Version: ${forgeConfig.RELEASE_VERSION}`; const appCommit = `Commit: ${forgeConfig.RELEASE_COMMIT}`; const cliVersion = version().formatted; + const copyright = forgeConfig.packagerConfig.appCopyright; const dialogOpts = { type: 'none', - message: `${appVersion}\n${appCommit}`, - detail: cliVersion, + message: app.getName(), + detail: `${appVersion}\n${appCommit}\n\n${cliVersion}\n\n${copyright}`, }; dialog.showMessageBox(dialogOpts); },
{{@caption}}