From 37de7e3480e588705a4e81a83d09331814324bf5 Mon Sep 17 00:00:00 2001 From: Lisbet Alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Fri, 6 Mar 2026 14:19:45 -0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Create=20string=20format?= =?UTF-8?q?s=20component=20(#3191)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 Create string formats component * Add missing copyright headers * fix: 🐛 change to readonly ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-18458 --- addons/core/translations/resources/en-us.yaml | 17 +++++ .../form/role/edit-grants/index.hbs | 22 +++++-- .../components/grant-string-formats/index.hbs | 63 +++++++++++++++++++ .../components/grant-string-formats/index.js | 41 ++++++++++++ ui/admin/config/environment.js | 2 + .../grant-string-formats/index-test.js | 62 ++++++++++++++++++ 6 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 ui/admin/app/components/grant-string-formats/index.hbs create mode 100644 ui/admin/app/components/grant-string-formats/index.js create mode 100644 ui/admin/tests/integration/components/grant-string-formats/index-test.js diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index d7f673b19..2b2f70318 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -663,6 +663,23 @@ role: edit-grants: title: Edit Grants description: Modify existing grant strings or add new grant strings to this role. + string-formats: + title: String format + title_plural: String formats + resource-type: + label: Singular resource type + help: Applies actions to a specific resource type + resource: + label: Specific resource(s) + help: Applies actions to one or more individual resources + pinned-id: + label: Pinned ID + help: '"Pins" actions to a non-top-level type within a specific resource ID. Only available for certain resource types. ' + link: More info + insert-actions: insert actions + insert-resource-types: insert resource types + insert-id: insert id + insert-resource-ids: insert resource ids scope: title: Scope title_plural: Scopes diff --git a/ui/admin/app/components/form/role/edit-grants/index.hbs b/ui/admin/app/components/form/role/edit-grants/index.hbs index 809766cb0..d3ee4c92d 100644 --- a/ui/admin/app/components/form/role/edit-grants/index.hbs +++ b/ui/admin/app/components/form/role/edit-grants/index.hbs @@ -4,15 +4,25 @@ }} - {{! TODO: Add responsive options to @colspan once we upgrade to HDS v6.0.0}} - - + + {{! TODO: Add grants code editor. }} - - {{! TODO: Add string options and actions. }} - + + + <:toggle>{{t + 'resources.role.edit-grants.string-formats.title_plural' + }} + <:content> + + + + diff --git a/ui/admin/app/components/grant-string-formats/index.hbs b/ui/admin/app/components/grant-string-formats/index.hbs new file mode 100644 index 000000000..fb1c8b1ff --- /dev/null +++ b/ui/admin/app/components/grant-string-formats/index.hbs @@ -0,0 +1,63 @@ +{{! + Copyright IBM Corp. 2021, 2026 + SPDX-License-Identifier: BUSL-1.1 +}} + + + + {{t + 'resources.role.edit-grants.string-formats.resource-type.label' + }} + {{t + 'resources.role.edit-grants.string-formats.resource-type.help' + }} + + + {{t + 'resources.role.edit-grants.string-formats.resource.label' + }} + {{t + 'resources.role.edit-grants.string-formats.resource.help' + }} + + + {{t + 'resources.role.edit-grants.string-formats.pinned-id.label' + }} + + {{t 'resources.role.edit-grants.string-formats.pinned-id.help'}} + + {{t 'resources.role.edit-grants.string-formats.pinned-id.link'}} + + + + + + + {{t 'resources.role.edit-grants.string-formats.title'}} + \ No newline at end of file diff --git a/ui/admin/app/components/grant-string-formats/index.js b/ui/admin/app/components/grant-string-formats/index.js new file mode 100644 index 000000000..2915008b1 --- /dev/null +++ b/ui/admin/app/components/grant-string-formats/index.js @@ -0,0 +1,41 @@ +/** + * Copyright IBM Corp. 2021, 2026 + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { service } from '@ember/service'; + +export default class GrantStringFormatsIndex extends Component { + // =services + + @service intl; + + // =attributes + + stringFormatTypes = { + resourceType: 'resource-type', + resource: 'resource', + pinnedId: 'pinned-id', + }; + + stringFormats = { + [this.stringFormatTypes.resourceType]: + `type=<${this.intl.t('resources.role.edit-grants.string-formats.insert-resource-types')}>;actions=<${this.intl.t('resources.role.edit-grants.string-formats.insert-actions')}>`, + [this.stringFormatTypes.resource]: + `id=<${this.intl.t('resources.role.edit-grants.string-formats.insert-resource-ids')}>;actions=<${this.intl.t('resources.role.edit-grants.string-formats.insert-actions')}>`, + [this.stringFormatTypes.pinnedId]: + `id=<${this.intl.t('resources.role.edit-grants.string-formats.insert-id')}>;type=<${this.intl.t('resources.role.edit-grants.string-formats.insert-resource-types')}>;actions=<${this.intl.t('resources.role.edit-grants.string-formats.insert-actions')}>`, + }; + + @tracked selectedFormatType = this.stringFormatTypes.resourceType; + + /** + * Returns the string format based on the selected format type. + * @type {string} + */ + get stringFormat() { + return this.stringFormats[this.selectedFormatType]; + } +} diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index f72c61ca8..80691ea63 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -97,6 +97,8 @@ module.exports = function (environment) { 'role.add-principals': '/tutorials/oss-administration/oss-manage-roles#create-a-role', 'role.add-grant-scopes': '/docs/commands/roles/add-grant-scopes', + 'role.grant-string-format.pinned-id': + '/docs/rbac/permission-grant-formats#pinned-id', session: '/docs/concepts/domain-model/sessions', target: '/docs/concepts/domain-model/targets', 'target.new': '/docs/common-workflows/manage-targets', diff --git a/ui/admin/tests/integration/components/grant-string-formats/index-test.js b/ui/admin/tests/integration/components/grant-string-formats/index-test.js new file mode 100644 index 000000000..6f44637ef --- /dev/null +++ b/ui/admin/tests/integration/components/grant-string-formats/index-test.js @@ -0,0 +1,62 @@ +/** + * Copyright IBM Corp. 2021, 2026 + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'admin/tests/helpers'; +import { setupIntl } from 'ember-intl/test-support'; +import { render, click } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module( + 'Integration | Component | grant-string-formats/index', + function (hooks) { + setupRenderingTest(hooks); + setupIntl(hooks, 'en-us'); + + const RESOURCE_TYPE_OPTION = '[value="resource-type"]'; + const RESOURCE_OPTION = '[value="resource"]'; + const PINNED_ID_OPTION = '[value="pinned-id"]'; + const STRING_FORMAT_FIELD = '[name="string-format"]'; + + test('it renders string format with resource type by default', async function (assert) { + await render(hbs``); + + assert.dom(RESOURCE_TYPE_OPTION).isChecked(); + assert.dom(RESOURCE_OPTION).isNotChecked(); + assert.dom(PINNED_ID_OPTION).isNotChecked(); + assert + .dom(STRING_FORMAT_FIELD) + .hasValue('type=;actions='); + }); + + test('it renders string format when type is changed to specific resource', async function (assert) { + await render(hbs``); + + await click(RESOURCE_OPTION); + + assert.dom(RESOURCE_OPTION).isChecked(); + assert.dom(RESOURCE_TYPE_OPTION).isNotChecked(); + assert.dom(PINNED_ID_OPTION).isNotChecked(); + assert + .dom(STRING_FORMAT_FIELD) + .hasValue('id=;actions='); + }); + + test('it renders string format when type is changed to pinned id', async function (assert) { + await render(hbs``); + + await click(PINNED_ID_OPTION); + + assert.dom(PINNED_ID_OPTION).isChecked(); + assert.dom(RESOURCE_TYPE_OPTION).isNotChecked(); + assert.dom(RESOURCE_OPTION).isNotChecked(); + assert + .dom(STRING_FORMAT_FIELD) + .hasValue( + 'id=;type=;actions=', + ); + }); + }, +);