diff --git a/front/package-lock.json b/front/package-lock.json
index 2623ae73f8..2e3f424f90 100644
--- a/front/package-lock.json
+++ b/front/package-lock.json
@@ -38,7 +38,6 @@
"react-dnd-touch-backend": "^16.0.1",
"react-select": "^4.3.1",
"react-slider": "^2.0.6",
- "react-tag-input-component": "^2.0.2",
"unistore": "^3.5.2",
"useragent-parser-js": "^1.0.3",
"uuid": "^3.4.0"
@@ -24562,15 +24561,6 @@
"react": "^16 || ^17 || ^18"
}
},
- "node_modules/react-tag-input-component": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/react-tag-input-component/-/react-tag-input-component-2.0.2.tgz",
- "integrity": "sha512-dydI9luVwwv9vrjE5u1TTnkcOVkOVL6mhFti8r6hLi78V2F2EKWQOLptURz79UYbDHLSk6tnbvGl8FE+sMpADg==",
- "peerDependencies": {
- "react": "^16 || ^17 || ^18",
- "react-dom": "^16 || ^17 || ^18"
- }
- },
"node_modules/react-transition-group": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",
@@ -50567,12 +50557,6 @@
"prop-types": "^15.8.1"
}
},
- "react-tag-input-component": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/react-tag-input-component/-/react-tag-input-component-2.0.2.tgz",
- "integrity": "sha512-dydI9luVwwv9vrjE5u1TTnkcOVkOVL6mhFti8r6hLi78V2F2EKWQOLptURz79UYbDHLSk6tnbvGl8FE+sMpADg==",
- "requires": {}
- },
"react-transition-group": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",
diff --git a/front/package.json b/front/package.json
index 0da2adf430..5bce21c9cc 100644
--- a/front/package.json
+++ b/front/package.json
@@ -76,7 +76,6 @@
"react-dnd-touch-backend": "^16.0.1",
"react-select": "^4.3.1",
"react-slider": "^2.0.6",
- "react-tag-input-component": "^2.0.2",
"unistore": "^3.5.2",
"useragent-parser-js": "^1.0.3",
"uuid": "^3.4.0"
diff --git a/front/src/components/layout/CardFilter.jsx b/front/src/components/layout/CardFilter.jsx
index be8c67d289..f1f3511f74 100644
--- a/front/src/components/layout/CardFilter.jsx
+++ b/front/src/components/layout/CardFilter.jsx
@@ -1,7 +1,16 @@
import { Fragment } from 'preact';
import { Text } from 'preact-i18n';
+import Select from 'react-select';
-const CardFilter = ({ changeOrderDir, orderValue = 'asc', search, searchValue, searchPlaceHolder }) => (
+const CardFilter = ({
+ changeOrderDir,
+ orderValue = 'asc',
+ search,
+ searchValue,
+ searchPlaceHolder,
+ tags,
+ searchTags
+}) => (
+ {tags && (
+
+
+ )}
+
-
+
);
diff --git a/front/src/config/i18n/en.json b/front/src/config/i18n/en.json
index ac1ccabbee..6fd4dc1711 100644
--- a/front/src/config/i18n/en.json
+++ b/front/src/config/i18n/en.json
@@ -1339,6 +1339,7 @@
"editDescriptionPlaceholder": "Enter a scene description",
"tagsTitle": "Tags",
"editTagsPlaceholder": "Enter a scene tags",
+ "createTag": "Create tag: '{{tagName}}'",
"startButton": "Start",
"saveButton": "Save",
"deleteButton": "Delete",
diff --git a/front/src/config/i18n/fr.json b/front/src/config/i18n/fr.json
index a2b05dd334..9da94dfd63 100644
--- a/front/src/config/i18n/fr.json
+++ b/front/src/config/i18n/fr.json
@@ -1339,6 +1339,7 @@
"descriptionTitle": "Description",
"iconLabel": "Icône",
"editDescriptionPlaceholder": "Entrez une description pour la scène",
+ "createTag": "Créer le tag : '{{tagName}}'",
"tagsTitle": "Tags",
"editTagsPlaceholder": "Entrez un tag pour la scène",
"startButton": "Démarrer",
diff --git a/front/src/routes/scene/SceneCard.jsx b/front/src/routes/scene/SceneCard.jsx
index e5388e4775..af4bf283e6 100644
--- a/front/src/routes/scene/SceneCard.jsx
+++ b/front/src/routes/scene/SceneCard.jsx
@@ -36,7 +36,7 @@ class SceneCard extends Component {
-
+
diff --git a/front/src/routes/scene/ScenePage.jsx b/front/src/routes/scene/ScenePage.jsx
index 79b5fbb122..45fbdf2847 100644
--- a/front/src/routes/scene/ScenePage.jsx
+++ b/front/src/routes/scene/ScenePage.jsx
@@ -24,9 +24,11 @@ const ScenePage = ({ children, ...props }) => (
search={props.debouncedSearch}
searchValue={props.sceneSearch}
searchPlaceHolder={
}
+ tags={props.tags}
+ searchTags={props.searchTags}
/>
-
+
diff --git a/front/src/routes/scene/edit-scene/Settings.jsx b/front/src/routes/scene/edit-scene/Settings.jsx
index 955da0d029..ff47c36437 100644
--- a/front/src/routes/scene/edit-scene/Settings.jsx
+++ b/front/src/routes/scene/edit-scene/Settings.jsx
@@ -89,6 +89,9 @@ class Settings extends Component {
isMulti
options={props.tags && props.tags.map(tag => ({ value: tag.name, label: tag.name }))}
onChange={tags => props.setTags(tags.map(tag => tag.value))}
+ formatCreateLabel={inputValue => (
+
+ )}
/>
diff --git a/front/src/routes/scene/index.js b/front/src/routes/scene/index.js
index ee6b54fff3..41a899509e 100644
--- a/front/src/routes/scene/index.js
+++ b/front/src/routes/scene/index.js
@@ -18,6 +18,9 @@ class Scene extends Component {
if (this.state.sceneSearch && this.state.sceneSearch.length) {
params.search = this.state.sceneSearch;
}
+ if (this.state.sceneTagSearch && this.state.sceneTagSearch.length) {
+ params.searchTags = this.state.sceneTagSearch.join(',');
+ }
const scenes = await this.props.httpClient.get('/api/v1/scene', params);
this.setState({
scenes,
@@ -31,12 +34,30 @@ class Scene extends Component {
});
}
};
+ getTags = async () => {
+ try {
+ const tags = await this.props.httpClient.get(`/api/v1/tag_scene`);
+ this.setState({
+ tags
+ });
+ } catch (e) {
+ console.error(e);
+ }
+ };
search = async e => {
await this.setState({
sceneSearch: e.target.value
});
await this.getScenes();
};
+ searchTags = async tags => {
+ console.log(tags);
+ await this.setState({
+ sceneTagSearch: tags
+ });
+ await this.getScenes();
+ };
+
changeOrderDir = async e => {
await this.setState({
getScenesOrderDir: e.target.value
@@ -88,6 +109,7 @@ class Scene extends Component {
getScenesOrderDir: 'asc',
scenes: [],
sceneSearch: null,
+ sceneTagSearch: null,
loading: true
};
this.debouncedSearch = debounce(this.search.bind(this), 200);
@@ -95,9 +117,10 @@ class Scene extends Component {
componentWillMount() {
this.getScenes();
+ this.getTags();
}
- render(props, { scenes, loading, getError }) {
+ render(props, { scenes, loading, getError, tags }) {
return (
);
}
diff --git a/front/src/routes/scene/style.css b/front/src/routes/scene/style.css
index 449c7c8814..f70dc5350b 100644
--- a/front/src/routes/scene/style.css
+++ b/front/src/routes/scene/style.css
@@ -39,9 +39,14 @@
}
.descriptionSceneEllipsis {
+ flex-grow: 2;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
line-clamp: 3;
-webkit-box-orient: vertical;
}
+
+.newButton {
+ min-width: min-content;
+}
diff --git a/server/lib/scene/scene.get.js b/server/lib/scene/scene.get.js
index bf54a01ab1..115a01b24f 100644
--- a/server/lib/scene/scene.get.js
+++ b/server/lib/scene/scene.get.js
@@ -1,4 +1,5 @@
const { Op } = require('sequelize');
+const Sequelize = require('sequelize');
const db = require('../../models');
const DEFAULT_OPTIONS = {
@@ -46,30 +47,27 @@ async function get(options) {
})),
};
}
-
- const scenes = await db.Scene.findAll(queryParams);
-
- let scenesPlain = scenes.map((scene) => scene.get({ plain: true }));
-
if (optionsWithDefault.search) {
- scenesPlain = scenesPlain.filter((scene) => {
- if (scene.name.toLowerCase().includes(optionsWithDefault.search.toLowerCase())) {
- return scene;
- }
- const tagsFound = scene.tags.find((tag) => {
- if (tag.name.toLowerCase().includes(optionsWithDefault.search.toLowerCase())) {
- return true;
- }
- return false;
- });
- if (tagsFound) {
- return scene;
- }
- return null;
+ queryParams.where = Sequelize.where(Sequelize.fn('lower', Sequelize.col('t_scene.name')), {
+ [Op.like]: `%${optionsWithDefault.search}%`,
+ });
+ }
+
+ if (optionsWithDefault.searchTags) {
+ const tags = await db.TagScene.findAll({
+ fields: 'scene_id',
+ where: {
+ [Op.or]: optionsWithDefault.searchTags.split(',').map((tag) => ({ name: { [Op.like]: `%${tag}%` } })),
+ },
});
+ queryParams.where = {
+ [Op.or]: tags.map((tag) => tag.get({ plain: true })).map((tag) => ({ id: tag.scene_id })),
+ };
}
- return scenesPlain;
+ const scenes = await db.Scene.findAll(queryParams);
+
+ return scenes.map((scene) => scene.get({ plain: true }));
}
module.exports = {