Icu 13889 update tags column to action that opens hds flyout and add link to tags tab if more than 10 tags (#2355)

* refactor: 💡 update worker factory to include api_tags

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* feat: 🎸 add tags flyout for workers table

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* refactor: 💡 move test selector to const

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* refactor: 💡 only show 'view more tags' if more than 10 tags

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* test: 💍 update test name

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* refactor: 💡 update how worker tags are shown in flyout

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* refactor: 💡 add one more api tag for worker in mirage

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* refactor: 💡 fix tagDisplayName signature

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889

* refactor: 💡 update tag shortener styling

✅ Closes: https://hashicorp.atlassian.net/browse/ICU-13889
This commit is contained in:
Cameron Perera authored and cameronperera committed 2024-07-16 15:48:10 -05:00
1 parent f51124cfdb
commit 40ebbf8b09
7 files changed
+277 -19

No files matched your search

@@ -7,6 +7,7 @@ import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { loading } from 'ember-loading';
import { tracked } from '@glimmer/tracking';
import { confirm } from 'core/decorators/confirm';
import { notifySuccess, notifyError } from 'core/decorators/notify';
@@ -16,8 +17,39 @@ export default class ScopesScopeWorkersIndexController extends Controller {
@service router;
@service can;
// =attributes
@tracked selectedWorker;
/**
* Get the first 10 tags of the selected worker.
* @type {object[]}
*/
get selectedWorkerTags() {
// only show the first 10 tags if there are more than 10
return this.selectedWorker.allTags.slice(0, 10);
}
/**
* Build the display name for a worker tag
* @param {object} tag
* @returns {string}
*/
tagDisplayName(tag) {
return `${tag.key} = ${tag.value}`;
}
// =actions
/**
* Toggle the tags flyout to display or hide the tags of a worker.
* @param {object} selectedWorker
*/
@action
selectWorker(selectedWorker) {
this.selectedWorker = selectedWorker;
}
/**
* Rollback changes on workers.
* @param {WorkerModel} worker
@@ -68,6 +68,16 @@ export default class ScopesScopeWorkersIndexRoute extends Route {
return workers;
}
resetController(controller, isExiting) {
// Clear selected worker when exiting route to prevent
// the flyout from showing when returning to this route
if (isExiting) {
controller.setProperties({
selectedWorker: null,
});
}
}
/**
* Clears filter selections.
*/
+12
View File
@@ -1069,3 +1069,15 @@
margin-bottom: 2rem;
}
}
// workers
.view-more-tags {
margin-top: 1.5rem;
}
.tag-shortener {
display: inline-block;
max-width: 310px;
overflow: hidden;
text-overflow: ellipsis;
}
@@ -124,12 +124,16 @@
</B.Td>
<B.Td>
{{#if B.data.tagCount}}
<Hds::Badge
<Hds::Button
data-test-worker-tags-flyout-button={{B.data.id}}
@icon='tag'
@text={{t
'resources.worker.table.tag_count'
tagCount=B.data.tagCount
}}
@color='tertiary'
@size='small'
{{on 'click' (fn this.selectWorker B.data)}}
/>
{{/if}}
</B.Td>
@@ -145,6 +149,56 @@
</B.Tr>
</:body>
</Hds::Table>
{{#if this.selectedWorker}}
<Hds::Flyout
data-test-worker-tags-flyout
@onClose={{fn this.selectWorker null}}
as |M|
>
<M.Header>
{{t
'resources.worker.flyout.title'
workerName=this.selectedWorker.displayName
}}
</M.Header>
<M.Body>
<Hds::Table
@model={{this.selectedWorkerTags}}
@columns={{array
(hash label=(t 'resources.worker.flyout.table.tag'))
(hash label=(t 'resources.worker.flyout.table.type'))
}}
@valign='middle'
>
<:body as |B|>
<B.Tr>
<B.Td>
<Hds::Text::Code class='tag-shortener'>
{{this.tagDisplayName B.data}}
</Hds::Text::Code>
</B.Td>
<B.Td>
<Hds::Badge @text={{B.data.type}} />
</B.Td>
</B.Tr>
</:body>
</Hds::Table>
{{#if (gt this.selectedWorker.allTags.length 10)}}
<div class='view-more-tags'>
{{! TODO: Update route to worker.tags once route is added }}
<Hds::Link::Standalone
@icon='arrow-right'
@iconPosition='trailing'
@text={{t 'resources.worker.flyout.action.view_more'}}
@route='scopes.scope.workers.worker'
@model={{this.selectedWorker}}
/>
</div>
{{/if}}
</M.Body>
</Hds::Flyout>
{{/if}}
{{else}}
<Rose::Layout::Centered>
<Rose::Message
+120 -1
View File
@@ -4,7 +4,7 @@
*/
import { module, test } from 'qunit';
import { visit } from '@ember/test-helpers';
import { visit, click, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
import { setupIndexedDb } from 'api/test-support/helpers/indexed-db';
@@ -15,6 +15,15 @@ import {
//invalidateSession,
} from 'ember-simple-auth/test-support';
const WORKERS_FLYOUT = '[data-test-worker-tags-flyout]';
const WORKERS_FLYOUT_DISMISS = '[data-test-worker-tags-flyout] div button';
const WORKERS_FLYOUT_TABLE_BODY = '[data-test-worker-tags-flyout] tbody';
const WORKERS_FLYOUT_TABLE_ROWS = '[data-test-worker-tags-flyout] tbody tr';
const WORKERS_FLYOUT_VIEW_MORE_TAGS =
'[data-test-worker-tags-flyout] .view-more-tags a';
const WORKER_TAGS_BUTTON = (workerId) =>
`[data-test-worker-tags-flyout-button="${workerId}"]`;
module('Acceptance | workers | list', function (hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
@@ -26,17 +35,22 @@ module('Acceptance | workers | list', function (hooks) {
scopes: {
global: null,
},
worker: null,
};
const urls = {
globalScope: null,
workers: null,
worker: 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.globalScope = `/scopes/global/scopes`;
urls.workers = `/scopes/global/workers`;
urls.worker = `${urls.workers}/${instances.worker.id}`;
authenticateSession({});
featuresService = this.owner.lookup('service:features');
});
@@ -77,4 +91,109 @@ module('Acceptance | workers | list', function (hooks) {
await visit(urls.globalScope);
assert.dom(`[href="${urls.workers}"]`).isVisible();
});
test('Users can open and close tags flyout for a specific worker', async function (assert) {
featuresService.enable('byow');
await visit(urls.workers);
assert.dom(WORKERS_FLYOUT).isNotVisible();
await click(WORKER_TAGS_BUTTON(instances.worker.id));
assert.dom(WORKERS_FLYOUT).isVisible();
await click(WORKERS_FLYOUT_DISMISS);
assert.dom(WORKERS_FLYOUT).isNotVisible();
});
test('Users can see worker tags in the tags flyout', async function (assert) {
featuresService.enable('byow');
await visit(urls.workers);
await click(WORKER_TAGS_BUTTON(instances.worker.id));
assert.dom(WORKERS_FLYOUT_TABLE_BODY).includesText('os = z-os');
});
test('Users can only see first 10 tags in the tags flyout', async function (assert) {
featuresService.enable('byow');
instances.worker.update({
configTags: {
tag1: ['value1', 'value2'],
tag2: ['value3'],
tag3: ['value4'],
tag4: ['value5'],
tag5: ['value6'],
tag6: ['value7'],
tag7: ['value8'],
tag8: ['value9'],
tag9: ['value10'],
tag10: ['value11'],
tag11: ['value12'],
},
});
await visit(urls.workers);
await click(WORKER_TAGS_BUTTON(instances.worker.id));
assert.dom(WORKERS_FLYOUT_TABLE_ROWS).exists({ count: 10 });
});
test('Users can click on "view more tags" if there are more than 10 tags', async function (assert) {
featuresService.enable('byow');
instances.worker.update({
configTags: {
tag1: ['value1', 'value2'],
tag2: ['value3'],
tag3: ['value4'],
tag4: ['value5'],
tag5: ['value6'],
tag6: ['value7'],
tag7: ['value8'],
tag8: ['value9'],
tag9: ['value10'],
tag10: ['value11'],
tag11: ['value12'],
},
});
await visit(urls.workers);
await click(WORKER_TAGS_BUTTON(instances.worker.id));
assert.dom(WORKERS_FLYOUT_TABLE_ROWS).exists({ count: 10 });
assert.dom(WORKERS_FLYOUT_VIEW_MORE_TAGS).isVisible();
});
test('Users do not see "view more tags" if there are 10 or less tags', async function (assert) {
featuresService.enable('byow');
instances.worker.update({
configTags: {
tag1: ['value1', 'value2'],
tag2: ['value3'],
tag3: ['value4'],
tag4: ['value5'],
},
apiTags: null,
});
await visit(urls.workers);
await click(WORKER_TAGS_BUTTON(instances.worker.id));
assert.dom(WORKERS_FLYOUT_TABLE_ROWS).exists({ count: 5 });
assert.dom(WORKERS_FLYOUT_VIEW_MORE_TAGS).isNotVisible();
});
test('Users do not see worker tags flyout when returning to workers list', async function (assert) {
featuresService.enable('byow');
await visit(urls.workers);
await click(WORKER_TAGS_BUTTON(instances.worker.id));
assert.dom(WORKERS_FLYOUT).isVisible();
await click(WORKERS_FLYOUT_VIEW_MORE_TAGS);
assert.strictEqual(currentURL(), urls.worker);
await click(`[href="${urls.workers}"]`);
assert.strictEqual(currentURL(), urls.workers);
assert.dom(WORKERS_FLYOUT).isNotVisible();
});
});