Skip to content

Commit 75254e3

Browse files
Clementlgzdwdw666corentinprp51dylanbonelli
committed
FEATURE: (un)select items from a corpus.
Co-authored-by: dwdw666 <807740079@qq.com> Co-authored-by: corentinprp51 <corentinprp@gmail.com> Co-authored-by: dylanbonelli <dylan.bonelli@utt.fr>
1 parent d94c631 commit 75254e3

File tree

7 files changed

+110
-14
lines changed

7 files changed

+110
-14
lines changed

src/Selection.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,49 @@ export default class Selection {
154154
clause.type = (clause.type === 'intersection') ? 'union' : 'intersection';
155155
}
156156

157+
addCorpus = (corpusId) => {
158+
const existing = this.selectionJSON.data.some(e =>
159+
e.selection.find(corpus => corpus === corpusId)
160+
|| e.exclusion.find(corpus => corpus === corpusId)
161+
);
162+
if (!existing) {
163+
this.selectionJSON.data = [];
164+
this.selectionJSON.data.push({type: 'intersection', selection: [], exclusion: [corpusId]});
165+
}
166+
}
167+
168+
toggleCorpus = (corpusId) => {
169+
const existingClause = this.selectionJSON.data.find(s => {
170+
const allTopics = [...s.selection, ...s.exclusion];
171+
if (allTopics.length === 0) {
172+
return false;
173+
}
174+
return true;
175+
});
176+
if (existingClause) {
177+
this.testSwitchPlace(existingClause, corpusId, false, true);
178+
if ([...existingClause.selection, ...existingClause.exclusion].length === 0)
179+
this.selectionJSON.data.splice(this.selectionJSON.data.indexOf(existingClause), 1);
180+
} else {
181+
this.addCorpus(corpusId);
182+
}
183+
}
184+
185+
testSwitchPlace = (clause, criterion, toDelete, threeState) => {
186+
let index;
187+
if ((index = clause.selection.indexOf(criterion)) > -1) {
188+
clause.selection.splice(index, 1);
189+
if (!toDelete)
190+
clause.exclusion.push(criterion);
191+
} else if ((index = clause.exclusion.indexOf(criterion)) > -1) {
192+
clause.exclusion.splice(index, 1);
193+
if (!toDelete && !threeState)
194+
clause.selection.push(criterion);
195+
} else {
196+
clause.exclusion.push(criterion);
197+
}
198+
};
199+
157200
getClauses = () => this.selectionJSON.data;
158201

159202
getMainClause = () => this.selectionJSON;

