Skip to content

Commit ba256e8

Browse files
author
Arnaud9145
committed
Added Cloud and Fragment View
1 parent 745c4a5 commit ba256e8

15 files changed

Lines changed: 1011 additions & 434 deletions

File tree

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"react-autosuggest": "^9.3.4",
1414
"react-dom": "^16.4.0",
1515
"react-router-dom": "^4.1.1",
16+
"react-switch": "^5.0.0",
17+
"react-tagcloud": "^1.4.0",
1618
"sort-by": "^1.2.0"
1719
},
1820
"devDependencies": {

public/favicon.ico

20.3 KB
Binary file not shown.

src/components/Authenticated/Authenticated.jsx

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ class Authenticated extends Component {
1111
user: '',
1212
ask: false
1313
}
14-
this.handleAsk = this.handleAsk.bind(this);
15-
this.handleLogin = this.handleLogin.bind(this);
16-
this.handleLogout = this.handleLogout.bind(this);
1714
}
1815

1916
render() {
@@ -40,18 +37,18 @@ class Authenticated extends Component {
4037
);
4138
}
4239

43-
handleAsk(e) {
44-
e.preventDefault();
45-
this.setState({ask: true});
40+
handleAsk = e => {
41+
e.preventDefault()
42+
this.setState({ ask: true })
4643
}
4744

48-
handleLogin(e) {
45+
handleLogin = e => {
4946
e.preventDefault();
5047
this._openSession();
5148
this.setState({ask: false});
5249
}
5350

54-
handleLogout(e) {
51+
handleLogout = e => {
5552
e.preventDefault();
5653
this._closeSession();
5754
}
@@ -66,16 +63,16 @@ class Authenticated extends Component {
6663
_openSession() {
6764
let user = this.login.value;
6865
fetch(SESSION_URI, {
69-
method:'POST',
66+
method: 'POST',
7067
headers: {
7168
"Content-Type": "application/x-www-form-urlencoded",
7269
},
73-
body:`name=${user}&password=${this.password.value}`,
74-
credentials:'include'
70+
body: `name=${user}&password=${this.password.value}`,
71+
credentials: 'include'
7572
})
7673
.then(x => {
7774
if (!x.ok) throw new Error('Bad credentials!');
78-
this.setState({user})
75+
this.setState({user});
7976
})
8077
.catch(() => this.setState({user: ''}));
8178
}

src/components/Cloud/Cloud.jsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React, { Component } from 'react';
2+
import { Link } from 'react-router-dom';
3+
import queryString from 'query-string';
4+
import { TagCloud } from 'react-tagcloud';
5+
6+
class Cloud extends Component {
7+
shouldComponentUpdate(nextProps) {
8+
if (this.props.selection.length !== nextProps.selection.length) return true;
9+
if (
10+
Object.keys(this.props.viewpoint).length !==
11+
Object.keys(nextProps.viewpoint).length
12+
)
13+
return true;
14+
return false;
15+
}
16+
17+
render() {
18+
const { selection, viewpoint, topicsItems } = this.props;
19+
let alltopics = [];
20+
this.pushChildInTab(viewpoint.upper || [], alltopics);
21+
alltopics = alltopics
22+
.filter(topic => topic.name)
23+
.map(topic => {
24+
let items = topicsItems.get(topic.id);
25+
let found = selection.find(s => s === topic.id);
26+
27+
let uri =
28+
'?' +
29+
queryString.stringify({
30+
t: this.toggle(selection, topic.id)
31+
});
32+
return {
33+
value: topic.name[0],
34+
count: items ? items.size : 0,
35+
color: found ? 'selected' : '',
36+
uri
37+
};
38+
})
39+
.sort((a, b) => {
40+
if (a.value > b.value) return 1;
41+
if (a.value < b.value) return -1;
42+
return 0;
43+
});
44+
return (
45+
<TagCloud
46+
minSize={10}
47+
maxSize={25}
48+
shuffle={false}
49+
tags={alltopics}
50+
disableRandomColor
51+
renderer={(tag, size, color) => {
52+
return (
53+
<Link key={tag.value} to={tag.uri}>
54+
<span
55+
style={{
56+
fontSize: `${size}px`,
57+
margin: '3px',
58+
padding: '3px',
59+
display: 'inline-block',
60+
color: 'black'
61+
}}
62+
className={color === 'selected' ? 'Cloud-Selected' : ''}
63+
>
64+
{tag.value}
65+
</span>
66+
</Link>
67+
);
68+
}}
69+
/>
70+
);
71+
}
72+
73+
pushChildInTab = (topics, tab) => {
74+
topics.forEach(t => {
75+
let topic = this.props.viewpoint[t.id];
76+
if (topic.narrower) {
77+
this.pushChildInTab(topic.narrower, tab);
78+
}
79+
topic.id = t.id;
80+
tab.push(topic);
81+
});
82+
};
83+
toggle = (array, item) => {
84+
let s = new Set(array);
85+
if (!s.delete(item)) {
86+
s.add(item);
87+
}
88+
return [...s];
89+
};
90+
}
91+
92+
export default Cloud;

src/components/Corpora/Corpora.jsx

Lines changed: 104 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,128 @@
11
import React, { Component } from 'react';
22
import { Link } from 'react-router-dom';
33
import getConfig from '../../config/config.js';
4+
import Fragment from '../Item/Fragment';
5+
import Switch from 'react-switch';
46

5-
// Get the configured list display mode
67
let listView = getConfig('listView', {
78
mode: 'picture',
89
name: 'name',
910
image: 'thumbnail'
1011
});
1112

1213
class Corpora extends Component {
14+
constructor(props) {
15+
super(props);
16+
this.state = {
17+
view: 'item'
18+
};
19+
this.changeViewPossible = true;
20+
}
21+
22+
componentDidMount(prevProps) {
23+
if (prevProps !== this.props) {
24+
if (!this.props.pictures || this.props.pictures.length === 0) {
25+
this.changeViewPossible = false;
26+
this.setState({ view: 'fragment' });
27+
} else if (!this.props.fragments || this.props.fragments.length === 0) {
28+
this.changeViewPossible = false;
29+
this.setState({ view: 'item' });
30+
} else {
31+
this.changeViewPossible = true;
32+
this.setState({ view: 'item' });
33+
}
34+
}
35+
}
36+
37+
componentDidUpdate(prevProps, prevState, snapshot) {
38+
if (prevProps !== this.props) {
39+
if (!this.props.pictures || this.props.pictures.length === 0) {
40+
this.changeViewPossible = false;
41+
this.setState({ view: 'fragment' });
42+
} else if (!this.props.fragments || this.props.fragments.length === 0) {
43+
this.changeViewPossible = false;
44+
this.setState({ view: 'item' });
45+
} else {
46+
this.changeViewPossible = true;
47+
this.setState({ view: 'item' });
48+
}
49+
}
50+
}
1351

1452
render() {
15-
let items = this._getItems();
16-
let count = this.props.items.length;
17-
let total = this.props.from;
18-
return(
53+
const { fragments } = this.props;
54+
return (
1955
<div className="col-md-8 p-4">
56+
{this._choiceView()}
2057
<div className="Subject">
2158
<h2 className="h4 font-weight-bold text-center">
2259
{this.props.ids.join(' + ')}
23-
<span className="badge badge-pill badge-light ml-4">{count} / {total}</span>
60+
<span className="badge badge-pill badge-light ml-4">
61+
{fragments ? fragments.length : 0} / {this.props.from}
62+
</span>
2463
</h2>
25-
<div className="Items m-3">
26-
{items}
27-
</div>
64+
<div className="Items m-3">{this._getView()}</div>
2865
</div>
2966
</div>
3067
);
3168
}
3269

70+
_getView() {
71+
switch (this.state.view) {
72+
case 'item':
73+
return this._getItems();
74+
case 'fragment':
75+
return (
76+
<Fragment
77+
from={this.props.fragments.length}
78+
items={this.props.fragments}
79+
viewpoint={this.props.viewpoint}
80+
selection={this.props.selection}
81+
/>
82+
);
83+
default:
84+
return <p> arrête de jouer avec le code</p>;
85+
}
86+
}
87+
3388
_getItems() {
34-
return this.props.items.map(item =>
35-
<Item key={item.id} item={item}
36-
id={item.corpus+'/'+item.id} />
37-
);
89+
return this.props.pictures.map(item => (
90+
<Picture key={item.id} item={item} id={item.corpus + '/' + item.id} />
91+
));
3892
}
3993

40-
}
94+
_changeview() {
95+
if (this.state.view === 'item') {
96+
this.setState({ view: 'fragment' });
97+
}
98+
if (this.state.view === 'fragment') {
99+
this.setState({ view: 'item' });
100+
}
101+
}
41102

42-
function Item(props) {
43-
switch (listView.mode) {
44-
case 'article':
45-
return Article(props.item);
46-
case 'picture':
47-
return Picture(props.item);
48-
default:
49-
return Picture(props.item);
103+
_choiceView() {
104+
if (this.changeViewPossible) {
105+
let changeview = this._changeview.bind(this);
106+
return (
107+
<h4>
108+
<label>
109+
<span>
110+
<b>choix de la vue:</b> image{' '}
111+
</span>
112+
<Switch
113+
onChange={changeview}
114+
checked={!(this.state.view === 'item')}
115+
checkedIcon={false}
116+
uncheckedIcon={false}
117+
height={20}
118+
width={45}
119+
onColor="#888"
120+
/>
121+
<span> fragment</span>
122+
</label>
123+
</h4>
124+
);
125+
}
50126
}
51127
}
52128

@@ -57,29 +133,15 @@ function getString(obj) {
57133
return String(obj);
58134
}
59135

60-
function Article(item) {
61-
let propList = (listView.props || []).map(key => {
62-
return <li>{key} : <strong>{getString(item[key])}</strong></li>;
63-
});
64-
65-
let uri = `/item/${item.corpus}/${item.id}`;
66-
let name = getString(item[listView.name]);
67-
return (
68-
<div className="Article">
69-
<div className="ArticleTitle"><Link to={uri}>{name}</Link></div>
70-
<ul>{propList}</ul>
71-
</div>
72-
);
73-
}
74-
75-
function Picture(item) {
76-
let uri = `/item/${item.corpus}/${item.id}`;
77-
let img = getString(item[listView.image]);
78-
let name = getString(item[listView.name]);
136+
function Picture(items) {
137+
items = items.item;
138+
let uri = `/item/${items.corpus}/${items.id}`;
139+
let img = getString(items[listView.image]);
140+
let name = getString(items[listView.name]);
79141
return (
80142
<div className="Item">
81143
<Link to={uri}>
82-
<img src={img} alt={name}/>
144+
<img src={img} alt={name} />
83145
</Link>
84146
<div className="text-center">{name}</div>
85147
</div>

src/components/Header/Header.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Header extends Component {
1111
render() {
1212
return (
1313
<header className="row align-items-center">
14-
<div className="col-lg-2 col-md-3 d-none d-md-block logo"></div>
14+
<div className="col-lg-2 col-md-3 d-none d-md-block logo" />
1515
<div className="col-lg-2 col-md-3 col-sm-4">
1616
<input className="form-control" type="text" placeholder="Rechercher..."/>
1717
</div>

0 commit comments

Comments
 (0)