diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml
index f972197c0..57d379ac9 100644
--- a/addons/core/translations/resources/en-us.yaml
+++ b/addons/core/translations/resources/en-us.yaml
@@ -983,11 +983,15 @@ worker:
ip_address: IP Address
release_version: Release Version
tag_count: '{tagCount, plural, =1 {# tag} other {# tags}}'
+ tag: Tag
+ key: Key
+ value: Value
+ type: Type
+ tags:
+ title_plural: Tags
+ description: Tags are used to define the type of worker and to make it distinguishable amongst other workers.
flyout:
title: Tags in {workerName}
- table:
- tag: Tag
- type: Type
action:
view_more: View more tags
form:
diff --git a/ui/admin/app/components/workers/worker/actions/index.hbs b/ui/admin/app/components/workers/worker/actions/index.hbs
new file mode 100644
index 000000000..e6882134e
--- /dev/null
+++ b/ui/admin/app/components/workers/worker/actions/index.hbs
@@ -0,0 +1,16 @@
+{{!
+ Copyright (c) HashiCorp, Inc.
+ SPDX-License-Identifier: BUSL-1.1
+}}
+
+
+
+ {{#if (can 'delete worker' @model)}}
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/ui/admin/app/components/workers/worker/header/index.hbs b/ui/admin/app/components/workers/worker/header/index.hbs
new file mode 100644
index 000000000..cd932eb18
--- /dev/null
+++ b/ui/admin/app/components/workers/worker/header/index.hbs
@@ -0,0 +1,11 @@
+{{!
+ Copyright (c) HashiCorp, Inc.
+ SPDX-License-Identifier: BUSL-1.1
+}}
+
+
+ {{t 'resources.worker.title'}}
+
+
+{{t 'resources.worker.description'}}
+
\ No newline at end of file
diff --git a/ui/admin/app/components/workers/worker/nav/index.hbs b/ui/admin/app/components/workers/worker/nav/index.hbs
new file mode 100644
index 000000000..db8eaed35
--- /dev/null
+++ b/ui/admin/app/components/workers/worker/nav/index.hbs
@@ -0,0 +1,13 @@
+{{!
+ Copyright (c) HashiCorp, Inc.
+ SPDX-License-Identifier: BUSL-1.1
+}}
+
+
+
+ {{t 'titles.details'}}
+
+
+ {{t 'resources.worker.tags.title_plural'}}
+
+
\ No newline at end of file
diff --git a/ui/admin/app/controllers/scopes/scope/workers/worker/tags.js b/ui/admin/app/controllers/scopes/scope/workers/worker/tags.js
new file mode 100644
index 000000000..95fd1a3ef
--- /dev/null
+++ b/ui/admin/app/controllers/scopes/scope/workers/worker/tags.js
@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import Controller, { inject as controller } from '@ember/controller';
+
+export default class ScopesScopeWorkersWorkerTagsController extends Controller {
+ @controller('scopes/scope/workers/index') workers;
+}
diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js
index ecac55a4e..8e7970414 100644
--- a/ui/admin/app/router.js
+++ b/ui/admin/app/router.js
@@ -153,7 +153,9 @@ Router.map(function () {
});
this.route('workers', function () {
this.route('new');
- this.route('worker', { path: ':worker_id' }, function () {});
+ this.route('worker', { path: ':worker_id' }, function () {
+ this.route('tags');
+ });
});
this.route('session-recordings', function () {
this.route(
diff --git a/ui/admin/app/routes/scopes/scope/workers/worker/tags.js b/ui/admin/app/routes/scopes/scope/workers/worker/tags.js
new file mode 100644
index 000000000..a472aac49
--- /dev/null
+++ b/ui/admin/app/routes/scopes/scope/workers/worker/tags.js
@@ -0,0 +1,8 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import Route from '@ember/routing/route';
+
+export default class ScopesScopeWorkersWorkerTagsRoute extends Route {}
diff --git a/ui/admin/app/templates/scopes/scope/workers/index.hbs b/ui/admin/app/templates/scopes/scope/workers/index.hbs
index c33f3ec3c..054eb45ff 100644
--- a/ui/admin/app/templates/scopes/scope/workers/index.hbs
+++ b/ui/admin/app/templates/scopes/scope/workers/index.hbs
@@ -166,8 +166,8 @@
@@ -186,12 +186,11 @@
{{#if (gt this.selectedWorker.allTags.length 10)}}
- {{! TODO: Update route to worker.tags once route is added }}
diff --git a/ui/admin/app/templates/scopes/scope/workers/worker/index.hbs b/ui/admin/app/templates/scopes/scope/workers/worker/index.hbs
index b3bb0260c..34679a7c9 100644
--- a/ui/admin/app/templates/scopes/scope/workers/worker/index.hbs
+++ b/ui/admin/app/templates/scopes/scope/workers/worker/index.hbs
@@ -10,38 +10,18 @@
-
- {{t 'resources.worker.title'}}
-
-
- {{t 'resources.worker.description'}}
-
+
-
-
- {{t 'titles.details'}}
-
-
+
-
- {{#if (can 'delete worker' @model)}}
-
- {{t 'resources.worker.actions.delete'}}
-
- {{/if}}
-
+
diff --git a/ui/admin/app/templates/scopes/scope/workers/worker/tags.hbs b/ui/admin/app/templates/scopes/scope/workers/worker/tags.hbs
new file mode 100644
index 000000000..18bb2ea59
--- /dev/null
+++ b/ui/admin/app/templates/scopes/scope/workers/worker/tags.hbs
@@ -0,0 +1,62 @@
+{{!
+ Copyright (c) HashiCorp, Inc.
+ SPDX-License-Identifier: BUSL-1.1
+}}
+
+{{page-title (t 'resources.worker.tags.title_plural')}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{#if @model.allTags}}
+
+ <:body as |B|>
+
+
+ {{B.data.key}}
+
+
+ {{B.data.value}}
+
+
+
+
+
+
+
+ {{/if}}
+
+
+
+
\ No newline at end of file
diff --git a/ui/admin/tests/acceptance/workers/delete-test.js b/ui/admin/tests/acceptance/workers/delete-test.js
index 4ddb06992..9350c1e79 100644
--- a/ui/admin/tests/acceptance/workers/delete-test.js
+++ b/ui/admin/tests/acceptance/workers/delete-test.js
@@ -21,6 +21,10 @@ module('Acceptance | workers | delete', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
+ const MANAGE_DROPDOWN_TOGGLE =
+ '[data-test-manage-worker-dropdown] div button';
+ const REMOVE_WORKER_BUTTON =
+ '[data-test-manage-worker-dropdown] div:nth-child(2) button';
let getWorkerCount;
const instances = {
@@ -54,7 +58,8 @@ module('Acceptance | workers | delete', function (hooks) {
test('can delete a worker', async function (assert) {
const count = getWorkerCount();
await visit(urls.worker);
- await click('.rose-layout-page-actions .rose-dropdown-button-danger');
+ await click(MANAGE_DROPDOWN_TOGGLE);
+ await click(REMOVE_WORKER_BUTTON);
assert.strictEqual(getWorkerCount(), count - 1);
});
@@ -64,7 +69,8 @@ module('Acceptance | workers | delete', function (hooks) {
confirmService.confirm = sinon.fake.returns(resolve());
const count = getWorkerCount();
await visit(urls.worker);
- await click('.rose-layout-page-actions .rose-dropdown-button-danger');
+ await click(MANAGE_DROPDOWN_TOGGLE);
+ await click(REMOVE_WORKER_BUTTON);
assert.strictEqual(getWorkerCount(), count - 1);
assert.ok(confirmService.confirm.calledOnce);
});
@@ -75,7 +81,8 @@ module('Acceptance | workers | delete', function (hooks) {
confirmService.confirm = sinon.fake.returns(reject());
const count = getWorkerCount();
await visit(urls.worker);
- await click('.rose-layout-page-actions .rose-dropdown-button-danger');
+ await click(MANAGE_DROPDOWN_TOGGLE);
+ await click(REMOVE_WORKER_BUTTON);
assert.strictEqual(getWorkerCount(), count);
assert.ok(confirmService.confirm.calledOnce);
});
@@ -84,9 +91,8 @@ module('Acceptance | workers | delete', function (hooks) {
instances.worker.authorized_actions =
instances.worker.authorized_actions.filter((item) => item !== 'delete');
await visit(urls.worker);
- assert
- .dom('.rose-layout-page-actions .rose-dropdown-button-danger')
- .isNotVisible();
+ await click(MANAGE_DROPDOWN_TOGGLE);
+ assert.dom(REMOVE_WORKER_BUTTON).isNotVisible();
});
test('deleting a worker which errors displays error messages', async function (assert) {
@@ -102,7 +108,8 @@ module('Acceptance | workers | delete', function (hooks) {
);
});
await visit(urls.worker);
- await click('.rose-layout-page-actions .rose-dropdown-button-danger');
+ await click(MANAGE_DROPDOWN_TOGGLE);
+ await click(REMOVE_WORKER_BUTTON);
assert.ok(find('[role="alert"]').textContent.trim(), 'Oops.');
});
});
diff --git a/ui/admin/tests/acceptance/workers/list-test.js b/ui/admin/tests/acceptance/workers/list-test.js
index f9275b506..2e73cb327 100644
--- a/ui/admin/tests/acceptance/workers/list-test.js
+++ b/ui/admin/tests/acceptance/workers/list-test.js
@@ -42,6 +42,7 @@ module('Acceptance | workers | list', function (hooks) {
globalScope: null,
workers: null,
worker: null,
+ workerTags: null,
};
hooks.beforeEach(function () {
@@ -51,6 +52,7 @@ module('Acceptance | workers | list', function (hooks) {
urls.globalScope = `/scopes/global/scopes`;
urls.workers = `/scopes/global/workers`;
urls.worker = `${urls.workers}/${instances.worker.id}`;
+ urls.workerTags = `${urls.worker}/tags`;
authenticateSession({});
featuresService = this.owner.lookup('service:features');
});
@@ -189,7 +191,7 @@ module('Acceptance | workers | list', function (hooks) {
await click(WORKERS_FLYOUT_VIEW_MORE_TAGS);
- assert.strictEqual(currentURL(), urls.worker);
+ assert.strictEqual(currentURL(), urls.workerTags);
await click(`[href="${urls.workers}"]`);
diff --git a/ui/admin/tests/acceptance/workers/tags-test.js b/ui/admin/tests/acceptance/workers/tags-test.js
new file mode 100644
index 000000000..fe1390aca
--- /dev/null
+++ b/ui/admin/tests/acceptance/workers/tags-test.js
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import { module, test } from 'qunit';
+import { visit, currentURL, click, findAll } from '@ember/test-helpers';
+import { setupApplicationTest } from 'ember-qunit';
+import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
+import a11yAudit from 'ember-a11y-testing/test-support/audit';
+import { authenticateSession } from 'ember-simple-auth/test-support';
+
+module('Acceptance | workers | tags', function (hooks) {
+ setupApplicationTest(hooks);
+ setupMirage(hooks);
+
+ const instances = {
+ scopes: {
+ global: null,
+ },
+ };
+
+ const urls = {
+ workers: null,
+ worker: null,
+ tags: null,
+ };
+
+ hooks.beforeEach(function () {
+ instances.scopes.global = this.server.create('scope', { id: 'global' });
+ const scope = instances.scopes.global;
+ instances.worker = this.server.create('worker', { scopeId: scope.id });
+ urls.workers = `/scopes/global/workers`;
+ urls.worker = `${urls.workers}/${instances.worker.id}`;
+ urls.tags = `${urls.worker}/tags`;
+ authenticateSession({});
+ });
+
+ test('visiting worker tags', async function (assert) {
+ await visit(urls.worker);
+ await click(`[href="${urls.tags}"]`);
+ await a11yAudit();
+
+ assert.strictEqual(currentURL(), urls.tags);
+ assert.strictEqual(findAll('tbody tr').length, 11);
+ });
+});
diff --git a/ui/admin/tests/integration/components/workers/worker/actions/index-test.js b/ui/admin/tests/integration/components/workers/worker/actions/index-test.js
new file mode 100644
index 000000000..cc4d07343
--- /dev/null
+++ b/ui/admin/tests/integration/components/workers/worker/actions/index-test.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * 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 { click, render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module(
+ 'Integration | Component | workers/worker/actions/index',
+ function (hooks) {
+ setupRenderingTest(hooks);
+ setupIntl(hooks);
+
+ test('it renders', async function (assert) {
+ this.set('model', { id: 'w_123', authorized_actions: ['delete'] });
+ this.set('delete', () => {});
+
+ await render(
+ hbs``,
+ );
+ await click('button');
+
+ assert.dom(this.element).includesText('Remove Worker');
+ });
+ },
+);
diff --git a/ui/admin/tests/integration/components/workers/worker/header/index-test.js b/ui/admin/tests/integration/components/workers/worker/header/index-test.js
new file mode 100644
index 000000000..48bd3cda8
--- /dev/null
+++ b/ui/admin/tests/integration/components/workers/worker/header/index-test.js
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * 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 } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module(
+ 'Integration | Component | workers/worker/header/index',
+ function (hooks) {
+ setupRenderingTest(hooks);
+ setupIntl(hooks);
+
+ test('it renders with the id of the model passed in', async function (assert) {
+ this.set('model', { id: 'w_123' });
+
+ await render(hbs`
+
+ `);
+
+ assert.dom(this.element).includesText('w_123');
+ });
+ },
+);
diff --git a/ui/admin/tests/integration/components/workers/worker/nav/index-test.js b/ui/admin/tests/integration/components/workers/worker/nav/index-test.js
new file mode 100644
index 000000000..5027a8df2
--- /dev/null
+++ b/ui/admin/tests/integration/components/workers/worker/nav/index-test.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * 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 } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | workers/worker/nav/index', function (hooks) {
+ setupRenderingTest(hooks);
+ setupIntl(hooks);
+
+ test('it renders', async function (assert) {
+ await render(hbs`
+
+ `);
+
+ assert.dom(this.element).hasText('Details Tags');
+ });
+});
diff --git a/ui/admin/tests/unit/controllers/scopes/scope/workers/worker/tags-test.js b/ui/admin/tests/unit/controllers/scopes/scope/workers/worker/tags-test.js
new file mode 100644
index 000000000..16d60750d
--- /dev/null
+++ b/ui/admin/tests/unit/controllers/scopes/scope/workers/worker/tags-test.js
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import { module, test } from 'qunit';
+import { setupTest } from 'admin/tests/helpers';
+
+module(
+ 'Unit | Controller | scopes/scope/workers/worker/tags',
+ function (hooks) {
+ setupTest(hooks);
+
+ test('it exists', function (assert) {
+ let controller = this.owner.lookup(
+ 'controller:scopes/scope/workers/worker/tags',
+ );
+ assert.ok(controller);
+ });
+ },
+);
diff --git a/ui/admin/tests/unit/routes/scopes/scope/workers/worker/tags-test.js b/ui/admin/tests/unit/routes/scopes/scope/workers/worker/tags-test.js
new file mode 100644
index 000000000..cb8cdec88
--- /dev/null
+++ b/ui/admin/tests/unit/routes/scopes/scope/workers/worker/tags-test.js
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import { module, test } from 'qunit';
+import { setupTest } from 'admin/tests/helpers';
+
+module('Unit | Route | scopes/scope/workers/worker/tags', function (hooks) {
+ setupTest(hooks);
+
+ test('it exists', function (assert) {
+ let route = this.owner.lookup('route:scopes/scope/workers/worker/tags');
+ assert.ok(route);
+ });
+});