mirror of
https://github.com/sismics/docs.git
synced 2024-11-25 07:07:57 +01:00
Search on creation date (server), edit creation date (client)
This commit is contained in:
parent
a8b9148359
commit
871e531c4b
@ -41,7 +41,6 @@ public class DocumentDao {
|
||||
|
||||
// Create the document
|
||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||
document.setCreateDate(new Date());
|
||||
em.persist(document);
|
||||
|
||||
return document.getId();
|
||||
@ -121,11 +120,18 @@ public class DocumentDao {
|
||||
criteriaList.add("d.DOC_IDUSER_C = :userId");
|
||||
parameterMap.put("userId", criteria.getUserId());
|
||||
}
|
||||
|
||||
if (criteria.getSearch() != null) {
|
||||
criteriaList.add("(d.DOC_TITLE_C LIKE :search OR d.DOC_DESCRIPTION_C LIKE :search)");
|
||||
parameterMap.put("search", "%" + criteria.getSearch() + "%");
|
||||
}
|
||||
if (criteria.getCreateDateMin() != null) {
|
||||
criteriaList.add("d.DOC_CREATEDATE_D >= :createDateMin");
|
||||
parameterMap.put("createDateMin", criteria.getCreateDateMin());
|
||||
}
|
||||
if (criteria.getCreateDateMax() != null) {
|
||||
criteriaList.add("d.DOC_CREATEDATE_D <= :createDateMax");
|
||||
parameterMap.put("createDateMax", criteria.getCreateDateMax());
|
||||
}
|
||||
|
||||
criteriaList.add("d.DOC_DELETEDATE_D is null");
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.sismics.docs.core.dao.jpa.criteria;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* Document criteria.
|
||||
@ -17,6 +19,16 @@ public class DocumentCriteria {
|
||||
*/
|
||||
private String search;
|
||||
|
||||
/**
|
||||
* Minimum creation date.
|
||||
*/
|
||||
private Date createDateMin;
|
||||
|
||||
/**
|
||||
* Maximum creation date.
|
||||
*/
|
||||
private Date createDateMax;
|
||||
|
||||
/**
|
||||
* Getter of userId.
|
||||
*
|
||||
@ -52,4 +64,40 @@ public class DocumentCriteria {
|
||||
public void setSearch(String search) {
|
||||
this.search = search;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of createDateMin.
|
||||
*
|
||||
* @return the createDateMin
|
||||
*/
|
||||
public Date getCreateDateMin() {
|
||||
return createDateMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of createDateMin.
|
||||
*
|
||||
* @param createDateMin createDateMin
|
||||
*/
|
||||
public void setCreateDateMin(Date createDateMin) {
|
||||
this.createDateMin = createDateMin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter of createDateMax.
|
||||
*
|
||||
* @return the createDateMax
|
||||
*/
|
||||
public Date getCreateDateMax() {
|
||||
return createDateMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter of createDateMax.
|
||||
*
|
||||
* @param createDateMax createDateMax
|
||||
*/
|
||||
public void setCreateDateMax(Date createDateMax) {
|
||||
this.createDateMax = createDateMax;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
- Client/server side edition of created date
|
||||
- Client/server side search on tags
|
||||
- Client/server side search on creation date
|
||||
- Client side search on creation date
|
||||
- Client/server side edition of existing tag names
|
||||
- Server side reordering files
|
@ -2,6 +2,7 @@ package com.sismics.docs.rest.resource;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -105,11 +106,17 @@ public class DocumentResource extends BaseResource {
|
||||
@QueryParam("offset") Integer offset,
|
||||
@QueryParam("sort_column") Integer sortColumn,
|
||||
@QueryParam("asc") Boolean asc,
|
||||
@QueryParam("search") String search) throws JSONException {
|
||||
@QueryParam("search") String search,
|
||||
@QueryParam("create_date_min") String createDateMinStr,
|
||||
@QueryParam("create_date_max") String createDateMaxStr) throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
// Validate input data
|
||||
Date createDateMin = ValidationUtil.validateDate(createDateMinStr, "create_date_min", true);
|
||||
Date createDateMax = ValidationUtil.validateDate(createDateMaxStr, "create_date_max", true);
|
||||
|
||||
JSONObject response = new JSONObject();
|
||||
List<JSONObject> documents = new ArrayList<JSONObject>();
|
||||
|
||||
@ -118,6 +125,8 @@ public class DocumentResource extends BaseResource {
|
||||
SortCriteria sortCriteria = new SortCriteria(sortColumn, asc);
|
||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||
documentCriteria.setUserId(principal.getId());
|
||||
documentCriteria.setCreateDateMin(createDateMin);
|
||||
documentCriteria.setCreateDateMax(createDateMax);
|
||||
if (!Strings.isNullOrEmpty(search)) {
|
||||
documentCriteria.setSearch(search);
|
||||
}
|
||||
@ -150,7 +159,8 @@ public class DocumentResource extends BaseResource {
|
||||
public Response add(
|
||||
@FormParam("title") String title,
|
||||
@FormParam("description") String description,
|
||||
@FormParam("tags[]") List<String> tagList) throws JSONException {
|
||||
@FormParam("tags[]") List<String> tagList,
|
||||
@FormParam("create_date") String createDateStr) throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
@ -158,6 +168,7 @@ public class DocumentResource extends BaseResource {
|
||||
// Validate input data
|
||||
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
||||
description = ValidationUtil.validateLength(description, "description", 0, 4000, true);
|
||||
Date createDate = ValidationUtil.validateDate(createDateStr, "create_date", true);
|
||||
|
||||
// Create the document
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
@ -165,6 +176,11 @@ public class DocumentResource extends BaseResource {
|
||||
document.setUserId(principal.getId());
|
||||
document.setTitle(title);
|
||||
document.setDescription(description);
|
||||
if (createDate == null) {
|
||||
document.setCreateDate(new Date());
|
||||
} else {
|
||||
document.setCreateDate(createDate);
|
||||
}
|
||||
String documentId = documentDao.create(document);
|
||||
|
||||
// Update tags
|
||||
@ -190,7 +206,8 @@ public class DocumentResource extends BaseResource {
|
||||
@PathParam("id") String id,
|
||||
@FormParam("title") String title,
|
||||
@FormParam("description") String description,
|
||||
@FormParam("tags[]") List<String> tagList) throws JSONException {
|
||||
@FormParam("tags[]") List<String> tagList,
|
||||
@FormParam("create_date") String createDateStr) throws JSONException {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
@ -198,6 +215,7 @@ public class DocumentResource extends BaseResource {
|
||||
// Validate input data
|
||||
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
||||
description = ValidationUtil.validateLength(description, "description", 0, 4000, true);
|
||||
Date createDate = ValidationUtil.validateDate(createDateStr, "create_date", true);
|
||||
|
||||
// Get the document
|
||||
DocumentDao documentDao = new DocumentDao();
|
||||
@ -215,6 +233,9 @@ public class DocumentResource extends BaseResource {
|
||||
if (description != null) {
|
||||
document.setDescription(description);
|
||||
}
|
||||
if (createDate != null) {
|
||||
document.setCreateDate(createDate);
|
||||
}
|
||||
|
||||
// Update tags
|
||||
updateTagList(id, tagList);
|
||||
|
@ -26,6 +26,9 @@ App.controller('DocumentEdit', function($scope, $q, $http, $state, $stateParams,
|
||||
$scope.edit = function() {
|
||||
var promise = null;
|
||||
var document = angular.copy($scope.document);
|
||||
if (document.create_date instanceof Date) {
|
||||
document.create_date = document.create_date.getTime();
|
||||
}
|
||||
|
||||
// Extract ids from tags
|
||||
document.tags = _.pluck(document.tags, 'id');
|
||||
|
@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Document view controller.
|
||||
*/
|
||||
App.controller('DocumentView', function($rootScope, $scope, $state, $stateParams, $dialog, Restangular) {
|
||||
App.controller('DocumentView', function($scope, $state, $stateParams, $dialog, Restangular) {
|
||||
// Load data from server
|
||||
$scope.document = Restangular.one('document', $stateParams.id).get();
|
||||
|
||||
@ -25,7 +25,7 @@ App.controller('DocumentView', function($rootScope, $scope, $state, $stateParams
|
||||
*/
|
||||
$scope.loadFiles = function() {
|
||||
Restangular.one('file').getList('list', { id: $stateParams.id }).then(function(data) {
|
||||
$rootScope.files = data.files;
|
||||
$scope.files = data.files;
|
||||
});
|
||||
};
|
||||
$scope.loadFiles();
|
||||
|
@ -7,23 +7,28 @@ App.controller('FileView', function($dialog, $state, $stateParams) {
|
||||
var dialog = $dialog.dialog({
|
||||
keyboard: true,
|
||||
templateUrl: 'partial/file.view.html',
|
||||
controller: function($rootScope, $scope, $state, $stateParams) {
|
||||
controller: function($scope, $state, $stateParams, Restangular) {
|
||||
$scope.id = $stateParams.fileId;
|
||||
|
||||
// Search current file
|
||||
_.each($rootScope.files, function(value, key, list) {
|
||||
if (value.id == $scope.id) {
|
||||
$scope.file = value;
|
||||
}
|
||||
// Load files
|
||||
Restangular.one('file').getList('list', { id: $stateParams.id }).then(function(data) {
|
||||
$scope.files = data.files;
|
||||
|
||||
// Search current file
|
||||
_.each($scope.files, function(value, key, list) {
|
||||
if (value.id == $scope.id) {
|
||||
$scope.file = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Navigate to the next file.
|
||||
*/
|
||||
$scope.nextFile = function() {
|
||||
_.each($rootScope.files, function(value, key, list) {
|
||||
_.each($scope.files, function(value, key, list) {
|
||||
if (value.id == $scope.id) {
|
||||
var next = $rootScope.files[key + 1];
|
||||
var next = $scope.files[key + 1];
|
||||
if (next) {
|
||||
dialog.close({});
|
||||
$state.transitionTo('document.view.file', { id: $stateParams.id, fileId: next.id });
|
||||
@ -36,9 +41,9 @@ App.controller('FileView', function($dialog, $state, $stateParams) {
|
||||
* Navigate to the previous file.
|
||||
*/
|
||||
$scope.previousFile = function() {
|
||||
_.each($rootScope.files, function(value, key, list) {
|
||||
_.each($scope.files, function(value, key, list) {
|
||||
if (value.id == $scope.id) {
|
||||
var previous = $rootScope.files[key - 1];
|
||||
var previous = $scope.files[key - 1];
|
||||
if (previous) {
|
||||
dialog.close({});
|
||||
$state.transitionTo('document.view.file', { id: $stateParams.id, fileId: previous.id });
|
||||
|
@ -3,9 +3,10 @@
|
||||
/**
|
||||
* Login controller.
|
||||
*/
|
||||
App.controller('Login', function($scope, $state, $dialog, User) {
|
||||
App.controller('Login', function($scope, $rootScope, $state, $dialog, User) {
|
||||
$scope.login = function() {
|
||||
User.login($scope.user).then(function() {
|
||||
$rootScope.userInfo = User.userInfo(true);
|
||||
$state.transitionTo('document.default');
|
||||
}, function() {
|
||||
var title = 'Login failed';
|
||||
|
@ -3,6 +3,6 @@
|
||||
/**
|
||||
* Navigation controller.
|
||||
*/
|
||||
App.controller('Navigation', function($scope, User) {
|
||||
$scope.userInfo = User.userInfo();
|
||||
App.controller('Navigation', function($scope, $rootScope, User) {
|
||||
$rootScope.userInfo = User.userInfo();
|
||||
});
|
@ -12,17 +12,7 @@ App.factory('Tag', function(Restangular) {
|
||||
* @param force If true, force reloading data
|
||||
*/
|
||||
tags: function(force) {
|
||||
if (tags == null || force) {
|
||||
tags = Restangular.one('tag/list').get();
|
||||
}
|
||||
return tags;
|
||||
},
|
||||
|
||||
/**
|
||||
* Login an user.
|
||||
*/
|
||||
login: function(user) {
|
||||
return Restangular.one('user').post('login', user);
|
||||
return Restangular.one('tag/list').get();
|
||||
}
|
||||
}
|
||||
});
|
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,12 @@
|
||||
<textarea ng-maxlength="4000" class="input-block-level" rows="5" id="inputDescription" name="description" ng-model="document.description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputCreateDate">Creation date</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="inputCreateDate" datepicker-popup="yyyy-MM-dd" ng-model="document.create_date" starting-day="1" show-weeks="false" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputFiles">New files</label>
|
||||
<div class="controls">
|
||||
|
@ -18,7 +18,7 @@
|
||||
<tbody>
|
||||
<tr ng-click="viewDocument(document.id)" ng-repeat="document in documents.documents">
|
||||
<td>{{ document.title }}</td>
|
||||
<td>{{ document.create_date | date: 'short' }}</td>
|
||||
<td>{{ document.create_date | date: 'yyyy-MM-dd' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -6,7 +6,7 @@
|
||||
</div>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>{{ document.title }} <small>{{ document.create_date | date: 'short' }}</small></h1>
|
||||
<h1>{{ document.title }} <small>{{ document.create_date | date: 'yyyy-MM-dd' }}</small></h1>
|
||||
<ul class="inline">
|
||||
<li ng-repeat="tag in document.tags"><span class="label label-info">{{ tag.name }}</span></li>
|
||||
</ul>
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.sismics.docs.rest;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.codehaus.jettison.json.JSONArray;
|
||||
@ -48,6 +51,8 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
postParams.add("title", "My super document 1");
|
||||
postParams.add("description", "My super description for document 1");
|
||||
postParams.add("tags[]", tag1Id);
|
||||
long create1Date = new Date().getTime();
|
||||
postParams.add("create_date", create1Date);
|
||||
response = documentResource.put(ClientResponse.class, postParams);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.getEntity(JSONObject.class);
|
||||
@ -67,7 +72,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
Assert.assertTrue(documents.length() == 1);
|
||||
Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id"));
|
||||
|
||||
// Search documents
|
||||
// Search documents by query
|
||||
documentResource = resource().path("/document/list");
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||
getParams = new MultivaluedMapImpl();
|
||||
@ -78,6 +83,20 @@ public class TestDocumentResource extends BaseJerseyTest {
|
||||
documents = json.getJSONArray("documents");
|
||||
Assert.assertTrue(documents.length() == 1);
|
||||
Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id"));
|
||||
Assert.assertEquals(create1Date, documents.getJSONObject(0).getLong("create_date"));
|
||||
|
||||
// Search documents by date
|
||||
documentResource = resource().path("/document/list");
|
||||
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||
getParams = new MultivaluedMapImpl();
|
||||
getParams.putSingle("create_date_min", create1Date - 3600000);
|
||||
getParams.putSingle("create_date_max", create1Date + 1800000);
|
||||
response = documentResource.queryParams(getParams).get(ClientResponse.class);
|
||||
json = response.getEntity(JSONObject.class);
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
documents = json.getJSONArray("documents");
|
||||
Assert.assertTrue(documents.length() == 1);
|
||||
Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id"));
|
||||
|
||||
// Search documents (nothing)
|
||||
documentResource = resource().path("/document/list");
|
||||
|
Loading…
Reference in New Issue
Block a user