mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Added new settings to determine how to search on tags during short URL creation, and how many suggestions to display
This commit is contained in:
parent
590393dcfd
commit
9f02bc6496
4 changed files with 25 additions and 4 deletions
|
@ -17,8 +17,12 @@ interface RealTimeUpdatesSettings {
|
||||||
interval?: number;
|
interval?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TagFilteringMode = 'startsWith' | 'includes';
|
||||||
|
|
||||||
export interface ShortUrlCreationSettings {
|
export interface ShortUrlCreationSettings {
|
||||||
validateUrls: boolean;
|
validateUrls: boolean;
|
||||||
|
tagFilteringMode?: TagFilteringMode;
|
||||||
|
maxTagSuggestions?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UiSettings {
|
export interface UiSettings {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import ReactTags, { SuggestionComponentProps, TagComponentProps } from 'react-tag-autocomplete';
|
import ReactTags, { SuggestionComponentProps, TagComponentProps } from 'react-tag-autocomplete';
|
||||||
import ColorGenerator from '../../utils/services/ColorGenerator';
|
import ColorGenerator from '../../utils/services/ColorGenerator';
|
||||||
|
import { Settings } from '../../settings/reducers/settings';
|
||||||
import { TagsList } from '../reducers/tagsList';
|
import { TagsList } from '../reducers/tagsList';
|
||||||
import TagBullet from './TagBullet';
|
import TagBullet from './TagBullet';
|
||||||
import Tag from './Tag';
|
import Tag from './Tag';
|
||||||
|
@ -14,17 +15,20 @@ export interface TagsSelectorProps {
|
||||||
interface TagsSelectorConnectProps extends TagsSelectorProps {
|
interface TagsSelectorConnectProps extends TagsSelectorProps {
|
||||||
listTags: Function;
|
listTags: Function;
|
||||||
tagsList: TagsList;
|
tagsList: TagsList;
|
||||||
|
settings: Settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
const toComponentTag = (tag: string) => ({ id: tag, name: tag });
|
const toComponentTag = (tag: string) => ({ id: tag, name: tag });
|
||||||
|
|
||||||
const TagsSelector = (colorGenerator: ColorGenerator) => (
|
const TagsSelector = (colorGenerator: ColorGenerator) => (
|
||||||
{ selectedTags, onChange, listTags, tagsList, placeholder = 'Add tags to the URL' }: TagsSelectorConnectProps,
|
{ selectedTags, onChange, placeholder, listTags, tagsList, settings }: TagsSelectorConnectProps,
|
||||||
) => {
|
) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
listTags();
|
listTags();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const searchMode = settings.shortUrlCreation?.tagFilteringMode ?? 'startsWith';
|
||||||
|
const maxSuggestions = settings.shortUrlCreation?.maxTagSuggestions;
|
||||||
const ReactTagsTag = ({ tag, onDelete }: TagComponentProps) =>
|
const ReactTagsTag = ({ tag, onDelete }: TagComponentProps) =>
|
||||||
<Tag colorGenerator={colorGenerator} text={tag.name} clearable className="react-tags__tag" onClose={onDelete} />;
|
<Tag colorGenerator={colorGenerator} text={tag.name} clearable className="react-tags__tag" onClose={onDelete} />;
|
||||||
const ReactTagsSuggestion = ({ item }: SuggestionComponentProps) => (
|
const ReactTagsSuggestion = ({ item }: SuggestionComponentProps) => (
|
||||||
|
@ -42,9 +46,15 @@ const TagsSelector = (colorGenerator: ColorGenerator) => (
|
||||||
suggestionComponent={ReactTagsSuggestion}
|
suggestionComponent={ReactTagsSuggestion}
|
||||||
allowNew
|
allowNew
|
||||||
addOnBlur
|
addOnBlur
|
||||||
placeholderText={placeholder}
|
placeholderText={placeholder ?? 'Add tags to the URL'}
|
||||||
minQueryLength={1}
|
minQueryLength={1}
|
||||||
|
maxSuggestionsLength={maxSuggestions}
|
||||||
delimiters={[ 'Enter', 'Tab', ',' ]}
|
delimiters={[ 'Enter', 'Tab', ',' ]}
|
||||||
|
suggestionsTransform={
|
||||||
|
searchMode === 'includes'
|
||||||
|
? (query, suggestions) => suggestions.filter(({ name }) => name.includes(query))
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
onDelete={(removedTagIndex) => {
|
onDelete={(removedTagIndex) => {
|
||||||
const tagsCopy = [ ...selectedTags ];
|
const tagsCopy = [ ...selectedTags ];
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { ConnectDecorator } from '../../container/types';
|
||||||
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||||
// Components
|
// Components
|
||||||
bottle.serviceFactory('TagsSelector', TagsSelector, 'ColorGenerator');
|
bottle.serviceFactory('TagsSelector', TagsSelector, 'ColorGenerator');
|
||||||
bottle.decorator('TagsSelector', connect([ 'tagsList' ], [ 'listTags' ]));
|
bottle.decorator('TagsSelector', connect([ 'tagsList', 'settings' ], [ 'listTags' ]));
|
||||||
|
|
||||||
bottle.serviceFactory(
|
bottle.serviceFactory(
|
||||||
'TagCard',
|
'TagCard',
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Mock } from 'ts-mockery';
|
||||||
import createTagsSelector from '../../../src/tags/helpers/TagsSelector';
|
import createTagsSelector from '../../../src/tags/helpers/TagsSelector';
|
||||||
import ColorGenerator from '../../../src/utils/services/ColorGenerator';
|
import ColorGenerator from '../../../src/utils/services/ColorGenerator';
|
||||||
import { TagsList } from '../../../src/tags/reducers/tagsList';
|
import { TagsList } from '../../../src/tags/reducers/tagsList';
|
||||||
|
import { Settings } from '../../../src/settings/reducers/settings';
|
||||||
|
|
||||||
describe('<TagsSelector />', () => {
|
describe('<TagsSelector />', () => {
|
||||||
const onChange = jest.fn();
|
const onChange = jest.fn();
|
||||||
|
@ -14,7 +15,13 @@ describe('<TagsSelector />', () => {
|
||||||
beforeEach(jest.clearAllMocks);
|
beforeEach(jest.clearAllMocks);
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<TagsSelector selectedTags={tags} tagsList={tagsList} listTags={jest.fn()} onChange={onChange} />,
|
<TagsSelector
|
||||||
|
selectedTags={tags}
|
||||||
|
tagsList={tagsList}
|
||||||
|
settings={Mock.all<Settings>()}
|
||||||
|
listTags={jest.fn()}
|
||||||
|
onChange={onChange}
|
||||||
|
/>,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue