Merge pull request #3185 from FinnStutzenstein/export-dialog
Export dialog for motions
This commit is contained in:
commit
598dc30486
@ -4,9 +4,11 @@
|
|||||||
|
|
||||||
https://openslides.org/
|
https://openslides.org/
|
||||||
|
|
||||||
Version 2.1.2 (unreleased)
|
Version 2.2 (unreleased)
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
Motions:
|
||||||
|
- New export dialog.
|
||||||
|
|
||||||
Version 2.1.1 (2017-04-05)
|
Version 2.1.1 (2017-04-05)
|
||||||
==========================
|
==========================
|
||||||
|
@ -1346,6 +1346,10 @@ img {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-group > label > input[type=radio] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* user details */
|
/* user details */
|
||||||
.user_details fieldset {
|
.user_details fieldset {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
@ -648,6 +648,10 @@ angular.module('OpenSlidesApp.core.site', [
|
|||||||
templateUrl: 'static/templates/core/checkbox.html',
|
templateUrl: 'static/templates/core/checkbox.html',
|
||||||
overwriteOk: true,
|
overwriteOk: true,
|
||||||
});
|
});
|
||||||
|
formlyConfig.setType({
|
||||||
|
name: 'select-radio',
|
||||||
|
templateUrl: 'static/templates/core/select-radio.html',
|
||||||
|
});
|
||||||
formlyConfig.setType({
|
formlyConfig.setType({
|
||||||
name: 'select-single',
|
name: 'select-single',
|
||||||
extends: 'select',
|
extends: 'select',
|
||||||
|
17
openslides/core/static/templates/core/select-radio.html
Normal file
17
openslides/core/static/templates/core/select-radio.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<label class="control-label" ng-if="to.label">
|
||||||
|
{{ to.label }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group">
|
||||||
|
<label ng-repeat="option in to.options" class="btn btn-default btn-sm"
|
||||||
|
ng-class="{active: (model[options.key] === option.value)}"
|
||||||
|
ng-disabled="option.disabled">
|
||||||
|
<input type="radio" name="select-radio-{{ options.key }}" ng-value="option.value"
|
||||||
|
ng-model="model[options.key]" ng-checked="model[options.key] === option.value"
|
||||||
|
ng-disabled="option.disabled" ng-change="to.change(option.value)">
|
||||||
|
{{ option.name | translate }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -6,8 +6,10 @@ angular.module('OpenSlidesApp.motions.csv', [])
|
|||||||
|
|
||||||
.factory('MotionCsvExport', [
|
.factory('MotionCsvExport', [
|
||||||
'gettextCatalog',
|
'gettextCatalog',
|
||||||
|
'Config',
|
||||||
'CsvDownload',
|
'CsvDownload',
|
||||||
function (gettextCatalog, CsvDownload) {
|
'lineNumberingService',
|
||||||
|
function (gettextCatalog, Config, CsvDownload, lineNumberingService) {
|
||||||
var makeHeaderline = function () {
|
var makeHeaderline = function () {
|
||||||
var headerline = ['Identifier', 'Title', 'Text', 'Reason', 'Submitter', 'Category', 'Origin'];
|
var headerline = ['Identifier', 'Title', 'Text', 'Reason', 'Submitter', 'Category', 'Origin'];
|
||||||
return _.map(headerline, function (entry) {
|
return _.map(headerline, function (entry) {
|
||||||
@ -15,16 +17,36 @@ angular.module('OpenSlidesApp.motions.csv', [])
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
export: function (motions) {
|
export: function (motions, params) {
|
||||||
|
if (!params) {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
_.defaults(params, {
|
||||||
|
filename: 'motions-export.csv',
|
||||||
|
changeRecommendationMode: Config.get('motions_recommendation_text_mode').value,
|
||||||
|
includeReason: true,
|
||||||
|
});
|
||||||
|
if (!_.includes(['original', 'changed', 'agreed'], params.changeRecommendationMode)) {
|
||||||
|
params.changeRecommendationMode = 'original';
|
||||||
|
}
|
||||||
|
|
||||||
var csvRows = [
|
var csvRows = [
|
||||||
makeHeaderline()
|
makeHeaderline()
|
||||||
];
|
];
|
||||||
_.forEach(motions, function (motion) {
|
_.forEach(motions, function (motion) {
|
||||||
|
// TODO: Add a parameter 'noLineBreaks' to 'getTextByMode'. Currently linenumbers are
|
||||||
|
// removed directy after inserting --> not necessary. (See issue 3183)
|
||||||
|
var text = motion.getTextByMode(params.changeRecommendationMode);
|
||||||
|
text = lineNumberingService.stripLineNumbers(text);
|
||||||
var row = [];
|
var row = [];
|
||||||
row.push('"' + motion.identifier !== null ? motion.identifier : '' + '"');
|
row.push('"' + motion.identifier !== null ? motion.identifier : '' + '"');
|
||||||
row.push('"' + motion.getTitle() + '"');
|
row.push('"' + motion.getTitle() + '"');
|
||||||
row.push('"' + motion.getText() + '"');
|
row.push('"' + text + '"');
|
||||||
row.push('"' + motion.getReason() + '"');
|
if (params.includeReason) {
|
||||||
|
row.push('"' + motion.getReason() + '"');
|
||||||
|
} else {
|
||||||
|
row.push('""');
|
||||||
|
}
|
||||||
var submitter = motion.submitters[0] ? motion.submitters[0].get_full_name() : '';
|
var submitter = motion.submitters[0] ? motion.submitters[0].get_full_name() : '';
|
||||||
row.push('"' + submitter + '"');
|
row.push('"' + submitter + '"');
|
||||||
var category = motion.category ? motion.category.name : '';
|
var category = motion.category ? motion.category.name : '';
|
||||||
|
@ -8,9 +8,11 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
'$http',
|
'$http',
|
||||||
'$q',
|
'$q',
|
||||||
'Config',
|
'Config',
|
||||||
|
'Category',
|
||||||
'gettextCatalog',
|
'gettextCatalog',
|
||||||
'FileSaver',
|
'FileSaver',
|
||||||
function ($http, $q, Config, gettextCatalog, FileSaver) {
|
'lineNumberingService',
|
||||||
|
function ($http, $q, Config, Category, gettextCatalog, FileSaver, lineNumberingService) {
|
||||||
|
|
||||||
var PAGEBREAK = '<w:p><w:r><w:br w:type="page" /></w:r></w:p>';
|
var PAGEBREAK = '<w:p><w:r><w:br w:type="page" /></w:r></w:p>';
|
||||||
var TAGS_NO_PARAM = ['b', 'strong', 'em', 'i'];
|
var TAGS_NO_PARAM = ['b', 'strong', 'em', 'i'];
|
||||||
@ -19,10 +21,9 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
var relationships;
|
var relationships;
|
||||||
var contentTypes;
|
var contentTypes;
|
||||||
|
|
||||||
// $scope.motionsFiltered, $scope.categories
|
var getData = function (motions, params) {
|
||||||
|
|
||||||
var getData = function (motions, categories) {
|
|
||||||
var data = {};
|
var data = {};
|
||||||
|
var categories = Category.getAll();
|
||||||
// header
|
// header
|
||||||
var headerline1 = [
|
var headerline1 = [
|
||||||
Config.translate(Config.get('general_event_name').value),
|
Config.translate(Config.get('general_event_name').value),
|
||||||
@ -47,7 +48,7 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
|
|
||||||
// motions
|
// motions
|
||||||
data.tableofcontents_translation = gettextCatalog.getString('Table of contents');
|
data.tableofcontents_translation = gettextCatalog.getString('Table of contents');
|
||||||
data.motions = getMotionFullData(motions);
|
data.motions = getMotionFullData(motions, params);
|
||||||
data.motions_list = getMotionShortData(motions);
|
data.motions_list = getMotionShortData(motions);
|
||||||
data.no_motions = gettextCatalog.getString('No motions available.');
|
data.no_motions = gettextCatalog.getString('No motions available.');
|
||||||
|
|
||||||
@ -72,13 +73,18 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var getMotionFullData = function (motions) {
|
var getMotionFullData = function (motions, params) {
|
||||||
var translation = gettextCatalog.getString('Motion'),
|
var translation = gettextCatalog.getString('Motion'),
|
||||||
sequential_translation = gettextCatalog.getString('Sequential number'),
|
sequential_translation = gettextCatalog.getString('Sequential number'),
|
||||||
submitters_translation = gettextCatalog.getString('Submitters'),
|
submitters_translation = gettextCatalog.getString('Submitters'),
|
||||||
status_translation = gettextCatalog.getString('Status'),
|
status_translation = gettextCatalog.getString('Status'),
|
||||||
reason_translation = gettextCatalog.getString('Reason'),
|
reason_translation = gettextCatalog.getString('Reason'),
|
||||||
data = _.map(motions, function (motion) {
|
data = _.map(motions, function (motion) {
|
||||||
|
// TODO: Add a parameter 'noLineBreaks' to 'getTextByMode'. Currently linenumbers are
|
||||||
|
// removed directy after inserting --> not necessary. (See issue #3183)
|
||||||
|
var text = motion.getTextByMode(params.changeRecommendationMode);
|
||||||
|
text = lineNumberingService.stripLineNumbers(text);
|
||||||
|
var reason = params.includeReason ? motion.getReason() : '';
|
||||||
return {
|
return {
|
||||||
motion_translation: translation,
|
motion_translation: translation,
|
||||||
sequential_translation: sequential_translation,
|
sequential_translation: sequential_translation,
|
||||||
@ -92,9 +98,9 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
status_translation: status_translation,
|
status_translation: status_translation,
|
||||||
status: motion.getStateName(),
|
status: motion.getStateName(),
|
||||||
preamble: gettextCatalog.getString(Config.get('motions_preamble').value),
|
preamble: gettextCatalog.getString(Config.get('motions_preamble').value),
|
||||||
text: html2docx(motion.getText()),
|
text: html2docx(text),
|
||||||
reason_translation: motion.getReason().length === 0 ? '' : reason_translation,
|
reason_translation: reason.length === 0 ? '' : reason_translation,
|
||||||
reason: html2docx(motion.getReason()),
|
reason: html2docx(reason),
|
||||||
pagebreak: PAGEBREAK,
|
pagebreak: PAGEBREAK,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -353,7 +359,19 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
export: function (motions, categories) {
|
export: function (motions, params) {
|
||||||
|
if (!params) {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
_.defaults(params, {
|
||||||
|
filename: 'motions-export.docx',
|
||||||
|
changeRecommendationMode: Config.get('motions_recommendation_text_mode').value,
|
||||||
|
includeReason: true,
|
||||||
|
});
|
||||||
|
if (!_.includes(['original', 'changed', 'agreed'], params.changeRecommendationMode)) {
|
||||||
|
params.changeRecommendationMode = 'original';
|
||||||
|
}
|
||||||
|
|
||||||
images = [];
|
images = [];
|
||||||
relationships = [];
|
relationships = [];
|
||||||
contentTypes = [];
|
contentTypes = [];
|
||||||
@ -361,7 +379,7 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
var content = window.atob(success.data);
|
var content = window.atob(success.data);
|
||||||
var doc = new Docxgen(content);
|
var doc = new Docxgen(content);
|
||||||
|
|
||||||
doc.setData(getData(motions, categories));
|
doc.setData(getData(motions, params));
|
||||||
doc.render();
|
doc.render();
|
||||||
var zip = doc.getZip();
|
var zip = doc.getZip();
|
||||||
|
|
||||||
@ -384,7 +402,7 @@ angular.module('OpenSlidesApp.motions.docx', [])
|
|||||||
// wait for all images to be resolved
|
// wait for all images to be resolved
|
||||||
$q.all(imgPromises).then(function () {
|
$q.all(imgPromises).then(function () {
|
||||||
var out = zip.generate({type: 'blob'});
|
var out = zip.generate({type: 'blob'});
|
||||||
FileSaver.saveAs(out, 'motions-export.docx');
|
FileSaver.saveAs(out, params.filename);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -4,60 +4,6 @@
|
|||||||
|
|
||||||
angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions', 'OpenSlidesApp.motions.lineNumbering'])
|
angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions', 'OpenSlidesApp.motions.lineNumbering'])
|
||||||
|
|
||||||
.factory('MotionPDFExport', [
|
|
||||||
'HTMLValidizer',
|
|
||||||
'Motion',
|
|
||||||
'User',
|
|
||||||
'PdfMakeConverter',
|
|
||||||
'PdfMakeDocumentProvider',
|
|
||||||
'PdfMakeBallotPaperProvider',
|
|
||||||
'MotionContentProvider',
|
|
||||||
'PollContentProvider',
|
|
||||||
'gettextCatalog',
|
|
||||||
'$http',
|
|
||||||
'PdfCreate',
|
|
||||||
function (HTMLValidizer, Motion, User, PdfMakeConverter, PdfMakeDocumentProvider, PdfMakeBallotPaperProvider,
|
|
||||||
MotionContentProvider, PollContentProvider, gettextCatalog, $http, PdfCreate) {
|
|
||||||
var obj = {};
|
|
||||||
|
|
||||||
var $scope;
|
|
||||||
|
|
||||||
obj.createMotion = function() {
|
|
||||||
var text = $scope.motion.getTextByMode($scope.viewChangeRecommendations.mode, $scope.version);
|
|
||||||
var content = HTMLValidizer.validize(text) + HTMLValidizer.validize($scope.motion.getReason($scope.version));
|
|
||||||
var map = Function.prototype.call.bind([].map);
|
|
||||||
var image_sources = map($(content).find("img"), function(element) {
|
|
||||||
return element.getAttribute("src");
|
|
||||||
});
|
|
||||||
|
|
||||||
$http.post('/core/encode_media/', JSON.stringify(image_sources)).then(function (success) {
|
|
||||||
var converter = PdfMakeConverter.createInstance(success.data.images);
|
|
||||||
var motionContentProvider = MotionContentProvider.createInstance(converter, $scope.motion, $scope, User, $http);
|
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(motionContentProvider);
|
|
||||||
var identifier = $scope.motion.identifier ? '-' + $scope.motion.identifier : '';
|
|
||||||
var filename = gettextCatalog.getString("Motion") + identifier + ".pdf";
|
|
||||||
PdfCreate.download(documentProvider.getDocument(), filename);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//make PDF for polls
|
|
||||||
obj.createPoll = function() {
|
|
||||||
var id = $scope.motion.identifier.replace(" ", "");
|
|
||||||
var title = $scope.motion.getTitle($scope.version);
|
|
||||||
var filename = gettextCatalog.getString("Motion") + "-" + id + "-" + gettextCatalog.getString("ballot-paper") + ".pdf";
|
|
||||||
var pollContentProvider = PollContentProvider.createInstance(title, id, gettextCatalog);
|
|
||||||
var documentProvider = PdfMakeBallotPaperProvider.createInstance(pollContentProvider);
|
|
||||||
PdfCreate.download(documentProvider.getDocument(), filename);
|
|
||||||
};
|
|
||||||
|
|
||||||
obj.init = function (_scope) {
|
|
||||||
$scope = _scope;
|
|
||||||
};
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
.factory('MotionInlineEditing', [
|
.factory('MotionInlineEditing', [
|
||||||
'Editor',
|
'Editor',
|
||||||
'Motion',
|
'Motion',
|
||||||
|
@ -5,24 +5,26 @@
|
|||||||
angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
||||||
|
|
||||||
.factory('MotionContentProvider', [
|
.factory('MotionContentProvider', [
|
||||||
|
'operator',
|
||||||
'gettextCatalog',
|
'gettextCatalog',
|
||||||
'PDFLayout',
|
'PDFLayout',
|
||||||
'Category',
|
'Category',
|
||||||
'Config',
|
'Config',
|
||||||
'Motion',
|
'Motion',
|
||||||
function(gettextCatalog, PDFLayout, Category, Config, Motion) {
|
function(operator, gettextCatalog, PDFLayout, Category, Config, Motion) {
|
||||||
/**
|
/**
|
||||||
* Provides the content as JS objects for Motions in pdfMake context
|
* Provides the content as JS objects for Motions in pdfMake context
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var createInstance = function(converter, motion, $scope) {
|
var createInstance = function(converter, motion, motionVersion, changeRecommendationMode,
|
||||||
|
changeRecommendations, lineNumberMode, includeReason, includeComments) {
|
||||||
|
|
||||||
// title
|
// title
|
||||||
var identifier = motion.identifier ? ' ' + motion.identifier : '';
|
var identifier = motion.identifier ? ' ' + motion.identifier : '';
|
||||||
var title = PDFLayout.createTitle(
|
var title = PDFLayout.createTitle(
|
||||||
gettextCatalog.getString('Motion') + identifier + ': ' +
|
gettextCatalog.getString('Motion') + identifier + ': ' +
|
||||||
motion.getTitle($scope.version)
|
motion.getTitle(motionVersion)
|
||||||
);
|
);
|
||||||
|
|
||||||
// subtitle
|
// subtitle
|
||||||
@ -175,51 +177,49 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// summary of change recommendations (for motion diff version only)
|
// summary of change recommendations (for motion diff version only)
|
||||||
if ($scope.viewChangeRecommendations) {
|
if (changeRecommendationMode == "diff") {
|
||||||
if ($scope.viewChangeRecommendations.mode == "diff") {
|
var columnLineNumbers = [];
|
||||||
var columnLineNumbers = [];
|
var columnChangeType = [];
|
||||||
var columnChangeType = [];
|
angular.forEach(_.orderBy(changeRecommendations, ['line_from']), function(change) {
|
||||||
angular.forEach(_.orderBy($scope.change_recommendations, ['line_from']), function(change) {
|
// line numbers column
|
||||||
// line numbers column
|
var line;
|
||||||
var line;
|
if (change.line_from >= change.line_to - 1) {
|
||||||
if (change.line_from >= change.line_to - 1) {
|
line = change.line_from;
|
||||||
line = change.line_from;
|
} else {
|
||||||
} else {
|
line = change.line_from + ' - ' + (change.line_to - 1);
|
||||||
line = change.line_from + ' - ' + (change.line_to - 1);
|
}
|
||||||
}
|
columnLineNumbers.push(
|
||||||
columnLineNumbers.push(
|
gettextCatalog.getString('Line') + ' ' + line + ': '
|
||||||
gettextCatalog.getString('Line') + ' ' + line + ': '
|
);
|
||||||
);
|
// change type column
|
||||||
// change type column
|
if (change.getType(motion.getVersion(motionVersion).text) === 0) {
|
||||||
if (change.getType(motion.getVersion($scope.version).text) === 0) {
|
columnChangeType.push(gettextCatalog.getString("Replacement"));
|
||||||
columnChangeType.push(gettextCatalog.getString("Replacement"));
|
} else if (change.getType(motion.getVersion(motionVersion).text) === 1) {
|
||||||
} else if (change.getType(motion.getVersion($scope.version).text) === 1) {
|
columnChangeType.push(gettextCatalog.getString("Insertion"));
|
||||||
columnChangeType.push(gettextCatalog.getString("Insertion"));
|
} else if (change.getType(motion.getVersion(motionVersion).text) === 2) {
|
||||||
} else if (change.getType(motion.getVersion($scope.version).text) === 2) {
|
columnChangeType.push(gettextCatalog.getString("Deletion"));
|
||||||
columnChangeType.push(gettextCatalog.getString("Deletion"));
|
}
|
||||||
}
|
});
|
||||||
});
|
metaTableBody.push([
|
||||||
metaTableBody.push([
|
{
|
||||||
{
|
text: gettextCatalog.getString('Summary of change recommendations'),
|
||||||
text: gettextCatalog.getString('Summary of change recommendations'),
|
style: ['bold', 'grey']
|
||||||
style: ['bold', 'grey']
|
},
|
||||||
},
|
{
|
||||||
{
|
columns: [
|
||||||
columns: [
|
{
|
||||||
{
|
text: columnLineNumbers.join('\n'),
|
||||||
text: columnLineNumbers.join('\n'),
|
width: 'auto'
|
||||||
width: 'auto'
|
},
|
||||||
},
|
{
|
||||||
{
|
text: columnChangeType.join('\n'),
|
||||||
text: columnChangeType.join('\n'),
|
width: 'auto'
|
||||||
width: 'auto'
|
}
|
||||||
}
|
],
|
||||||
],
|
columnGap: 7,
|
||||||
columnGap: 7,
|
style: 'grey'
|
||||||
style: 'grey'
|
}
|
||||||
}
|
]);
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// build table
|
// build table
|
||||||
@ -241,7 +241,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
// motion title
|
// motion title
|
||||||
var motionTitle = function() {
|
var motionTitle = function() {
|
||||||
return [{
|
return [{
|
||||||
text: motion.getTitle($scope.version),
|
text: motion.getTitle(motionVersion),
|
||||||
style: 'heading3'
|
style: 'heading3'
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
@ -257,28 +257,56 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
|
|
||||||
// motion text (with line-numbers)
|
// motion text (with line-numbers)
|
||||||
var motionText = function() {
|
var motionText = function() {
|
||||||
var motionTextContent = motion.getTextByMode($scope.viewChangeRecommendations.mode, $scope.version);
|
var motionTextContent = motion.getTextByMode(changeRecommendationMode, motionVersion);
|
||||||
return converter.convertHTML(motionTextContent, $scope.lineNumberMode);
|
return converter.convertHTML(motionTextContent, lineNumberMode);
|
||||||
};
|
};
|
||||||
|
|
||||||
// motion reason heading
|
// motion reason heading
|
||||||
var motionReason = function() {
|
var motionReason = function() {
|
||||||
var reason = [];
|
if (includeReason) {
|
||||||
if (motion.getReason($scope.version)) {
|
var reason = [];
|
||||||
reason.push({
|
if (motion.getReason(motionVersion)) {
|
||||||
text: gettextCatalog.getString('Reason'),
|
reason.push({
|
||||||
style: 'heading3',
|
text: gettextCatalog.getString('Reason'),
|
||||||
marginTop: 25,
|
style: 'heading3',
|
||||||
});
|
marginTop: 25,
|
||||||
reason.push(converter.convertHTML(motion.getReason($scope.version), $scope.lineNumberMode));
|
});
|
||||||
|
reason.push(converter.convertHTML(motion.getReason(motionVersion), lineNumberMode));
|
||||||
|
}
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
return reason;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// motion comments handling
|
||||||
|
var motionComments = function () {
|
||||||
|
if (includeComments) {
|
||||||
|
var fields = Config.get('motions_comments').value;
|
||||||
|
var canSeeComment = function (index) {
|
||||||
|
return fields[index].public || operator.hasPerms('motions.can_manage');
|
||||||
|
};
|
||||||
|
var comments = [];
|
||||||
|
for (var i = 0; i < fields.length; i++) {
|
||||||
|
if (motion.comments[i] && canSeeComment(i)) {
|
||||||
|
var title = gettextCatalog.getString('Comment') + ' ' + fields[i].name;
|
||||||
|
console.log(fields[i]);
|
||||||
|
if (!fields[i].public) {
|
||||||
|
title += ' (' + gettextCatalog.getString('private') + ')';
|
||||||
|
}
|
||||||
|
comments.push({
|
||||||
|
text: title,
|
||||||
|
style: 'heading3',
|
||||||
|
marginTop: 25,
|
||||||
|
});
|
||||||
|
comments.push(converter.convertHTML(motion.comments[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
var getTitle = function() {
|
var getTitle = function() {
|
||||||
return motion.getTitle($scope.version);
|
return motion.getTitle(motionVersion);
|
||||||
};
|
};
|
||||||
|
|
||||||
var getIdentifier = function() {
|
var getIdentifier = function() {
|
||||||
@ -299,8 +327,13 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
motionPreamble(),
|
motionPreamble(),
|
||||||
motionText(),
|
motionText(),
|
||||||
];
|
];
|
||||||
if (motionReason()) {
|
var reason = motionReason();
|
||||||
content.push(motionReason());
|
if (reason) {
|
||||||
|
content.push(reason);
|
||||||
|
}
|
||||||
|
var comments = motionComments();
|
||||||
|
if (comments) {
|
||||||
|
content.push(comments);
|
||||||
}
|
}
|
||||||
return content;
|
return content;
|
||||||
};
|
};
|
||||||
@ -319,17 +352,17 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
|
|
||||||
.factory('PollContentProvider', [
|
.factory('PollContentProvider', [
|
||||||
'PDFLayout',
|
'PDFLayout',
|
||||||
|
'gettextCatalog',
|
||||||
'Config',
|
'Config',
|
||||||
'User',
|
'User',
|
||||||
function(PDFLayout, Config, User) {
|
function(PDFLayout, gettextCatalog, Config, User) {
|
||||||
/**
|
/**
|
||||||
* Generates a content provider for polls
|
* Generates a content provider for polls
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {string} title - title of poll
|
* @param {string} title - title of poll
|
||||||
* @param {string} id - if of poll
|
* @param {string} id - if of poll
|
||||||
* @param {object} gettextCatalog - for translation
|
|
||||||
*/
|
*/
|
||||||
var createInstance = function(title, id, gettextCatalog) {
|
var createInstance = function(title, id) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a single section on the ballot paper
|
* Returns a single section on the ballot paper
|
||||||
@ -440,9 +473,8 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
* Constructor
|
* Constructor
|
||||||
* @function
|
* @function
|
||||||
* @param {object} allMotions - A sorted array of all motions to parse
|
* @param {object} allMotions - A sorted array of all motions to parse
|
||||||
* @param {object} $scope - Current $scope
|
|
||||||
*/
|
*/
|
||||||
var createInstance = function(allMotions, $scope) {
|
var createInstance = function(allMotions) {
|
||||||
|
|
||||||
var title = PDFLayout.createTitle(
|
var title = PDFLayout.createTitle(
|
||||||
Config.translate(Config.get('motions_export_title').value)
|
Config.translate(Config.get('motions_export_title').value)
|
||||||
@ -566,6 +598,101 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
return {
|
return {
|
||||||
createInstance: createInstance
|
createInstance: createInstance
|
||||||
};
|
};
|
||||||
}]);
|
}])
|
||||||
|
|
||||||
|
.factory('MotionPdfExport', [
|
||||||
|
'$http',
|
||||||
|
'Config',
|
||||||
|
'gettextCatalog',
|
||||||
|
'MotionChangeRecommendation',
|
||||||
|
'HTMLValidizer',
|
||||||
|
'PdfMakeConverter',
|
||||||
|
'MotionContentProvider',
|
||||||
|
'MotionCatalogContentProvider',
|
||||||
|
'PdfMakeDocumentProvider',
|
||||||
|
'PollContentProvider',
|
||||||
|
'PdfMakeBallotPaperProvider',
|
||||||
|
'PdfCreate',
|
||||||
|
function ($http, Config, gettextCatalog, MotionChangeRecommendation, HTMLValidizer, PdfMakeConverter,
|
||||||
|
MotionContentProvider, MotionCatalogContentProvider, PdfMakeDocumentProvider, PollContentProvider,
|
||||||
|
PdfMakeBallotPaperProvider, PdfCreate) {
|
||||||
|
return {
|
||||||
|
export: function (motions, params, singleMotion) {
|
||||||
|
if (!params) {
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
_.defaults(params, {
|
||||||
|
filename: gettextCatalog.getString('motions') + '.pdf',
|
||||||
|
changeRecommendationMode: Config.get('motions_recommendation_text_mode').value,
|
||||||
|
lineNumberMode: Config.get('motions_default_line_numbering').value,
|
||||||
|
includeReason: true,
|
||||||
|
includeComments: false,
|
||||||
|
});
|
||||||
|
var image_sources = [];
|
||||||
|
|
||||||
|
if (singleMotion) {
|
||||||
|
_.defaults(params, {
|
||||||
|
version: motions.active_version,
|
||||||
|
});
|
||||||
|
motions = [motions];
|
||||||
|
}
|
||||||
|
|
||||||
|
//save the arrays of all motions to an array
|
||||||
|
angular.forEach(motions, function (motion) {
|
||||||
|
if (singleMotion) {
|
||||||
|
motion.changeRecommendations = MotionChangeRecommendation.filter({
|
||||||
|
'where': {'motion_version_id': {'==': motion.active_version}}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
motion.changeRecommendations = MotionChangeRecommendation.filter({
|
||||||
|
'where': {'motion_version_id': {'==': params.version}}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var text = motion.getTextByMode(params.changeRecommendationMode, null);
|
||||||
|
var content = HTMLValidizer.validize(text) + HTMLValidizer.validize(motion.getReason());
|
||||||
|
var map = Function.prototype.call.bind([].map);
|
||||||
|
var tmp_image_sources = map($(content).find('img'), function(element) {
|
||||||
|
return element.getAttribute('src');
|
||||||
|
});
|
||||||
|
image_sources = image_sources.concat(tmp_image_sources);
|
||||||
|
});
|
||||||
|
|
||||||
|
//post-request to convert the images. Async.
|
||||||
|
$http.post('/core/encode_media/', JSON.stringify(image_sources)).then(function (success) {
|
||||||
|
var converter = PdfMakeConverter.createInstance(success.data.images);
|
||||||
|
var motionContentProviderArray = [];
|
||||||
|
|
||||||
|
//convert all motions to motionContentProviders
|
||||||
|
angular.forEach(motions, function (motion) {
|
||||||
|
var version = (singleMotion ? params.version : motion.active_version);
|
||||||
|
motionContentProviderArray.push(MotionContentProvider.createInstance(
|
||||||
|
converter, motion, version, params.changeRecommendationMode,
|
||||||
|
motion.changeRecommendations, params.lineNumberMode,
|
||||||
|
params.includeReason, params.includeComments
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
var documentProvider;
|
||||||
|
if (singleMotion) {
|
||||||
|
documentProvider = PdfMakeDocumentProvider.createInstance(motionContentProviderArray[0]);
|
||||||
|
} else {
|
||||||
|
var motionCatalogContentProvider = MotionCatalogContentProvider.createInstance(motionContentProviderArray);
|
||||||
|
documentProvider = PdfMakeDocumentProvider.createInstance(motionCatalogContentProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
PdfCreate.download(documentProvider.getDocument(), params.filename);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
createPollPdf: function (motion, version) {
|
||||||
|
var id = motion.identifier.replace(' ', '');
|
||||||
|
var title = motion.getTitle(version);
|
||||||
|
var filename = gettextCatalog.getString('Motion') + '-' + id + '-' + gettextCatalog.getString('ballot-paper') + '.pdf';
|
||||||
|
var pollContentProvider = PollContentProvider.createInstance(title, id);
|
||||||
|
var documentProvider = PdfMakeBallotPaperProvider.createInstance(pollContentProvider);
|
||||||
|
PdfCreate.download(documentProvider.getDocument(), filename);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
@ -613,6 +613,179 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
.factory('MotionExportForm', [
|
||||||
|
'operator',
|
||||||
|
'gettextCatalog',
|
||||||
|
'Config',
|
||||||
|
function (operator, gettextCatalog, Config) {
|
||||||
|
return {
|
||||||
|
getDialog: function (motions, params, singleMotion) {
|
||||||
|
return {
|
||||||
|
template: 'static/templates/motions/motion-export-form.html',
|
||||||
|
controller: 'MotionExportCtrl',
|
||||||
|
className: 'ngdialog-theme-default wide-form',
|
||||||
|
closeByEscape: false,
|
||||||
|
closeByDocument: false,
|
||||||
|
resolve: {
|
||||||
|
motions: function () {return motions;},
|
||||||
|
params: function () {return params;},
|
||||||
|
singleMotion: function () {return singleMotion;},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getFormFields: function (singleMotion, formatChangeCallback) {
|
||||||
|
var fields = [];
|
||||||
|
var commentsAvailable = Config.get('motions_comments').value.length !== 0;
|
||||||
|
if (!singleMotion) {
|
||||||
|
fields = [
|
||||||
|
{
|
||||||
|
key: 'format',
|
||||||
|
type: 'select-radio',
|
||||||
|
templateOptions: {
|
||||||
|
label: gettextCatalog.getString('Format'),
|
||||||
|
options: [
|
||||||
|
{name: gettextCatalog.getString('PDF'), value: 'pdf'},
|
||||||
|
{name: gettextCatalog.getString('CSV'), value: 'csv'},
|
||||||
|
{name: gettextCatalog.getString('DOCX'), value: 'docx'},
|
||||||
|
],
|
||||||
|
change: formatChangeCallback,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (operator.hasPerms('motions.can_manage')) {
|
||||||
|
fields.push.apply(fields, [
|
||||||
|
{
|
||||||
|
key: 'lineNumberMode',
|
||||||
|
type: 'select-radio',
|
||||||
|
templateOptions: {
|
||||||
|
label: gettextCatalog.getString('Line numbering'),
|
||||||
|
options: [
|
||||||
|
{name: gettextCatalog.getString('None'), value: 'none'},
|
||||||
|
{name: gettextCatalog.getString('inline'), value: 'inline'},
|
||||||
|
{name: gettextCatalog.getString('outside'), value: 'outside'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hideExpression: "model.format !== 'pdf'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lineNumberMode',
|
||||||
|
type: 'select-radio',
|
||||||
|
templateOptions: {
|
||||||
|
label: gettextCatalog.getString('Line numbering'),
|
||||||
|
options: [
|
||||||
|
{name: gettextCatalog.getString('None'), value: 'none'},
|
||||||
|
{name: gettextCatalog.getString('inline'), value: 'inline', disabled: true},
|
||||||
|
{name: gettextCatalog.getString('outside'), value: 'outside', disabled: true},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hideExpression: "model.format === 'pdf'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'changeRecommendationMode',
|
||||||
|
type: 'select-radio',
|
||||||
|
templateOptions: {
|
||||||
|
label: gettextCatalog.getString('Change recommendations'),
|
||||||
|
options: [
|
||||||
|
{name: gettextCatalog.getString('Original version'), value: 'original'},
|
||||||
|
{name: gettextCatalog.getString('Changed version'), value: 'changed'},
|
||||||
|
{name: gettextCatalog.getString('Diff version'), value: 'diff'},
|
||||||
|
{name: gettextCatalog.getString('Final version'), value: 'agreed'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hideExpression: "model.format !== 'pdf'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'changeRecommendationMode',
|
||||||
|
type: 'select-radio',
|
||||||
|
templateOptions: {
|
||||||
|
label: gettextCatalog.getString('Change recommendations'),
|
||||||
|
options: [
|
||||||
|
{name: gettextCatalog.getString('Original version'), value: 'original'},
|
||||||
|
{name: gettextCatalog.getString('Changed version'), value: 'changed'},
|
||||||
|
{name: gettextCatalog.getString('Diff version'), value: 'diff', disabled: true},
|
||||||
|
{name: gettextCatalog.getString('Final version'), value: 'agreed'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hideExpression: "model.format === 'pdf'",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'includeReason',
|
||||||
|
type: 'select-radio',
|
||||||
|
templateOptions: {
|
||||||
|
label: gettextCatalog.getString('Reason'),
|
||||||
|
options: [
|
||||||
|
{name: gettextCatalog.getString('Yes'), value: true},
|
||||||
|
{name: gettextCatalog.getString('No'), value: false},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
if (commentsAvailable) {
|
||||||
|
fields.push({
|
||||||
|
key: 'includeComments',
|
||||||
|
type: 'select-radio',
|
||||||
|
templateOptions: {
|
||||||
|
label: gettextCatalog.getString('Kommentare'),
|
||||||
|
options: [
|
||||||
|
{name: gettextCatalog.getString('Yes'), value: true},
|
||||||
|
{name: gettextCatalog.getString('No'), value: false},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
hideExpression: "model.format !== 'pdf'",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
.controller('MotionExportCtrl', [
|
||||||
|
'$scope',
|
||||||
|
'Config',
|
||||||
|
'MotionExportForm',
|
||||||
|
'MotionPdfExport',
|
||||||
|
'MotionCsvExport',
|
||||||
|
'MotionDocxExport',
|
||||||
|
'motions',
|
||||||
|
'params',
|
||||||
|
'singleMotion',
|
||||||
|
function ($scope, Config, MotionExportForm, MotionPdfExport, MotionCsvExport,
|
||||||
|
MotionDocxExport, motions, params, singleMotion) {
|
||||||
|
$scope.formFields = MotionExportForm.getFormFields(singleMotion, function () {
|
||||||
|
$scope.params.changeRecommendationMode = 'original';
|
||||||
|
$scope.params.lineNumberMode = 'none';
|
||||||
|
});
|
||||||
|
$scope.params = params || {};
|
||||||
|
_.defaults($scope.params, {
|
||||||
|
format: 'pdf',
|
||||||
|
changeRecommendationMode: Config.get('motions_recommendation_text_mode').value,
|
||||||
|
lineNumberMode: Config.get('motions_default_line_numbering').value,
|
||||||
|
includeReason: true,
|
||||||
|
includeComments: false,
|
||||||
|
});
|
||||||
|
$scope.motions = motions;
|
||||||
|
$scope.singleMotion = singleMotion;
|
||||||
|
|
||||||
|
$scope.export = function () {
|
||||||
|
switch ($scope.params.format) {
|
||||||
|
case 'pdf':
|
||||||
|
MotionPdfExport.export(motions, $scope.params, singleMotion);
|
||||||
|
break;
|
||||||
|
case 'csv':
|
||||||
|
MotionCsvExport.export(motions, $scope.params);
|
||||||
|
break;
|
||||||
|
case 'docx':
|
||||||
|
MotionDocxExport.export(motions, $scope.params);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$scope.closeThisDialog();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
// Cache for MotionPollDetailCtrl so that users choices are keeped during user actions (e. g. save poll form).
|
// Cache for MotionPollDetailCtrl so that users choices are keeped during user actions (e. g. save poll form).
|
||||||
.value('MotionPollDetailCtrlCache', {})
|
.value('MotionPollDetailCtrlCache', {})
|
||||||
|
|
||||||
@ -672,24 +845,15 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
'User',
|
'User',
|
||||||
'Agenda',
|
'Agenda',
|
||||||
'MotionBlock',
|
'MotionBlock',
|
||||||
'MotionChangeRecommendation',
|
|
||||||
'MotionCsvExport',
|
|
||||||
'MotionDocxExport',
|
|
||||||
'MotionContentProvider',
|
|
||||||
'MotionCatalogContentProvider',
|
|
||||||
'PdfMakeConverter',
|
|
||||||
'PdfMakeDocumentProvider',
|
|
||||||
'HTMLValidizer',
|
|
||||||
'Projector',
|
'Projector',
|
||||||
'ProjectionDefault',
|
'ProjectionDefault',
|
||||||
'osTableFilter',
|
'osTableFilter',
|
||||||
'osTableSort',
|
'osTableSort',
|
||||||
'PdfCreate',
|
'MotionExportForm',
|
||||||
|
'MotionPdfExport',
|
||||||
function($scope, $state, $http, gettext, gettextCatalog, ngDialog, MotionForm, Motion,
|
function($scope, $state, $http, gettext, gettextCatalog, ngDialog, MotionForm, Motion,
|
||||||
Category, Config, Tag, Workflow, User, Agenda, MotionBlock, MotionChangeRecommendation,
|
Category, Config, Tag, Workflow, User, Agenda, MotionBlock, Projector,
|
||||||
MotionCsvExport, MotionDocxExport, MotionContentProvider, MotionCatalogContentProvider,
|
ProjectionDefault, osTableFilter, osTableSort, MotionExportForm, MotionPdfExport) {
|
||||||
PdfMakeConverter, PdfMakeDocumentProvider, 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');
|
||||||
@ -883,52 +1047,12 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
$scope.openDialog = function (motion) {
|
$scope.openDialog = function (motion) {
|
||||||
ngDialog.open(MotionForm.getDialog(motion));
|
ngDialog.open(MotionForm.getDialog(motion));
|
||||||
};
|
};
|
||||||
|
// Export dialog
|
||||||
// Export as a pdf file
|
$scope.openExportDialog = function () {
|
||||||
$scope.pdfExport = function() {
|
ngDialog.open(MotionExportForm.getDialog($scope.motionsFiltered));
|
||||||
var filename = gettextCatalog.getString("Motions") + ".pdf";
|
|
||||||
var image_sources = [];
|
|
||||||
$scope.viewChangeRecommendations = {};
|
|
||||||
$scope.viewChangeRecommendations.mode = Config.get('motions_recommendation_text_mode').value;
|
|
||||||
$scope.lineNumberMode = Config.get('motions_default_line_numbering').value;
|
|
||||||
|
|
||||||
//save the arrays of the filtered motions to an array
|
|
||||||
angular.forEach($scope.motionsFiltered, function (motion) {
|
|
||||||
$scope.change_recommendations = MotionChangeRecommendation.filter({
|
|
||||||
'where': {'motion_version_id': {'==': motion.active_version}}
|
|
||||||
});
|
|
||||||
var text = motion.getTextByMode($scope.viewChangeRecommendations.mode, null);
|
|
||||||
var content = HTMLValidizer.validize(text) + HTMLValidizer.validize(motion.getReason());
|
|
||||||
var map = Function.prototype.call.bind([].map);
|
|
||||||
var tmp_image_sources = map($(content).find("img"), function(element) {
|
|
||||||
return element.getAttribute("src");
|
|
||||||
});
|
|
||||||
image_sources = image_sources.concat(tmp_image_sources);
|
|
||||||
});
|
|
||||||
|
|
||||||
//post-request to convert the images. Async.
|
|
||||||
$http.post('/core/encode_media/', JSON.stringify(image_sources)).then(function (success) {
|
|
||||||
var converter = PdfMakeConverter.createInstance(success.data.images);
|
|
||||||
var motionContentProviderArray = [];
|
|
||||||
|
|
||||||
//convert the filtered motions to motionContentProviders
|
|
||||||
angular.forEach($scope.motionsFiltered, function (motion) {
|
|
||||||
motionContentProviderArray.push(MotionContentProvider.createInstance(converter, motion, $scope, User, $http));
|
|
||||||
});
|
|
||||||
var motionCatalogContentProvider = MotionCatalogContentProvider.createInstance(motionContentProviderArray, $scope, User, Category);
|
|
||||||
var documentProvider = PdfMakeDocumentProvider.createInstance(motionCatalogContentProvider);
|
|
||||||
|
|
||||||
PdfCreate.download(documentProvider.getDocument(), filename);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
$scope.pdfExport = function () {
|
||||||
// Export as a csv file
|
MotionPdfExport.export($scope.motionsFiltered);
|
||||||
$scope.csvExport = function () {
|
|
||||||
MotionCsvExport.export($scope.motionsFiltered);
|
|
||||||
};
|
|
||||||
// Export as docx file
|
|
||||||
$scope.docxExport = function () {
|
|
||||||
MotionDocxExport.export($scope.motionsFiltered, $scope.categories);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// *** select mode functions ***
|
// *** select mode functions ***
|
||||||
@ -993,11 +1117,11 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
'$timeout',
|
'$timeout',
|
||||||
'operator',
|
'operator',
|
||||||
'ngDialog',
|
'ngDialog',
|
||||||
|
'gettextCatalog',
|
||||||
'MotionForm',
|
'MotionForm',
|
||||||
'ChangeRecommmendationCreate',
|
'ChangeRecommmendationCreate',
|
||||||
'ChangeRecommmendationView',
|
'ChangeRecommmendationView',
|
||||||
'MotionChangeRecommendation',
|
'MotionChangeRecommendation',
|
||||||
'MotionPDFExport',
|
|
||||||
'Motion',
|
'Motion',
|
||||||
'MotionComment',
|
'MotionComment',
|
||||||
'Category',
|
'Category',
|
||||||
@ -1012,10 +1136,11 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
'Projector',
|
'Projector',
|
||||||
'ProjectionDefault',
|
'ProjectionDefault',
|
||||||
'MotionBlock',
|
'MotionBlock',
|
||||||
function($scope, $http, $timeout, operator, ngDialog, MotionForm,
|
'MotionPdfExport',
|
||||||
ChangeRecommmendationCreate, ChangeRecommmendationView, MotionChangeRecommendation, MotionPDFExport,
|
function($scope, $http, $timeout, operator, ngDialog, gettextCatalog, MotionForm,
|
||||||
|
ChangeRecommmendationCreate, ChangeRecommmendationView, MotionChangeRecommendation,
|
||||||
Motion, MotionComment, Category, Mediafile, Tag, User, Workflow, Config, motionId, MotionInlineEditing,
|
Motion, MotionComment, Category, Mediafile, Tag, User, Workflow, Config, motionId, MotionInlineEditing,
|
||||||
MotionCommentsInlineEditing, Projector, ProjectionDefault, MotionBlock) {
|
MotionCommentsInlineEditing, Projector, ProjectionDefault, MotionBlock, MotionPdfExport) {
|
||||||
var motion = Motion.get(motionId);
|
var motion = Motion.get(motionId);
|
||||||
Category.bindAll({}, $scope, 'categories');
|
Category.bindAll({}, $scope, 'categories');
|
||||||
Mediafile.bindAll({}, $scope, 'mediafiles');
|
Mediafile.bindAll({}, $scope, 'mediafiles');
|
||||||
@ -1296,8 +1421,19 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
$scope.viewChangeRecommendations.init($scope, Config.get('motions_recommendation_text_mode').value);
|
$scope.viewChangeRecommendations.init($scope, Config.get('motions_recommendation_text_mode').value);
|
||||||
|
|
||||||
// PDF creating functions
|
// PDF creating functions
|
||||||
$scope.pdfExport = MotionPDFExport;
|
$scope.pdfExport = function () {
|
||||||
$scope.pdfExport.init($scope);
|
var identifier = $scope.motion.identifier ? '-' + $scope.motion.identifier : '';
|
||||||
|
var params = {
|
||||||
|
filename: gettextCatalog.getString('Motion') + identifier + '.pdf',
|
||||||
|
version: $scope.version,
|
||||||
|
changeRecommendationMode: $scope.viewChangeRecommendations.mode,
|
||||||
|
lineNumberMode: $scope.lineNumberMode,
|
||||||
|
};
|
||||||
|
MotionPdfExport.export(motion, params, true);
|
||||||
|
};
|
||||||
|
$scope.createPollPdf = function () {
|
||||||
|
MotionPdfExport.createPollPdf($scope.motion, $scope.version);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
<i class="fa fa-pencil"></i>
|
<i class="fa fa-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
<!-- pdf -->
|
<!-- pdf -->
|
||||||
<a ng-click="pdfExport.createMotion()" class="btn btn-default btn-sm">
|
<a ng-click="pdfExport()" 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>
|
||||||
@ -310,7 +310,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Print poll PDF -->
|
<!-- Print poll PDF -->
|
||||||
<a os-perms="motions.can_manage" ng-click="pdfExport.createPoll()" class="btn btn-default btn-xs"
|
<a os-perms="motions.can_manage" ng-click="createPollPdf()" class="btn btn-default btn-xs"
|
||||||
title="{{ 'Print ballot paper' | translate }}">
|
title="{{ 'Print ballot paper' | translate }}">
|
||||||
<i class="fa fa-file-pdf-o"></i>
|
<i class="fa fa-file-pdf-o"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
<h1 translate ng-if="!singleMotion && motions.length !== 1">Export motions</h1>
|
||||||
|
<h1 translate ng-if="!singleMotion && motions.length === 1">Export motion</h1>
|
||||||
|
<h1 ng-if="singleMotion"><translate>Export motion</translate> "{{ motions.getTitle() }}"</h1>
|
||||||
|
|
||||||
|
<form name="motionPdfExportForm" ng-submit="export(params)">
|
||||||
|
<formly-form model="params" fields="formFields">
|
||||||
|
<button type="submit" ng-disabled="motionPdfExportForm.$invalid" class="btn btn-primary" translate>
|
||||||
|
Export as {{ params.format.toUpperCase() | translate }}
|
||||||
|
</button>
|
||||||
|
<button ng-click="closeThisDialog()" class="btn btn-default" translate>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</formly-form>
|
||||||
|
</form>
|
@ -36,43 +36,27 @@
|
|||||||
<i class="fa fa-check-square-o"></i>
|
<i class="fa fa-check-square-o"></i>
|
||||||
<translate>Select ...</translate>
|
<translate>Select ...</translate>
|
||||||
</button>
|
</button>
|
||||||
<!-- Export dropdown -->
|
<!-- Export button -->
|
||||||
<div class="dropdown pull-right" uib-dropdown>
|
<button type="button" class="btn btn-default btn-sm pull-right"
|
||||||
<button type="button" class="btn btn-default btn-sm" id="dropdownExport" uib-dropdown-toggle>
|
os-perms="motions.can_manage" ng-click="openExportDialog()">
|
||||||
<i class="fa fa-upload"></i>
|
<i class="fa fa-upload"></i>
|
||||||
<span ng-if="motionsFiltered.length == motions.length" translate>
|
<span ng-if="motionsFiltered.length === motions.length" translate>
|
||||||
Export all
|
Export all
|
||||||
</span>
|
</span>
|
||||||
<span ng-if="motionsFiltered.length != motions.length" translate>
|
<span ng-if="motionsFiltered.length !== motions.length" translate>
|
||||||
Export filtered
|
Export filtered
|
||||||
</span>
|
</span>
|
||||||
<span class="caret"></span>
|
</button>
|
||||||
</button>
|
<button type="button" class="btn btn-default btn-sm pull-right"
|
||||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownExport">
|
os-perms="!motions.can_manage" ng-click="pdfExport()">
|
||||||
<!-- PDF export -->
|
<i class="fa fa-file-pdf-o"></i>
|
||||||
<li>
|
<span ng-if="motionsFiltered.length === motions.length" translate>
|
||||||
<a href="" ng-click="pdfExport()">
|
Export all
|
||||||
<i class="fa fa-file-pdf-o"></i>
|
</span>
|
||||||
PDF
|
<span ng-if="motionsFiltered.length !== motions.length" translate>
|
||||||
</a>
|
Export filtered
|
||||||
</li>
|
</span>
|
||||||
<!-- CSV export -->
|
</button>
|
||||||
<li os-perms="motions.can_manage">
|
|
||||||
<a href="" id="downloadLinkCSV"
|
|
||||||
ng-click="csvExport()">
|
|
||||||
<i class="fa fa-file-text-o"></i>
|
|
||||||
CSV
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<!-- DOCX export -->
|
|
||||||
<li os-perms="motions.can_manage">
|
|
||||||
<a href="" ng-click="docxExport()">
|
|
||||||
<i class="fa fa-file-word-o"></i>
|
|
||||||
DOCX
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user