Skip to content

Commit

Permalink
Add user search and filtering (#59)
Browse files Browse the repository at this point in the history
* Add user search

* Lint js

* [COM-632] - updated styling on the user directory search tools to look okay on all screens

* [COM-632] added trim to refreshParams so that when groups are selected and then deselected it does not cause text search to fail

Co-authored-by: Ian Morland <ian@morland.me>
Co-authored-by: Ian Morland <ianm@giffgaff.co.uk>
Co-authored-by: Blake Payne <blake@mac-blake.local>
  • Loading branch information
4 people authored Mar 2, 2021
1 parent 83fbab1 commit bc4ffe8
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 48 deletions.
31 changes: 14 additions & 17 deletions js/src/admin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,20 @@ app.initializers.add('fof-user-directory', (app) => {
sortOptions[sort] = app.translator.trans('fof-user-directory.lib.sort.' + sort);
});

app.extensionData.for('fof-user-directory')
.registerSetting(
{
setting: 'fof-user-directory-link',
label: app.translator.trans('fof-user-directory.admin.settings.link'),
type: 'boolean',
}
)
.registerSetting(
{
setting: 'fof-user-directory.default-sort',
label: app.translator.trans('fof-user-directory.admin.settings.default-sort'),
options: sortOptions,
type: 'select',
default: '',
}
)
app.extensionData
.for('fof-user-directory')
.registerSetting({
setting: 'fof-user-directory-link',
label: app.translator.trans('fof-user-directory.admin.settings.link'),
type: 'boolean',
})
.registerSetting({
setting: 'fof-user-directory.default-sort',
label: app.translator.trans('fof-user-directory.admin.settings.default-sort'),
options: sortOptions,
type: 'select',
default: '',
})
.registerPermission(
{
icon: 'far fa-address-book',
Expand Down
2 changes: 1 addition & 1 deletion js/src/forum/components/CheckableButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class CheckableButton extends Button {
getButtonContent(children) {
const prev = super.getButtonContent(children);

if (this.attrs.checked) prev.push(icon('fas fa-check', { className: 'Button-icon ButtonCheck' }))
if (this.attrs.checked) prev.push(icon('fas fa-check', { className: 'Button-icon ButtonCheck' }));

return prev;
}
Expand Down
29 changes: 29 additions & 0 deletions js/src/forum/components/SearchField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import app from 'flarum/app';
import Component from 'flarum/Component';
import withAttr from 'flarum/utils/withAttr';

export default class SearchField extends Component {
oninit(vnode) {
super.oninit(vnode);
}

view() {
return (
<div className="Form-group Usersearchbox">
<input
className="FormControl"
placeholder={app.translator.trans('fof-user-directory.forum.search.field.placeholder')}
value={this.filter}
oninput={withAttr('value', (value) => {
this.filter = value;
this.performNewSearch();
})}
/>
</div>
);
}

performNewSearch() {
this.attrs.state.refreshParams({ ...this.attrs.state.getParams(), qBuilder: { filter: this.filter } });
}
}
80 changes: 51 additions & 29 deletions js/src/forum/components/UserDirectoryPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Dropdown from 'flarum/components/Dropdown';
import UserDirectoryList from './UserDirectoryList';
import UserDirectoryState from '../states/UserDirectoryState';
import CheckableButton from './CheckableButton';
import SearchField from './SearchField';

/**
* This page re-uses Flarum's IndexPage CSS classes
Expand All @@ -26,11 +27,14 @@ export default class UserDirectoryPage extends Page {

let idSegments = [];
if (this.params().q) {
Array.from(this.params().q.matchAll(/group:([\d,]+)/g)).forEach(match => {
Array.from(this.params().q.matchAll(/group:([\d,]+)/g)).forEach((match) => {
idSegments.push(match[1]);
});
}
this.enabledGroupFilters = idSegments.join(',').split(',').filter(id => id);
this.enabledGroupFilters = idSegments
.join(',')
.split(',')
.filter((id) => id);
}

view() {
Expand Down Expand Up @@ -117,36 +121,54 @@ export default class UserDirectoryPage extends Page {
Select.component({
options: sortOptions,
value: this.params().sort || app.forum.attribute('userDirectoryDefaultSort'),
onchange: this.changeParams.bind(this)
onchange: this.changeParams.bind(this),
})
);

const groupButtons = app.store
.all('groups')
.filter(group => group.id() !== '2' && group.id() !== '3')
.map(group => CheckableButton.component({
className: "GroupFilterButton",
icon: group.icon(),
checked: this.enabledGroupFilters.includes(group.id()),
onclick: () => {
const id = group.id();
if (this.enabledGroupFilters.includes(id)) {
this.enabledGroupFilters = this.enabledGroupFilters.filter(e => e != id);
} else {
this.enabledGroupFilters.push(id);
}
.filter((group) => group.id() !== '2' && group.id() !== '3')
.map(
(group) =>
CheckableButton.component(
{
className: 'GroupFilterButton',
icon: group.icon(),
checked: this.enabledGroupFilters.includes(group.id()),
onclick: () => {
const id = group.id();
if (this.enabledGroupFilters.includes(id)) {
this.enabledGroupFilters = this.enabledGroupFilters.filter((e) => e != id);
} else {
this.enabledGroupFilters.push(id);
}

this.changeParams(this.params().sort);
},
},
group.namePlural()
),
this
);

items.add(
'filterGroups',
Dropdown.component(
{
caretIcon: 'fas fa-filter',
label: app.translator.trans('fof-user-directory.forum.page.filter_button'),
buttonClassName: 'FormControl',
className: 'GroupFilterDropdown',
},
groupButtons
)
);

this.changeParams(this.params().sort)
}
}, group.namePlural()), this);

items.add('filterGroups',
Dropdown.component({
caretIcon: 'fas fa-filter',
label: app.translator.trans('fof-user-directory.forum.page.filter_button'),
buttonClassName: 'FormControl',
className: 'GroupFilterDropdown'
}, groupButtons)
items.add(
'search',
SearchField.component({
state: this.state,
})
);

return items;
Expand Down Expand Up @@ -189,12 +211,12 @@ export default class UserDirectoryPage extends Page {
}

if (this.enabledGroupFilters.length > 0) {
params.q = 'group:' + this.enabledGroupFilters.join(',');
params.qBuilder = { groups: 'group:' + this.enabledGroupFilters.join(',') };
} else {
delete params.q;
params.qBuilder = { groups: '' };
}

m.route.set(app.route(this.attrs.routeName, params));
this.state.refreshParams(params);
}

stickyParams() {
Expand Down
7 changes: 6 additions & 1 deletion js/src/forum/states/UserDirectoryState.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export default class UserDirectoryState {
this.moreResults = false;

this.loading = false;

this.qBuilder = {};
}

requestParams() {
Expand Down Expand Up @@ -50,7 +52,9 @@ export default class UserDirectoryState {
refreshParams(newParams) {
if (!this.hasUsers() || Object.keys(newParams).some((key) => this.getParams()[key] !== newParams[key])) {
this.params = newParams;

Object.assign(this.qBuilder, newParams.qBuilder || {});
console.log(this.params)
this.params.q = Object.values(this.qBuilder).join(' ').trim();
this.refresh();
}
}
Expand All @@ -62,6 +66,7 @@ export default class UserDirectoryState {

return this.loadResults().then(
(results) => {
this.users = [];
this.parseResults(results);
},
() => {
Expand Down
28 changes: 28 additions & 0 deletions resources/less/forum.less
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,26 @@
.item-filterGroups {
margin-left: 15px;

@media screen and (max-width: 360px) {
margin-left: 13px;
}

@media screen and (max-width: 320px) {
margin-left: 0;
}

@media @phone {
margin-top: 5px;
}

.ButtonGroup {
button {
@media @phone {
padding-top: 4px;
}
}
}

.GroupFilterButton {
display: flex;

Expand All @@ -55,3 +75,11 @@
}
}
}

.item-search {
vertical-align: bottom;

@media @phone {
margin-top: 5px;
}
}
2 changes: 2 additions & 0 deletions resources/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ fof-user-directory:
forum:
search:
users_heading: 'Search all users for "{query}"'
field:
placeholder: Search all users
page:
nav: User Directory
refresh_tooltip: => core.forum.index.refresh_tooltip
Expand Down

0 comments on commit bc4ffe8

Please sign in to comment.