Skip to content

Commit

Permalink
FEATURE: (un)select items from a corpus.
Browse files Browse the repository at this point in the history
Co-authored-by: dwdw666 <[email protected]>
Co-authored-by: corentinprp51 <[email protected]>
Co-authored-by: dylanbonelli <[email protected]>
  • Loading branch information
4 people committed Jun 16, 2022
1 parent d94c631 commit 8cebb8f
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 14 deletions.
43 changes: 43 additions & 0 deletions src/Selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,49 @@ export default class Selection {
clause.type = (clause.type === 'intersection') ? 'union' : 'intersection';
}

addCorpus = (corpusId) => {
const existing = this.selectionJSON.data.some(e =>
e.selection.find(corpus => corpus === corpusId)
|| e.exclusion.find(corpus => corpus === corpusId)
);
if (!existing) {
this.selectionJSON.data = [];
this.selectionJSON.data.push({type: 'intersection', selection: [], exclusion: [corpusId]});
}
}

toggleCorpus = (corpusId) => {
const existingClause = this.selectionJSON.data.find(s => {
const allTopics = [...s.selection, ...s.exclusion];
if (allTopics.length === 0) {
return false;
}
return true;
});
if (existingClause) {
this.testSwitchPlace(existingClause, corpusId, false, true);
if ([...existingClause.selection, ...existingClause.exclusion].length === 0)
this.selectionJSON.data.splice(this.selectionJSON.data.indexOf(existingClause), 1);
} else {
this.addCorpus(corpusId);
}
}

testSwitchPlace = (clause, criterion, toDelete, threeState) => {
let index;
if ((index = clause.selection.indexOf(criterion)) > -1) {
clause.selection.splice(index, 1);
if (!toDelete)
clause.exclusion.push(criterion);
} else if ((index = clause.exclusion.indexOf(criterion)) > -1) {
clause.exclusion.splice(index, 1);
if (!toDelete && !threeState)
clause.selection.push(criterion);
} else {
clause.exclusion.push(criterion);
}
};

getClauses = () => this.selectionJSON.data;

