Closes #256: display version history

This commit is contained in:
Benjamin Gamard 2019-01-31 15:44:58 +01:00
parent 8bdab73ae9
commit a2a3297986
8 changed files with 109 additions and 12 deletions

View File

@ -32,15 +32,16 @@ Features
- Responsive user interface - Responsive user interface
- Optical character recognition - Optical character recognition
- Support image, PDF, ODT, DOCX, PPTX files - Support image, PDF, ODT, DOCX, PPTX files
- Video file support ![New!](https://www.sismics.com/public/img/new.png) - Video file support
- Flexible search engine with suggestions and highlighting - Flexible search engine with suggestions and highlighting
- Full text search in all supported files - Full text search in all supported files
- All [Dublin Core](http://dublincore.org/) metadata - All [Dublin Core](http://dublincore.org/) metadata
- Workflow system ![New!](https://www.sismics.com/public/img/new.png) - Workflow system ![New!](https://www.sismics.com/public/img/new.png)
- 256-bit AES encryption of stored files - 256-bit AES encryption of stored files
- File versioning ![New!](https://www.sismics.com/public/img/new.png)
- Tag system with nesting - Tag system with nesting
- Import document from email (EML format) ![New!](https://www.sismics.com/public/img/new.png) - Import document from email (EML format)
- Automatic inbox scanning and importing ![New!](https://www.sismics.com/public/img/new.png) - Automatic inbox scanning and importing
- User/group permission system - User/group permission system
- 2-factor authentication - 2-factor authentication
- Hierarchical groups - Hierarchical groups
@ -49,9 +50,9 @@ Features
- Storage quota per user - Storage quota per user
- Document sharing by URL - Document sharing by URL
- RESTful Web API - RESTful Web API
- Webhooks to trigger external service ![New!](https://www.sismics.com/public/img/new.png) - Webhooks to trigger external service
- Fully featured Android client - Fully featured Android client
- [Bulk files importer](https://github.com/sismics/docs/tree/master/docs-importer) (single or scan mode) ![New!](https://www.sismics.com/public/img/new.png) - [Bulk files importer](https://github.com/sismics/docs/tree/master/docs-importer) (single or scan mode)
- Tested to one million documents - Tested to one million documents
Install with Docker Install with Docker

View File

@ -64,6 +64,9 @@ angular.module('docs').controller('DocumentViewContent', function ($scope, $root
}); });
}; };
/**
* Upload a new version.
*/
$scope.uploadNewVersion = function (files, file) { $scope.uploadNewVersion = function (files, file) {
if (!$scope.document.writable || !files || files.length === 0) { if (!$scope.document.writable || !files || files.length === 0) {
return; return;
@ -182,4 +185,16 @@ angular.module('docs').controller('DocumentViewContent', function ($scope, $root
file.processing = true; file.processing = true;
}); });
}; };
$scope.openVersions = function (file) {
$uibModal.open({
templateUrl: 'partial/docs/file.versions.html',
controller: 'ModalFileVersions',
resolve: {
file: function () {
return file;
}
}
})
};
}); });

View File

