
diff -r 000000000000 -r 5f4fcbc80b37 clientjs/packages/dashboard-components/src/pages/documents.jsx
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clientjs/packages/dashboard-components/src/pages/documents.jsx	Fri Sep 14 17:57:34 2018 +0200
@@ -0,0 +1,141 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import { FormattedMessage } from 'react-intl';
+import _ from 'lodash';
+
+import { AnnotationsDocumentsTable, Document } from '../ui';
+
+const DocumentCategoryList = ({ stats, documents, viaBaseUrl }) => (documents || []).map(
+  document => (
+    <div key={document.uri} className="col col-4 mb-3 d-flex align-items-stretch">
+      <Document
+        document={document}
+        stats={stats[document.uri]}
+        viaBaseUrl={viaBaseUrl}
+      />
+    </div>
+  ),
+);
+
+const DocumentsCategory = ({ stats, documentCategory, viaBaseUrl }) => {
+  const { category, documents } = documentCategory;
+  return (
+    <div className="row">
+      <h3>{ category }</h3>
+
+      <div className="row">
+        <DocumentCategoryList stats={stats} documents={documents} viaBaseUrl={viaBaseUrl} />
+      </div>
+
+    </div>
+  );
+};
+
+DocumentsCategory.propTypes = {
+  stats: PropTypes.object.isRequired,
+  documentCategory: PropTypes.object.isRequired,
+  viaBaseUrl: PropTypes.string.isRequired,
+};
+
+const GroupDocuments = ({ annotationsStats, categories, viaBaseUrl }) => categories.map(
+  category => (
+    <DocumentsCategory
+      key={category.category}
+      documentCategory={category}
+      stats={annotationsStats}
+      viaBaseUrl={viaBaseUrl}
+    />
+  ),
+);
+
+const DocumentsPage = ({
+  documents,
+  documentsMap,
+  otherDocuments,
+  viaBaseUrl,
+  topics,
+  metacategories,
+  children,
+}) => (
+  <div className="row">
+    <div className="col col-12">
+      {
+        children
+      }
+      <GroupDocuments
+        annotationsStats={documents}
+        categories={documentsMap}
+        viaBaseUrl={viaBaseUrl}
+      />
+      <div className="row">
+        <h3><FormattedMessage id="documents.other_documents_title" defaultMessage="Other documents" /></h3>
+        <AnnotationsDocumentsTable
+          documents={otherDocuments}
+          viaBaseUrl={viaBaseUrl}
+          topics={topics}
+          metacategories={metacategories}
+        />
+      </div>
+    </div>
+  </div>
+);
+
+DocumentsPage.propTypes = {
+  documents: PropTypes.object.isRequired,
+  documentsMap: PropTypes.arrayOf(PropTypes.object).isRequired,
+  otherDocuments: PropTypes.arrayOf(PropTypes.object).isRequired,
+  viaBaseUrl: PropTypes.string.isRequired,
+  metacategories: PropTypes.arrayOf(PropTypes.object).isRequired,
+  topics: PropTypes.arrayOf(PropTypes.string).isRequired,
+  children: PropTypes.node.isRequired,
+};
+
+export default connect(
+  (state, props) => {
+    const { documents: { documents }, annotations: { items: annotations } } = state;
+    const { documentsMap } = props;
+
+    const documentsUrls = documentsMap.reduce(
+      (res, cat) => cat.documents.reduce(
+        (docRes, doc) => {
+          if (!docRes.includes(doc.uri)) {
+            docRes.push(doc.uri);
+          }
+          return docRes;
+        }, res,
+      ),
+      [],
+    );
+
+    const otherDocuments = _(annotations)
+      .filter(annot => !documentsUrls.includes(annot.uri))
+      .groupBy('uri').map((d, uri) => {
+        if (d.length > 0) {
+          const firstAnnotation = d[0];
+
+          const usersNb = _.chain(d)
+            .map('user')
+            .uniq()
+            .value().length;
+          const titles = firstAnnotation.document.title;
+          return {
+            uri,
+            name: titles ? titles[0] : '',
+            updated: firstAnnotation.updated,
+            usersNb,
+            annotationsNb: d.length,
+            annotations: d,
+          };
+        }
+        return {};
+      })
+      .value();
+
+    return {
+      documents,
+      documentsUrls,
+      otherDocuments,
+    };
+  },
+)(DocumentsPage);




