diff --git a/addons/core/addon/helpers/truncate-list.js b/addons/core/addon/helpers/truncate-list.js new file mode 100644 index 000000000..4bd05c037 --- /dev/null +++ b/addons/core/addon/helpers/truncate-list.js @@ -0,0 +1,42 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +/** + * Use this helper to truncate the list if there are more items than the limit specified + * + * @example + * + * {{truncate-list array limit}} + */ + +import Helper from '@ember/component/helper'; +import { inject as service } from '@ember/service'; + +export default class extends Helper { + // =services + @service intl; + + // =compute method + + /** + * This helper truncates the list if there are more items than the limit specified + * and returns the original list appended with +N remaining items + * @param {array} list List of items + * @return string + */ + + compute([translation, list, limit = 3]) { + if (list) { + const numberOfItems = Object.keys(list).length; + const items = list.map(({ value }) => value); + if (numberOfItems > limit) { + const remainingItems = items.splice(limit).length; + return items.join(', ') + this.intl.t(translation, { remainingItems }); + } else { + return items.join(', '); + } + } + } +} diff --git a/addons/core/app/helpers/truncate-list.js b/addons/core/app/helpers/truncate-list.js new file mode 100644 index 000000000..5f20142b6 --- /dev/null +++ b/addons/core/app/helpers/truncate-list.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from 'core/helpers/truncate-list'; diff --git a/addons/core/tests/dummy/app/controllers/index.js b/addons/core/tests/dummy/app/controllers/index.js index c7c7df131..5f1418fff 100644 --- a/addons/core/tests/dummy/app/controllers/index.js +++ b/addons/core/tests/dummy/app/controllers/index.js @@ -14,4 +14,29 @@ export default class IndexController extends Controller { // =properties now = new Date(); + + list = [ + { key: 1, value: 'boundary' }, + { key: 2, value: 'consul' }, + { key: 3, value: 'vault' }, + { key: 4, value: 'hcp' }, + { key: 5, value: 'packer' }, + ]; + + listTwo = [ + { key: 1, value: 'boundary' }, + { key: 2, value: 'consul' }, + ]; + + listThree = [{ key: 1, value: 'boundary' }]; + + listFour = [ + { key: 1, value: 'boundary' }, + { key: 2, value: 'consul' }, + { key: 3, value: 'vault' }, + { key: 4, value: 'hcp' }, + { key: 5, value: 'packer' }, + { key: 6, value: 'new' }, + { key: 7, value: 'newA' }, + ]; } diff --git a/addons/core/tests/dummy/app/templates/index.hbs b/addons/core/tests/dummy/app/templates/index.hbs index 1121c9cb5..08abd9aa0 100644 --- a/addons/core/tests/dummy/app/templates/index.hbs +++ b/addons/core/tests/dummy/app/templates/index.hbs @@ -4,4 +4,11 @@ }}

Welcome to Ember

-

{{relative-datetime-live this.now}}

\ No newline at end of file +

{{relative-datetime-live this.now}}

+ + \ No newline at end of file diff --git a/addons/core/tests/integration/helpers/truncate-list-test.js b/addons/core/tests/integration/helpers/truncate-list-test.js new file mode 100644 index 000000000..59d277344 --- /dev/null +++ b/addons/core/tests/integration/helpers/truncate-list-test.js @@ -0,0 +1,55 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { setupIntl } from 'ember-intl/test-support'; + +const list = [ + { key: 1, value: 'boundary' }, + { key: 2, value: 'consul' }, + { key: 3, value: 'packer' }, + { key: 4, value: 'vault' }, +]; + +const listWithNoItem = []; + +const listWithOneItem = [{ key: 1, value: 'boundary' }]; +const limit = 3; +module('Integration | Helper | truncate-list', function (hooks) { + setupRenderingTest(hooks); + setupIntl(hooks); + + test('it renders correctly when there is list with more than the limit specificed', async function (assert) { + assert.expect(1); + this.set('inputValue', list); + this.set('limit', limit); + await render( + hbs`{{truncate-list 'actions.more' this.inputValue this.limit}}` + ); + assert.strictEqual( + this.element.textContent.trim(), + 'boundary, consul, packer, +1 more' + ); + }); + + test('it renders correctly when there is list with one item', async function (assert) { + assert.expect(1); + this.set('inputValue', listWithOneItem); + + await render(hbs`{{truncate-list 'actions.more' this.inputValue}}`); + assert.strictEqual(this.element.textContent.trim(), 'boundary'); + }); + + test('it renders correctly when the list is empty', async function (assert) { + assert.expect(1); + this.set('inputValue', listWithNoItem); + + await render(hbs`{{truncate-list 'actions.more' this.inputValue}}`); + assert.strictEqual(this.element.textContent.trim(), ''); + }); +}); diff --git a/addons/core/translations/actions/en-us.yaml b/addons/core/translations/actions/en-us.yaml index 8b0a726fc..f6f081e8f 100644 --- a/addons/core/translations/actions/en-us.yaml +++ b/addons/core/translations/actions/en-us.yaml @@ -51,3 +51,4 @@ do-this-later: Do this later toggle-color-theme: Toggle Color Theme toggle-feature-edition: Toggle Feature Edition toggle-licensed-features: Toggle Licensed Features +more: ', +{remainingItems} more'