diff --git a/.gitignore b/.gitignore
index 79222102..d4644475 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ build
# misc
.DS_Store
+yarn.lock
diff --git a/features/assign_a_topic_to_every_selected_item.feature b/features/assign_a_topic_to_every_selected_item.feature
new file mode 100644
index 00000000..38fb92d4
--- /dev/null
+++ b/features/assign_a_topic_to_every_selected_item.feature
@@ -0,0 +1,30 @@
+#language: fr
+
+Fonctionnalité: Ajouter une rubrique à tous les items séléctionnés
+
+Contexte:
+ Soit le point de vue "Histoire de l'art" rattaché au portfolio "vitraux"
+ Soit le point de vue "Histoire des religions" rattaché au portfolio "vitraux"
+
+ Soit le corpus "Vitraux - Bénel" rattaché au portfolio "vitraux"
+ Soit le corpus "Vitraux - Recensement" rattaché au portfolio "vitraux"
+ Soit le corpus "Vitraux - Dr. Krieger" rattaché au portfolio "vitraux"
+
+ Soit la rubrique "XIXe s." rattachée au point de vue "Histoire de l'art"
+ Soit la rubrique "Technique du verre" rattachée au point de vue "Histoire de l'art"
+
+ Soit l'item "DSN 000" rattaché à la rubrique "XIXe s."
+ Soit l'item "DSN 001" rattaché à la rubrique "XIXe s."
+ Soit l'item "DSN 002" rattaché à la rubrique "XIXe s."
+ Soit l'item "DSN 004" rattaché à la rubrique "XIXe s."
+ Soit l'item "DSN 005" rattaché à la rubrique "XIXe s."
+
+Scénario:
+ Soit "vitraux" le portfolio ouvert
+ Et l'utilisateur est connecté
+ Et "Datation" une des rubriques développées
+ Et la rubrique "XIXe s." sélectionnée
+ Et le mode sélection activé
+ Quand on attribue la rubrique "Technique du verre" aux items "DSN 000", "DSN 001", "DSN 002", "DSN 004", et "DSN 005"
+ Alors les items "DSN 000", "DSN 001", "DSN 002", "DSN 004" et "DSN 005" ont la rubrique "Technique du verre"
+
diff --git a/features/step_definitions/portfolio.rb b/features/step_definitions/portfolio.rb
index ea92eea7..6de14dbd 100644
--- a/features/step_definitions/portfolio.rb
+++ b/features/step_definitions/portfolio.rb
@@ -60,7 +60,7 @@ def getUUID(itemName)
end
Soit("{string} le portfolio ouvert") do |portfolio|
- visit "/"
+ visit "/" + portfolio
end
Soit("{string} une des rubriques développées") do |topic|
@@ -92,6 +92,22 @@ def getUUID(itemName)
visit "/"
end
+Soit("la rubrique {string} sélectionnée") do |topic|
+ find_link(topic).click
+end
+
+Soit("l'utilisateur est connecté") do
+ find_link(href: '#login').click
+ fill_in("nom d'utilisateur", with: "alice")
+ fill_in("mot de passe", with: "whiterabbit")
+ click_on('Se connecter')
+end
+
+# For scenatio with multiple selection
+Soit("le mode sélection activé") do
+ click_on('Attribuer Topic')
+end
+
# Events
Quand("un visiteur ouvre la page d'accueil du site") do
@@ -110,6 +126,39 @@ def getUUID(itemName)
click_on item
end
+Quand("on ajoute un attribut de recherche {string} avec pour valeur {string}") do |attribut, valeur|
+fill_in('Attribut1', with: attribut)
+fill_in('Valeur1', with: valeur)
+click_button('Rechercher')
+end
+
+Quand("on ajoute un attribut de recherche {string} avec pour valeur {string} et un attribut de recherche {string} avec pour valeur {string}") do |attribut1, attribut2, valeur1, valeur2|
+fill_in('Attribut1', with: attribut1)
+fill_in('Valeur1', with: valeur1)
+find_button(class: ['btn', 'btn-light', 'creationButton']).click
+fill_in('Attribut2', with: attribut2)
+fill_in('Valeur2', with: valeur2)
+click_button('Rechercher')
+end
+
+Quand("on attribue la rubrique {string} aux items {string}, {string}, {string}, {string}, et {string}") do |topic, item1, item2, item3, item4, item5|
+
+ click_on(item1)
+ click_on(item2)
+ click_on(item3)
+ click_on(item4)
+ click_on(item5)
+ find('.TopicGroupAddInput').send_keys [topic, :down, :enter]
+ find('.TopicGroupAddButton').click
+ click_button('Confirmer')
+ click_button('Fermer')
+ click_button('Annuler')
+end
+
+Quand("on met {string} dans la barre de recherche") do |value|
+ fill_in('Rechercher...', with: value).native.send_keys(:return)
+end
+
# Outcomes
Alors("le titre affiché est {string}") do |portfolio|
@@ -140,3 +189,22 @@ def getUUID(itemName)
expect(page).not_to have_content item
end
+
+Alors("les dessins {string} et {string} sont parmi les dessins affichés") do |valeur1, valeur2|
+expect(page).to have_content(valeur1)
+expect(page).to have_content(valeur2)
+end
+
+
+Alors("les items {string}, {string}, {string}, {string} et {string} ont la rubrique {string}") do |item1, item2, item3, item4, item5, topic|
+ click_on(topic)
+ expect(page).to have_content item1
+ expect(page).to have_content item2
+ expect(page).to have_content item3
+ expect(page).to have_content item4
+ expect(page).to have_content item5
+end
+
+Alors("il doit y avoir au moins {int} items dans la rubrique {string}") do |int, string|
+ pending # Write code here that turns the phrase above into concrete actions
+end
diff --git a/src/components/Corpora/Corpora.jsx b/src/components/Corpora/Corpora.jsx
index ef7f91c3..95cd1c8a 100644
--- a/src/components/Corpora/Corpora.jsx
+++ b/src/components/Corpora/Corpora.jsx
@@ -1,6 +1,12 @@
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
+import Autosuggest from 'react-autosuggest';
import getConfig from '../../config/config.js';
+import Hypertopic from 'hypertopic';
+import conf from '../../config/config.json';
+
+
+let hypertopic = new Hypertopic(conf.services);
// Get the configured list display mode
let listView = getConfig('listView', {
@@ -10,18 +16,104 @@ let listView = getConfig('listView', {
});
class Corpora extends Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ selectMode: false,
+ selectedItems: {},
+ suggestions: [],
+ topics: [],
+ topicInputValue: '',
+ topicSelected: null,
+ confirm: false,
+ addInProgress: false,
+ addCompleted: false
+ };
+ }
render() {
let items = this._getItems();
let count = this.props.items.length;
let total = this.props.from;
+
+ // For the Autosuggest
+ const inputProps = {
+ placeholder: "Ajouter une rubrique...",
+ value: this.state.topicInputValue,
+ onChange: this.topicInputOnChange.bind(this),
+ type: "text",
+ className: "form-control TopicGroupAddInput"
+ }
+ const suggestTheme = {
+ container: 'autosuggest',
+ input: 'form-control',
+ suggestionsContainer: 'dropdown open',
+ suggestionsList: `dropdown-menu ${this.state.suggestions.length ? 'show' : ''}`,
+ suggestion: 'dropdown-item',
+ suggestionHighlighted: 'active'
+ };
+
+ let numberOfSelectedItems = Object.values(this.state.selectedItems).reduce((total, currentValue) => { return currentValue ? total + 1 : total }, 0);
+
+ let subjectH2;
+ if (this.state.selectMode) {
+ subjectH2 = (
+
+ Mode sélection
+
+
+
+
+
+
+
+
+
+
+ );
+ } else {
+ subjectH2 = (
+
+ {this.props.ids.join(' + ')}
+
+ {count} / {total}
+
+
+
+ );
+ }
+
+ let confirm = "";
+ if (this.state.confirm && this.state.topicSelected !== null) {
+ let confirmButton = ();
+ confirm = (
+
+
+
Ajout du topic "{this.state.topicSelected.topicName}" à la sélection
+
{this.state.addInProgress ? "Ajout en cours..." : (this.state.addCompleted ? "Ajout des topics completé!" : `${numberOfSelectedItems} items sélectionnés`)}
+ {topicNameParts}
+
+ );
+ };
+
+ // Simply returns the name of the given suggestion
+ getSuggestionValue(suggestion) {
+ return suggestion.topicName;
+ }
+
+ // The change event for the topic suggest
+ topicInputOnChange(event, { newValue }) {
+ this.setState({
+ topicInputValue: newValue,
+ canValidateTopic: false
+ });
+ }
}
function Item(props) {
switch (listView.mode) {
case 'article':
- return Article(props.item);
+ return Article(props);
case 'picture':
- return Picture(props.item);
+ return Picture(props);
default:
- return Picture(props.item);
+ return Picture(props);
}
}
@@ -57,13 +296,13 @@ function getString(obj) {
return String(obj);
}
-function Article(item) {
+function Article(props) {
let propList = (listView.props || []).map(key => {
- return
{key} : {getString(item[key])}
;
+ return
{key} : {getString(props.item[key])}
;
});
- let uri = `/item/${item.corpus}/${item.id}`;
- let name = getString(item[listView.name]);
+ let uri = `/item/${props.item.corpus}/${props.item.id}`;
+ let name = getString(props.item[listView.name]);
return (
{name}
@@ -72,13 +311,15 @@ function Article(item) {
);
}
-function Picture(item) {
- let uri = `/item/${item.corpus}/${item.id}`;
- let img = getString(item[listView.image]);
- let name = getString(item[listView.name]);
+function Picture(props) {
+ let uri = `/item/${props.item.corpus}/${props.item.id}`;
+ let img = getString(props.item[listView.image]);
+ let name = getString(props.item[listView.name]);
+ let selected = props.corpora.state.selectedItems[props.item.id];
return (
-