From 9f02bc64963616ba76968317f51f8a06b6b5cbe5 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 15 Aug 2021 10:55:58 +0200 Subject: [PATCH] Added new settings to determine how to search on tags during short URL creation, and how many suggestions to display --- src/settings/reducers/settings.ts | 4 ++++ src/tags/helpers/TagsSelector.tsx | 14 ++++++++++++-- src/tags/services/provideServices.ts | 2 +- test/tags/helpers/TagsSelector.test.tsx | 9 ++++++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/settings/reducers/settings.ts b/src/settings/reducers/settings.ts index 0ba6f106..df405e2a 100644 --- a/src/settings/reducers/settings.ts +++ b/src/settings/reducers/settings.ts @@ -17,8 +17,12 @@ interface RealTimeUpdatesSettings { interval?: number; } +type TagFilteringMode = 'startsWith' | 'includes'; + export interface ShortUrlCreationSettings { validateUrls: boolean; + tagFilteringMode?: TagFilteringMode; + maxTagSuggestions?: number; } export interface UiSettings { diff --git a/src/tags/helpers/TagsSelector.tsx b/src/tags/helpers/TagsSelector.tsx index c7041576..83e62b15 100644 --- a/src/tags/helpers/TagsSelector.tsx +++ b/src/tags/helpers/TagsSelector.tsx @@ -1,6 +1,7 @@ import { useEffect } from 'react'; import ReactTags, { SuggestionComponentProps, TagComponentProps } from 'react-tag-autocomplete'; import ColorGenerator from '../../utils/services/ColorGenerator'; +import { Settings } from '../../settings/reducers/settings'; import { TagsList } from '../reducers/tagsList'; import TagBullet from './TagBullet'; import Tag from './Tag'; @@ -14,17 +15,20 @@ export interface TagsSelectorProps { interface TagsSelectorConnectProps extends TagsSelectorProps { listTags: Function; tagsList: TagsList; + settings: Settings; } const toComponentTag = (tag: string) => ({ id: tag, name: tag }); const TagsSelector = (colorGenerator: ColorGenerator) => ( - { selectedTags, onChange, listTags, tagsList, placeholder = 'Add tags to the URL' }: TagsSelectorConnectProps, + { selectedTags, onChange, placeholder, listTags, tagsList, settings }: TagsSelectorConnectProps, ) => { useEffect(() => { listTags(); }, []); + const searchMode = settings.shortUrlCreation?.tagFilteringMode ?? 'startsWith'; + const maxSuggestions = settings.shortUrlCreation?.maxTagSuggestions; const ReactTagsTag = ({ tag, onDelete }: TagComponentProps) => ; const ReactTagsSuggestion = ({ item }: SuggestionComponentProps) => ( @@ -42,9 +46,15 @@ const TagsSelector = (colorGenerator: ColorGenerator) => ( suggestionComponent={ReactTagsSuggestion} allowNew addOnBlur - placeholderText={placeholder} + placeholderText={placeholder ?? 'Add tags to the URL'} minQueryLength={1} + maxSuggestionsLength={maxSuggestions} delimiters={[ 'Enter', 'Tab', ',' ]} + suggestionsTransform={ + searchMode === 'includes' + ? (query, suggestions) => suggestions.filter(({ name }) => name.includes(query)) + : undefined + } onDelete={(removedTagIndex) => { const tagsCopy = [ ...selectedTags ]; diff --git a/src/tags/services/provideServices.ts b/src/tags/services/provideServices.ts index 3e71c32f..ba5951c1 100644 --- a/src/tags/services/provideServices.ts +++ b/src/tags/services/provideServices.ts @@ -12,7 +12,7 @@ import { ConnectDecorator } from '../../container/types'; const provideServices = (bottle: Bottle, connect: ConnectDecorator) => { // Components bottle.serviceFactory('TagsSelector', TagsSelector, 'ColorGenerator'); - bottle.decorator('TagsSelector', connect([ 'tagsList' ], [ 'listTags' ])); + bottle.decorator('TagsSelector', connect([ 'tagsList', 'settings' ], [ 'listTags' ])); bottle.serviceFactory( 'TagCard', diff --git a/test/tags/helpers/TagsSelector.test.tsx b/test/tags/helpers/TagsSelector.test.tsx index 3c3739cb..91934aca 100644 --- a/test/tags/helpers/TagsSelector.test.tsx +++ b/test/tags/helpers/TagsSelector.test.tsx @@ -3,6 +3,7 @@ import { Mock } from 'ts-mockery'; import createTagsSelector from '../../../src/tags/helpers/TagsSelector'; import ColorGenerator from '../../../src/utils/services/ColorGenerator'; import { TagsList } from '../../../src/tags/reducers/tagsList'; +import { Settings } from '../../../src/settings/reducers/settings'; describe('', () => { const onChange = jest.fn(); @@ -14,7 +15,13 @@ describe('', () => { beforeEach(jest.clearAllMocks); beforeEach(() => { wrapper = shallow( - , + ()} + listTags={jest.fn()} + onChange={onChange} + />, ); });