Commit 02d71ce4 authored by Lyza Danger Gardner's avatar Lyza Danger Gardner Committed by Lyza Gardner

Add `useUserFilterOptions` hook

parent 6bf8e3b9
import { mount } from 'enzyme';
import { createElement } from 'preact';
import { useUserFilterOptions } from '../use-filter-options';
import { $imports } from '../use-filter-options';
describe('sidebar/components/hooks/use-user-filter-options', () => {
let fakeStore;
let lastUserOptions;
// Mount a dummy component to be able to use the hook
function DummyComponent() {
lastUserOptions = useUserFilterOptions();
}
function annotationFixtures() {
return [
{
user: 'acct:dingbat@localhost',
user_info: { display_name: 'Ding Bat' },
},
{
user: 'acct:abalone@localhost',
user_info: { display_name: 'Aba Lone' },
},
{
user: 'acct:bananagram@localhost',
user_info: { display_name: 'Zerk' },
},
{
user: 'acct:dingbat@localhost',
user_info: { display_name: 'Ding Bat' },
},
];
}
beforeEach(() => {
fakeStore = {
allAnnotations: sinon.stub().returns([]),
getFocusFilters: sinon.stub().returns({}),
isFeatureEnabled: sinon.stub().returns(false),
};
$imports.$mock({
'../../store/use-store': { useStoreProxy: () => fakeStore },
});
});
afterEach(() => {
$imports.$restore();
});
it('should return a user filter option for each user who has authored an annotation', () => {
fakeStore.allAnnotations.returns(annotationFixtures());
mount(<DummyComponent />);
assert.deepEqual(lastUserOptions, [
{ value: 'abalone', display: 'abalone' },
{ value: 'bananagram', display: 'bananagram' },
{ value: 'dingbat', display: 'dingbat' },
]);
});
it('should use display names if feature flag enabled', () => {
fakeStore.allAnnotations.returns(annotationFixtures());
fakeStore.isFeatureEnabled.withArgs('client_display_names').returns(true);
mount(<DummyComponent />);
assert.deepEqual(lastUserOptions, [
{ value: 'abalone', display: 'Aba Lone' },
{ value: 'dingbat', display: 'Ding Bat' },
{ value: 'bananagram', display: 'Zerk' },
]);
});
it('should add focused-user filter information if configured', () => {
fakeStore.allAnnotations.returns(annotationFixtures());
fakeStore.isFeatureEnabled.withArgs('client_display_names').returns(true);
fakeStore.getFocusFilters.returns({
user: { value: 'carrotNumberOne', display: 'Number One Carrot' },
});
mount(<DummyComponent />);
assert.deepEqual(lastUserOptions, [
{ value: 'abalone', display: 'Aba Lone' },
{ value: 'dingbat', display: 'Ding Bat' },
{ value: 'carrotNumberOne', display: 'Number One Carrot' },
{ value: 'bananagram', display: 'Zerk' },
]);
});
it('always uses display name for focused user', () => {
fakeStore.allAnnotations.returns(annotationFixtures());
fakeStore.isFeatureEnabled.withArgs('client_display_names').returns(false);
fakeStore.getFocusFilters.returns({
user: { value: 'carrotNumberOne', display: 'Numero Uno Zanahoria' },
});
mount(<DummyComponent />);
assert.deepEqual(lastUserOptions, [
{ value: 'abalone', display: 'abalone' },
{ value: 'bananagram', display: 'bananagram' },
{ value: 'dingbat', display: 'dingbat' },
{ value: 'carrotNumberOne', display: 'Numero Uno Zanahoria' },
]);
});
});
import { useMemo } from 'preact/hooks';
import { useStoreProxy } from '../../store/use-store';
import { username } from '../../util/account-id';
/** @typedef {import('../../store/modules/filters').FilterOption} FilterOption */
/**
* Generate a list of users for filtering annotations; update when set of
* annotations or filter state changes meaningfully.
*
* @return {FilterOption[]}
*/
export function useUserFilterOptions() {
const store = useStoreProxy();
const annotations = store.allAnnotations();
const focusFilters = store.getFocusFilters();
const showDisplayNames = store.isFeatureEnabled('client_display_names');
return useMemo(() => {
// Determine unique users (authors) in annotation collection
const users = {};
annotations.forEach(annotation => {
const username_ = username(annotation.user);
const displayValue =
showDisplayNames && annotation.user_info?.display_name
? annotation.user_info.display_name
: username_;
users[username_] = displayValue;
});
// If user-focus is configured (even if not applied) add a filter
// option for that user. Note that this always respects the display
// value, even if `client_display_names` feature flags is not enabled:
// this matches current implementation of focus mode.
if (focusFilters.user) {
const username_ =
username(focusFilters.user.value) || focusFilters.user.value;
users[username_] = focusFilters.user.display;
}
// Convert to `FilterOption` objects
const userOptions = Object.keys(users).map(user => {
return { display: users[user], value: user };
});
userOptions.sort((a, b) => a.display.localeCompare(b.display));
return userOptions;
}, [annotations, focusFilters, showDisplayNames]);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment