|
1 import React from 'react'; |
|
2 import PropTypes from 'prop-types'; |
|
3 import { connect } from 'react-redux'; |
|
4 import { FormattedMessage } from 'react-intl'; |
|
5 import _ from 'lodash'; |
|
6 |
|
7 import { AnnotationsDocumentsTable, Document } from '../ui'; |
|
8 |
|
9 const DocumentCategoryList = ({ stats, documents, viaBaseUrl }) => (documents || []).map( |
|
10 document => ( |
|
11 <div key={document.uri} className="col col-4 mb-3 d-flex align-items-stretch"> |
|
12 <Document |
|
13 document={document} |
|
14 stats={stats[document.uri]} |
|
15 viaBaseUrl={viaBaseUrl} |
|
16 /> |
|
17 </div> |
|
18 ), |
|
19 ); |
|
20 |
|
21 const DocumentsCategory = ({ stats, documentCategory, viaBaseUrl }) => { |
|
22 const { category, documents } = documentCategory; |
|
23 return ( |
|
24 <div className="row"> |
|
25 <h3>{ category }</h3> |
|
26 |
|
27 <div className="row"> |
|
28 <DocumentCategoryList stats={stats} documents={documents} viaBaseUrl={viaBaseUrl} /> |
|
29 </div> |
|
30 |
|
31 </div> |
|
32 ); |
|
33 }; |
|
34 |
|
35 DocumentsCategory.propTypes = { |
|
36 stats: PropTypes.object.isRequired, |
|
37 documentCategory: PropTypes.object.isRequired, |
|
38 viaBaseUrl: PropTypes.string.isRequired, |
|
39 }; |
|
40 |
|
41 const GroupDocuments = ({ annotationsStats, categories, viaBaseUrl }) => categories.map( |
|
42 category => ( |
|
43 <DocumentsCategory |
|
44 key={category.category} |
|
45 documentCategory={category} |
|
46 stats={annotationsStats} |
|
47 viaBaseUrl={viaBaseUrl} |
|
48 /> |
|
49 ), |
|
50 ); |
|
51 |
|
52 const DocumentsPage = ({ |
|
53 documents, |
|
54 documentsMap, |
|
55 otherDocuments, |
|
56 viaBaseUrl, |
|
57 topics, |
|
58 metacategories, |
|
59 children, |
|
60 }) => ( |
|
61 <div className="row"> |
|
62 <div className="col col-12"> |
|
63 { |
|
64 children |
|
65 } |
|
66 <GroupDocuments |
|
67 annotationsStats={documents} |
|
68 categories={documentsMap} |
|
69 viaBaseUrl={viaBaseUrl} |
|
70 /> |
|
71 <div className="row"> |
|
72 <h3><FormattedMessage id="documents.other_documents_title" defaultMessage="Other documents" /></h3> |
|
73 <AnnotationsDocumentsTable |
|
74 documents={otherDocuments} |
|
75 viaBaseUrl={viaBaseUrl} |
|
76 topics={topics} |
|
77 metacategories={metacategories} |
|
78 /> |
|
79 </div> |
|
80 </div> |
|
81 </div> |
|
82 ); |
|
83 |
|
84 DocumentsPage.propTypes = { |
|
85 documents: PropTypes.object.isRequired, |
|
86 documentsMap: PropTypes.arrayOf(PropTypes.object).isRequired, |
|
87 otherDocuments: PropTypes.arrayOf(PropTypes.object).isRequired, |
|
88 viaBaseUrl: PropTypes.string.isRequired, |
|
89 metacategories: PropTypes.arrayOf(PropTypes.object).isRequired, |
|
90 topics: PropTypes.arrayOf(PropTypes.string).isRequired, |
|
91 children: PropTypes.node.isRequired, |
|
92 }; |
|
93 |
|
94 export default connect( |
|
95 (state, props) => { |
|
96 const { documents: { documents }, annotations: { items: annotations } } = state; |
|
97 const { documentsMap } = props; |
|
98 |
|
99 const documentsUrls = documentsMap.reduce( |
|
100 (res, cat) => cat.documents.reduce( |
|
101 (docRes, doc) => { |
|
102 if (!docRes.includes(doc.uri)) { |
|
103 docRes.push(doc.uri); |
|
104 } |
|
105 return docRes; |
|
106 }, res, |
|
107 ), |
|
108 [], |
|
109 ); |
|
110 |
|
111 const otherDocuments = _(annotations) |
|
112 .filter(annot => !documentsUrls.includes(annot.uri)) |
|
113 .groupBy('uri').map((d, uri) => { |
|
114 if (d.length > 0) { |
|
115 const firstAnnotation = d[0]; |
|
116 |
|
117 const usersNb = _.chain(d) |
|
118 .map('user') |
|
119 .uniq() |
|
120 .value().length; |
|
121 const titles = firstAnnotation.document.title; |
|
122 return { |
|
123 uri, |
|
124 name: titles ? titles[0] : '', |
|
125 updated: firstAnnotation.updated, |
|
126 usersNb, |
|
127 annotationsNb: d.length, |
|
128 annotations: d, |
|
129 }; |
|
130 } |
|
131 return {}; |
|
132 }) |
|
133 .value(); |
|
134 |
|
135 return { |
|
136 documents, |
|
137 documentsUrls, |
|
138 otherDocuments, |
|
139 }; |
|
140 }, |
|
141 )(DocumentsPage); |