@ -4,17 +4,27 @@
* File modal view controller. * File modal view controller.
*/ */
angular.module('docs').controller('FileModalView', function ($uibModalInstance, $scope, $state, $stateParams, $sce, Restangular, $transitions) { angular.module('docs').controller('FileModalView', function ($uibModalInstance, $scope, $state, $stateParams, $sce, Restangular, $transitions) {
// Load files var setFile = function (files) {
Restangular.one('file/list').get({ id: $stateParams.id }).then(function (data) {
$scope.files = data.files;
// Search current file // Search current file
_.each($scope.files, function (value) { _.each(files, function (value) {
if (value.id === $stateParams.fileId) { if (value.id === $stateParams.fileId) {
$scope.file = value; $scope.file = value;
$scope.trustedFileUrl = $sce.trustAsResourceUrl('../api/file/' + $stateParams.fileId + '/data'); $scope.trustedFileUrl = $sce.trustAsResourceUrl('../api/file/' + $stateParams.fileId + '/data');
} }
}); });
};
// Load files
Restangular.one('file/list').get({ id: $stateParams.id }).then(function (data) {
$scope.files = data.files;
setFile(data.files);
// File not found, maybe it's a version
if (!$scope.file) {
Restangular.one('file/' + $stateParams.fileId + '/versions').get().then(function (data) {
setFile(data.files);
});
}
}); });
/** /**

View File

@ -0,0 +1,18 @@
'use strict';
/**
* Modal file versions controller.
*/
angular.module('docs').controller('ModalFileVersions', function ($scope, $state, $stateParams, $uibModalInstance, Restangular, file) {
Restangular.one('file/' + file.id + '/versions').get().then(function (data) {
$scope.files = data.files;
});
$scope.openFile = function (file) {
$state.go('document.view.content.file', { id: $stateParams.id, fileId: file.id })
};
$scope.close = function() {
$uibModalInstance.close();
};
});

View File

@ -72,6 +72,7 @@
<script src="app/docs/controller/document/FileView.js" type="text/javascript"></script> <script src="app/docs/controller/document/FileView.js" type="text/javascript"></script>
<script src="app/docs/controller/document/FileModalView.js" type="text/javascript"></script> <script src="app/docs/controller/document/FileModalView.js" type="text/javascript"></script>
<script src="app/docs/controller/document/FileRename.js" type="text/javascript"></script> <script src="app/docs/controller/document/FileRename.js" type="text/javascript"></script>
<script src="app/docs/controller/document/ModalFileVersions.js" type="text/javascript"></script>
<script src="app/docs/controller/tag/Tag.js" type="text/javascript"></script> <script src="app/docs/controller/tag/Tag.js" type="text/javascript"></script>
<script src="app/docs/controller/tag/TagEdit.js" type="text/javascript"></script> <script src="app/docs/controller/tag/TagEdit.js" type="text/javascript"></script>
<script src="app/docs/controller/settings/Settings.js" type="text/javascript"></script> <script src="app/docs/controller/settings/Settings.js" type="text/javascript"></script>

View File

@ -119,7 +119,8 @@
"add_files": "Add files", "add_files": "Add files",
"file_processing_indicator": "This file is being processed. Searching will not be available before it is complete.", "file_processing_indicator": "This file is being processed. Searching will not be available before it is complete.",
"reprocess_file": "Reprocess this file", "reprocess_file": "Reprocess this file",
"upload_new_version": "Upload a new version" "upload_new_version": "Upload a new version",
"open_versions": "Show version history"
}, },
"workflow": { "workflow": {
"workflow": "Workflow", "workflow": "Workflow",
@ -204,6 +205,13 @@
"edit": { "edit": {
"title": "Edit file", "title": "Edit file",
"name": "Filename" "name": "Filename"
},
"versions": {
"title": "Version history",
"filename": "Filename",
"mimetype": "Type",
"create_date": "Creation date",
"version": "Version"
} }
}, },
"tag": { "tag": {

View File

@ -68,18 +68,32 @@
<span class="fas fa-pencil-alt"></span> <span class="fas fa-pencil-alt"></span>
{{ 'rename' | translate }} {{ 'rename' | translate }}
</a> </a>
</li>
<li>
<a href ng-click="processFile(file)"> <a href ng-click="processFile(file)">
<span class="fas fa-eye"></span> <span class="fas fa-eye"></span>
{{ 'document.view.content.reprocess_file' | translate }} {{ 'document.view.content.reprocess_file' | translate }}
</a> </a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href ngf-select <a href ngf-select
ngf-change="uploadNewVersion($files, file)" ngf-change="uploadNewVersion($files, file)"
ngf-multiple="false"> ngf-multiple="false">
<span class="fas fa-plus"></span> <span class="fas fa-plus"></span>
{{ 'document.view.content.upload_new_version' | translate }} {{ 'document.view.content.upload_new_version' | translate }}
</a> </a>
</li>
<li>
<a href ng-click="openVersions(file)">
<span class="fas fa-angle-double-left"></span>
{{ 'document.view.content.open_versions' | translate }}
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href ng-click="deleteFile(file)"> <a href ng-click="deleteFile(file)">
<span class="fas fa-trash"></span> <span class="fas fa-trash text-danger"></span>
{{ 'delete' | translate }} {{ 'delete' | translate }}
</a> </a>
</li> </li>

View File

@ -0,0 +1,30 @@
<div class="modal-header">
<h3>{{ 'file.versions.title' | translate }}</h3>
</div>
<div class="modal-body">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>{{ 'file.versions.filename' | translate }}</th>
<th>{{ 'file.versions.mimetype' | translate }}</th>
<th>{{ 'file.versions.create_date' | translate }}</th>
<th>{{ 'file.versions.version' | translate }}</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="file in files">
<td>{{ file.name }}</td>
<td>{{ file.mimetype }}</td>
<td>{{ file.create_date | timeAgo: dateFormat }}</td>
<td>v{{ file.version +1 }}.0</td>
<td>
<span class="fas fa-eye pointer" ng-click="openFile(file)"></span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button ng-click="close()" class="btn btn-default">{{ 'close' | translate }}</button>
</div>