0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

Improving the member filters

- Closes dropdown when removing labels
- Larger width to handle multiple labels better
- Subtle focuses when using tabs only
- Bigger close button hitpoints on labels
- Added text ellipis for larger labels in dropdown
- Added some event propagation stops

no issue
This commit is contained in:
James Morris 2022-10-06 12:21:49 +01:00
parent a2bfdc7534
commit 4e3380190b
7 changed files with 116 additions and 82 deletions

View file

@ -15,10 +15,10 @@
@allowCreation={{@allowCreation}}
as |label|
>
<div style="display: flex">
<div style="display: flex; width: 100%;">
<span
class="dropdown-label"
style="flex-grow: 1"
style="flex-grow: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"
title="{{label.name}}"
data-test-label-filter={{label.name}}>
{{label.name}}

View file

@ -6,6 +6,10 @@ import {isBlank} from '@ember/utils';
export default class Trigger extends EmberPowerSelectMultipleTrigger {
@action
handleOptionMouseDown(event) {
event.stopPropagation();
this.args.select.actions.close();
if (!event.target.closest('[data-selected-index]')) {
let optionMouseDown = this.args.extra.optionMouseDown;
if (optionMouseDown) {

View file

@ -13,80 +13,82 @@
</span>
</dd.Trigger>
<dd.Content class="gh-member-actions-menu gh-filter-builder gh-members-filter-builder fade-in-scale {{if this.feature.memberAttribution 'feature-memberAttribution'}} dropdown-menu dropdown-triangle-top-right">
<h3>Filter list</h3>
<section class="gh-filters">
{{#each this.filters as |filter index|}}
<div class="gh-filter-block">
<div class="form-group max-width" data-test-members-filter={{index}}>
<div class="gh-filter-inputgroup">
<span class="gh-select">
<OneWaySelect
@value={{filter.type}}
@options={{this.availableFilterProperties}}
@optionValuePath="name"
@optionLabelPath="label"
@optionTargetPath="name"
@groupLabelPath="group"
@update={{fn this.setFilterType filter}}
data-test-select="members-filter"
<dd.Content>
<div class="gh-member-actions-menu gh-filter-builder gh-members-filter-builder dropdown-menu dropdown-triangle-top-right" {{css-transition "anim-fade-in-scale"}}>
<h3>Filter list</h3>
<section class="gh-filters">
{{#each this.filters as |filter index|}}
<div class="gh-filter-block">
<div class="form-group max-width" data-test-members-filter={{index}}>
<div class="gh-filter-inputgroup">
<span class="gh-select">
<OneWaySelect
@value={{filter.type}}
@options={{this.availableFilterProperties}}
@optionValuePath="name"
@optionLabelPath="label"
@optionTargetPath="name"
@groupLabelPath="group"
@update={{fn this.setFilterType filter}}
data-test-select="members-filter"
/>
{{svg-jar "arrow-down-small"}}
</span>
<span class="gh-select">
<OneWaySelect
@value={{filter.relation}}
@options={{filter.relationOptions}}
@optionValuePath="name"
@optionLabelPath="label"
@optionTargetPath="name"
@update={{fn this.setFilterRelation filter}}
data-test-select="members-filter-operator"
/>
{{svg-jar "arrow-down-small"}}
</span>
<Members::FilterValue
@index={{index}}
@filter={{filter}}
@setFilterValue={{this.setFilterValue}}
@onLabelEdit={{@onLabelEdit}}
/>
{{svg-jar "arrow-down-small"}}
</span>
<span class="gh-select">
<OneWaySelect
@value={{filter.relation}}
@options={{filter.relationOptions}}
@optionValuePath="name"
@optionLabelPath="label"
@optionTargetPath="name"
@update={{fn this.setFilterRelation filter}}
data-test-select="members-filter-operator"
/>
{{svg-jar "arrow-down-small"}}
</span>
<Members::FilterValue
@index={{index}}
@filter={{filter}}
@setFilterValue={{this.setFilterValue}}
@onLabelEdit={{@onLabelEdit}}
/>
<button
type="button"
class="gh-btn gh-btn-text gh-btn-link gh-btn-icon gh-delete-filter"
title="Delete filter"
{{on "click" (fn this.deleteFilter filter)}}
data-test-delete-members-filter={{index}}
>
{{svg-jar "close"}} <span class="hidden">Delete filter</span>
</button>
<button
type="button"
class="gh-btn gh-btn-text gh-btn-link gh-btn-icon gh-delete-filter"
title="Delete filter"
{{on "click" (fn this.deleteFilter filter)}}
data-test-delete-members-filter={{index}}
>
{{svg-jar "close"}} <span class="hidden">Delete filter</span>
</button>
</div>
</div>
</div>
{{/each}}
<div>
<button type="button"
class="gh-btn gh-btn-text gh-btn-link green gh-btn-icon gh-add-filter"
{{on "click" this.addFilter}}
data-test-button="add-members-filter"
>
<span>{{svg-jar "plus"}} Add filter</span>
</button>
</div>
{{/each}}
<div>
<button type="button"
class="gh-btn gh-btn-text gh-btn-link green gh-btn-icon gh-add-filter"
{{on "click" this.addFilter}}
data-test-button="add-members-filter"
</section>
<div class="gh-filter-builder-footer">
<button
class="gh-btn" type="button" {{on "click" this.resetFilter}}
data-test-button="reset-members-filter"
>
<span>{{svg-jar "plus"}} Add filter</span>
<span>Reset all</span>
</button>
<button
class="gh-btn gh-btn-primary"
data-test-button="members-apply-filter" type="button" {{on "click" this.applyFilter}} {{on "keyup" this.handleSubmitKeyup}}
>
<span>Apply filters</span>
</button>
</div>
</section>
<div class="gh-filter-builder-footer">
<button
class="gh-btn" type="button" {{on "click" this.resetFilter}}
data-test-button="reset-members-filter"
>
<span>Reset all</span>
</button>
<button
class="gh-btn gh-btn-primary"
data-test-button="members-apply-filter" type="button" {{on "click" this.applyFilter}}
>
<span>Apply filters</span>
</button>
</div>
</dd.Content>

View file

@ -426,6 +426,15 @@ export default class MembersFilter extends Component {
return relationMap[relation] || '';
}
@action
handleSubmitKeyup(e) {
e.preventDefault();
if (e.key === 'Enter') {
this.applyFilter();
}
}
@action
deleteFilter(filter, event) {
event.stopPropagation();

View file

@ -54,7 +54,8 @@
color: var(--middarkgrey);
}
.gh-filter-builder .gh-delete-filter:hover {
.gh-filter-builder .gh-delete-filter:hover,
.gh-filter-builder .gh-delete-filter:focus {
color: var(--red);
}
@ -69,6 +70,20 @@
margin: 0 6px 0 2px;
}
.gh-filter-builder .gh-btn-text.green.gh-add-filter:hover span,
.gh-filter-builder .gh-btn-text.green.gh-add-filter:focus-visible span {
color: #1da42d;
}
.gh-filter-builder-footer .gh-btn:not(.gh-btn-primary):focus-visible {
color: #394047;
background: #dde0e2;
}
.gh-filter-builder-footer .gh-btn.gh-btn-primary:focus-visible {
box-shadow: 0 0 0 2px var(--green-d2);
}
.gh-filter-builder .gh-filter-block-divider {
display: flex;
align-items: center;
@ -134,7 +149,8 @@
}
.gh-filter-builder .ember-power-select-multiple-option {
padding: 1px 6px;
padding: 1px 1px 1px 6px;
z-index: 9999;
}
.gh-filter-builder .ember-power-select-trigger-multiple-input {
@ -142,6 +158,10 @@
display: flex;
}
.gh-filter-builder .ember-power-select-multiple-options {
padding-right: 28px;
}
@media (max-width: 690px) {
.gh-filter-builder .gh-filter-inputgroup {
grid-template-columns: 1fr 18px;

View file

@ -243,11 +243,14 @@
}
.ember-power-select-multiple-remove-btn {
padding: 2px;
width: 10px;
height: 10px;
flex: 1;
display: flex;
width: 20px;
height: 100%;
line-height: 0;
margin-left: 4px;
padding: 0;
justify-content: center;
align-items: center;
}
.ember-power-select-multiple-remove-btn:not(:hover) {
@ -257,6 +260,7 @@
.ember-power-select-multiple-remove-btn svg {
width: 8px;
height: 8px;
pointer-events: none;
}
.ember-power-select-multiple-remove-btn svg path {

View file

@ -2418,12 +2418,8 @@ p.gh-members-import-errordetail:first-of-type {
}
.gh-members-filter-builder {
width: 720px;
margin-top: 8px;
}
.gh-members-filter-builder.feature-memberAttribution {
width: 780px;
margin-top: 8px;
}
@media (max-width: 980px) {
@ -2439,8 +2435,7 @@ p.gh-members-import-errordetail:first-of-type {
}
@media (max-width: 690px) {
.gh-members-filter-builder,
.gh-members-filter-builder.feature-memberAttribution {
.gh-members-filter-builder {
width: calc(100vw - 20px);
min-width: calc(100vw - 20px);
max-width: calc(100vw - 20px);