Merge pull request #3208 from tsiegleauq/logos-in-pdf

add logos in PDF
This commit is contained in:
Emanuel Schütze 2017-04-27 15:08:36 +02:00 committed by GitHub
commit 941ac8809e
15 changed files with 916 additions and 759 deletions

View File

@ -38,7 +38,8 @@ Users:
Core: Core:
- No reload on logoff. OpenSlides is now a full single page - No reload on logoff. OpenSlides is now a full single page
application [#3172]. application [#3172].
- Adding support for choosing image files as logos [#3184, #3207]. - Adding support for choosing image files as logos for projector and
pdf [#3184, #3207, #3208].
- Fixing error when clearing empty chat [#3199]. - Fixing error when clearing empty chat [#3199].
- Added notify system [#3212]. - Added notify system [#3212].

View File

@ -75,6 +75,24 @@ angular.module('OpenSlidesApp.agenda.pdf', ['OpenSlidesApp.core.pdf'])
createInstance: createInstance createInstance: createInstance
}; };
}]); }])
.factory('AgendaPdfExport', [
'gettextCatalog',
'AgendaContentProvider',
'PdfMakeDocumentProvider',
'PdfCreate',
function (gettextCatalog, AgendaContentProvider, PdfMakeDocumentProvider, PdfCreate) {
return {
export: function (items) {
var filename = gettextCatalog.getString('Agenda') + '.pdf';
var agendaContentProvider = AgendaContentProvider.createInstance(items);
PdfMakeDocumentProvider.createInstance(agendaContentProvider).then(function (documentProvider) {
PdfCreate.download(documentProvider.getDocument(), filename);
});
},
};
}
]);
}()); }());

View File

