-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UI: Update custom message list filters #26653
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:improvement | ||
ui (enterprise): Update filters on the custom messages list view. | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -136,3 +136,7 @@ a.disabled.toolbar-link { | |
margin: 0 $spacing-8; | ||
width: 0; | ||
} | ||
|
||
.segment-filter { | ||
width: min-content; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,14 +3,14 @@ | |
* SPDX-License-Identifier: BUSL-1.1 | ||
*/ | ||
|
||
import Ember from 'ember'; | ||
import Component from '@glimmer/component'; | ||
import { service } from '@ember/service'; | ||
import { task } from 'ember-concurrency'; | ||
import { task, timeout } from 'ember-concurrency'; | ||
import { dateFormat } from 'core/helpers/date-format'; | ||
import { action } from '@ember/object'; | ||
import { tracked } from '@glimmer/tracking'; | ||
import errorMessage from 'vault/utils/error-message'; | ||
import { next } from '@ember/runloop'; | ||
|
||
/** | ||
* @module Page::MessagesList | ||
|
@@ -32,26 +32,6 @@ export default class MessagesList extends Component { | |
@tracked showMaxMessageModal = false; | ||
@tracked messageToDelete = null; | ||
|
||
// This follows the pattern in sync/addon/components/secrets/page/destinations for FilterInput. | ||
// Currently, FilterInput doesn't do a full page refresh causing it to lose focus. | ||
// The work around is to verify that a transition from this route was completed and then focus the input. | ||
constructor(owner, args) { | ||
super(owner, args); | ||
this.router.on('routeDidChange', this.focusNameFilter); | ||
} | ||
|
||
willDestroy() { | ||
super.willDestroy(); | ||
this.router.off('routeDidChange', this.focusNameFilter); | ||
} | ||
|
||
focusNameFilter(transition) { | ||
const route = 'vault.cluster.config-ui.messages.index'; | ||
if (transition?.from?.name === route && transition?.to?.name === route) { | ||
next(() => document.getElementById('message-filter')?.focus()); | ||
} | ||
} | ||
|
||
get formattedMessages() { | ||
return this.args.messages.map((message) => { | ||
let badgeDisplayText = ''; | ||
|
@@ -91,20 +71,6 @@ export default class MessagesList extends Component { | |
return [{ label: 'Messages' }, { label }]; | ||
} | ||
|
||
get statusFilterOptions() { | ||
return [ | ||
{ id: 'active', name: 'active' }, | ||
{ id: 'inactive', name: 'inactive' }, | ||
]; | ||
} | ||
|
||
get typeFilterOptions() { | ||
return [ | ||
{ id: 'modal', name: 'modal' }, | ||
{ id: 'banner', name: 'banner' }, | ||
]; | ||
} | ||
|
||
// callback from HDS pagination to set the queryParams page | ||
get paginationQueryParams() { | ||
return (page) => { | ||
|
@@ -116,7 +82,8 @@ export default class MessagesList extends Component { | |
|
||
transitionToMessagesWithParams(queryParams) { | ||
this.router.transitionTo('vault.cluster.config-ui.messages', { | ||
queryParams, | ||
// always reset back to page 1 when changing filters | ||
queryParams: { ...queryParams, page: 1 }, | ||
}); | ||
} | ||
|
||
|
@@ -136,17 +103,24 @@ export default class MessagesList extends Component { | |
} | ||
} | ||
|
||
@action | ||
onFilterInputChange(pageFilter) { | ||
this.transitionToMessagesWithParams({ pageFilter }); | ||
@task | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nicely handled! |
||
*handleSearch(evt) { | ||
evt.preventDefault(); | ||
const formData = new FormData(evt.target); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 today I learned about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's right! As long as we pass a |
||
// shows loader to indicate that the search was executed | ||
yield timeout(Ember.testing ? 0 : 250); | ||
const params = {}; | ||
for (const key of formData.keys()) { | ||
const valDefault = key === 'pageFilter' ? '' : null; | ||
const val = formData.get(key) || valDefault; | ||
params[key] = val; | ||
} | ||
this.transitionToMessagesWithParams(params); | ||
} | ||
|
||
@action | ||
onFilterChange(filterType, [filterOption]) { | ||
const param = {}; | ||
param[filterType] = filterOption; | ||
param.page = 1; | ||
this.transitionToMessagesWithParams(param); | ||
resetFilters() { | ||
this.transitionToMessagesWithParams({ pageFilter: '', status: null, type: null }); | ||
} | ||
|
||
@action | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,34 +12,22 @@ import logout from 'vault/tests/pages/logout'; | |
import { format, addDays, startOfDay } from 'date-fns'; | ||
import { datetimeLocalStringFormat } from 'core/utils/date-formatters'; | ||
import { CUSTOM_MESSAGES } from 'vault/tests/helpers/config-ui/message-selectors'; | ||
import { clickTrigger } from 'ember-power-select/test-support/helpers'; | ||
import { GENERAL } from 'vault/tests/helpers/general-selectors'; | ||
|
||
const MESSAGES_LIST = { | ||
listItem: '.linked-block', | ||
filterBy: (name) => `[data-test-filter-by="${name}"]`, | ||
filterSubmit: '[data-test-filter-submit]', | ||
filterReset: '[data-test-filter-reset]', | ||
}; | ||
|
||
module('Acceptance | Community | config-ui/messages', function (hooks) { | ||
setupApplicationTest(hooks); | ||
setupMirage(hooks); | ||
|
||
hooks.beforeEach(async function () { | ||
this.server.get('/sys/health', function () { | ||
return { | ||
enterprise: false, | ||
initialized: true, | ||
sealed: false, | ||
standby: false, | ||
license: { | ||
expiry: '2024-01-12T23:20:50.52Z', | ||
state: 'stored', | ||
}, | ||
performance_standby: false, | ||
replication_performance_mode: 'disabled', | ||
replication_dr_mode: 'disabled', | ||
server_time_utc: 1622562585, | ||
version: '1.16.0', | ||
cluster_name: 'vault-cluster-e779cd7c', | ||
cluster_id: '5f20f5ab-acea-0481-787e-71ec2ff5a60b', | ||
last_wal: 121, | ||
}; | ||
}); | ||
const version = this.owner.lookup('service:version'); | ||
version.type = 'community'; | ||
await authPage.login(); | ||
}); | ||
|
||
|
@@ -58,6 +46,8 @@ module('Acceptance | Enterprise | config-ui/message', function (hooks) { | |
setupMirage(hooks); | ||
|
||
hooks.beforeEach(async function () { | ||
const version = this.owner.lookup('service:version'); | ||
version.type = 'enterprise'; | ||
this.messageDetailId = () => { | ||
return currentURL().match(/messages\/(.*)\/details/)[1]; | ||
}; | ||
|
@@ -97,26 +87,6 @@ module('Acceptance | Enterprise | config-ui/message', function (hooks) { | |
await click(CUSTOM_MESSAGES.confirmActionButton('Delete message')); | ||
await click(GENERAL.confirmButton); | ||
}; | ||
this.server.get('/sys/health', function () { | ||
return { | ||
enterprise: true, | ||
initialized: true, | ||
sealed: false, | ||
standby: false, | ||
license: { | ||
expiry: '2024-01-12T23:20:50.52Z', | ||
state: 'stored', | ||
}, | ||
performance_standby: false, | ||
replication_performance_mode: 'disabled', | ||
replication_dr_mode: 'disabled', | ||
server_time_utc: 1622562585, | ||
version: '1.16.0+ent', | ||
cluster_name: 'vault-cluster-e779cd7c', | ||
cluster_id: '5f20f5ab-acea-0481-787e-71ec2ff5a60b', | ||
last_wal: 121, | ||
}; | ||
}); | ||
await authPage.login(); | ||
}); | ||
|
||
|
@@ -126,10 +96,10 @@ module('Acceptance | Enterprise | config-ui/message', function (hooks) { | |
test('it should show an empty state when no messages are created', async function (assert) { | ||
assert.expect(4); | ||
await click(CUSTOM_MESSAGES.navLink); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice clean up work |
||
assert.dom('[data-test-component="empty-state"]').exists(); | ||
assert.dom(GENERAL.emptyStateTitle).exists(); | ||
assert.dom(GENERAL.emptyStateTitle).hasText('No messages yet'); | ||
await click(CUSTOM_MESSAGES.tab('On login page')); | ||
assert.dom('[data-test-component="empty-state"]').exists(); | ||
assert.dom(GENERAL.emptyStateTitle).exists(); | ||
assert.dom(GENERAL.emptyStateTitle).hasText('No messages yet'); | ||
}); | ||
|
||
|
@@ -165,37 +135,41 @@ module('Acceptance | Enterprise | config-ui/message', function (hooks) { | |
await click(CUSTOM_MESSAGES.listItem('Awesome custom message title')); | ||
await click(CUSTOM_MESSAGES.confirmActionButton('Delete message')); | ||
await click(GENERAL.confirmButton); | ||
assert.dom('[data-test-component="empty-state"]').exists('Message was deleted'); | ||
assert.dom(GENERAL.emptyStateTitle).exists('Message was deleted'); | ||
}); | ||
test('it should filter by type and status', async function (assert) { | ||
await this.createMessage('banner', null); | ||
const msg1 = this.messageDetailId(); | ||
await this.createMessage('banner'); | ||
const msg2 = this.messageDetailId(); | ||
await visit('vault/config-ui/messages'); | ||
await visit('vault/config-ui/messages?pageFilter=foobar&status=inactive&type=banner'); | ||
// check that filters inherit param values | ||
assert.dom(MESSAGES_LIST.filterBy('pageFilter')).hasValue('foobar'); | ||
assert.dom(MESSAGES_LIST.filterBy('status')).hasValue('inactive'); | ||
assert.dom(MESSAGES_LIST.filterBy('type')).hasValue('banner'); | ||
assert.dom(GENERAL.emptyStateTitle).exists(); | ||
|
||
// clear filters works | ||
await click(MESSAGES_LIST.filterReset); | ||
assert.dom(MESSAGES_LIST.listItem).exists({ count: 2 }); | ||
|
||
// check number of messages with status filters | ||
await clickTrigger('#filter-by-message-status'); | ||
await click('.ember-power-select-options [data-option-index="0"]'); | ||
assert.dom('.linked-block').exists({ count: 1 }, 'filtered by active'); | ||
await click('[data-test-selected-list-button="delete"]'); | ||
await clickTrigger('#filter-by-message-status'); | ||
await click('.ember-power-select-options [data-option-index="1"]'); | ||
assert.dom('.linked-block').exists({ count: 1 }, 'filtered by inactive'); | ||
await click('[data-test-selected-list-button="delete"]'); | ||
await fillIn(MESSAGES_LIST.filterBy('status'), 'active'); | ||
assert.dom(MESSAGES_LIST.listItem).exists({ count: 2 }, 'list does not filter before clicking submit'); | ||
await click(MESSAGES_LIST.filterSubmit); | ||
assert.dom(MESSAGES_LIST.listItem).exists({ count: 1 }); | ||
|
||
// check number of messages with type filters | ||
await clickTrigger('#filter-by-message-type'); | ||
await click('.ember-power-select-options [data-option-index="0"]'); | ||
assert.dom('.linked-block').exists({ count: 0 }, 'filtered by modal'); | ||
await click('[data-test-selected-list-button="delete"]'); | ||
await clickTrigger('#filter-by-message-type'); | ||
await click('.ember-power-select-options [data-option-index="1"]'); | ||
assert.dom('.linked-block').exists({ count: 2 }, 'filtered by banner'); | ||
await click('[data-test-selected-list-button="delete"]'); | ||
await click(MESSAGES_LIST.filterReset); | ||
await fillIn(MESSAGES_LIST.filterBy('type'), 'modal'); | ||
await click(MESSAGES_LIST.filterSubmit); | ||
assert.dom(GENERAL.emptyStateTitle).exists(); | ||
|
||
// check number of messages with no filters | ||
assert.dom('.linked-block').exists({ count: 2 }, 'no filters selected'); | ||
// unsetting a filter will reset that item in the query | ||
await fillIn(MESSAGES_LIST.filterBy('type'), ''); | ||
await fillIn(MESSAGES_LIST.filterBy('status'), 'inactive'); | ||
await click(MESSAGES_LIST.filterSubmit); | ||
assert.dom(MESSAGES_LIST.listItem).exists({ count: 1 }); | ||
|
||
// clean up custom messages | ||
await this.deleteMessage(msg1); | ||
|
@@ -270,7 +244,7 @@ module('Acceptance | Enterprise | config-ui/message', function (hooks) { | |
await click(CUSTOM_MESSAGES.listItem('Awesome custom message title')); | ||
await click(CUSTOM_MESSAGES.confirmActionButton('Delete message')); | ||
await click(GENERAL.confirmButton); | ||
assert.dom('[data-test-component="empty-state"]').exists('Message was deleted'); | ||
assert.dom(GENERAL.emptyStateTitle).exists('Message was deleted'); | ||
}); | ||
test('it should show info message on create and edit form', async function (assert) { | ||
assert.expect(1); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