diff --git a/addons/api/addon/serializers/host-set.js b/addons/api/addon/serializers/host-set.js index 613caf1ab..5749cd993 100644 --- a/addons/api/addon/serializers/host-set.js +++ b/addons/api/addon/serializers/host-set.js @@ -1,4 +1,5 @@ import ApplicationSerializer from './application'; +import { copy } from 'ember-copy'; const fieldByType = { aws: ['preferred_endpoints', 'filters'], @@ -69,4 +70,19 @@ export default class HostSetSerializer extends ApplicationSerializer { } return value; } + + /** + * Temporarily converts `filters` to an array if it is a string. This is a + * quirk of the API. + * + * TODO: remove once API consistently returns arrays. + */ + normalize(typeClass, hash, ...rest) { + const normalizedHash = copy(hash, true); + if (typeof normalizedHash?.filters === 'string') { + normalizedHash.filters = [normalizedHash.filters]; + } + const normalized = super.normalize(typeClass, normalizedHash, ...rest); + return normalized; + } } diff --git a/addons/api/package.json b/addons/api/package.json index f92862d48..55b9ab7bb 100644 --- a/addons/api/package.json +++ b/addons/api/package.json @@ -36,12 +36,12 @@ "js-bexpr": "hashicorp/js-bexpr#9b4a4b54d85eba67fdfc0990133d1518d890b1e1", "@babel/core": "^7.16.5", "@ember/optional-features": "^2.0.0", - "@ember/test-helpers": "^2.4.2", + "@ember/test-helpers": "^2.6.0", "@glimmer/component": "^1.0.4", "@glimmer/tracking": "^1.0.4", "babel-eslint": "^10.1.0", "broccoli-asset-rev": "^3.0.0", - "doctoc": "^2.0.1", + "doctoc": "^2.1.0", "ember-auto-import": "^1.12.0", "ember-cli": "~4.1.0", "ember-cli-dependency-checker": "^3.2.0", diff --git a/addons/auth/package.json b/addons/auth/package.json index 14e337b01..b48822efc 100644 --- a/addons/auth/package.json +++ b/addons/auth/package.json @@ -28,13 +28,13 @@ }, "devDependencies": { "@ember/optional-features": "^2.0.0", - "@ember/test-helpers": "^2.4.2", + "@ember/test-helpers": "^2.6.0", "@glimmer/component": "^1.0.4", "@glimmer/tracking": "^1.0.4", "babel-eslint": "^10.1.0", "broccoli-asset-rev": "^3.0.0", "core": "*", - "doctoc": "^2.0.1", + "doctoc": "^2.1.0", "ember-auto-import": "^1.12.0", "ember-cli": "~4.1.0", "ember-cli-dependency-checker": "^3.2.0", diff --git a/addons/core/addon/components/doc-link/index.hbs b/addons/core/addon/components/doc-link/index.hbs index 86f028f73..18ecb8406 100644 --- a/addons/core/addon/components/doc-link/index.hbs +++ b/addons/core/addon/components/doc-link/index.hbs @@ -1,6 +1,6 @@ diff --git a/addons/core/package.json b/addons/core/package.json index 34d8a6e2b..795e304b5 100644 --- a/addons/core/package.json +++ b/addons/core/package.json @@ -42,12 +42,12 @@ }, "devDependencies": { "@ember/optional-features": "^2.0.0", - "@ember/test-helpers": "^2.4.2", + "@ember/test-helpers": "^2.6.0", "@glimmer/component": "^1.0.4", "@glimmer/tracking": "^1.0.4", "babel-eslint": "^10.1.0", "broccoli-asset-rev": "^3.0.0", - "doctoc": "^2.0.1", + "doctoc": "^2.1.0", "ember-auto-import": "^1.12.0", "ember-cli": "~4.1.0", "ember-cli-dependency-checker": "^3.2.0", diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index 1341dcc76..57de894d3 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -111,6 +111,9 @@ host-set: filter: label: Filter help: Create a filter to select resources using values such as tag name or tag value. Filter format is specific to each provider + preferred_endpoints: + label: Preferred Endpoints + help: Selects addresses of hosts, in cidr: or dns: format messages: welcome: title: Welcome to Host Sets diff --git a/addons/rose/addon/components/rose/nav/breadcrumbs/index.hbs b/addons/rose/addon/components/rose/nav/breadcrumbs/index.hbs index 287e2cba3..2e67e42df 100644 --- a/addons/rose/addon/components/rose/nav/breadcrumbs/index.hbs +++ b/addons/rose/addon/components/rose/nav/breadcrumbs/index.hbs @@ -1,5 +1,5 @@ diff --git a/addons/rose/addon/components/rose/nav/link/index.hbs b/addons/rose/addon/components/rose/nav/link/index.hbs new file mode 100644 index 000000000..37df6a85b --- /dev/null +++ b/addons/rose/addon/components/rose/nav/link/index.hbs @@ -0,0 +1,9 @@ +{{#if @model}} + + {{yield}} + +{{else}} + + {{yield}} + +{{/if}} diff --git a/addons/rose/addon/components/rose/nav/link/index.stories.mdx b/addons/rose/addon/components/rose/nav/link/index.stories.mdx new file mode 100644 index 000000000..198f434f4 --- /dev/null +++ b/addons/rose/addon/components/rose/nav/link/index.stories.mdx @@ -0,0 +1,23 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { action } from '@storybook/addon-actions'; +import { text, boolean, select } from '@storybook/addon-knobs'; + + + +# Generic Navigation Link + +Proxies the built-in `LinkTo` component, applying a class `rose-nav-link`. + +```html +Text +``` + + + {{ + template: hbs` + Text + `, + context: {}, + }} + diff --git a/addons/rose/addon/components/rose/nav/sidebar/index.hbs b/addons/rose/addon/components/rose/nav/sidebar/index.hbs index 28250c8d6..8d5dd5f9b 100644 --- a/addons/rose/addon/components/rose/nav/sidebar/index.hbs +++ b/addons/rose/addon/components/rose/nav/sidebar/index.hbs @@ -12,7 +12,7 @@ {{/if}} {{yield (hash - link=(component "link-to" class="rose-nav-link") + link=(component "rose/nav/link") )}} diff --git a/addons/rose/addon/components/rose/nav/tabs/index.hbs b/addons/rose/addon/components/rose/nav/tabs/index.hbs index 18470f7d5..bef7428e2 100644 --- a/addons/rose/addon/components/rose/nav/tabs/index.hbs +++ b/addons/rose/addon/components/rose/nav/tabs/index.hbs @@ -3,7 +3,7 @@ class="rose-nav-tabs"> {{yield (hash - link=(component "link-to" class="rose-nav-link") + link=(component "rose/nav/link") )}} diff --git a/addons/rose/addon/styles/rose/components/form/_input.scss b/addons/rose/addon/styles/rose/components/form/_input.scss index 214f57734..889c933ef 100644 --- a/addons/rose/addon/styles/rose/components/form/_input.scss +++ b/addons/rose/addon/styles/rose/components/form/_input.scss @@ -30,6 +30,10 @@ border-radius: sizing.rems(xxxs); box-shadow: inset 0px 3px 1px rgba(var(--stark-components), var(--opacity-4)); + &::placeholder { + color: var(--ui-gray-subtler-1); + } + &.error { color: var(--failure); border-color: currentColor; diff --git a/addons/rose/addon/styles/rose/components/form/_radio-card.scss b/addons/rose/addon/styles/rose/components/form/_radio-card.scss index d8b69c896..18081e154 100644 --- a/addons/rose/addon/styles/rose/components/form/_radio-card.scss +++ b/addons/rose/addon/styles/rose/components/form/_radio-card.scss @@ -32,12 +32,12 @@ $radio-svg: ( ); .rose-form-radio-card { - $cardWideWidth: $size-m * 11; + $cardWideWidth: $size-m * 10; $cardTileWidth: $size-m * 7.25; $borderWidth: $size-xxxs * 2; &.wide { - width: ($size-m) * 23; + width: ($size-m) * 20; } &.tile { diff --git a/addons/rose/addon/styles/rose/components/nav/_breadcrumbs.scss b/addons/rose/addon/styles/rose/components/nav/_breadcrumbs.scss index e7ac5572e..f87fb9ae7 100644 --- a/addons/rose/addon/styles/rose/components/nav/_breadcrumbs.scss +++ b/addons/rose/addon/styles/rose/components/nav/_breadcrumbs.scss @@ -6,7 +6,7 @@ display: flex; flex-wrap: wrap; - .rose-nav-breadcrumbs-link { + .rose-nav-link { --color: var(--ui-gray); color: var(--color); text-decoration: none; diff --git a/addons/rose/app/components/rose/nav/link.js b/addons/rose/app/components/rose/nav/link.js new file mode 100644 index 000000000..b4f6d844f --- /dev/null +++ b/addons/rose/app/components/rose/nav/link.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/nav/link'; diff --git a/addons/rose/package.json b/addons/rose/package.json index 292c1f3ca..3254f48b0 100644 --- a/addons/rose/package.json +++ b/addons/rose/package.json @@ -30,18 +30,18 @@ }, "dependencies": { "ember-cli-babel": "^7.26.8", + "ember-composable-helpers": "^5.0.0", "ember-cli-htmlbars": "^5.7.1", - "ember-composable-helpers": "^4.5.0", "ember-focus-trap": "^0.7.0", - "ember-named-blocks-polyfill": "^0.2.4", - "ember-radio-button": "^2.0.1", + "ember-named-blocks-polyfill": "^0.2.5", + "ember-radio-button": "github:yapplabs/ember-radio-button.git#b2ab65f", "ember-uuid": "^2.1.0", "emberx-select": "github:adopted-ember-addons/emberx-select#bc5f774" }, "devDependencies": { "@babel/core": "^7.16.5", "@ember/optional-features": "^2.0.0", - "@ember/test-helpers": "^2.4.2", + "@ember/test-helpers": "^2.6.0", "@glimmer/component": "^1.0.4", "@glimmer/tracking": "^1.0.4", "@hashicorp/flight-icons": "^2.0.1", @@ -55,13 +55,13 @@ "@storybook/components": "^6.3.12", "@storybook/core-events": "^6.3.0", "@storybook/ember": "^6.3.8", - "@storybook/ember-cli-storybook": "^0.4.0", + "@storybook/ember-cli-storybook": "^0.5.0", "@storybook/theming": "^6.3.0", "babel-eslint": "^10.1.0", "babel-loader": "^8.2.2", - "babel-plugin-ember-modules-api-polyfill": "^2.12.0", + "babel-plugin-ember-modules-api-polyfill": "^3.5.0", "broccoli-asset-rev": "^3.0.0", - "doctoc": "^2.0.1", + "doctoc": "^2.1.0", "ember-auto-import": "^1.12.0", "ember-cli": "~4.1.0", "ember-cli-dependency-checker": "^3.2.0", diff --git a/addons/rose/tests/integration/components/rose/form/radio/group-test.js b/addons/rose/tests/integration/components/rose/form/radio/group-test.js index 4354004e7..c1706fe5e 100644 --- a/addons/rose/tests/integration/components/rose/form/radio/group-test.js +++ b/addons/rose/tests/integration/components/rose/form/radio/group-test.js @@ -54,7 +54,10 @@ module('Integration | Component | rose/form/radio/group', function (hooks) { test('it reflects active radiofield value in @selectedValue and triggers a @changed function', async function (assert) { assert.expect(5); - this.changed = (value) => assert.ok(value); + this.changed = (value) => { + this.selectedValue = value; + assert.ok(value); + }; await render(hbs` `); - assert.equal(findAll('.rose-nav-breadcrumbs-link').length, 2); + assert.equal(findAll('.rose-nav-link').length, 2); }); }); diff --git a/addons/rose/tests/integration/components/rose/nav/link-test.js b/addons/rose/tests/integration/components/rose/nav/link-test.js new file mode 100644 index 000000000..2887900bc --- /dev/null +++ b/addons/rose/tests/integration/components/rose/nav/link-test.js @@ -0,0 +1,18 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; + +module('Integration | Component | rose/nav/link', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + assert.expect(1); + await render(hbs` + + Item Name + + `); + assert.equal(find('.rose-nav-link').textContent.trim(), 'Item Name'); + }); +}); diff --git a/package.json b/package.json index eb0ba9c44..12b0237f7 100755 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ }, "devDependencies": { "cz-conventional-changelog": "^3.1.0", - "doctoc": "^2.0.1", + "doctoc": "^2.1.0", "git-cz": "^4.3.1", "license-checker": "^25.0.1" }, @@ -87,7 +87,8 @@ "json-schema": "^0.4.0", "follow-redirects": "^1.14.7", "node-fetch": "^2.6.7", - "shelljs": "^0.8.5" + "shelljs": "^0.8.5", + "ember-template-recast": "^6.0.0" }, "config": { "commitizen": { diff --git a/ui/admin/app/components/bread-crumbs.js b/ui/admin/app/components/bread-crumbs.js index 93f5a78a7..1f2ac7cea 100644 --- a/ui/admin/app/components/bread-crumbs.js +++ b/ui/admin/app/components/bread-crumbs.js @@ -1,9 +1,118 @@ -import BreadCrumbsComponent from 'ember-breadcrumbs/components/bread-crumbs'; +import Component from '@glimmer/component'; +import EmberObject, { computed, get } from '@ember/object'; import { inject as service } from '@ember/service'; +import { isBlank, isPresent } from '@ember/utils'; +import { A } from '@ember/array'; -export default class crumbs extends BreadCrumbsComponent { +// This component copies and modifies source from ember-breadcrumbs 0.2.3, +// updating it for Ember v4 compatibility. + +// The original copyright is below. + +/* +The MIT License (MIT) + +Copyright (c) 2014-2019 Chris Farber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +export default class BreadcrumbsComponent extends Component { // =services @service session; @service scope; + @service router; + + // =properties + + /* eslint-disable-next-line ember/require-computed-property-dependencies */ + @computed('router.currentRouteName') + get routeInfos() { + /* eslint-disable-next-line ember/no-private-routing-service */ + return this.router._router._routerMicrolib.currentRouteInfos; + } + + /* + For the pathNames and controllers properties, we must be careful not to NOT + specify the properties of the route in our dependent keys. + + Observing the controller property of the route causes some serious problems: + https://github.com/chrisfarber/ember-breadcrumbs/issues/21 + */ + + @computed('routeInfos.[]') + get pathNames() { + return this.routeInfos.map(function (routeInfo) { + return routeInfo.name; + }); + } + + @computed('routeInfos.[]') + get controllers() { + return this.routeInfos.map(function (routeInfo) { + var route = routeInfo.route || routeInfo.handler; + return route.controller; + }); + } + + @computed( + 'controllers.@each.{breadCrumbs,breadCrumb,breadCrumbPath,breadCrumbModel}', + 'pathNames.[]' + ) + get breadCrumbs() { + var controllers = this.controllers; + var defaultPaths = this.pathNames; + var breadCrumbs = A([]); + + controllers.forEach(function (controller, index) { + var crumbs = controller.breadCrumbs || A([]); + var singleCrumb = controller.breadCrumb; + + if (!isBlank(singleCrumb)) { + crumbs.push({ + label: singleCrumb, + path: controller.breadCrumbPath, + model: controller.breadCrumbModel, + }); + } + + crumbs.forEach(function (crumb) { + breadCrumbs.addObject( + EmberObject.create({ + label: crumb.label, + path: crumb.path || defaultPaths[index], + model: crumb.model, + linkable: isPresent(crumb.linkable) + ? crumb.linkable + : crumb.path !== false, + isCurrent: false, + }) + ); + }); + }); + + var deepestCrumb = get(breadCrumbs, 'lastObject'); + if (deepestCrumb) { + deepestCrumb.isCurrent = true; + } + + return breadCrumbs; + } } diff --git a/ui/admin/app/components/form/host-set/aws/index.hbs b/ui/admin/app/components/form/host-set/aws/index.hbs index 3af6ce47f..3d7b974ab 100644 --- a/ui/admin/app/components/form/host-set/aws/index.hbs +++ b/ui/admin/app/components/form/host-set/aws/index.hbs @@ -74,6 +74,94 @@ + + <:title>{{t 'resources.host-set.form.preferred_endpoints.label'}} + <:description>{{t + 'resources.host-set.form.preferred_endpoints.help' + }} + <:body> + {{#if @model.errors.preferred_endpoints}} + + {{#each @model.errors.preferred_endpoints as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t 'titles.value'}} + + + + + {{#each @model.preferred_endpoints as |endpoint i|}} + + + + + + + + + {{t 'actions.remove'}} + + + + {{/each}} + + + + + + + + {{t 'actions.add'}} + + + + + + + + <:title>{{t 'resources.host-set.form.filter.label'}} <:description>{{t 'resources.host-set.form.filter.help'}} diff --git a/ui/admin/app/components/form/host-set/azure/index.hbs b/ui/admin/app/components/form/host-set/azure/index.hbs index 686cb70d4..866577b7d 100644 --- a/ui/admin/app/components/form/host-set/azure/index.hbs +++ b/ui/admin/app/components/form/host-set/azure/index.hbs @@ -74,6 +74,94 @@ + + <:title>{{t 'resources.host-set.form.preferred_endpoints.label'}} + <:description>{{t + 'resources.host-set.form.preferred_endpoints.help' + }} + <:body> + {{#if @model.errors.preferred_endpoints}} + + {{#each @model.errors.preferred_endpoints as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + {{t 'titles.value'}} + + + + + {{#each @model.preferred_endpoints as |endpoint i|}} + + + + + + + + + {{t 'actions.remove'}} + + + + {{/each}} + + + + + + + + {{t 'actions.add'}} + + + + + + + + - + {{#if this.session.isAuthenticated}} @@ -71,11 +71,11 @@ - + {{company-copyright}} {{app-name}} - + {{t 'titles.documentation'}} diff --git a/ui/admin/app/templates/scopes/scope/authenticate/method/index.hbs b/ui/admin/app/templates/scopes/scope/authenticate/method/index.hbs index 14266bf9c..2217bff0a 100644 --- a/ui/admin/app/templates/scopes/scope/authenticate/method/index.hbs +++ b/ui/admin/app/templates/scopes/scope/authenticate/method/index.hbs @@ -3,7 +3,7 @@ {{else}} {{! OIDC disabled: hide OIDC auth form}} @@ -11,7 +11,7 @@ {{/unless}} {{/if}} \ No newline at end of file diff --git a/ui/admin/package.json b/ui/admin/package.json index 6d2ac1828..8455faaf3 100644 --- a/ui/admin/package.json +++ b/ui/admin/package.json @@ -32,13 +32,13 @@ "posttest": "ember coverage-merge && yarn clean:coverage" }, "dependencies": { - "ember-named-blocks-polyfill": "^0.2.4" + "ember-named-blocks-polyfill": "^0.2.5" }, "devDependencies": { "@babel/core": "^7.16.5", "@ember/optional-features": "^2.0.0", "@ember/render-modifiers": "^2.0.2", - "@ember/test-helpers": "^2.4.2", + "@ember/test-helpers": "^2.6.0", "@glimmer/component": "^1.0.4", "@glimmer/tracking": "^1.0.4", "babel-eslint": "^10.1.0", @@ -46,10 +46,9 @@ "broccoli-asset-rev": "^3.0.0", "clipboard": "^2.0.8", "core": "*", - "doctoc": "^2.0.1", + "doctoc": "^2.1.0", "ember-a11y-testing": "^4.2.0", "ember-auto-import": "^1.12.0", - "ember-breadcrumbs": "^0.2.3", "ember-cli": "~4.1.0", "ember-cli-app-version": "^5.0.0", "ember-cli-babel": "^7.26.8", diff --git a/ui/admin/tests/acceptance/auth-methods/oidc-test.js b/ui/admin/tests/acceptance/auth-methods/oidc-test.js index 2ab3e56bd..a9a784cb8 100644 --- a/ui/admin/tests/acceptance/auth-methods/oidc-test.js +++ b/ui/admin/tests/acceptance/auth-methods/oidc-test.js @@ -64,7 +64,7 @@ module('Acceptance | auth methods | oidc', function (hooks) { await visit(urls.authMethod); await click('.rose-layout-page-actions .rose-dropdown-trigger'); assert.equal( - find('.rose-dropdown[open] input[aria-checked=true]').value, + find('.rose-dropdown[open] input:checked').value, instances.authMethod.attributes.state ); }); diff --git a/ui/desktop/CHANGELOG.md b/ui/desktop/CHANGELOG.md index 9e8fc2f53..923135f1c 100644 --- a/ui/desktop/CHANGELOG.md +++ b/ui/desktop/CHANGELOG.md @@ -2,6 +2,12 @@ Canonical reference for changes, improvements, and bugfixes for Boundary Desktop. +## v1.4.2 [CLI 0.7.5] (2022.02.17) + +### New + +- Support dynamic host catalogs. ([PR](https://github.com/hashicorp/boundary-ui/pull/981)) + ## v1.4.1 [CLI 0.7.3] (2021.12.16) ### New diff --git a/ui/desktop/app/templates/application.hbs b/ui/desktop/app/templates/application.hbs index 085201768..76923c4c4 100644 --- a/ui/desktop/app/templates/application.hbs +++ b/ui/desktop/app/templates/application.hbs @@ -11,7 +11,7 @@ {{if this.hasMacOSChrome ' header-cushion'}}' as |header| > - +
diff --git a/ui/desktop/app/templates/origin.hbs b/ui/desktop/app/templates/origin.hbs index 5ecd70b94..fb953f0c8 100644 --- a/ui/desktop/app/templates/origin.hbs +++ b/ui/desktop/app/templates/origin.hbs @@ -7,7 +7,7 @@ class='full-width' @onSubmit={{route-action 'setOrigin' this.origin}} @cancel={{false}} - @disabled={{is-loading}} + @disabled={{(is-loading)}} as |form| > {{else}} {{! OIDC disabled: hide OIDC auth form}} @@ -11,7 +11,7 @@ {{/unless}} {{/if}} \ No newline at end of file diff --git a/ui/desktop/app/templates/scopes/scope/projects/targets/target/hosts.hbs b/ui/desktop/app/templates/scopes/scope/projects/targets/target/hosts.hbs index 1f25fe243..8e30c4bbc 100644 --- a/ui/desktop/app/templates/scopes/scope/projects/targets/target/hosts.hbs +++ b/ui/desktop/app/templates/scopes/scope/projects/targets/target/hosts.hbs @@ -26,7 +26,13 @@ {{host.id}} - {{host.attributes.address}} + + {{#if host.isStatic}} + {{host.address}} + {{else}} + {{t 'resources.host-catalog.types.dynamic'}} + {{/if}} +