From cee82f39c285b8510dd53d551c9cae3c0489e7e2 Mon Sep 17 00:00:00 2001 From: Benjamin Gamard Date: Thu, 1 Nov 2018 16:27:35 +0100 Subject: [PATCH] #254: display documents in grid + concept of main file --- .../sismics/docs/core/dao/DocumentDao.java | 27 +++++++--- .../docs/core/dao/dto/DocumentDto.java | 16 +++++- .../async/DocumentUpdatedAsyncListener.java | 16 +++++- .../sismics/docs/core/model/jpa/Document.java | 15 ++++++ .../util/indexing/LuceneIndexingHandler.java | 3 +- .../src/main/resources/config.properties | 2 +- .../resources/db/update/dbupdate-021-0.sql | 4 ++ .../sismics/docs/rest/util/ClientUtil.java | 10 ++++ docs-web/src/dev/resources/config.properties | 2 +- .../docs/rest/resource/DocumentResource.java | 2 + .../docs/rest/resource/FileResource.java | 6 +++ .../app/docs/controller/document/Document.js | 10 +++- docs-web/src/main/webapp/src/locale/en.json | 2 + .../webapp/src/partial/docs/document.html | 51 ++++++++++++++++++- docs-web/src/main/webapp/src/style/main.less | 4 ++ docs-web/src/prod/resources/config.properties | 2 +- .../src/stress/resources/config.properties | 2 +- .../docs/rest/TestDocumentResource.java | 1 + 18 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 docs-core/src/main/resources/db/update/dbupdate-021-0.sql diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/DocumentDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/DocumentDao.java index f3bb555c..34d170c7 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/DocumentDao.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/DocumentDao.java @@ -189,20 +189,35 @@ public class DocumentDao { } /** - * Update a document. + * Update a document and log the action. * * @param document Document to update * @param userId User ID * @return Updated document */ public Document update(Document document, String userId) { - EntityManager em = ThreadLocalContext.get().getEntityManager(); + Document documentDb = updateSilently(document); + // Create audit log + AuditLogUtil.create(documentDb, AuditLogType.UPDATE, userId); + + return documentDb; + } + + /** + * Update a document without audit log. + * + * @param document Document to update + * @return Updated document + */ + public Document updateSilently(Document document) { + EntityManager em = ThreadLocalContext.get().getEntityManager(); + // Get the document Query q = em.createQuery("select d from Document d where d.id = :id and d.deleteDate is null"); q.setParameter("id", document.getId()); Document documentDb = (Document) q.getSingleResult(); - + // Update the document documentDb.setTitle(document.getTitle()); documentDb.setDescription(document.getDescription()); @@ -216,11 +231,9 @@ public class DocumentDao { documentDb.setRights(document.getRights()); documentDb.setCreateDate(document.getCreateDate()); documentDb.setLanguage(document.getLanguage()); + documentDb.setFileId(document.getFileId()); documentDb.setUpdateDate(new Date()); - - // Create audit log - AuditLogUtil.create(documentDb, AuditLogType.UPDATE, userId); - + return documentDb; } diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/dto/DocumentDto.java b/docs-core/src/main/java/com/sismics/docs/core/dao/dto/DocumentDto.java index 63aeb58f..48907984 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/dto/DocumentDto.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/dto/DocumentDto.java @@ -10,7 +10,12 @@ public class DocumentDto { * Document ID. */ private String id; - + + /** + * Main file ID. + */ + private String fileId; + /** * Title. */ @@ -114,6 +119,15 @@ public class DocumentDto { this.id = id; } + public String getFileId() { + return fileId; + } + + public DocumentDto setFileId(String fileId) { + this.fileId = fileId; + return this; + } + public String getTitle() { return title; } diff --git a/docs-core/src/main/java/com/sismics/docs/core/listener/async/DocumentUpdatedAsyncListener.java b/docs-core/src/main/java/com/sismics/docs/core/listener/async/DocumentUpdatedAsyncListener.java index da0eb5b7..fb791d2a 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/listener/async/DocumentUpdatedAsyncListener.java +++ b/docs-core/src/main/java/com/sismics/docs/core/listener/async/DocumentUpdatedAsyncListener.java @@ -4,10 +4,12 @@ import com.google.common.eventbus.AllowConcurrentEvents; import com.google.common.eventbus.Subscribe; import com.sismics.docs.core.dao.ContributorDao; import com.sismics.docs.core.dao.DocumentDao; +import com.sismics.docs.core.dao.FileDao; import com.sismics.docs.core.event.DocumentUpdatedAsyncEvent; import com.sismics.docs.core.model.context.AppContext; import com.sismics.docs.core.model.jpa.Contributor; import com.sismics.docs.core.model.jpa.Document; +import com.sismics.docs.core.model.jpa.File; import com.sismics.docs.core.util.TransactionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,13 +40,25 @@ public class DocumentUpdatedAsyncListener { } TransactionUtil.handle(() -> { - // Update index + // Get the document DocumentDao documentDao = new DocumentDao(); Document document = documentDao.getById(event.getDocumentId()); if (document == null) { // Document deleted since event fired return; } + + // Set the main file + FileDao fileDao = new FileDao(); + List fileList = fileDao.getByDocumentId(null, event.getDocumentId()); + if (fileList.isEmpty()) { + document.setFileId(null); + } else { + document.setFileId(fileList.get(0).getId()); + } + + // Update database and index + documentDao.updateSilently(document); AppContext.getInstance().getIndexingHandler().updateDocument(document); // Update contributors list diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Document.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Document.java index 626e631c..9fc76692 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Document.java +++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Document.java @@ -29,6 +29,12 @@ public class Document implements Loggable { @Column(name = "DOC_IDUSER_C", nullable = false, length = 36) private String userId; + /** + * Main file ID. + */ + @Column(name = "DOC_IDFILE_C", length = 36) + private String fileId; + /** * Language (ISO 639-9). */ @@ -137,6 +143,15 @@ public class Document implements Loggable { this.userId = userId; } + public String getFileId() { + return fileId; + } + + public Document setFileId(String fileId) { + this.fileId = fileId; + return this; + } + public String getTitle() { return title; } diff --git a/docs-core/src/main/java/com/sismics/docs/core/util/indexing/LuceneIndexingHandler.java b/docs-core/src/main/java/com/sismics/docs/core/util/indexing/LuceneIndexingHandler.java index 6062557c..40f17127 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/util/indexing/LuceneIndexingHandler.java +++ b/docs-core/src/main/java/com/sismics/docs/core/util/indexing/LuceneIndexingHandler.java @@ -219,7 +219,7 @@ public class LuceneIndexingHandler implements IndexingHandler { List criteriaList = new ArrayList<>(); Map documentSearchMap = Maps.newHashMap(); - StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C c0, d.DOC_TITLE_C c1, d.DOC_DESCRIPTION_C c2, d.DOC_CREATEDATE_D c3, d.DOC_LANGUAGE_C c4, "); + StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C c0, d.DOC_TITLE_C c1, d.DOC_DESCRIPTION_C c2, d.DOC_CREATEDATE_D c3, d.DOC_LANGUAGE_C c4, d.DOC_IDFILE_C, "); sb.append(" s.count c5, "); sb.append(" f.count c6, "); sb.append(" rs2.RTP_ID_C c7, rs2.RTP_NAME_C, d.DOC_UPDATEDATE_D c8 "); @@ -323,6 +323,7 @@ public class LuceneIndexingHandler implements IndexingHandler { documentDto.setDescription((String) o[i++]); documentDto.setCreateTimestamp(((Timestamp) o[i++]).getTime()); documentDto.setLanguage((String) o[i++]); + documentDto.setFileId((String) o[i++]); Number shareCount = (Number) o[i++]; documentDto.setShared(shareCount != null && shareCount.intValue() > 0); Number fileCount = (Number) o[i++]; diff --git a/docs-core/src/main/resources/config.properties b/docs-core/src/main/resources/config.properties index 4d9e12ea..eb3e256a 100644 --- a/docs-core/src/main/resources/config.properties +++ b/docs-core/src/main/resources/config.properties @@ -1 +1 @@ -db.version=20 \ No newline at end of file +db.version=21 \ No newline at end of file diff --git a/docs-core/src/main/resources/db/update/dbupdate-021-0.sql b/docs-core/src/main/resources/db/update/dbupdate-021-0.sql new file mode 100644 index 00000000..5564fcf4 --- /dev/null +++ b/docs-core/src/main/resources/db/update/dbupdate-021-0.sql @@ -0,0 +1,4 @@ +alter table T_DOCUMENT add column DOC_IDFILE_C varchar(36); +alter table T_DOCUMENT add constraint FK_DOC_IDFILE_C foreign key (DOC_IDFILE_C) references T_FILE (FIL_ID_C) on delete restrict on update restrict; + +update T_CONFIG set CFG_VALUE_C = '21' where CFG_ID_C = 'DB_VERSION'; diff --git a/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java b/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java index a45254e2..2213160e 100644 --- a/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java +++ b/docs-web-common/src/test/java/com/sismics/docs/rest/util/ClientUtil.java @@ -154,6 +154,16 @@ public class ClientUtil { return authToken; } + /** + * Add a file to a document. + * + * @param file File path + * @param filename Filename + * @param token Authentication token + * @param documentId Document ID + * @return File ID + * @throws IOException e + */ public String addFileToDocument(String file, String filename, String token, String documentId) throws IOException { try (InputStream is = Resources.getResource(file).openStream()) { StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is, filename); diff --git a/docs-web/src/dev/resources/config.properties b/docs-web/src/dev/resources/config.properties index 1c8df450..e55e3dbc 100644 --- a/docs-web/src/dev/resources/config.properties +++ b/docs-web/src/dev/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=20 \ No newline at end of file +db.version=21 \ No newline at end of file diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java index 9e5fb928..2c7380b7 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java @@ -326,6 +326,7 @@ public class DocumentResource extends BaseResource { * @apiSuccess {Object[]} documents List of documents * @apiSuccess {String} documents.id ID * @apiSuccess {String} documents.highlight Search highlight (for fulltext search) + * @apiSuccess {String} documents.file_id Main file ID * @apiSuccess {String} documents.title Title * @apiSuccess {String} documents.description Description * @apiSuccess {Number} documents.create_date Create date (timestamp) @@ -395,6 +396,7 @@ public class DocumentResource extends BaseResource { documents.add(Json.createObjectBuilder() .add("id", documentDto.getId()) .add("highlight", JsonUtil.nullable(documentDto.getHighlight())) + .add("file_id", JsonUtil.nullable(documentDto.getFileId())) .add("title", documentDto.getTitle()) .add("description", JsonUtil.nullable(documentDto.getDescription())) .add("create_date", documentDto.getCreateTimestamp()) diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java index e972d197..4f03f156 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java @@ -367,6 +367,12 @@ public class FileResource extends BaseResource { file.setOrder(order); } } + + // Raise a document updated event + DocumentUpdatedAsyncEvent event = new DocumentUpdatedAsyncEvent(); + event.setUserId(principal.getId()); + event.setDocumentId(documentId); + ThreadLocalContext.get().addAsyncEvent(event); // Always return OK JsonObjectBuilder response = Json.createObjectBuilder() diff --git a/docs-web/src/main/webapp/src/app/docs/controller/document/Document.js b/docs-web/src/main/webapp/src/app/docs/controller/document/Document.js index 7305ed3d..e3365405 100644 --- a/docs-web/src/main/webapp/src/app/docs/controller/document/Document.js +++ b/docs-web/src/main/webapp/src/app/docs/controller/document/Document.js @@ -12,6 +12,7 @@ angular.module('docs').controller('Document', function ($scope, $rootScope, $tim $scope.offset = 0; $scope.currentPage = 1; $scope.limit = _.isUndefined(localStorage.documentsPageSize) ? '10' : localStorage.documentsPageSize; + $scope.displayMode = _.isUndefined(localStorage.displayMode) ? 'list' : localStorage.displayMode; $scope.search = $state.params.search ? $state.params.search : ''; $scope.setSearch = function (search) { $scope.search = search }; $scope.searchOpened = false; @@ -113,7 +114,14 @@ angular.module('docs').controller('Document', function ($scope, $rootScope, $tim } $scope.loadDocuments(); }); - + + /** + * Watch for display mode change. + */ + $scope.$watch('displayMode', function (next) { + localStorage.displayMode = next; + }); + /** * Display a document. */ diff --git a/docs-web/src/main/webapp/src/locale/en.json b/docs-web/src/main/webapp/src/locale/en.json index f8b9c473..869760ac 100644 --- a/docs-web/src/main/webapp/src/locale/en.json +++ b/docs-web/src/main/webapp/src/locale/en.json @@ -41,6 +41,8 @@ "document": { "navigation_up": "Go up one level", "toggle_navigation": "Toggle folder navigation", + "display_mode_list": "Display documents in list", + "display_mode_grid": "Display documents in grid", "search_simple": "Simple search", "search_fulltext": "Fulltext search", "search_creator": "Creator", diff --git a/docs-web/src/main/webapp/src/partial/docs/document.html b/docs-web/src/main/webapp/src/partial/docs/document.html index 00f64cc0..8fa5ad05 100644 --- a/docs-web/src/main/webapp/src/partial/docs/document.html +++ b/docs-web/src/main/webapp/src/partial/docs/document.html @@ -169,6 +169,22 @@ + +
+ + + + + + +
+