src/components/portfolioPage/Badge.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Badge extends Component {
1414
{this.props.name}
1515
<button className={'badge badge-pill badge-dark oi ml-1 border-0 ' + (this.props.exclusion ? 'oi-plus' : 'oi-minus')}
1616
title={this.props.exclusion ? t`Inclure` : t`Exclure`}
17-
onClick={this.handleChangeState}
17+
onClick={!this.props.id.includes('corpus') ? this.handleChangeState : this.handleDeletion}
1818
> </button>
1919
<button className="badge badge-pill badge-dark oi oi-x border-0"
2020
title={t`Déselectionner`}

src/components/portfolioPage/Corpora.jsx

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,32 @@ import memoize from 'memoize-one';
55
import ItemCreator from './ItemCreator.jsx';
66
import GeographicMap from './GeographicMap.jsx';
77
import { Items } from '../../model.js';
8+
import Selection from '../../Selection.js';
89

910
class Corpora extends Component {
1011

1112
state = {
12-
criteria: 'name'
13+
criteria: 'name',
14+
listCorpus: [],
15+
firstReceive: false,
1316
};
1417

1518
sort = memoize((items, criteria) => items.sort(by(`${criteria}.0`)));
1619

20+
componentDidUpdate(prevProps) {
21+
if (this.props.ids.length !== prevProps.ids.length) {
22+
let listFormated = [...this.props.ids];
23+
listFormated = listFormated.map(corpus => {
24+
corpus = 'corpus : '.concat(corpus);
25+
return corpus;
26+
});
27+
this.setState({
28+
listCorpus: listFormated,
29+
firstReceive: true,
30+
});
31+
}
32+
}
33+
1734
render() {
1835
let itemsData = this.sort(this.props.items, this.state.criteria);
1936
let items = itemsData.map(x =>
@@ -23,8 +40,10 @@ class Corpora extends Component {
2340
let options = this._getOptions(attributes);
2441
let count = this.props.items.length;
2542
let total = this.props.from;
26-
let listIds = this.props.ids.map((corpus) =>
27-
<div key={corpus}>{corpus} <ItemCreator corpus={corpus} conf={this.props.conf} /></div>
43+
let listIds = this.props.ids.map((corpus) =>{
44+
let corpusFormated = 'corpus : '.concat(corpus);
45+
return <div key={corpusFormated}> <input className="corpus_checkbox" type="checkbox" value={corpusFormated} onChange={this.handleChange} checked={this.isChecked(corpusFormated)}/> {corpus} <ItemCreator corpus={corpus} conf={this.props.conf} /></div>;
46+
}
2847
);
2948
return (
3049
<div className="col-md-8 p-4">
@@ -63,12 +82,37 @@ class Corpora extends Component {
6382
<option key={attribute} value={attribute}> {attribute} </option>
6483
));
6584
}
85+
86+
handleChange = (e) => {
87+
let list = this.state.listCorpus;
88+
let index = list.indexOf(e.target.value);
89+
if (index !== -1) {
90+
list.splice(index, 1);
91+
} else {
92+
list.push(e.target.value);
93+
}
94+
this.setState({
95+
listCorpus: list
96+
});
97+
this.handleCorpusSelected(e.target.value);
98+
}
99+
100+
isChecked(corpus) {
101+
const selection = Selection.fromURI();
102+
return selection.isSelectedOrExcluded(corpus) !== 'Excluded';
103+
}
104+
105+
handleCorpusSelected(corpusId) {
106+
const selection = Selection.fromURI();
107+
selection.toggleCorpus(corpusId);
108+
this.props.history.push(selection.toURI());
109+
}
66110
}
67111

68112
function Item(props) {
69113
let uri = `/item/${props.item.corpus}/${props.item.id}`;
70114
let name = [props.item.name].join(', '); //Name can be an array
71-
let thumbnail = props.item.thumbnail && <img src={props.item.thumbnail} alt={name}/>;
115+
let thumbnail = props.item.thumbnail && <img src={props.item.thumbnail} alt={name} />;
72116
let criteria = (props.criteria !== 'name')
73117
&& <div className="About"> {props.item[props.criteria]} </div>;
74118
return (

src/components/portfolioPage/Portfolio.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ class Portfolio extends Component {
155155
}
156156

157157
_getItemAttributes(item) {
158-
return new Items(
158+
let result = new Items(
159159
[item]
160160
).getAttributes()
161161
.map(([key, value]) => key.concat(' : ', value.replace('\'', '’')));
162+
return result;
162163
}
163164

164165
_isSelected(item) {
@@ -260,6 +261,7 @@ class Portfolio extends Component {
260261
from={this.state.items.length}
261262
items={this.state.selectedItems}
262263
conf={conf}
264+
history={this.props.history}
263265
/>
264266
);
265267
}

src/components/portfolioPage/SearchBar.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ class SearchBar extends React.Component {
4646
handleSuggestionSelected = (_, { suggestion }) => {
4747
this.setState({pattern: ''});
4848
const selection = Selection.fromURI();
49-
selection.addTopic(suggestion.id);
49+
if (suggestion.id.includes('corpus')) {
50+
selection.addCorpus(suggestion.id);
51+
} else {
52+
selection.addTopic(suggestion.id);
53+
}
5054
this.props.history.push(selection.toURI());
5155
};
5256

src/components/portfolioPage/Status.jsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ class Status extends Component {
2020
...clause.exclusion.map(id => ({excluded: true, id, topic: this._getCandidate(id)}))]
2121
.sort(filter)
2222
.map(
23-
t =>
24-
(t.topic === null)
25-
? <Trans>Rubrique inconnue</Trans>
26-
: <Badge exclusion={t.excluded} id={t.id} name={t.topic.name} _changeItemState={this._changeItemState}/>
23+
t => {
24+
let res = (t.topic === null) ? <Trans>Rubrique inconnue</Trans> : <Badge exclusion={t.excluded} id={t.id} name={t.topic.name} _changeItemState={this._changeItemState}/>;
25+
return res;
26+
}
2727
);
2828
status.push(topicsHTML.map((e, i) => i < topicsHTML.length - 1 ? [e, <Button clause={clause} _changeUnionState={this._changeUnionState}/>] : [e]).reduce((a, b) => a.concat(b))
2929
);
@@ -38,7 +38,9 @@ class Status extends Component {
3838

3939
_getCandidate(id) {
4040
for (let v of this.props.candidates) {
41-
if (v[id]) return v[id];
41+
if (v[id]) {
42+
return v[id];
43+
}
4244
}
4345
return null;
4446
}

src/model.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ class Items {
4444
this.items
4545
.map(
4646
x => Object.entries(x).filter(
47-
y => !['topic', 'resource', 'thumbnail', 'id', 'item', 'corpus', 'record', 'original', '_attachments'].includes(y[0])
47+
y => !['topic', 'resource', 'thumbnail', 'id', 'item', 'record', 'original', '_attachments'].includes(y[0])
4848
)
4949
)
5050
.reduce((x, y) => x.concat(y), [])
51-
.map(([x, y]) => JSON.stringify([x, y[0]]))
51+
.map(([x, y]) => Array.isArray(y) ? [x, y[0]] : [x, y])
52+
.map(JSON.stringify)
5253
)].map(JSON.parse);
5354

5455
getAttributeKeys = () => [...new Set(this.getAttributes().map(x => x[0]))];

0 commit comments

Comments
 (0)