mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 14:07:55 +01:00
#20: Display logs on documents
This commit is contained in:
parent
ea4e3fd8f2
commit
6add34bb33
@ -75,6 +75,7 @@ public class AuditLogDao {
|
||||
if (criteria.getUserId() != null) {
|
||||
StringBuilder sb0 = new StringBuilder(" (l.LOG_IDENTITY_C = :userId and l.LOG_CLASSENTITY_C = 'User' ");
|
||||
sb0.append(" or l.LOG_IDENTITY_C in (select t.TAG_ID_C from T_TAG t where t.TAG_IDUSER_C = :userId) and l.LOG_CLASSENTITY_C = 'Tag' ");
|
||||
// Show only logs from owned documents, ACL are lost on delete
|
||||
sb0.append(" or l.LOG_IDENTITY_C in (select d.DOC_ID_C from T_DOCUMENT d where d.DOC_IDUSER_C = :userId) and l.LOG_CLASSENTITY_C = 'Document') ");
|
||||
criteriaList.add(sb0.toString());
|
||||
parameterMap.put("userId", criteria.getUserId());
|
||||
|
@ -45,7 +45,7 @@ public class AuditLogResource extends BaseResource {
|
||||
}
|
||||
|
||||
// On a document or a user?
|
||||
PaginatedList<AuditLogDto> paginatedList = PaginatedLists.create(100, 0);
|
||||
PaginatedList<AuditLogDto> paginatedList = PaginatedLists.create(20, 0);
|
||||
SortCriteria sortCriteria = new SortCriteria(1, true);
|
||||
AuditLogCriteria criteria = new AuditLogCriteria();
|
||||
if (documentId == null) {
|
||||
|
@ -57,6 +57,7 @@ import com.sismics.rest.exception.ServerException;
|
||||
import com.sismics.rest.util.ValidationUtil;
|
||||
import com.sismics.util.mime.MimeType;
|
||||
import com.sismics.util.mime.MimeTypeUtil;
|
||||
import com.sun.jersey.api.client.ClientResponse.Status;
|
||||
import com.sun.jersey.multipart.FormDataBodyPart;
|
||||
import com.sun.jersey.multipart.FormDataParam;
|
||||
|
||||
@ -417,7 +418,7 @@ public class FileResource extends BaseResource {
|
||||
}
|
||||
}
|
||||
} catch (NoResultException e) {
|
||||
throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", fileId));
|
||||
return Response.status(Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
|
||||
@ -461,7 +462,7 @@ public class FileResource extends BaseResource {
|
||||
}
|
||||
};
|
||||
} catch (Exception e) {
|
||||
throw new ServerException("FileError", "Error while reading the file", e);
|
||||
return Response.status(Status.SERVICE_UNAVAILABLE).build();
|
||||
}
|
||||
|
||||
return Response.ok(stream)
|
||||
|
@ -4,11 +4,18 @@
|
||||
* Document view controller.
|
||||
*/
|
||||
angular.module('docs').controller('DocumentView', function ($scope, $state, $stateParams, $location, $dialog, $modal, Restangular, $upload, $q) {
|
||||
// Load data from server
|
||||
// Load document data from server
|
||||
Restangular.one('document', $stateParams.id).get().then(function(data) {
|
||||
$scope.document = data;
|
||||
});
|
||||
|
||||
// Load audit log data from server
|
||||
Restangular.one('auditlog').get({
|
||||
document: $stateParams.id
|
||||
}).then(function(data) {
|
||||
$scope.logs = data.logs;
|
||||
});
|
||||
|
||||
// Watch for ACLs change and group them for easy displaying
|
||||
$scope.$watch('document.acls', function(acls) {
|
||||
$scope.acls = _.groupBy(acls, function(acl) {
|
||||
|
15
docs-web/src/main/webapp/src/app/docs/directive/AuditLog.js
Normal file
15
docs-web/src/main/webapp/src/app/docs/directive/AuditLog.js
Normal file
@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Audit log directive.
|
||||
*/
|
||||
angular.module('docs').directive('auditLog', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'partial/docs/directive.auditlog.html',
|
||||
replace: true,
|
||||
scope: {
|
||||
logs: '='
|
||||
}
|
||||
}
|
||||
});
|
@ -62,6 +62,7 @@
|
||||
<script src="app/docs/filter/Shorten.js" type="text/javascript"></script>
|
||||
<script src="app/docs/directive/File.js" type="text/javascript"></script>
|
||||
<script src="app/docs/directive/SelectTag.js" type="text/javascript"></script>
|
||||
<script src="app/docs/directive/AuditLog.js" type="text/javascript"></script>
|
||||
<script src="app/docs/directive/InlineEdit.js" type="text/javascript"></script>
|
||||
<!-- endref -->
|
||||
</head>
|
||||
|
@ -0,0 +1,32 @@
|
||||
<table class="table">
|
||||
<tr ng-repeat="log in logs">
|
||||
<td>{{ log.create_date | date: 'yyyy-MM-dd HH:mm' }}</td>
|
||||
<td>
|
||||
{{ log.class }}
|
||||
<span ng-switch="log.type">
|
||||
<span ng-switch-when="CREATE">created</span>
|
||||
<span ng-switch-when="UPDATE">updated</span>
|
||||
<span ng-switch-when="DELETE">deleted</span>
|
||||
</span>
|
||||
|
||||
<span ng-switch="log.class">
|
||||
:
|
||||
<span ng-switch-when="Document">
|
||||
<a ng-href="#/document/view/{{ log.target }}">{{ log.message }}</a>
|
||||
</span>
|
||||
<span ng-switch-when="File">
|
||||
<a ng-href="#/document/view/{{ log.message }}/file/{{ log.target }}">Open</a>
|
||||
</span>
|
||||
<span ng-switch-when="Acl">
|
||||
{{ log.message }}
|
||||
</span>
|
||||
<span ng-switch-when="Tag">
|
||||
<a href="#/tag">{{ log.message }}</a>
|
||||
</span>
|
||||
<span ng-switch-when="User">
|
||||
<a href="#/settings/account">{{ log.message }}</a>
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
@ -1,6 +1,8 @@
|
||||
<img src="img/loader.gif" ng-show="!app" />
|
||||
|
||||
<div ng-show="app">
|
||||
<div class="well">
|
||||
<h3>Quick upload</h3>
|
||||
<div class="row upload-zone" ng-model="dropFiles" ng-file-drop drag-over-class="bg-success"
|
||||
ng-multiple="true" allow-dir="false" accept="image/*,application/pdf,application/zip" ng-file-change="fileDropped($files, $event, $rejectedFiles)">
|
||||
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2 text-center" ng-repeat="file in files">
|
||||
@ -38,19 +40,14 @@
|
||||
<div class="btn-group" ng-show="checkedFiles().length > 0">
|
||||
<button class="btn btn-primary" ng-click="addDocument()"><span class="glyphicon glyphicon-plus"></span> Add to new document</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ui-view="file"></div>
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Message</th>
|
||||
</tr>
|
||||
<tr ng-repeat="log in logs">
|
||||
<td>{{ log.create_date | date: 'yyyy-MM-dd HH:mm' }}</td>
|
||||
<td>{{ log.class }} {{ log.type }} {{ log.message }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="well">
|
||||
<h3>Latest activity</h3>
|
||||
<audit-log logs="logs" />
|
||||
</div>
|
||||
|
||||
<div class="text-muted text-right">
|
||||
<ul class="list-inline">
|
||||
|
@ -135,6 +135,14 @@
|
||||
</form>
|
||||
</div>
|
||||
</tab>
|
||||
|
||||
<tab>
|
||||
<tab-heading class="pointer">
|
||||
<span class="glyphicon glyphicon-tasks"></span> Activity
|
||||
</tab-heading>
|
||||
|
||||
<audit-log logs="logs" />
|
||||
</tab>
|
||||
</tabset>
|
||||
|
||||
<div ui-view="file"></div>
|
||||
|
@ -178,6 +178,12 @@ public class TestFileResource extends BaseJerseyTest {
|
||||
json = response.getEntity(JSONObject.class);
|
||||
Assert.assertEquals("ok", json.getString("status"));
|
||||
|
||||
// Get the file data (not found)
|
||||
fileResource = resource().path("/file/" + file1Id + "/data");
|
||||
fileResource.addFilter(new CookieAuthenticationFilter(file1AuthenticationToken));
|
||||
response = fileResource.get(ClientResponse.class);
|
||||
Assert.assertEquals(Status.NOT_FOUND, Status.fromStatusCode(response.getStatus()));
|
||||
|
||||
// Check that files are deleted from FS
|
||||
storedFile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), file1Id).toFile();
|
||||
java.io.File webFile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), file1Id + "_web").toFile();
|
||||
|
Loading…
Reference in New Issue
Block a user