Used worker for pdf generation.
Moved pdfmake.createPdf() into a web worker thread to prevent blocking UI and max_script_runtime error in browser. Used gulp to manage separate worker files (pdf-worker and pdf-worker-lib).
This commit is contained in:
parent
872f05ec31
commit
e1b4c1fc68
@ -18,6 +18,7 @@ Core:
|
|||||||
- Added control for the resolution of the projectors.
|
- Added control for the resolution of the projectors.
|
||||||
- Set the projector language in the settings.
|
- Set the projector language in the settings.
|
||||||
- Used pdfMake for clientside generation of PDFs.
|
- Used pdfMake for clientside generation of PDFs.
|
||||||
|
Run pdf creation in background (in a web worker thread).
|
||||||
- Introduced new table design for list views with serveral filters and
|
- Introduced new table design for list views with serveral filters and
|
||||||
CSV export.
|
CSV export.
|
||||||
- Used session cookies and store filter settings in session storage.
|
- Used session cookies and store filter settings in session storage.
|
||||||
|
@ -39,10 +39,7 @@
|
|||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"pdfmake": {
|
"pdfmake": {
|
||||||
"main": [
|
"main": []
|
||||||
"build/pdfmake.js",
|
|
||||||
"build/vfs_fonts.js"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"pdfjs-dist": {
|
"pdfjs-dist": {
|
||||||
"main": "build/pdf.combined.js"
|
"main": "build/pdf.combined.js"
|
||||||
|
27
gulpfile.js
27
gulpfile.js
@ -41,10 +41,13 @@ var output_directory = path.join('openslides', 'static');
|
|||||||
* Default tasks to be run before start.
|
* Default tasks to be run before start.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Catches all JavaScript files from all core apps and concats them to one
|
// Catches all JavaScript files (excluded worker files) from all core apps and concats them to one
|
||||||
// file js/openslides.js. In production mode the file is uglified.
|
// file js/openslides.js. In production mode the file is uglified.
|
||||||
gulp.task('js', function () {
|
gulp.task('js', function () {
|
||||||
return gulp.src(path.join('openslides', '*', 'static', 'js', '**', '*.js'))
|
return gulp.src([
|
||||||
|
path.join('openslides', '*', 'static', 'js', '**', '*.js'),
|
||||||
|
'!' + path.join('openslides', 'core', 'static', 'js', 'core', 'pdf-worker.js'),
|
||||||
|
])
|
||||||
.pipe(sourcemaps.init())
|
.pipe(sourcemaps.init())
|
||||||
.pipe(concat('openslides.js'))
|
.pipe(concat('openslides.js'))
|
||||||
.pipe(sourcemaps.write())
|
.pipe(sourcemaps.write())
|
||||||
@ -68,6 +71,24 @@ gulp.task('js-libs', function () {
|
|||||||
.pipe(gulp.dest(path.join(output_directory, 'js')));
|
.pipe(gulp.dest(path.join(output_directory, 'js')));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Catches all pdfmake files for pdf worker.
|
||||||
|
gulp.task('pdf-worker', function () {
|
||||||
|
return gulp.src([
|
||||||
|
path.join('openslides', 'core', 'static', 'js', 'core', 'pdf-worker.js'),
|
||||||
|
])
|
||||||
|
.pipe(gulpif(argv.production, uglify()))
|
||||||
|
.pipe(gulp.dest(path.join(output_directory, 'js', 'workers')));
|
||||||
|
});
|
||||||
|
// pdfmake files
|
||||||
|
gulp.task('pdf-worker-libs', function () {
|
||||||
|
return gulp.src([
|
||||||
|
path.join('bower_components', 'pdfmake', 'build', 'pdfmake.min.js'),
|
||||||
|
path.join('bower_components', 'pdfmake', 'build', 'vfs_fonts.js'),
|
||||||
|
])
|
||||||
|
.pipe(concat('pdf-worker-libs.js'))
|
||||||
|
.pipe(gulp.dest(path.join(output_directory, 'js', 'workers')));
|
||||||
|
});
|
||||||
|
|
||||||
// Catches all template files from all core apps and concats them to one
|
// Catches all template files from all core apps and concats them to one
|
||||||
// file js/openslides-templates.js. In production mode the file is uglified.
|
// file js/openslides-templates.js. In production mode the file is uglified.
|
||||||
gulp.task('templates', function () {
|
gulp.task('templates', function () {
|
||||||
@ -191,6 +212,8 @@ gulp.task('translations', function () {
|
|||||||
gulp.task('default', [
|
gulp.task('default', [
|
||||||
'js',
|
'js',
|
||||||
'js-libs',
|
'js-libs',
|
||||||
|
'pdf-worker',
|
||||||
|
'pdf-worker-libs',
|
||||||
'templates',
|
'templates',
|
||||||
'css-libs',
|
'css-libs',
|
||||||
'fonts-libs',
|
'fonts-libs',
|
||||||
|
@ -82,9 +82,10 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
'gettext',
|
'gettext',
|
||||||
'osTableFilter',
|
'osTableFilter',
|
||||||
'AgendaCsvExport',
|
'AgendaCsvExport',
|
||||||
|
'PdfCreate',
|
||||||
function($scope, $filter, $http, $state, DS, operator, ngDialog, Agenda, TopicForm, AgendaTree, Projector,
|
function($scope, $filter, $http, $state, DS, operator, ngDialog, Agenda, TopicForm, AgendaTree, Projector,
|
||||||
ProjectionDefault, AgendaContentProvider, PdfMakeDocumentProvider, gettextCatalog, gettext, osTableFilter,
|
ProjectionDefault, AgendaContentProvider, PdfMakeDocumentProvider, gettextCatalog, gettext, osTableFilter,
|
||||||
AgendaCsvExport) {
|
AgendaCsvExport, PdfCreate) {
|
||||||
// Bind agenda tree to the scope
|
// Bind agenda tree to the scope
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
return Agenda.lastModified();
|
return Agenda.lastModified();
|
||||||
@ -266,7 +267,7 @@ angular.module('OpenSlidesApp.agenda.site', [
|
|||||||
var filename = gettextCatalog.getString('Agenda') + '.pdf';
|
var filename = gettextCatalog.getString('Agenda') + '.pdf';
|
||||||
var agendaContentProvider = AgendaContentProvider.createInstance($scope.itemsFiltered);
|
var agendaContentProvider = AgendaContentProvider.createInstance($scope.itemsFiltered);
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(agendaContentProvider);
|
var documentProvider = PdfMakeDocumentProvider.createInstance(agendaContentProvider);
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
};
|
};
|
||||||
$scope.csvExport = function () {
|
$scope.csvExport = function () {
|
||||||
var element = document.getElementById('downloadLinkCSV');
|
var element = document.getElementById('downloadLinkCSV');
|
||||||
|
@ -264,9 +264,10 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
'osTableSort',
|
'osTableSort',
|
||||||
'gettext',
|
'gettext',
|
||||||
'phases',
|
'phases',
|
||||||
|
'PdfCreate',
|
||||||
function($scope, ngDialog, AssignmentForm, Assignment, Tag, Agenda, Projector, ProjectionDefault,
|
function($scope, ngDialog, AssignmentForm, Assignment, Tag, Agenda, Projector, ProjectionDefault,
|
||||||
gettextCatalog, AssignmentContentProvider, AssignmentCatalogContentProvider, PdfMakeDocumentProvider,
|
gettextCatalog, AssignmentContentProvider, AssignmentCatalogContentProvider, PdfMakeDocumentProvider,
|
||||||
User, osTableFilter, osTableSort, gettext, phases) {
|
User, osTableFilter, osTableSort, gettext, phases, PdfCreate) {
|
||||||
Assignment.bindAll({}, $scope, 'assignments');
|
Assignment.bindAll({}, $scope, 'assignments');
|
||||||
Tag.bindAll({}, $scope, 'tags');
|
Tag.bindAll({}, $scope, 'tags');
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
@ -386,7 +387,7 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
AssignmentCatalogContentProvider.createInstance(assignmentContentProviderArray);
|
AssignmentCatalogContentProvider.createInstance(assignmentContentProviderArray);
|
||||||
var documentProvider =
|
var documentProvider =
|
||||||
PdfMakeDocumentProvider.createInstance(assignmentCatalogContentProvider);
|
PdfMakeDocumentProvider.createInstance(assignmentCatalogContentProvider);
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
@ -411,9 +412,10 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
'PdfMakeDocumentProvider',
|
'PdfMakeDocumentProvider',
|
||||||
'PdfMakeBallotPaperProvider',
|
'PdfMakeBallotPaperProvider',
|
||||||
'gettextCatalog',
|
'gettextCatalog',
|
||||||
|
'PdfCreate',
|
||||||
function($scope, $http, $filter, filterFilter, gettext, ngDialog, AssignmentForm, operator, Assignment,
|
function($scope, $http, $filter, filterFilter, gettext, ngDialog, AssignmentForm, operator, Assignment,
|
||||||
User, assignmentId, phases, Projector, ProjectionDefault, AssignmentContentProvider, BallotContentProvider,
|
User, assignmentId, phases, Projector, ProjectionDefault, AssignmentContentProvider, BallotContentProvider,
|
||||||
PdfMakeDocumentProvider, PdfMakeBallotPaperProvider, gettextCatalog) {
|
PdfMakeDocumentProvider, PdfMakeBallotPaperProvider, gettextCatalog, PdfCreate) {
|
||||||
var assignment = Assignment.get(assignmentId);
|
var assignment = Assignment.get(assignmentId);
|
||||||
User.bindAll({}, $scope, 'users');
|
User.bindAll({}, $scope, 'users');
|
||||||
Assignment.loadRelations(assignment, 'agenda_item');
|
Assignment.loadRelations(assignment, 'agenda_item');
|
||||||
@ -593,7 +595,7 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
var filename = gettextCatalog.getString("Election") + "_" + $scope.assignment.title + ".pdf";
|
var filename = gettextCatalog.getString("Election") + "_" + $scope.assignment.title + ".pdf";
|
||||||
var assignmentContentProvider = AssignmentContentProvider.createInstance(assignment);
|
var assignmentContentProvider = AssignmentContentProvider.createInstance(assignment);
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(assignmentContentProvider);
|
var documentProvider = PdfMakeDocumentProvider.createInstance(assignmentContentProvider);
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
//creates the ballotpaper as pdf
|
//creates the ballotpaper as pdf
|
||||||
@ -609,7 +611,7 @@ angular.module('OpenSlidesApp.assignments.site', [
|
|||||||
var filename = gettextCatalog.getString("Ballot") + "_" + pollNumber + "_" + $scope.assignment.title + ".pdf";
|
var filename = gettextCatalog.getString("Ballot") + "_" + pollNumber + "_" + $scope.assignment.title + ".pdf";
|
||||||
var ballotContentProvider = BallotContentProvider.createInstance($scope, thePoll, pollNumber);
|
var ballotContentProvider = BallotContentProvider.createInstance($scope, thePoll, pollNumber);
|
||||||
var documentProvider = PdfMakeBallotPaperProvider.createInstance(ballotContentProvider);
|
var documentProvider = PdfMakeBallotPaperProvider.createInstance(ballotContentProvider);
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Just mark some vote value strings for translation.
|
// Just mark some vote value strings for translation.
|
||||||
|
@ -1133,6 +1133,39 @@ img {
|
|||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Pdf creation status bar **/
|
||||||
|
#pdf-status {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
#pdf-status-container {
|
||||||
|
margin: 0 auto 0 auto;
|
||||||
|
padding: 0px 20px;
|
||||||
|
max-width: 1400px;
|
||||||
|
}
|
||||||
|
#pdf-status-container > div {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||||
|
}
|
||||||
|
#pdf-status .generating {
|
||||||
|
color: #222;
|
||||||
|
background-color: #bed4de;
|
||||||
|
border-color: #46b8da;
|
||||||
|
}
|
||||||
|
#pdf-status .error {
|
||||||
|
color: #a94442;
|
||||||
|
background-color: #f2dede;
|
||||||
|
border-color: #ebccd1;
|
||||||
|
}
|
||||||
|
#pdf-status .finished {
|
||||||
|
color: #3c763d;
|
||||||
|
background-color: #dff0d8;
|
||||||
|
border-color: #d6e9c6;
|
||||||
|
}
|
||||||
|
|
||||||
/** General helper classes **/
|
/** General helper classes **/
|
||||||
|
|
||||||
|
37
openslides/core/static/js/core/pdf-worker.js
Normal file
37
openslides/core/static/js/core/pdf-worker.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* Worker for creating PDFs in a separate thread. The creation of larger PDFs
|
||||||
|
* needs (currently) a lot of time and we don't want to block the UI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Setup fake environment for pdfMake
|
||||||
|
var document = {
|
||||||
|
'createElementNS': function () {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var window = this;
|
||||||
|
|
||||||
|
// PdfMake and Fonts
|
||||||
|
importScripts('/static/js/workers/pdf-worker-libs.js');
|
||||||
|
|
||||||
|
// Set default font family.
|
||||||
|
// To use custom ttf font files you have to replace the vfs_fonts.js file.
|
||||||
|
// See https://github.com/pdfmake/pdfmake/wiki/Custom-Fonts---client-side
|
||||||
|
// "PdfFont" is used as generic name in core/pdf.js. Adjust the four
|
||||||
|
// font style names only.
|
||||||
|
pdfMake.fonts = {
|
||||||
|
PdfFont: {
|
||||||
|
normal: 'Roboto-Regular.ttf',
|
||||||
|
bold: 'Roboto-Medium.ttf',
|
||||||
|
italics: 'Roboto-Italic.ttf',
|
||||||
|
bolditalics: 'Roboto-Italic.ttf'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create PDF on message and return the base64 decoded document
|
||||||
|
self.addEventListener('message', function(e) {
|
||||||
|
var data = JSON.parse(e.data);
|
||||||
|
var pdf = pdfMake.createPdf(data);
|
||||||
|
pdf.getBase64(function (base64) {
|
||||||
|
self.postMessage(base64);
|
||||||
|
});
|
||||||
|
}, false);
|
@ -15,22 +15,6 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
size: 8
|
size: 8
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set and return default font family.
|
|
||||||
//
|
|
||||||
// To use custom ttf font files you have to replace the vfs_fonts.js file.
|
|
||||||
// See https://github.com/pdfmake/pdfmake/wiki/Custom-Fonts---client-side
|
|
||||||
PDFLayout.getFontName = function() {
|
|
||||||
pdfMake.fonts = {
|
|
||||||
Roboto: {
|
|
||||||
normal: 'Roboto-Regular.ttf',
|
|
||||||
bold: 'Roboto-Medium.ttf',
|
|
||||||
italics: 'Roboto-Italic.ttf',
|
|
||||||
bolditalics: 'Roboto-Italic.ttf'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return "Roboto";
|
|
||||||
};
|
|
||||||
|
|
||||||
// page title
|
// page title
|
||||||
PDFLayout.createTitle = function(title) {
|
PDFLayout.createTitle = function(title) {
|
||||||
return {
|
return {
|
||||||
@ -229,7 +213,7 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
pageSize: 'A4',
|
pageSize: 'A4',
|
||||||
pageMargins: [80, 90, 80, 60],
|
pageMargins: [80, 90, 80, 60],
|
||||||
defaultStyle: {
|
defaultStyle: {
|
||||||
font: PDFLayout.getFontName(),
|
font: 'PdfFont',
|
||||||
fontSize: 10
|
fontSize: 10
|
||||||
},
|
},
|
||||||
header: header,
|
header: header,
|
||||||
@ -353,7 +337,7 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
pageSize: 'A4',
|
pageSize: 'A4',
|
||||||
pageMargins: [0, 0, 0, 0],
|
pageMargins: [0, 0, 0, 0],
|
||||||
defaultStyle: {
|
defaultStyle: {
|
||||||
font: PDFLayout.getFontName(),
|
font: 'PdfFont',
|
||||||
fontSize: 10
|
fontSize: 10
|
||||||
},
|
},
|
||||||
content: content,
|
content: content,
|
||||||
@ -387,9 +371,8 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
* Converter component for HTML->JSON for pdfMake
|
* Converter component for HTML->JSON for pdfMake
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {object} images - Key-Value structure representing image.src/BASE64 of images
|
* @param {object} images - Key-Value structure representing image.src/BASE64 of images
|
||||||
* @param {object} pdfMake - the converter component enhances pdfMake
|
|
||||||
*/
|
*/
|
||||||
var createInstance = function(images, pdfMake) {
|
var createInstance = function(images) {
|
||||||
var slice = Function.prototype.call.bind([].slice),
|
var slice = Function.prototype.call.bind([].slice),
|
||||||
map = Function.prototype.call.bind([].map),
|
map = Function.prototype.call.bind([].map),
|
||||||
|
|
||||||
@ -820,6 +803,82 @@ angular.module('OpenSlidesApp.core.pdf', [])
|
|||||||
return {
|
return {
|
||||||
createInstance: createInstance
|
createInstance: createInstance
|
||||||
};
|
};
|
||||||
}]);
|
}])
|
||||||
|
|
||||||
|
.factory('PdfCreate', [
|
||||||
|
'$timeout',
|
||||||
|
'FileSaver',
|
||||||
|
function ($timeout, FileSaver) {
|
||||||
|
var stateChangeCallbacks = [];
|
||||||
|
var b64toBlob = function(b64Data) {
|
||||||
|
var byteCharacters = atob(b64Data);
|
||||||
|
var byteNumbers = new Array(byteCharacters.length);
|
||||||
|
for (var i = 0; i < byteCharacters.length; i++) {
|
||||||
|
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
||||||
|
}
|
||||||
|
var byteArray = new Uint8Array(byteNumbers);
|
||||||
|
var blob = new Blob([byteArray]);
|
||||||
|
return blob;
|
||||||
|
};
|
||||||
|
var stateChange = function (state, filename, error) {
|
||||||
|
_.forEach(stateChangeCallbacks, function (cb) {
|
||||||
|
$timeout(function () {cb(state, filename, error);}, 1);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
download: function (pdfDocument, filename) {
|
||||||
|
stateChange('generating', filename);
|
||||||
|
var pdfWorker = new Worker('/static/js/workers/pdf-worker.js');
|
||||||
|
|
||||||
|
pdfWorker.addEventListener('message', function (event) {
|
||||||
|
var blob = b64toBlob(event.data);
|
||||||
|
stateChange('finished', filename);
|
||||||
|
FileSaver.saveAs(blob, filename);
|
||||||
|
});
|
||||||
|
pdfWorker.addEventListener('error', function (event) {
|
||||||
|
stateChange('error', filename, event.message);
|
||||||
|
});
|
||||||
|
pdfWorker.postMessage(JSON.stringify(pdfDocument));
|
||||||
|
},
|
||||||
|
registerStateChangeCallback: function (cb) {
|
||||||
|
if (cb && typeof cb === 'function') {
|
||||||
|
stateChangeCallbacks.push(cb);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
.directive('pdfGenerationStatus', [
|
||||||
|
'$timeout',
|
||||||
|
'PdfCreate',
|
||||||
|
function($timeout, PdfCreate) {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
templateUrl: 'static/templates/pdf-status.html',
|
||||||
|
scope: {},
|
||||||
|
controller: function ($scope, $element, $attrs, $location) {
|
||||||
|
$scope.pdfs = {};
|
||||||
|
|
||||||
|
var createStateChange = function (state, filename, error) {
|
||||||
|
$scope.pdfs[filename] = {
|
||||||
|
state: state,
|
||||||
|
errorMessage: error
|
||||||
|
};
|
||||||
|
if (state === 'finished') {
|
||||||
|
$timeout(function () {
|
||||||
|
$scope.close(filename);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PdfCreate.registerStateChangeCallback(createStateChange);
|
||||||
|
|
||||||
|
$scope.close = function (filename) {
|
||||||
|
delete $scope.pdfs[filename];
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
@ -212,6 +212,8 @@
|
|||||||
</div><!--end content-container-->
|
</div><!--end content-container-->
|
||||||
</div><!--end content-->
|
</div><!--end content-->
|
||||||
|
|
||||||
|
<pdf-generation-status></pdf-generation-status>
|
||||||
|
|
||||||
</div><!--end wrapper-->
|
</div><!--end wrapper-->
|
||||||
|
|
||||||
<script src="/webclient/site/"></script>
|
<script src="/webclient/site/"></script>
|
||||||
|
24
openslides/core/static/templates/pdf-status.html
Normal file
24
openslides/core/static/templates/pdf-status.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<div id="pdf-status">
|
||||||
|
<div id="pdf-status-container">
|
||||||
|
<div ng-repeat="(filename, pdf) in pdfs" ng-class="pdf.state">
|
||||||
|
|
||||||
|
<span class="close fa fa-times fa-lg" ng-click="close(filename)"></span>
|
||||||
|
<span ng-if="pdf.state === 'generating'">
|
||||||
|
<i class="fa fa-spinner fa-pulse fa-lg spacer-right"></i>
|
||||||
|
<translate>Generating PDF file {{ filename }} ...</translate>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span ng-if="pdf.state === 'finished'">
|
||||||
|
<i class="fa fa-check fa-lg spacer-right"></i>
|
||||||
|
<translate>PDF successfully generated.</translate>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span ng-if="pdf.state === 'error'">
|
||||||
|
<i class="fa fa-exclamation-triangle fa-lg spacer-right"></i>
|
||||||
|
<translate>Error while generating PDF file</translate> {{ filename }}:
|
||||||
|
<span ng-if="pdf.errorMessage"><code>{{ pdf.errorMessage | translate }}</code></span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -15,8 +15,9 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions',
|
|||||||
'PollContentProvider',
|
'PollContentProvider',
|
||||||
'gettextCatalog',
|
'gettextCatalog',
|
||||||
'$http',
|
'$http',
|
||||||
|
'PdfCreate',
|
||||||
function (HTMLValidizer, Motion, User, PdfMakeConverter, PdfMakeDocumentProvider, PdfMakeBallotPaperProvider,
|
function (HTMLValidizer, Motion, User, PdfMakeConverter, PdfMakeDocumentProvider, PdfMakeBallotPaperProvider,
|
||||||
MotionContentProvider, PollContentProvider, gettextCatalog, $http) {
|
MotionContentProvider, PollContentProvider, gettextCatalog, $http, PdfCreate) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
|
|
||||||
var $scope;
|
var $scope;
|
||||||
@ -30,11 +31,11 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions',
|
|||||||
});
|
});
|
||||||
|
|
||||||
$http.post('/core/encode_media/', JSON.stringify(image_sources)).success(function(data) {
|
$http.post('/core/encode_media/', JSON.stringify(image_sources)).success(function(data) {
|
||||||
var converter = PdfMakeConverter.createInstance(data.images, pdfMake);
|
var converter = PdfMakeConverter.createInstance(data.images);
|
||||||
var motionContentProvider = MotionContentProvider.createInstance(converter, $scope.motion, $scope, User, $http);
|
var motionContentProvider = MotionContentProvider.createInstance(converter, $scope.motion, $scope, User, $http);
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(motionContentProvider);
|
var documentProvider = PdfMakeDocumentProvider.createInstance(motionContentProvider);
|
||||||
var filename = gettextCatalog.getString("Motion") + "-" + $scope.motion.identifier + ".pdf";
|
var filename = gettextCatalog.getString("Motion") + "-" + $scope.motion.identifier + ".pdf";
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions',
|
|||||||
var filename = gettextCatalog.getString("Motion") + "-" + id + "-" + gettextCatalog.getString("ballot-paper") + ".pdf";
|
var filename = gettextCatalog.getString("Motion") + "-" + id + "-" + gettextCatalog.getString("ballot-paper") + ".pdf";
|
||||||
var pollContentProvider = PollContentProvider.createInstance(title, id, gettextCatalog);
|
var pollContentProvider = PollContentProvider.createInstance(title, id, gettextCatalog);
|
||||||
var documentProvider = PdfMakeBallotPaperProvider.createInstance(pollContentProvider);
|
var documentProvider = PdfMakeBallotPaperProvider.createInstance(pollContentProvider);
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
obj.init = function (_scope) {
|
obj.init = function (_scope) {
|
||||||
|
@ -643,10 +643,11 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
'ProjectionDefault',
|
'ProjectionDefault',
|
||||||
'osTableFilter',
|
'osTableFilter',
|
||||||
'osTableSort',
|
'osTableSort',
|
||||||
|
'PdfCreate',
|
||||||
function($scope, $state, $http, gettext, gettextCatalog, ngDialog, MotionForm, Motion,
|
function($scope, $state, $http, gettext, gettextCatalog, ngDialog, MotionForm, Motion,
|
||||||
Category, Tag, Workflow, User, Agenda, MotionBlock, MotionCsvExport, MotionDocxExport,
|
Category, Tag, Workflow, User, Agenda, MotionBlock, MotionCsvExport, MotionDocxExport,
|
||||||
MotionContentProvider, MotionCatalogContentProvider, PdfMakeConverter, PdfMakeDocumentProvider,
|
MotionContentProvider, MotionCatalogContentProvider, PdfMakeConverter, PdfMakeDocumentProvider,
|
||||||
HTMLValidizer, Projector, ProjectionDefault, osTableFilter, osTableSort) {
|
HTMLValidizer, Projector, ProjectionDefault, osTableFilter, osTableSort, PdfCreate) {
|
||||||
Motion.bindAll({}, $scope, 'motions');
|
Motion.bindAll({}, $scope, 'motions');
|
||||||
Category.bindAll({}, $scope, 'categories');
|
Category.bindAll({}, $scope, 'categories');
|
||||||
MotionBlock.bindAll({}, $scope, 'motionBlocks');
|
MotionBlock.bindAll({}, $scope, 'motionBlocks');
|
||||||
@ -863,7 +864,7 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
|
|
||||||
//post-request to convert the images. Async.
|
//post-request to convert the images. Async.
|
||||||
$http.post('/core/encode_media/', JSON.stringify(image_sources)).success(function(data) {
|
$http.post('/core/encode_media/', JSON.stringify(image_sources)).success(function(data) {
|
||||||
var converter = PdfMakeConverter.createInstance(data.images, pdfMake);
|
var converter = PdfMakeConverter.createInstance(data.images);
|
||||||
var motionContentProviderArray = [];
|
var motionContentProviderArray = [];
|
||||||
|
|
||||||
//convert the filtered motions to motionContentProviders
|
//convert the filtered motions to motionContentProviders
|
||||||
@ -872,7 +873,8 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
});
|
});
|
||||||
var motionCatalogContentProvider = MotionCatalogContentProvider.createInstance(motionContentProviderArray, $scope, User, Category);
|
var motionCatalogContentProvider = MotionCatalogContentProvider.createInstance(motionContentProviderArray, $scope, User, Category);
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(motionCatalogContentProvider);
|
var documentProvider = PdfMakeDocumentProvider.createInstance(motionCatalogContentProvider);
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
|
||||||
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -425,9 +425,10 @@ angular.module('OpenSlidesApp.users.site', [
|
|||||||
'osTableFilter',
|
'osTableFilter',
|
||||||
'osTableSort',
|
'osTableSort',
|
||||||
'gettext',
|
'gettext',
|
||||||
|
'PdfCreate',
|
||||||
function($scope, $state, $http, ngDialog, UserForm, User, Group, PasswordGenerator, Projector, ProjectionDefault,
|
function($scope, $state, $http, ngDialog, UserForm, User, Group, PasswordGenerator, Projector, ProjectionDefault,
|
||||||
UserListContentProvider, Config, UserAccessDataListContentProvider, PdfMakeDocumentProvider, gettextCatalog,
|
UserListContentProvider, Config, UserAccessDataListContentProvider, PdfMakeDocumentProvider, gettextCatalog,
|
||||||
UserCsvExport, osTableFilter, osTableSort, gettext) {
|
UserCsvExport, osTableFilter, osTableSort, gettext, PdfCreate) {
|
||||||
User.bindAll({}, $scope, 'users');
|
User.bindAll({}, $scope, 'users');
|
||||||
Group.bindAll({where: {id: {'>': 1}}}, $scope, 'groups');
|
Group.bindAll({where: {id: {'>': 1}}}, $scope, 'groups');
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
@ -623,7 +624,7 @@ angular.module('OpenSlidesApp.users.site', [
|
|||||||
var filename = gettextCatalog.getString("List of participants")+".pdf";
|
var filename = gettextCatalog.getString("List of participants")+".pdf";
|
||||||
var userListContentProvider = UserListContentProvider.createInstance($scope.usersFiltered, $scope.groups);
|
var userListContentProvider = UserListContentProvider.createInstance($scope.usersFiltered, $scope.groups);
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(userListContentProvider);
|
var documentProvider = PdfMakeDocumentProvider.createInstance(userListContentProvider);
|
||||||
pdfMake.createPdf(documentProvider.getDocument()).download(filename);
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
};
|
};
|
||||||
$scope.pdfExportUserAccessDataList = function () {
|
$scope.pdfExportUserAccessDataList = function () {
|
||||||
var filename = gettextCatalog.getString("List of access data")+".pdf";
|
var filename = gettextCatalog.getString("List of access data")+".pdf";
|
||||||
@ -631,7 +632,7 @@ angular.module('OpenSlidesApp.users.site', [
|
|||||||
$scope.usersFiltered, $scope.groups, Config);
|
$scope.usersFiltered, $scope.groups, Config);
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(userAccessDataListContentProvider);
|
var documentProvider = PdfMakeDocumentProvider.createInstance(userAccessDataListContentProvider);
|
||||||
var noFooter = true;
|
var noFooter = true;
|
||||||
pdfMake.createPdf(documentProvider.getDocument(noFooter)).download(filename);
|
PdfCreate.download(documentProvider.getDocument(noFooter), filename);
|
||||||
};
|
};
|
||||||
// Export as a csv file
|
// Export as a csv file
|
||||||
$scope.csvExport = function () {
|
$scope.csvExport = function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user