Update to react-tag-autocomplete 7

This commit is contained in:
Alejandro Celaya 2023-08-12 10:26:42 +02:00
parent 5e2dce8f3f
commit 94ba244ae1
8 changed files with 39 additions and 41 deletions

View file

@ -11,6 +11,5 @@ jobs:
ci: ci:
uses: shlinkio/github-actions/.github/workflows/web-app-ci.yml@main uses: shlinkio/github-actions/.github/workflows/web-app-ci.yml@main
with: with:
node-version: 20.2 node-version: 20.5
publish-coverage: true publish-coverage: true
force-install: true

View file

@ -5,7 +5,7 @@ on:
jobs: jobs:
deploy: deploy:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
continue-on-error: true continue-on-error: true
steps: steps:
- name: Checkout code - name: Checkout code
@ -16,10 +16,10 @@ jobs:
- name: Use node.js - name: Use node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 20.2 node-version: 20.5
- name: Build - name: Build
run: | run: |
npm ci --force && \ npm ci && \
node ./scripts/set-homepage.js /shlink-web-client/${GITHUB_HEAD_REF#refs/heads/} && \ node ./scripts/set-homepage.js /shlink-web-client/${GITHUB_HEAD_REF#refs/heads/} && \
npm run build npm run build
- name: Deploy preview - name: Deploy preview

View file

@ -7,16 +7,16 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Use node.js - name: Use node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 20.2 node-version: 20.5
- name: Generate release assets - name: Generate release assets
run: npm ci --force && VERSION=${GITHUB_REF#refs/tags/v} npm run build:dist run: npm ci && VERSION=${GITHUB_REF#refs/tags/v} npm run build:dist
- name: Publish release with assets - name: Publish release with assets
uses: docker://antonyurchenko/git-release:latest uses: docker://antonyurchenko/git-release:latest
env: env:

View file

@ -1,8 +1,8 @@
FROM node:20.2-alpine as node FROM node:20.5-alpine as node
COPY . /shlink-web-client COPY . /shlink-web-client
ARG VERSION="latest" ARG VERSION="latest"
ENV VERSION ${VERSION} ENV VERSION ${VERSION}
RUN cd /shlink-web-client && npm ci --force && npm run build RUN cd /shlink-web-client && npm ci && npm run build
FROM nginx:1.23-alpine FROM nginx:1.23-alpine
LABEL maintainer="Alejandro Celaya <alejandro@alejandrocelaya.com>" LABEL maintainer="Alejandro Celaya <alejandro@alejandrocelaya.com>"

View file

@ -3,8 +3,8 @@ version: '3'
services: services:
shlink_web_client_node: shlink_web_client_node:
container_name: shlink_web_client_node container_name: shlink_web_client_node
image: node:20.2-alpine image: node:20.5-alpine
command: /bin/sh -c "cd /home/shlink/www && npm install --force && npm run start" command: /bin/sh -c "cd /home/shlink/www && npm install && npm run start"
volumes: volumes:
- ./:/home/shlink/www - ./:/home/shlink/www
ports: ports:

20
package-lock.json generated
View file

@ -39,7 +39,7 @@
"react-redux": "^8.1.2", "react-redux": "^8.1.2",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"react-swipeable": "^7.0.1", "react-swipeable": "^7.0.1",
"react-tag-autocomplete": "^6.3.0", "react-tag-autocomplete": "^7.0.0",
"reactstrap": "^9.2.0", "reactstrap": "^9.2.0",
"redux-localstorage-simple": "^2.5.1", "redux-localstorage-simple": "^2.5.1",
"uuid": "^9.0.0", "uuid": "^9.0.0",
@ -8900,16 +8900,14 @@
} }
}, },
"node_modules/react-tag-autocomplete": { "node_modules/react-tag-autocomplete": {
"version": "6.3.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/react-tag-autocomplete/-/react-tag-autocomplete-6.3.0.tgz", "resolved": "https://registry.npmjs.org/react-tag-autocomplete/-/react-tag-autocomplete-7.0.0.tgz",
"integrity": "sha512-MUBVUFh5eOqshUm5NM20qp7zXk8TzSiKO4GoktlFzBLIOLs356npaMKtL02bm0nFV2f1zInUrXn1fq6+i5YX0w==", "integrity": "sha512-PFxT7fpMB8Au+S9cJYAGRVTnacZpeXybc5SkpTCyuJHmUN1Bt8gHb9vZi3f+aX/eDX44x2WIwYiqfRBi2E5AMg==",
"engines": { "engines": {
"node": ">= 10.0.0" "node": ">= 16.12.0"
}, },
"peerDependencies": { "peerDependencies": {
"prop-types": "^15.5.0", "react": "^18.0.0"
"react": "^16.5.0 || ^17.0.0",
"react-dom": "^16.5.0 || ^17.0.0"
} }
}, },
"node_modules/react-transition-group": { "node_modules/react-transition-group": {
@ -17211,9 +17209,9 @@
"requires": {} "requires": {}
}, },
"react-tag-autocomplete": { "react-tag-autocomplete": {
"version": "6.3.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/react-tag-autocomplete/-/react-tag-autocomplete-6.3.0.tgz", "resolved": "https://registry.npmjs.org/react-tag-autocomplete/-/react-tag-autocomplete-7.0.0.tgz",
"integrity": "sha512-MUBVUFh5eOqshUm5NM20qp7zXk8TzSiKO4GoktlFzBLIOLs356npaMKtL02bm0nFV2f1zInUrXn1fq6+i5YX0w==", "integrity": "sha512-PFxT7fpMB8Au+S9cJYAGRVTnacZpeXybc5SkpTCyuJHmUN1Bt8gHb9vZi3f+aX/eDX44x2WIwYiqfRBi2E5AMg==",
"requires": {} "requires": {}
}, },
"react-transition-group": { "react-transition-group": {

View file

@ -55,7 +55,7 @@
"react-redux": "^8.1.2", "react-redux": "^8.1.2",
"react-router-dom": "^6.14.2", "react-router-dom": "^6.14.2",
"react-swipeable": "^7.0.1", "react-swipeable": "^7.0.1",
"react-tag-autocomplete": "^6.3.0", "react-tag-autocomplete": "^7.0.0",
"reactstrap": "^9.2.0", "reactstrap": "^9.2.0",
"redux-localstorage-simple": "^2.5.1", "redux-localstorage-simple": "^2.5.1",
"uuid": "^9.0.0", "uuid": "^9.0.0",

View file

@ -1,6 +1,6 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import type { SuggestionComponentProps, TagComponentProps } from 'react-tag-autocomplete'; import type { OptionRendererProps, TagRendererProps, TagSuggestion } from 'react-tag-autocomplete';
import ReactTags from 'react-tag-autocomplete'; import { ReactTags } from 'react-tag-autocomplete';
import type { ColorGenerator } from '../../utils/services/ColorGenerator'; import type { ColorGenerator } from '../../utils/services/ColorGenerator';
import { useSetting } from '../../utils/settings'; import { useSetting } from '../../utils/settings';
import type { TagsList } from '../reducers/tagsList'; import type { TagsList } from '../reducers/tagsList';
@ -19,7 +19,7 @@ interface TagsSelectorConnectProps extends TagsSelectorProps {
tagsList: TagsList; tagsList: TagsList;
} }
const toComponentTag = (tag: string) => ({ id: tag, name: tag }); const toTagSuggestion = (tag: string): TagSuggestion => ({ label: tag, value: tag });
export const TagsSelector = (colorGenerator: ColorGenerator) => ( export const TagsSelector = (colorGenerator: ColorGenerator) => (
{ selectedTags, onChange, placeholder, listTags, tagsList, allowNew = true }: TagsSelectorConnectProps, { selectedTags, onChange, placeholder, listTags, tagsList, allowNew = true }: TagsSelectorConnectProps,
@ -30,29 +30,30 @@ export const TagsSelector = (colorGenerator: ColorGenerator) => (
}, []); }, []);
const searchMode = shortUrlCreation?.tagFilteringMode ?? 'startsWith'; const searchMode = shortUrlCreation?.tagFilteringMode ?? 'startsWith';
const ReactTagsTag = ({ tag, onDelete }: TagComponentProps) => const ReactTagsTag = ({ tag, onClick: deleteTag }: TagRendererProps) => (
<Tag colorGenerator={colorGenerator} text={tag.name} clearable className="react-tags__tag" onClose={onDelete} />; <Tag colorGenerator={colorGenerator} text={tag.label} clearable className="react-tags__tag" onClose={deleteTag} />
const ReactTagsSuggestion = ({ item }: SuggestionComponentProps) => ( );
const ReactTagsSuggestion = ({ option }: OptionRendererProps) => (
<> <>
<TagBullet tag={`${item.name}`} colorGenerator={colorGenerator} /> <TagBullet tag={`${option.label}`} colorGenerator={colorGenerator} />
{item.name} {option.label}
</> </>
); );
return ( return (
<ReactTags <ReactTags
tags={selectedTags.map(toComponentTag)} selected={selectedTags.map(toTagSuggestion)}
tagComponent={ReactTagsTag} suggestions={tagsList.tags.filter((tag) => !selectedTags.includes(tag)).map(toTagSuggestion)}
suggestions={tagsList.tags.filter((tag) => !selectedTags.includes(tag)).map(toComponentTag)} renderTag={ReactTagsTag}
suggestionComponent={ReactTagsSuggestion} renderOption={ReactTagsSuggestion}
allowNew={allowNew} allowNew={allowNew}
addOnBlur // addOnBlur TODO Implement manually
placeholderText={placeholder ?? 'Add tags to the URL'} placeholderText={placeholder ?? 'Add tags to the URL'}
minQueryLength={1} onShouldExpand={(value) => value.length > 1}
delimiters={['Enter', 'Tab', ',']} delimiterKeys={['Enter', 'Tab', ',']}
suggestionsTransform={ suggestionsTransform={
searchMode === 'includes' searchMode === 'includes'
? (query, suggestions) => suggestions.filter(({ name }) => name.includes(query)) ? (query, suggestions) => suggestions.filter(({ label }) => label.includes(query))
: undefined : undefined
} }
onDelete={(removedTagIndex) => { onDelete={(removedTagIndex) => {
@ -61,7 +62,7 @@ export const TagsSelector = (colorGenerator: ColorGenerator) => (
tagsCopy.splice(removedTagIndex, 1); tagsCopy.splice(removedTagIndex, 1);
onChange(tagsCopy); onChange(tagsCopy);
}} }}
onAddition={({ name: newTag }) => onChange( onAdd={({ label: newTag }) => onChange(
// * Avoid duplicated tags (thanks to the Set), // * Avoid duplicated tags (thanks to the Set),
// * Split any of the new tags by comma, allowing to paste multiple comma-separated tags at once. // * Split any of the new tags by comma, allowing to paste multiple comma-separated tags at once.
[...new Set([...selectedTags, ...newTag.toLowerCase().split(',')])], [...new Set([...selectedTags, ...newTag.toLowerCase().split(',')])],