@ -89,17 +89,15 @@ angular.module('OpenSlidesApp.agenda.site', [
'AgendaTree', 'AgendaTree',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
'AgendaContentProvider',
'PdfMakeDocumentProvider',
'gettextCatalog', 'gettextCatalog',
'gettext', 'gettext',
'osTableFilter', 'osTableFilter',
'AgendaCsvExport', 'AgendaCsvExport',
'PdfCreate', 'AgendaPdfExport',
'ErrorMessage', 'ErrorMessage',
function($scope, $filter, $http, $state, DS, operator, ngDialog, Agenda, TopicForm, function($scope, $filter, $http, $state, DS, operator, ngDialog, Agenda, TopicForm,
AgendaTree, Projector, ProjectionDefault, AgendaContentProvider, PdfMakeDocumentProvider, AgendaTree, Projector, ProjectionDefault, gettextCatalog, gettext, osTableFilter,
gettextCatalog, gettext, osTableFilter, AgendaCsvExport, PdfCreate, ErrorMessage) { AgendaCsvExport, AgendaPdfExport, ErrorMessage) {
// Bind agenda tree to the scope // Bind agenda tree to the scope
$scope.$watch(function () { $scope.$watch(function () {
return Agenda.lastModified(); return Agenda.lastModified();
@ -276,10 +274,7 @@ angular.module('OpenSlidesApp.agenda.site', [
}; };
// export // export
$scope.pdfExport = function () { $scope.pdfExport = function () {
var filename = gettextCatalog.getString('Agenda') + '.pdf'; AgendaPdfExport.export($scope.itemsFiltered);
var agendaContentProvider = AgendaContentProvider.createInstance($scope.itemsFiltered);
var documentProvider = PdfMakeDocumentProvider.createInstance(agendaContentProvider);
PdfCreate.download(documentProvider.getDocument(), filename);
}; };
$scope.csvExport = function () { $scope.csvExport = function () {
AgendaCsvExport.export($scope.itemsFiltered); AgendaCsvExport.export($scope.itemsFiltered);

View File

@ -259,10 +259,11 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf'])
}; };
}; };
return { return {
createInstance: createInstance createInstance: createInstance
}; };
}]) }
])
.factory('BallotContentProvider', [ .factory('BallotContentProvider', [
'$filter', '$filter',
@ -271,12 +272,12 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf'])
'Config', 'Config',
'User', 'User',
function($filter, gettextCatalog, PDFLayout, Config, User) { function($filter, gettextCatalog, PDFLayout, Config, User) {
var createInstance = function(scope, poll, pollNumber) { var createInstance = function(assignment, poll, pollNumber) {
// page title // page title
var createTitle = function() { var createTitle = function() {
return { return {
text: scope.assignment.title, text: assignment.title,
style: 'title', style: 'title',
}; };
}; };
@ -477,10 +478,11 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf'])
}; };
}; };
return { return {
createInstance: createInstance createInstance: createInstance
}; };
}]) }
])
.factory('AssignmentCatalogContentProvider', [ .factory('AssignmentCatalogContentProvider', [
'gettextCatalog', 'gettextCatalog',
@ -552,9 +554,68 @@ angular.module('OpenSlidesApp.assignments.pdf', ['OpenSlidesApp.core.pdf'])
}; };
}; };
return { return {
createInstance: createInstance createInstance: createInstance
}; };
}]); }
])
.factory('AssignmentPdfExport', [
'gettextCatalog',
'AssignmentContentProvider',
'AssignmentCatalogContentProvider',
'PdfMakeDocumentProvider',
'BallotContentProvider',
'PdfMakeBallotPaperProvider',
'PdfCreate',
function (gettextCatalog, AssignmentContentProvider, AssignmentCatalogContentProvider,
PdfMakeDocumentProvider, BallotContentProvider, PdfMakeBallotPaperProvider, PdfCreate) {
return {
export: function (assignments, singleAssignment) {
var filename = singleAssignment ?
gettextCatalog.getString('Election') + '_' + assignments.title :
gettextCatalog.getString('Elections');
filename += '.pdf';
if (singleAssignment) {
assignments = [assignments];
}
var assignmentContentProviderArray = [];
// Convert the assignments to content providers
angular.forEach(assignments, function(assignment) {
assignmentContentProviderArray.push(AssignmentContentProvider.createInstance(assignment));
});
var documentProviderPromise;
if (singleAssignment) {
documentProviderPromise =
PdfMakeDocumentProvider.createInstance(assignmentContentProviderArray[0]);
} else {
var assignmentCatalogContentProvider =
AssignmentCatalogContentProvider.createInstance(assignmentContentProviderArray);
documentProviderPromise =
PdfMakeDocumentProvider.createInstance(assignmentCatalogContentProvider);
}
documentProviderPromise.then(function (documentProvider) {
PdfCreate.download(documentProvider.getDocument(), filename);
});
},
createBallotPdf: function (assignment, pollId) {
var thePoll;
var pollNumber;
angular.forEach(assignment.polls, function(poll, pollIndex) {
if (poll.id == pollId) {
thePoll = poll;
pollNumber = pollIndex+1;
}
});
var filename = gettextCatalog.getString('Ballot') + '_' + pollNumber + '_' + assignment.title + '.pdf';
var ballotContentProvider = BallotContentProvider.createInstance(assignment, thePoll, pollNumber);
var documentProvider = PdfMakeBallotPaperProvider.createInstance(ballotContentProvider);
PdfCreate.download(documentProvider.getDocument(), filename);
},
};
}
]);
}()); }());

View File

