diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/criteria/DocumentCriteria.java b/docs-core/src/main/java/com/sismics/docs/core/dao/criteria/DocumentCriteria.java index 1e6b46af..8d69f381 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/criteria/DocumentCriteria.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/criteria/DocumentCriteria.java @@ -84,9 +84,9 @@ public class DocumentCriteria { private String mimeType; /** - * The title. + * Titles to include. */ - private String title; + private List titleList = new ArrayList<>(); public List getTargetIdList() { return targetIdList; @@ -192,11 +192,7 @@ public class DocumentCriteria { this.mimeType = mimeType; } - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; + public List getTitleList() { + return titleList; } } 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 e9e8e734..bdb0f030 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 @@ -295,9 +295,9 @@ public class LuceneIndexingHandler implements IndexingHandler { criteriaList.add("d.DOC_UPDATEDATE_D <= :updateDateMax"); parameterMap.put("updateDateMax", criteria.getUpdateDateMax()); } - if (criteria.getTitle() != null) { - criteriaList.add("d.DOC_TITLE_C = :title"); - parameterMap.put("title", criteria.getTitle()); + if (!criteria.getTitleList().isEmpty()) { + criteriaList.add("d.DOC_TITLE_C in :title"); + parameterMap.put("title", criteria.getTitleList()); } if (!criteria.getTagIdList().isEmpty()) { int index = 0; 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 5fcb7c39..cde9f296 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 @@ -143,6 +143,11 @@ public class DocumentResource extends BaseResource { * @apiSuccess {String} files.version Zero-based version number * @apiSuccess {String} files.mimetype MIME type * @apiSuccess {String} files.create_date Create date (timestamp) + * @apiSuccess {Object[]} metadata List of metadata + * @apiSuccess {String} metadata.id ID + * @apiSuccess {String} metadata.name Name + * @apiSuccess {String="STRING","INTEGER","FLOAT","DATE","BOOLEAN"} metadata.type Type + * @apiSuccess {Object} metadata.value Value * @apiError (client) NotFound Document not found * @apiPermission none * @apiVersion 1.5.0 @@ -490,7 +495,36 @@ public class DocumentResource extends BaseResource { return Response.ok().entity(response.build()).build(); } - + + /** + * Returns all documents. + * + * @api {post} /document/list Get documents + * @apiDescription Get documents exposed as a POST endpoint to allow longer search parameters, see the GET endpoint for the API info + * @apiName PostDocumentList + * @apiGroup Document + * @apiVersion 1.12.0 + * + * @param limit Page limit + * @param offset Page offset + * @param sortColumn Sort column + * @param asc Sorting + * @param search Search query + * @param files Files list + * @return Response + */ + @POST + @Path("list") + public Response listPost( + @FormParam("limit") Integer limit, + @FormParam("offset") Integer offset, + @FormParam("sort_column") Integer sortColumn, + @FormParam("asc") Boolean asc, + @FormParam("search") String search, + @FormParam("files") Boolean files) { + return list(limit, offset, sortColumn, asc, search, files); + } + /** * Parse a query according to the specified syntax, eg.: * tag:assurance tag:other before:2012 after:2011-09 shared:yes lang:fra thing @@ -658,7 +692,7 @@ public class DocumentResource extends BaseResource { break; case "title": // New title criteria - documentCriteria.setTitle(paramValue); + documentCriteria.getTitleList().add(paramValue); break; default: fullQuery.add(criteria); diff --git a/docs-web/src/main/webapp/header.md b/docs-web/src/main/webapp/header.md index 87e9143a..5862af86 100644 --- a/docs-web/src/main/webapp/header.md +++ b/docs-web/src/main/webapp/header.md @@ -77,10 +77,10 @@ If a search `VALUE` is considered invalid, the search result will be empty. * `mime:VALUE`: the document must be of the specified mime type (example: `image/png`) * Shared * `shared:VALUE`: if `VALUE` is `yes`the document must be shared, for other `VALUE`s the criteria is ignored -* Tags +* Tags: several `tags` or `!tag:` can be specified and the document must match all filters * `tag:VALUE`: the document must contain a tag or a child of a tag that starts with `VALUE`, case is ignored * `!tag:VALUE`: the document must not contain a tag or a child of a tag that starts with `VALUE`, case is ignored -* Title +* Titles: several `title` can be specified, and the document must match any of the titles * `title:VALUE`: the title of the document must be `VALUE` * User * `by:VALUE`: the document creator's username must be `VALUE` with an exact match, the user must not be deleted diff --git a/docs-web/src/main/webapp/src/locale/fr.json b/docs-web/src/main/webapp/src/locale/fr.json index 85683211..5feec3eb 100644 --- a/docs-web/src/main/webapp/src/locale/fr.json +++ b/docs-web/src/main/webapp/src/locale/fr.json @@ -279,12 +279,14 @@ "menu_configuration": "Configuration", "menu_inbox": "Scanning de boîte de réception", "menu_ldap": "Authentification LDAP", + "menu_metadata": "Métadonnées spécifiques", "menu_monitoring": "Monitoring", "ldap": { "title": "Authentification LDAP", "enabled": "Activer l'authentication LDAP", "host": "Hôte LDAP", "port": "Port LDAP (389 par défaut)", + "usessl": "Activer SSL (ldaps)", "admin_dn": "DN administrateur", "admin_password": "Mot de passe administrateur", "base_dn": "DN de recherche", @@ -302,6 +304,8 @@ "edit": { "delete_user_title": "Supprimer un utilisateur", "delete_user_message": "Etes-vous sûr de vouloir supprimer cet utilisateur ? Tous les documents, fichiers et tags associés seront supprimés", + "user_used_title": "Utilisateur utilisé", + "user_used_message": "Cet utilisateur est utilisée dans le workflow \"{{ name }}\"", "edit_user_failed_title": "Cet utilisateur existe déjà", "edit_user_failed_message": "Ce nom d'utilisateur est déjà pris par un autre utilisateur", "edit_user_title": "Modifier \"{{ username }}\"", @@ -377,6 +381,8 @@ "delete_group_message": "Etes-vous sûr de vouloir supprimer ce groupe ?", "edit_group_failed_title": "Ce groupe existe déjà", "edit_group_failed_message": "Ce nom de groupe est déjà pris par un autre groupe", + "group_used_title": "Groupe utilisé", + "group_used_message": "Ce groupé est utilisé dans le workflow \"{{ name }}\"", "edit_group_title": "Modifier \"{{ name }}\"", "add_group_title": "Ajouter un groupe", "name": "Nom", @@ -422,12 +428,19 @@ "webhook_create_date": "Date de création", "webhook_add": "Ajouter un webhook" }, + "metadata": { + "title": "Configuration des métadonnées spécifiques", + "message": "Vous pouvez ajouter ici des métadonnées spécifiques à vos documents, comme un identifiant interne ou une date d'expiration. Veuillez notez que le type d'une métadonnée ne peut être modifié après sa création.", + "name": "Nom de métadonnée", + "type": "Type de métadonnée" + }, "inbox": { "title": "Scanning de boîte de réception", "message": "En activant cette fonctionnalité, le système scanne périodiquement la boîte de réception spécifiée pour rechercher de nouveaux messages et les importer automatiquement.
Après l'importation d'un email, celui-ci sera marqué comme lu.
Paramétrage pour Gmail, Outlook.com, Yahoo.", "enabled": "Activer le scan de boîte de réception", "hostname": "Nom d'hôte IMAP", "port": "Port IMAP (143 ou 993)", + "starttls": "Activer STARTTLS", "username": "Nom d'utilisateur IMAP", "password": "Mot de passe IMAP", "folder": "Dossier IMAP", @@ -436,7 +449,9 @@ "last_sync": "Dernière synchronisation : {{ data.date | date: 'medium' }}, {{ data.count }} message{{ data.count> 1 ? 's' : '' }} importé{{ data.count> 1 ? 's' : '' }}", "test_success": "La connexion à la boîte de réception est réussie ({{ count }} message{{ count> 1 ? 's' : '' }}) non lus", "test_fail": "Une erreur est survenue lors de la connexion à la boîte de réception, veuillez vérifier les paramètres", - "saved": "Configuration IMAP sauvegardée avec succès" + "saved": "Configuration IMAP sauvegardée avec succès", + "autoTagsEnabled": "Ajouter automatiquement les tags des titres marqués par #", + "deleteImported": "Supprimer les messages de la boîte de réception après leur importation" }, "monitoring": { "background_tasks": "Tâches d'arrière-plan", @@ -622,4 +637,4 @@ "send": "Envoyer", "enabled": "Activé", "disabled": "Désactivé" -} \ No newline at end of file +} diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java index 7304e4d9..5061ca5c 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java @@ -81,8 +81,17 @@ public class TestDocumentResource extends BaseJerseyTest { .param("create_date", Long.toString(create1Date))), JsonObject.class); String document1Id = json.getString("id"); Assert.assertNotNull(document1Id); - - // Create a document with document1 + + // Add a file to this document + String file1Id = clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, + document1Token, document1Id); + + // Share this document + target().path("/share").request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token) + .put(Entity.form(new Form().param("id", document1Id)), JsonObject.class); + + // Create another document with document1 json = target().path("/document").request() .cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token) .put(Entity.form(new Form() @@ -92,16 +101,7 @@ public class TestDocumentResource extends BaseJerseyTest { .param("relations", document1Id)), JsonObject.class); String document2Id = json.getString("id"); Assert.assertNotNull(document2Id); - - // Add a file - String file1Id = clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, - document1Token, document1Id); - // Share this document - target().path("/share").request() - .cookie(TokenBasedSecurityFilter.COOKIE_NAME, document1Token) - .put(Entity.form(new Form().param("id", document1Id)), JsonObject.class); - // List all documents json = target().path("/document/list") .queryParam("sort_column", 3) @@ -148,10 +148,19 @@ public class TestDocumentResource extends BaseJerseyTest { String document3Id = json.getString("id"); Assert.assertNotNull(document3Id); - // Add a file + // Add a file to this document clientUtil.addFileToDocument(FILE_EINSTEIN_ROOSEVELT_LETTER_PNG, document3Token, document3Id); + // Create another document with document3 + json = target().path("/document").request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, document3Token) + .put(Entity.form(new Form() + .param("title", "My_super_title_document_4") + .param("language", "eng")), JsonObject.class); + String document4Id = json.getString("id"); + Assert.assertNotNull(document4Id); + // List all documents from document3 json = target().path("/document/list") .queryParam("sort_column", 3) @@ -160,7 +169,7 @@ public class TestDocumentResource extends BaseJerseyTest { .cookie(TokenBasedSecurityFilter.COOKIE_NAME, document3Token) .get(JsonObject.class); documents = json.getJsonArray("documents"); - Assert.assertEquals(1, documents.size()); + Assert.assertEquals(2, documents.size()); // Check highlights json = target().path("/document/list") @@ -216,6 +225,7 @@ public class TestDocumentResource extends BaseJerseyTest { Assert.assertEquals(0, searchDocuments("mime:empty/void", document1Token)); Assert.assertEquals(1, searchDocuments("after:2010 before:2040-08 tag:super shared:yes lang:eng simple:title simple:description full:uranium", document1Token)); Assert.assertEquals(1, searchDocuments("title:My_super_title_document_3", document3Token)); + Assert.assertEquals(2, searchDocuments("title:My_super_title_document_3 title:My_super_title_document_4", document3Token)); // Search documents (nothing) Assert.assertEquals(0, searchDocuments("random", document1Token));