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}
+ />,
);
});