@ -265,18 +265,14 @@ angular.module('OpenSlidesApp.assignments.site', [
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
'gettextCatalog', 'gettextCatalog',
'AssignmentContentProvider',
'AssignmentCatalogContentProvider',
'PdfMakeDocumentProvider',
'User', 'User',
'osTableFilter', 'osTableFilter',
'osTableSort', 'osTableSort',
'gettext', 'gettext',
'PdfCreate',
'AssignmentPhases', 'AssignmentPhases',
'AssignmentPdfExport',
function($scope, ngDialog, AssignmentForm, Assignment, Tag, Agenda, Projector, ProjectionDefault, function($scope, ngDialog, AssignmentForm, Assignment, Tag, Agenda, Projector, ProjectionDefault,
gettextCatalog, AssignmentContentProvider, AssignmentCatalogContentProvider, PdfMakeDocumentProvider, gettextCatalog, User, osTableFilter, osTableSort, gettext, AssignmentPhases, AssignmentPdfExport) {
User, osTableFilter, osTableSort, gettext, PdfCreate, AssignmentPhases) {
Assignment.bindAll({}, $scope, 'assignments'); Assignment.bindAll({}, $scope, 'assignments');
Tag.bindAll({}, $scope, 'tags'); Tag.bindAll({}, $scope, 'tags');
$scope.$watch(function () { $scope.$watch(function () {
@ -383,20 +379,8 @@ angular.module('OpenSlidesApp.assignments.site', [
Assignment.destroy(assignment.id); Assignment.destroy(assignment.id);
}; };
// create the PDF List // create the PDF List
$scope.makePDF_assignmentList = function () { $scope.pdfExport = function () {
var filename = gettextCatalog.getString("Elections") + ".pdf"; AssignmentPdfExport.export($scope.assignmentsFiltered);
var assignmentContentProviderArray = [];
//convert the filtered assignments to content providers
angular.forEach($scope.assignmentsFiltered, function(assignment) {
assignmentContentProviderArray.push(AssignmentContentProvider.createInstance(assignment));
});
var assignmentCatalogContentProvider =
AssignmentCatalogContentProvider.createInstance(assignmentContentProviderArray);
var documentProvider =
PdfMakeDocumentProvider.createInstance(assignmentCatalogContentProvider);
PdfCreate.download(documentProvider.getDocument(), filename);
}; };
} }
]) ])
@ -416,18 +400,13 @@ angular.module('OpenSlidesApp.assignments.site', [
'assignmentId', 'assignmentId',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
'AssignmentContentProvider',
'BallotContentProvider',
'PdfMakeDocumentProvider',
'PdfMakeBallotPaperProvider',
'gettextCatalog', 'gettextCatalog',
'PdfCreate',
'AssignmentPhases', 'AssignmentPhases',
'AssignmentPdfExport',
'ErrorMessage', 'ErrorMessage',
function($scope, $http, $filter, $timeout, filterFilter, gettext, ngDialog, AssignmentForm, operator, Assignment, function($scope, $http, $filter, $timeout, filterFilter, gettext, ngDialog, AssignmentForm, operator,
User, assignmentId, Projector, ProjectionDefault, AssignmentContentProvider, BallotContentProvider, Assignment, User, assignmentId, Projector, ProjectionDefault, gettextCatalog, AssignmentPhases,
PdfMakeDocumentProvider, PdfMakeBallotPaperProvider, gettextCatalog, PdfCreate, AssignmentPhases, AssignmentPdfExport, ErrorMessage) {
ErrorMessage) {
User.bindAll({}, $scope, 'users'); User.bindAll({}, $scope, 'users');
var assignment = Assignment.get(assignmentId); var assignment = Assignment.get(assignmentId);
Assignment.loadRelations(assignment, 'agenda_item'); Assignment.loadRelations(assignment, 'agenda_item');
@ -600,28 +579,13 @@ angular.module('OpenSlidesApp.assignments.site', [
}; };
//creates the document as pdf // Creates the document as pdf
$scope.makePDF_singleAssignment = function() { $scope.pdfExport = function() {
var filename = gettextCatalog.getString("Election") + "_" + $scope.assignment.title + ".pdf"; AssignmentPdfExport.export($scope.assignment, true);
var assignmentContentProvider = AssignmentContentProvider.createInstance($scope.assignment);
var documentProvider = PdfMakeDocumentProvider.createInstance(assignmentContentProvider);
PdfCreate.download(documentProvider.getDocument(), filename);
}; };
// Creates the ballotpaper as pdf
//creates the ballotpaper as pdf $scope.ballotpaperExport = function(pollId) {
$scope.makePDF_assignmentpoll = function(pollID) { AssignmentPdfExport.createBallotPdf($scope.assignment, pollId);
var thePoll;
var pollNumber;
angular.forEach($scope.assignment.polls, function(poll, pollIndex) {
if (poll.id == pollID) {
thePoll = poll;
pollNumber = pollIndex+1;
}
});
var filename = gettextCatalog.getString("Ballot") + "_" + pollNumber + "_" + $scope.assignment.title + ".pdf";
var ballotContentProvider = BallotContentProvider.createInstance($scope, thePoll, pollNumber);
var documentProvider = PdfMakeBallotPaperProvider.createInstance(ballotContentProvider);
PdfCreate.download(documentProvider.getDocument(), filename);
}; };
// Just mark some vote value strings for translation. // Just mark some vote value strings for translation.

View File

@ -21,7 +21,7 @@
<i class="fa fa-pencil"></i> <i class="fa fa-pencil"></i>
</a> </a>
<!-- pdf --> <!-- pdf -->
<a ng-click="makePDF_singleAssignment()" target="_blank" class="btn btn-default btn-sm"> <a ng-click="pdfExport()" target="_blank" class="btn btn-default btn-sm">
<i class="fa fa-file-pdf-o fa-lg"></i> <i class="fa fa-file-pdf-o fa-lg"></i>
<translate>PDF</translate> <translate>PDF</translate>
</a> </a>
@ -152,7 +152,7 @@
<!-- angular requires to open the link in new tab with "target='_blank'". <!-- angular requires to open the link in new tab with "target='_blank'".
Otherwise the pdf url can't be open in same window; angular redirects to "/". --> Otherwise the pdf url can't be open in same window; angular redirects to "/". -->
<!-- PDF --> <!-- PDF -->
<a ng-click="makePDF_assignmentpoll(poll.id)" target="_blank" class="btn btn-default btn-sm"> <a ng-click="ballotpaperExport(poll.id)" target="_blank" class="btn btn-default btn-sm">
<i class="fa fa-file-pdf-o"></i> <i class="fa fa-file-pdf-o"></i>
<translate>Print ballot paper</translate> <translate>Print ballot paper</translate>
</a> </a>

View File

@ -39,7 +39,7 @@
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownExport"> <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownExport">
<!-- PDF export --> <!-- PDF export -->
<li> <li>
<a href="" ng-click="makePDF_assignmentList()"> <a href="" ng-click="pdfExport()">
<i class="fa fa-file-pdf-o"></i> <i class="fa fa-file-pdf-o"></i>
<translate>PDF</translate> <translate>PDF</translate>
</a> </a>

View File

@ -223,7 +223,9 @@ def get_config_variables():
name='logos_available', name='logos_available',
default_value=[ default_value=[
'logo_projector_main', 'logo_projector_main',
'logo_projector_header'], 'logo_projector_header',
'logo_pdf_header',
'logo_pdf_footer'],
weight=300, weight=300,
group='Logo', group='Logo',
hidden=True) hidden=True)
@ -247,3 +249,24 @@ def get_config_variables():
weight=302, weight=302,
group='Logo', group='Logo',
hidden=True) hidden=True)
# PDF logos
yield ConfigVariable(
name='logo_pdf_header',
default_value={
'display_name': 'PDF header logo',
'path': ''},
input_type='logo',
weight=310,
group='Logo',
hidden=True)
yield ConfigVariable(
name='logo_pdf_footer',
default_value={
'display_name': 'PDF footer logo',
'path': ''},
input_type='logo',
weight=311,
group='Logo',
hidden=True)

View File

@ -96,15 +96,16 @@ self.addEventListener('message', function(e) {
// see https://github.com/bpampuch/pdfmake/issues/38 // see https://github.com/bpampuch/pdfmake/issues/38
if (data.footerTpl) { if (data.footerTpl) {
data.footer = function (currentPage, pageCount) { data.footer = function (currentPage, pageCount) {
var footerText = data.footerTpl.text for(var i = 0; i < data.footerTpl.columns.length; i++) {
.replace('{{currentPage}}', currentPage) if (data.footerTpl.columns[i].text) {
.replace('{{pageCount}}', pageCount); data.footerTpl.columns[i].text = data.footerTpl.columns[i].text
.replace('{{currentPage}}', currentPage)
.replace('{{pageCount}}', pageCount);
}
}
return { return {
text: footerText, columns: data.footerTpl.columns,
alignment: data.footerTpl.alignment,
margin: data.footerTpl.margin, margin: data.footerTpl.margin,
fontSize: data.footerTpl.fontSize,
color: data.footerTpl.color
}; };
}; };
} }

View File

@ -135,27 +135,35 @@ angular.module('OpenSlidesApp.core.pdf', [])
.factory('PdfMakeDocumentProvider', [ .factory('PdfMakeDocumentProvider', [
'$q',
'Config', 'Config',
'PDFLayout', 'PDFLayout',
function(Config, PDFLayout) { 'PdfImageConverter',
function($q, Config, PDFLayout, PdfImageConverter) {
/** /**
* Provides the global document * Provides the global document
* @constructor * @constructor
* @param {object} contentProvider - Object with on method `getContent`, which * @param {object} contentProvider - Object with on method `getContent`, which
* returns an array for content * returns an array for content
*/ */
//images shall contain the the logos as URL: base64Str, just like the converter
var createInstance = function(contentProvider) { var createInstance = function(contentProvider) {
// Logo urls
var logoHeaderUrl = Config.get('logo_pdf_header').value.path,
logoFooterUrl = Config.get('logo_pdf_footer').value.path;
var imageMap = {};
// PDF header // PDF header
var getHeader = function() { var getHeader = function() {
var columns = []; var columns = [];
// add here your custom logo (which has to be added to a custom vfs_fonts.js) if (logoHeaderUrl) {
// see https://github.com/pdfmake/pdfmake/wiki/Custom-Fonts---client-side columns.push({
/* image: imageMap[logoHeaderUrl],
columns.push({ fit: [180, 40],
image: 'logo.png', width: '20%'
fit: [180,40] });
});*/ }
var line1 = [ var line1 = [
Config.translate(Config.get('general_event_name').value), Config.translate(Config.get('general_event_name').value),
@ -168,15 +176,16 @@ angular.module('OpenSlidesApp.core.pdf', [])
var text = [line1, line2].join('\n'); var text = [line1, line2].join('\n');
columns.push({ columns.push({
text: text, text: text,
fontSize:10, fontSize: 10,
width: '100%' alignment: 'right',
margin: [0, 10, 0, 0],
}); });
return { return {
color: '#555', color: '#555',
fontSize: 9, fontSize: 9,
margin: [75, 30, 75, 10], // [left, top, right, bottom] margin: [75, 30, 75, 10], // [left, top, right, bottom]
columns: columns, columns: columns,
columnGap: 10 columnGap: 10,
}; };
}; };
@ -185,12 +194,26 @@ angular.module('OpenSlidesApp.core.pdf', [])
// Used placeholder for currentPage and pageCount which // Used placeholder for currentPage and pageCount which
// are replaced by dynamic footer function in pdf-worker.js. // are replaced by dynamic footer function in pdf-worker.js.
var getFooter = function() { var getFooter = function() {
return { var columns = [];
alignment: 'right',
margin: [0, 15, 75, 0], if (logoFooterUrl) {
fontSize: 9, columns.push({
image: imageMap[logoFooterUrl],
fit: [400,50],
width: '80%'
});
}
columns.push({
text: '{{currentPage}} / {{pageCount}}',
color: '#555', color: '#555',
text: '{{currentPage}} / {{pageCount}}' fontSize: 9,
alignment: 'right',
margin: [0, 15, 0, 0],
});
return {
margin: [75, 0, 75, 10],
columns: columns,
columnGap: 10,
}; };
}; };
// Generates the document(definition) for pdfMake // Generates the document(definition) for pdfMake
@ -295,9 +318,18 @@ angular.module('OpenSlidesApp.core.pdf', [])
}; };
}; };
return { return $q(function (resolve) {
getDocument: getDocument var imageSources = [
}; logoHeaderUrl,
logoFooterUrl
];
PdfImageConverter.toBase64(imageSources).then(function (_imageMap) {
imageMap = _imageMap;
resolve({
getDocument: getDocument
});
});
});
}; };
return { return {
createInstance: createInstance createInstance: createInstance
@ -768,7 +800,7 @@ angular.module('OpenSlidesApp.core.pdf', [])
height *= scaleByHeight; height *= scaleByHeight;
} }
alreadyConverted.push({ alreadyConverted.push({
image: BaseMap[element.getAttribute("src")], image: images[element.getAttribute("src")],
width: width, width: width,
height: height height: height
}); });
@ -837,7 +869,6 @@ angular.module('OpenSlidesApp.core.pdf', [])
ParseHtml(content, html); ParseHtml(content, html);
return content; return content;
}, },
BaseMap = images,
/** /**
* Creates containerelements for pdfMake * Creates containerelements for pdfMake
* e.g create("text":"MyText") result in { text: "MyText" } * e.g create("text":"MyText") result in { text: "MyText" }
@ -862,7 +893,34 @@ angular.module('OpenSlidesApp.core.pdf', [])
return { return {
createInstance: createInstance createInstance: createInstance
}; };
}]) }
])
.factory('PdfImageConverter', [
'$q',
'PDFLayout',
function ($q, PDFLayout) {
return {
toBase64: function (imageSources) {
var imageMap = {};
var imagePromises = _.map(imageSources, function (imageSource) {
if (imageSource) {
return PDFLayout.imageURLtoBase64(imageSource).then(function (base64Str) {
imageMap[imageSource] = base64Str;
});
}
});
return $q(function (resolve) {
//resolve promises to get base64
$q.all(imagePromises).then(function() {
resolve(imageMap);
});
});
}
};
}
])
.factory('PdfCreate', [ .factory('PdfCreate', [
'$timeout', '$timeout',

View File

@ -1714,6 +1714,8 @@ angular.module('OpenSlidesApp.core.site', [
gettext('List of speakers overlay'); gettext('List of speakers overlay');
gettext('Projector logo'); gettext('Projector logo');
gettext('Projector header image'); gettext('Projector header image');
gettext('PDF header logo');
gettext('PDF footer logo');
// Mark the string 'Default projector' here, because it does not appear in the templates. // Mark the string 'Default projector' here, because it does not appear in the templates.
gettext('Default projector'); gettext('Default projector');

View File

@ -341,7 +341,7 @@
uib-tooltip="{{ 'The projector header should have a default size of 1024x70px. Adapt the image width if you change the projector resolution.' | translate }}"> uib-tooltip="{{ 'The projector header should have a default size of 1024x70px. Adapt the image width if you change the projector resolution.' | translate }}">
<i class="fa fa-info-circle"></i> <i class="fa fa-info-circle"></i>
</span> </span>
<i class="fa fa-cog fa-lg spacer-left" ng-show="mediafile.logoHover"></i> <i class="fa fa-cog fa-lg spacer-left" ng-show="mediafile.logoHover && mediafile.isUsedAsLogo()"></i>
</span> </span>
<ul class="dropdown-menu" aria-labelledby="dropdownLogos{{ mediafile.id }}"> <ul class="dropdown-menu" aria-labelledby="dropdownLogos{{ mediafile.id }}">
<li ng-repeat="logo in logos"> <li ng-repeat="logo in logos">

File diff suppressed because it is too large Load Diff

View File

@ -9,108 +9,109 @@ angular.module('OpenSlidesApp.users.pdf', ['OpenSlidesApp.core.pdf'])
'PDFLayout', 'PDFLayout',
function(gettextCatalog, PDFLayout) { function(gettextCatalog, PDFLayout) {
var createInstance = function(userList, groups) { var createInstance = function(userList, groups) {
//use the Predefined Functions to create the title //use the Predefined Functions to create the title
var title = PDFLayout.createTitle(gettextCatalog.getString("List of participants")); var title = PDFLayout.createTitle(gettextCatalog.getString("List of participants"));
//function to generate the user list //function to generate the user list
var createUserList = function() { var createUserList = function() {
var userJsonList = []; var userJsonList = [];
angular.forEach(userList, function (user, counter) { angular.forEach(userList, function (user, counter) {
//parse for the group names //parse for the group names
var userGroups = []; var userGroups = [];
angular.forEach(user.groups_id, function (id) { angular.forEach(user.groups_id, function (id) {
if (id) { if (id) {
angular.forEach(groups, function(group) { angular.forEach(groups, function(group) {
if (id == group.id) { if (id == group.id) {
userGroups.push(gettextCatalog.getString(group.name)); userGroups.push(gettextCatalog.getString(group.name));
} }
}); });
} }
});
var userJsonObj = [
{
text: "" + (counter+1),
style: PDFLayout.flipTableRowStyle(userJsonList.length)
},
{
text: user.short_name,
style: PDFLayout.flipTableRowStyle(userJsonList.length)
},
{
text: user.structure_level,
style: PDFLayout.flipTableRowStyle(userJsonList.length)
},
{
text: userGroups.join(" "),
style: PDFLayout.flipTableRowStyle(userJsonList.length)
}
];
userJsonList.push(userJsonObj);
}); });
var userJsonObj = [ var userTableBody = [
{ [
text: "" + (counter+1), {
style: PDFLayout.flipTableRowStyle(userJsonList.length) text: '#',
}, style: 'tableHeader'
{ },
text: user.short_name, {
style: PDFLayout.flipTableRowStyle(userJsonList.length) text: gettextCatalog.getString("Name"),
}, style: 'tableHeader'
{ },
text: user.structure_level, {
style: PDFLayout.flipTableRowStyle(userJsonList.length) text: gettextCatalog.getString("Structure level"),
}, style: 'tableHeader'
{ },
text: userGroups.join(" "), {
style: PDFLayout.flipTableRowStyle(userJsonList.length) text: gettextCatalog.getString("Groups"),
} style: 'tableHeader'
}
]
]; ];
userJsonList.push(userJsonObj); userTableBody = userTableBody.concat((userJsonList));
});
var userTableBody = [ var userTableJsonString = {
[ table: {
{ widths: ['auto', '*', 'auto', 'auto'],
text: '#', headerRows: 1,
style: 'tableHeader' body: userTableBody
}, },
{ layout: 'headerLineOnly'
text: gettextCatalog.getString("Name"), };
style: 'tableHeader'
},
{
text: gettextCatalog.getString("Structure level"),
style: 'tableHeader'
},
{
text: gettextCatalog.getString("Groups"),
style: 'tableHeader'
}
]
];
userTableBody = userTableBody.concat((userJsonList));
var userTableJsonString = { return userTableJsonString;
table: {
widths: ['auto', '*', 'auto', 'auto'],
headerRows: 1,
body: userTableBody
},
layout: 'headerLineOnly'
}; };
return userTableJsonString; var getContent = function() {
}; return [
title,
createUserList()
];
};
var getContent = function() { return {
return [ getContent: getContent
title, };
createUserList()
];
}; };
return { return {
getContent: getContent createInstance: createInstance
}; };
}; }
])
return {
createInstance: createInstance
};
}])
.factory('UserAccessDataListContentProvider', [ .factory('UserAccessDataListContentProvider', [
'gettextCatalog', 'gettextCatalog',
'PDFLayout', 'PDFLayout',
function(gettextCatalog, PDFLayout) { 'Config',
function(gettextCatalog, PDFLayout, Config) {
var createInstance = function(userList, groups, Config) { var createInstance = function(userList) {
var creadeUserHeadLine = function(user) { var creadeUserHeadLine = function(user) {
var titleLine = []; var titleLine = [];
@ -256,14 +257,17 @@ angular.module('OpenSlidesApp.users.pdf', ['OpenSlidesApp.core.pdf'])
var getContent = function() { var getContent = function() {
var content = []; var content = [];
angular.forEach(userList, function (user) { angular.forEach(userList, function (user, index) {
content.push(creadeUserHeadLine(user)); content.push(creadeUserHeadLine(user));
content.push(createAccessDataContent(user)); content.push(createAccessDataContent(user));
content.push(createWelcomeText()); content.push(createWelcomeText());
content.push({ // No pagebreak after the last user
text: '', if (index !== userList.length - 1) {
pageBreak: 'after' content.push({
}); text: '',
pageBreak: 'after'
});
}
}); });
return [ return [
@ -280,5 +284,38 @@ angular.module('OpenSlidesApp.users.pdf', ['OpenSlidesApp.core.pdf'])
createInstance: createInstance createInstance: createInstance
}; };
} }
])
.factory('UserPdfExport', [
'gettextCatalog',
'UserListContentProvider',
'UserAccessDataListContentProvider',
'PdfMakeDocumentProvider',
'PdfCreate',
function (gettextCatalog, UserListContentProvider, UserAccessDataListContentProvider, PdfMakeDocumentProvider, PdfCreate) {
return {
exportUserList: function (users) {
var filename = gettextCatalog.getString('List of participants') + '.pdf';
var userListContentProvider = UserListContentProvider.createInstance(users);
PdfMakeDocumentProvider.createInstance(userListContentProvider).then(
function (documentProvider) {
PdfCreate.download(documentProvider.getDocument(), filename);
}
);
},
exportUserAccessDataList: function (users) {
var filename = gettextCatalog.getString('List of access data') + '.pdf';
var userAccessDataListContentProvider = UserAccessDataListContentProvider.createInstance(
users);
PdfMakeDocumentProvider.createInstance(userAccessDataListContentProvider).then(
function (documentProvider) {
var noFooter = true;
PdfCreate.download(documentProvider.getDocument(noFooter), filename);
}
);
}
};
}
]); ]);
}()); }());

View File

@ -478,6 +478,7 @@ angular.module('OpenSlidesApp.users.site', [
'$scope', '$scope',
'$state', '$state',
'$http', '$http',
'$q',
'ngDialog', 'ngDialog',
'UserForm', 'UserForm',
'User', 'User',
@ -485,19 +486,15 @@ angular.module('OpenSlidesApp.users.site', [
'PasswordGenerator', 'PasswordGenerator',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
'UserListContentProvider',
'Config', 'Config',
'UserAccessDataListContentProvider',
'PdfMakeDocumentProvider',
'gettextCatalog', 'gettextCatalog',
'UserCsvExport', 'UserCsvExport',
'osTableFilter', 'osTableFilter',
'osTableSort', 'osTableSort',
'gettext', 'gettext',
'PdfCreate', 'UserPdfExport',
function($scope, $state, $http, ngDialog, UserForm, User, Group, PasswordGenerator, Projector, ProjectionDefault, function($scope, $state, $http, $q, ngDialog, UserForm, User, Group, PasswordGenerator, Projector, ProjectionDefault,
UserListContentProvider, Config, UserAccessDataListContentProvider, PdfMakeDocumentProvider, gettextCatalog, Config, gettextCatalog, UserCsvExport, osTableFilter, osTableSort, gettext, UserPdfExport) {
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 () {
@ -685,18 +682,10 @@ angular.module('OpenSlidesApp.users.site', [
// Export as PDF // Export as PDF
$scope.pdfExportUserList = function () { $scope.pdfExportUserList = function () {
var filename = gettextCatalog.getString("List of participants")+".pdf"; UserPdfExport.exportUserList($scope.usersFiltered);
var userListContentProvider = UserListContentProvider.createInstance($scope.usersFiltered, $scope.groups);
var documentProvider = PdfMakeDocumentProvider.createInstance(userListContentProvider);
PdfCreate.download(documentProvider.getDocument(), filename);
}; };
$scope.pdfExportUserAccessDataList = function () { $scope.pdfExportUserAccessDataList = function () {
var filename = gettextCatalog.getString("List of access data")+".pdf"; UserPdfExport.exportUserAccessDataList($scope.usersFiltered);
var userAccessDataListContentProvider = UserAccessDataListContentProvider.createInstance(
$scope.usersFiltered, $scope.groups, Config);
var documentProvider = PdfMakeDocumentProvider.createInstance(userAccessDataListContentProvider);
var noFooter = true;
PdfCreate.download(documentProvider.getDocument(noFooter), filename);
}; };
// Export as a csv file // Export as a csv file
$scope.csvExport = function () { $scope.csvExport = function () {
@ -1506,7 +1495,7 @@ angular.module('OpenSlidesApp.users.site', [
}, },
function (error) { function (error) {
// Error: Username or password is not correct. // Error: Username or password is not correct.
$state.transitionTo($state.current, {msg: error.data.detail}, { $state.transitionTo($state.current, {msg: error.data.detail}, {
reload: true, inherit: false, notify: true reload: true, inherit: false, notify: true
}); });
} }