Icu 12069 clear current filters component for scopes filter (#2051)
* feat: 🎸 add filters applied tags under search/filter bar ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * feat: 🎸 create Rose::FilterTags component ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 use Rose::FilterTags component in targets list ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 update FilterTags to handle multiple queryParams ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * test: 💍 update dropdown component tests - applyFilter ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * feat: 🎸 create filter-tags component in core ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * chore: 🤖 update core addon to export styles ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 remove filter-tags component from rose addon ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * chore: 🤖 update sass package version ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * feat: 🎸 use FilterTags component in targets list screen ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 reduce component complexity ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * chore: 🤖 add sinon to core ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 update how FilterTags displays filters ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 trucate long tag names ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 wrap FilterTags component in if this.filters to fix issue of static text displaying before the dynamic tags ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069 * refactor: 💡 address feedback ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12069
This commit is contained in:
1 parent
05553643a6
commit
7fa2541ddb
18 files changed
+251
-18
No files matched your search
@@ -13,6 +13,7 @@
|
||||
@color='secondary'
|
||||
@text={{@name}}
|
||||
@count={{@checkedItems.length}}
|
||||
{{!-- {{on 'click' this.open}} --}}
|
||||
/>
|
||||
{{#if @isSearchable}}
|
||||
<DD.Header @hasDivider={{true}}>
|
||||
|
||||
@@ -70,6 +70,16 @@ export default class DropdownComponent extends Component {
|
||||
onClose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selectedItems to checkedItems when the user opens
|
||||
* the dropdown and potentially has made changes
|
||||
* outside of the scope of dropdown
|
||||
*/
|
||||
@action
|
||||
open() {
|
||||
this.selectedItems = [...this.args.checkedItems];
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom close method for dropdown that resets selectedItems
|
||||
* to checkedItems when the user closes the dropdown
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{{#if this.filters}}
|
||||
<div class='filters-applied'>
|
||||
<Hds::Text::Display @size='100' @weight='medium' @color='faint'>{{t
|
||||
'titles.filters-applied'
|
||||
}}</Hds::Text::Display>
|
||||
{{#each this.filters as |filter|}}
|
||||
<Hds::Tag
|
||||
class='filter-tag'
|
||||
@text={{if filter.name filter.name filter.id}}
|
||||
@onDismiss={{fn this.removeFilter filter}}
|
||||
/>
|
||||
{{/each}}
|
||||
<Hds::Button
|
||||
@text={{t 'actions.clear-filters'}}
|
||||
@color='tertiary'
|
||||
@icon='x'
|
||||
@size='small'
|
||||
{{on 'click' this.clearAllFilters}}
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -0,0 +1,67 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { action } from '@ember/object';
|
||||
import { assert } from '@ember/debug';
|
||||
|
||||
export default class FilterTagsIndexComponent extends Component {
|
||||
// =services
|
||||
|
||||
@service router;
|
||||
|
||||
// =attributes
|
||||
|
||||
get filters() {
|
||||
return Object.entries(this.args.filters).flatMap(([key, value]) => {
|
||||
assert(`Tags must be an array for key ${key}`, Array.isArray(value));
|
||||
const paramsSet = new Set(this.getCurrentQueryParams(key));
|
||||
const filters = value.filter((item) => paramsSet.has(item.id));
|
||||
|
||||
return filters.map((item) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
type: key,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
getCurrentQueryParams(key) {
|
||||
let queryParamValue;
|
||||
try {
|
||||
queryParamValue = JSON.parse(this.router.currentRoute.queryParams[key]);
|
||||
} catch {
|
||||
// We should never get an error as we are always asserting the queryParam to an array
|
||||
queryParamValue = [];
|
||||
}
|
||||
return queryParamValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a single filter from queryParams for current route
|
||||
* @param {object} tag
|
||||
*/
|
||||
@action
|
||||
removeFilter(tag) {
|
||||
const queryParamValue = this.getCurrentQueryParams(tag.type);
|
||||
|
||||
const queryParams = {
|
||||
[tag.type]: queryParamValue.filter((item) => item !== tag.id),
|
||||
};
|
||||
|
||||
this.router.replaceWith({ queryParams });
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all filters based on provided queryParams
|
||||
*/
|
||||
@action
|
||||
clearAllFilters() {
|
||||
const queryParams = Object.keys(this.args.filters).reduce((params, key) => {
|
||||
params[key] = [];
|
||||
return params;
|
||||
}, {});
|
||||
|
||||
this.router.replaceWith({ queryParams });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
||||
.filters-applied {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
gap: 0.5rem;
|
||||
|
||||
.filter-tag {
|
||||
max-width: 200px;
|
||||
|
||||
.hds-tag__text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'core/components/filter-tags/index';
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
@@ -37,12 +37,14 @@
|
||||
"ember-browser-services": "^4.0.3",
|
||||
"ember-cli-babel": "^7.26.11",
|
||||
"ember-cli-htmlbars": "^6.2.0",
|
||||
"ember-cli-sass": "^11.0.1",
|
||||
"ember-feature-flags": "^6.0.0",
|
||||
"ember-intl": "^6.0.0-beta.6",
|
||||
"ember-loading": "^2.0.0",
|
||||
"ember-truth-helpers": "^3.0.0",
|
||||
"filesize": "^10.0.7",
|
||||
"intl-unofficial-duration-unit-format": "^3.1.0"
|
||||
"intl-unofficial-duration-unit-format": "^3.1.0",
|
||||
"sass": "^1.69.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "^7.21.3",
|
||||
@@ -82,6 +84,7 @@
|
||||
"qunit": "^2.19.4",
|
||||
"qunit-dom": "^2.0.0",
|
||||
"rose": "*",
|
||||
"sinon": "^17.0.1",
|
||||
"webpack": "^5.78.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*/
|
||||
|
||||
@import 'addon/styles/addons.scss';
|
||||
@@ -0,0 +1,29 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { setupIntl } from 'ember-intl/test-support';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import sinon from 'sinon';
|
||||
|
||||
module('Integration | Component | filter-tags/index', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
setupIntl(hooks);
|
||||
|
||||
hooks.afterEach(function () {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
const router = this.owner.lookup('service:router');
|
||||
sinon.stub(router, 'currentRoute').value({
|
||||
queryParams: {
|
||||
scopes: JSON.stringify(['1']),
|
||||
},
|
||||
});
|
||||
|
||||
this.set('filter', { scopes: [{ id: '1', name: 'Project 1' }] });
|
||||
await render(hbs`<FilterTags @filters={{this.filter}} />`);
|
||||
|
||||
assert.dom('.hds-tag__text').hasText('Project 1');
|
||||
});
|
||||
});
|
||||
@@ -44,6 +44,7 @@ toggle-secret: Toggle secret visibility
|
||||
minimize: Minimize
|
||||
fullscreen: Fullscreen
|
||||
clear-all-filters: Clear all filters
|
||||
clear-filters: Clear filters
|
||||
learn-more: Learn more
|
||||
refresh: Refresh
|
||||
remove-resources: Remove resources and save
|
||||
|
||||
@@ -39,6 +39,7 @@ titles:
|
||||
choose-an-option: Choose an option
|
||||
feature-edition: 'Edition: {edition}'
|
||||
no-results-found: No results found
|
||||
filters-applied: 'Filters Applied:'
|
||||
unit: Unit
|
||||
year: '{numberOfYears, plural, =1 {# year} other {# years}}'
|
||||
days: '{days, plural, =1 {# day} other {# days}}'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/filter-tags/index';
|
||||
@@ -44,7 +44,7 @@
|
||||
"ember-radio-button": "github:yapplabs/ember-radio-button.git#b2ab65f",
|
||||
"ember-uuid": "^2.1.0",
|
||||
"jsonlint": "^1.6.3",
|
||||
"sass": "^1.55.0"
|
||||
"sass": "^1.69.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.18.5",
|
||||
|
||||
@@ -103,6 +103,20 @@ export default class ScopesScopeProjectsTargetsIndexController extends Controlle
|
||||
return orderBy(sessions, 'created_time', 'desc');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns object of filters to be used for displaying selected filters
|
||||
* @returns {object}
|
||||
*/
|
||||
get filters() {
|
||||
return {
|
||||
scopes: this.model.projects,
|
||||
availableSessions: this.availableSessionOptions,
|
||||
type: [],
|
||||
};
|
||||
}
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Quick connect method used to call main connect method and handle
|
||||
* connection errors unique to this route
|
||||
@@ -202,6 +216,11 @@ export default class ScopesScopeProjectsTargetsIndexController extends Controlle
|
||||
this.page = 1;
|
||||
}
|
||||
|
||||
@action
|
||||
toggleSessionsFlyout() {
|
||||
this.sessionsFlyoutActive = !this.sessionsFlyoutActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scopes query param to value of selectedScopes
|
||||
* to trigger a query and closes the dropdown
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
</S.Generic>
|
||||
{{! TODO: Target type filter}}
|
||||
</Hds::SegmentedGroup>
|
||||
<FilterTags @filters={{this.filters}} />
|
||||
{{#if @model.targets}}
|
||||
<Hds::Table
|
||||
@model={{@model.targets}}
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
"qunit": "^2.19.4",
|
||||
"qunit-dom": "^2.0.0",
|
||||
"rose": "*",
|
||||
"sass": "^1.55.0",
|
||||
"sass": "^1.69.5",
|
||||
"shx": "^0.3.4",
|
||||
"sinon": "^14.0.0",
|
||||
"stylelint": "^15.10.1",
|
||||
|
||||
@@ -5341,6 +5341,20 @@
|
||||
dependencies:
|
||||
type-detect "4.0.8"
|
||||
|
||||
"@sinonjs/commons@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3"
|
||||
integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==
|
||||
dependencies:
|
||||
type-detect "4.0.8"
|
||||
|
||||
"@sinonjs/commons@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72"
|
||||
integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==
|
||||
dependencies:
|
||||
type-detect "4.0.8"
|
||||
|
||||
"@sinonjs/fake-timers@>=5", "@sinonjs/fake-timers@^9.1.2":
|
||||
version "9.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c"
|
||||
@@ -5348,6 +5362,20 @@
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^1.7.0"
|
||||
|
||||
"@sinonjs/fake-timers@^10.0.2":
|
||||
version "10.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66"
|
||||
integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^3.0.0"
|
||||
|
||||
"@sinonjs/fake-timers@^11.2.2":
|
||||
version "11.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz#50063cc3574f4a27bd8453180a04171c85cc9699"
|
||||
integrity sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^3.0.0"
|
||||
|
||||
"@sinonjs/fake-timers@^8.0.1":
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7"
|
||||
@@ -5364,6 +5392,15 @@
|
||||
lodash.get "^4.4.2"
|
||||
type-detect "^4.0.8"
|
||||
|
||||
"@sinonjs/samsam@^8.0.0":
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.0.tgz#0d488c91efb3fa1442e26abea81759dfc8b5ac60"
|
||||
integrity sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^2.0.0"
|
||||
lodash.get "^4.4.2"
|
||||
type-detect "^4.0.8"
|
||||
|
||||
"@sinonjs/text-encoding@^0.7.1":
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
|
||||
@@ -8286,9 +8323,9 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001502, caniuse-lite@^1.0.30001517, can
|
||||
integrity sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==
|
||||
|
||||
caniuse-lite@^1.0.30001565:
|
||||
version "1.0.30001570"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz#b4e5c1fa786f733ab78fc70f592df6b3f23244ca"
|
||||
integrity sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==
|
||||
version "1.0.30001571"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz#4182e93d696ff42930f4af7eba515ddeb57917ac"
|
||||
integrity sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==
|
||||
|
||||
capture-exit@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -9832,9 +9869,9 @@ electron-to-chromium@^1.4.535:
|
||||
integrity sha512-t2ZP4AcGE0iKCCQCBx/K2426crYdxD3YU6l0uK2EO3FZH0pbC4pFz/sZm2ruZsND6hQBTcDWWlo/MLpiOdif5g==
|
||||
|
||||
electron-to-chromium@^1.4.601:
|
||||
version "1.4.613"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.613.tgz#529e4fc65576ecfd055d7d4619fade4fac446af2"
|
||||
integrity sha512-r4x5+FowKG6q+/Wj0W9nidx7QO31BJwmR2uEo+Qh3YLGQ8SbBAFuDFpTxzly/I2gsbrFwBuIjrMp423L3O5U3w==
|
||||
version "1.4.615"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz#b1c41839962d2e4e63dca05519da9040e34848c2"
|
||||
integrity sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==
|
||||
|
||||
elliptic@^6.5.3, elliptic@^6.5.4:
|
||||
version "6.5.4"
|
||||
@@ -16849,6 +16886,17 @@ nise@^5.1.1:
|
||||
just-extend "^4.0.2"
|
||||
path-to-regexp "^1.7.0"
|
||||
|
||||
nise@^5.1.5:
|
||||
version "5.1.5"
|
||||
resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.5.tgz#f2aef9536280b6c18940e32ba1fbdc770b8964ee"
|
||||
integrity sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^2.0.0"
|
||||
"@sinonjs/fake-timers" "^10.0.2"
|
||||
"@sinonjs/text-encoding" "^0.7.1"
|
||||
just-extend "^4.0.2"
|
||||
path-to-regexp "^1.7.0"
|
||||
|
||||
no-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
|
||||
@@ -19163,15 +19211,6 @@ sane@^5.0.1:
|
||||
minimist "^1.1.1"
|
||||
walker "~1.0.5"
|
||||
|
||||
sass@^1.55.0:
|
||||
version "1.55.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.55.0.tgz#0c4d3c293cfe8f8a2e8d3b666e1cf1bff8065d1c"
|
||||
integrity sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
sass@^1.69.5:
|
||||
version "1.69.5"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.5.tgz#23e18d1c757a35f2e52cc81871060b9ad653dfde"
|
||||
@@ -19469,6 +19508,18 @@ sinon@^14.0.0:
|
||||
nise "^5.1.1"
|
||||
supports-color "^7.2.0"
|
||||
|
||||
sinon@^17.0.1:
|
||||
version "17.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sinon/-/sinon-17.0.1.tgz#26b8ef719261bf8df43f925924cccc96748e407a"
|
||||
integrity sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==
|
||||
dependencies:
|
||||
"@sinonjs/commons" "^3.0.0"
|
||||
"@sinonjs/fake-timers" "^11.2.2"
|
||||
"@sinonjs/samsam" "^8.0.0"
|
||||
diff "^5.1.0"
|
||||
nise "^5.1.5"
|
||||
supports-color "^7.2.0"
|
||||
|
||||
sisteransi@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
|
||||
|
||||
Reference in new issue
Block a user