getMainClause = () => this.selectionJSON;
Expand Down
2 changes: 1 addition & 1 deletion src/components/portfolioPage/Badge.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Badge extends Component {
{this.props.name}
<button className={'badge badge-pill badge-dark oi ml-1 border-0 ' + (this.props.exclusion ? 'oi-plus' : 'oi-minus')}
title={this.props.exclusion ? t`Inclure` : t`Exclure`}
onClick={this.handleChangeState}
onClick={!this.props.id.includes('corpus') ? this.handleChangeState : this.handleDeletion}
> </button>
<button className="badge badge-pill badge-dark oi oi-x border-0"
title={t`Déselectionner`}
Expand Down
52 changes: 48 additions & 4 deletions src/components/portfolioPage/Corpora.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,32 @@ import memoize from 'memoize-one';
import ItemCreator from './ItemCreator.jsx';
import GeographicMap from './GeographicMap.jsx';
import { Items } from '../../model.js';
import Selection from '../../Selection.js';

class Corpora extends Component {

state = {
criteria: 'name'
criteria: 'name',
listCorpus: [],
firstReceive: false,
};

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

componentDidUpdate(prevProps) {
if (this.props.ids.length !== prevProps.ids.length) {
let listFormated = [...this.props.ids];
listFormated = listFormated.map(corpus => {
corpus = 'corpus : '.concat(corpus);
return corpus;
});
this.setState({
listCorpus: listFormated,
firstReceive: true,
});
}
}

render() {
let itemsData = this.sort(this.props.items, this.state.criteria);
let items = itemsData.map(x =>
Expand All @@ -23,8 +40,10 @@ class Corpora extends Component {
let options = this._getOptions(attributes);
let count = this.props.items.length;
let total = this.props.from;
let listIds = this.props.ids.map((corpus) =>
<div key={corpus}>{corpus} <ItemCreator corpus={corpus} conf={this.props.conf} /></div>
let listIds = this.props.ids.map((corpus) =>{
let corpusFormated = 'corpus : '.concat(corpus);
return <div key={corpusFormated}> <input class="corpus_checkbox" type="checkbox" value={corpusFormated} onChange={this.handleChange} checked={this.isChecked(corpusFormated)}/> {corpus} <ItemCreator corpus={corpus} conf={this.props.conf} /></div>;
}
);
return (
<div className="col-md-8 p-4">
Expand Down Expand Up @@ -63,12 +82,37 @@ class Corpora extends Component {
<option key={attribute} value={attribute}> {attribute} </option>
));
}

handleChange = (e) => {
let list = this.state.listCorpus;
let index = list.indexOf(e.target.value);
if (index !== -1) {
list.splice(index, 1);
} else {
list.push(e.target.value);
}
this.setState({
listCorpus: list
});
this.handleCorpusSelected(e.target.value);
}

isChecked(corpus) {
const selection = Selection.fromURI();
return selection.isSelectedOrExcluded(corpus) !== 'Excluded';
}

handleCorpusSelected(corpusId) {
const selection = Selection.fromURI();
selection.toggleCorpus(corpusId);
this.props.history.push(selection.toURI());
}
}

function Item(props) {
let uri = `/item/${props.item.corpus}/${props.item.id}`;
let name = [props.item.name].join(', '); //Name can be an array
let thumbnail = props.item.thumbnail && <img src={props.item.thumbnail} alt={name}/>;
let thumbnail = props.item.thumbnail && <img src={props.item.thumbnail} alt={name} />;
let criteria = (props.criteria !== 'name')
&& <div className="About"> {props.item[props.criteria]} </div>;
return (
Expand Down
4 changes: 3 additions & 1 deletion src/components/portfolioPage/Portfolio.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,11 @@ class Portfolio extends Component {
}

_getItemAttributes(item) {
return new Items(
let result = new Items(
[item]
).getAttributes()
.map(([key, value]) => key.concat(' : ', value.replace('\'', '’')));
return result;
}

_isSelected(item) {
Expand Down Expand Up @@ -260,6 +261,7 @@ class Portfolio extends Component {
from={this.state.items.length}
items={this.state.selectedItems}
conf={conf}
history={this.props.history}
/>
);
}
Expand Down
6 changes: 5 additions & 1 deletion src/components/portfolioPage/SearchBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ class SearchBar extends React.Component {
handleSuggestionSelected = (_, { suggestion }) => {
this.setState({pattern: ''});
const selection = Selection.fromURI();
selection.addTopic(suggestion.id);
if (suggestion.id.includes('corpus')) {
selection.addCorpus(suggestion.id);
} else {
selection.addTopic(suggestion.id);
}
this.props.history.push(selection.toURI());
};

Expand Down
12 changes: 7 additions & 5 deletions src/components/portfolioPage/Status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ class Status extends Component {
...clause.exclusion.map(id => ({excluded: true, id, topic: this._getCandidate(id)}))]
.sort(filter)
.map(
t =>
(t.topic === null)
? <Trans>Rubrique inconnue</Trans>
: <Badge exclusion={t.excluded} id={t.id} name={t.topic.name} _changeItemState={this._changeItemState}/>
t => {
let res = (t.topic === null) ? <Trans>Rubrique inconnue</Trans> : <Badge exclusion={t.excluded} id={t.id} name={t.topic.name} _changeItemState={this._changeItemState}/>;
return res;
}
);
status.push(topicsHTML.map((e, i) => i < topicsHTML.length - 1 ? [e, <Button clause={clause} _changeUnionState={this._changeUnionState}/>] : [e]).reduce((a, b) => a.concat(b))
);
Expand All @@ -38,7 +38,9 @@ class Status extends Component {

_getCandidate(id) {
for (let v of this.props.candidates) {
if (v[id]) return v[id];
if (v[id]) {
return v[id];
}
}
return null;
}
Expand Down
5 changes: 3 additions & 2 deletions src/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ class Items {
this.items
.map(
x => Object.entries(x).filter(
y => !['topic', 'resource', 'thumbnail', 'id', 'item', 'corpus', 'record', 'original', '_attachments'].includes(y[0])
y => !['topic', 'resource', 'thumbnail', 'id', 'item', 'record', 'original', '_attachments'].includes(y[0])
)
)
.reduce((x, y) => x.concat(y), [])
.map(([x, y]) => JSON.stringify([x, y[0]]))
.map(([x, y]) => Array.isArray(y) ? [x, y[0]] : [x, y])
.map(JSON.stringify)
)].map(JSON.parse);

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

0 comments on commit 8cebb8f

Please sign in to comment.