OpenSlides/openslides/motions/static/js/motions/base.js
Norman Jäckel 09aa2dea72 Review.
2016-08-29 17:15:44 +02:00

357 lines
12 KiB
JavaScript

(function () {
"use strict";
angular.module('OpenSlidesApp.motions', [
'OpenSlidesApp.users',
'OpenSlidesApp.motions.lineNumbering',
'OpenSlidesApp.motions.diff'
])
.factory('WorkflowState', [
'DS',
function (DS) {
return DS.defineResource({
name: 'motions/workflowstate',
methods: {
getNextStates: function () {
var states = [];
_.forEach(this.next_states_id, function (stateId) {
states.push(DS.get('motions/workflowstate', stateId));
});
return states;
}
}
});
}
])
.factory('Workflow', [
'DS',
'jsDataModel',
'WorkflowState',
function (DS, jsDataModel, WorkflowState) {
return DS.defineResource({
name: 'motions/workflow',
useClass: jsDataModel,
relations: {
hasMany: {
'motions/workflowstate': {
localField: 'states',
foreignKey: 'workflow_id',
}
}
}
});
}
])
// Load all MotionWorkflows at startup
.run([
'Workflow',
function (Workflow) {
Workflow.findAll();
}
])
.factory('MotionPoll', [
'DS',
'gettextCatalog',
'Config',
function (DS, gettextCatalog, Config) {
return DS.defineResource({
name: 'motions/motionpoll',
relations: {
belongsTo: {
'motions/motion': {
localField: 'motion',
localKey: 'motion_id',
}
}
},
methods: {
// returns object with value and percent
getVote: function (vote, type) {
if (!this.has_votes) {
return;
}
var value = '';
switch (vote) {
case -1:
value = gettextCatalog.getString('majority');
break;
case -2:
value = gettextCatalog.getString('undocumented');
break;
default:
value = vote;
break;
}
// calculate percent value
var config = Config.get('motions_poll_100_percent_base').value;
var percentStr;
var percentNumber = null;
if (config == "WITHOUT_INVALID" && this.votesvalid > 0 && vote >= 0) {
percentNumber = Math.round(vote * 100 / this.votesvalid * 10) / 10;
} else if (config == "WITH_INVALID" && this.votescast > 0 && vote >= 0) {
percentNumber = Math.round(vote * 100 / (this.votescast) * 10) / 10;
} else if (config == "WITHOUT_ABSTAIN" && vote >= 0) {
if (type == 'yes' || type == 'no') {
percentNumber = Math.round(vote * 100 / (this.yes + this.no) * 10) / 10;
}
}
if (percentNumber !== null) {
percentStr = "(" + percentNumber + "%)";
}
return {
'value': value,
'percentStr': percentStr,
'percentNumber': percentNumber
};
}
}
});
}
])
.factory('Motion', [
'DS',
'MotionPoll',
'jsDataModel',
'gettext',
'operator',
'Config',
'lineNumberingService',
function(DS, MotionPoll, jsDataModel, gettext, operator, Config, lineNumberingService) {
var name = 'motions/motion';
return DS.defineResource({
name: name,
useClass: jsDataModel,
verboseName: gettext('Motion'),
verboseNamePlural: gettext('Motions'),
methods: {
getResourceName: function () {
return name;
},
getVersion: function (versionId) {
versionId = versionId || this.active_version;
var index;
if (versionId == -1) {
index = this.versions.length - 1;
} else {
index = _.findIndex(this.versions, function (element) {
return element.id == versionId;
});
}
return this.versions[index] || {};
},
getTitle: function (versionId) {
return this.getVersion(versionId).title;
},
getText: function (versionId) {
return this.getVersion(versionId).text;
},
getTextWithLineBreaks: function (versionId) {
var lineLength = Config.get('motions_line_length').value,
html = this.getVersion(versionId).text;
return lineNumberingService.insertLineNumbers(html, lineLength);
},
setTextStrippingLineBreaks: function (versionId, text) {
this.text = lineNumberingService.stripLineNumbers(text);
},
getReason: function (versionId) {
return this.getVersion(versionId).reason;
},
// link name which is shown in search result
getSearchResultName: function () {
return this.getTitle();
},
// subtitle of search result
getSearchResultSubtitle: function () {
return "Motion";
},
isAllowed: function (action) {
/*
* Return true if the requested user is allowed to do the specific action.
* There are the following possible actions.
* - see
* - update
* - delete
* - create_poll
* - support
* - unsupport
* - change_state
* - reset_state
*
* NOTE: If you update this function please also update the
* 'get_allowed_actions' function on server side in motions/models.py.
*/
switch (action) {
case 'see':
return (
operator.hasPerms('motions.can_see') &&
(
!this.state.required_permission_to_see ||
operator.hasPerms(this.state.required_permission_to_see) ||
(operator.user in this.submitters)
)
);
case 'update':
return (
operator.hasPerms('motions.can_manage') ||
(
($.inArray(operator.user, this.submitters) != -1) &&
this.state.allow_submitter_edit
)
);
case 'quickedit':
return operator.hasPerms('motions.can_manage');
case 'delete':
return operator.hasPerms('motions.can_manage');
case 'create_poll':
return (
operator.hasPerms('motions.can_manage') &&
this.state.allow_create_poll
);
case 'support':
return (
operator.hasPerms('motions.can_support') &&
this.state.allow_support &&
Config.get('motions_min_supporters').value > 0 &&
($.inArray(operator.user, this.submitters) == -1) &&
($.inArray(operator.user, this.supporters) == -1)
);
case 'unsupport':
return (
this.state.allow_support &&
($.inArray(operator.user, this.supporters) != -1)
);
case 'change_state':
return operator.hasPerms('motions.can_manage');
case 'reset_state':
return operator.hasPerms('motions.can_manage');
case 'can_manage':
return operator.hasPerms('motions.can_manage');
default:
return false;
}
}
},
relations: {
belongsTo: {
'motions/category': {
localField: 'category',
localKey: 'category_id',
},
'agenda/item': {
localKey: 'agenda_item_id',
localField: 'agenda_item',
}
},
hasMany: {
'core/tag': {
localField: 'tags',
localKeys: 'tags_id',
},
'mediafiles/mediafile': {
localField: 'attachments',
localKeys: 'attachments_id',
},
'users/user': [
{
localField: 'submitters',
localKeys: 'submitters_id',
},
{
localField: 'supporters',
localKeys: 'supporters_id',
}
],
'motions/motionpoll': {
localField: 'polls',
foreignKey: 'motion_id',
}
},
hasOne: {
'motions/workflowstate': {
localField: 'state',
localKey: 'state_id',
}
}
}
});
}
])
.factory('Category', [
'DS',
function(DS) {
return DS.defineResource({
name: 'motions/category',
});
}
])
.factory('MotionList', [
function () {
return {
getList: function (items){
var list = [];
_.each(items, function (item) {
list.push({ id: item.id,
item: item });
});
return list;
}
};
}
])
.run([
'Motion',
'Category',
function(Motion, Category) {}
])
// Mark all motion workflow state strings for translation in JavaScript.
// (see motions/signals.py)
.config([
'gettext',
function (gettext) {
// workflow 1
gettext('Simple Workflow');
gettext('submitted');
gettext('accepted');
gettext('Accept');
gettext('rejected');
gettext('Reject');
gettext('not decided');
gettext('Do not decide');
// workflow 2
gettext('Complex Workflow');
gettext('published');
gettext('permitted');
gettext('Permit');
gettext('accepted');
gettext('Accept');
gettext('rejected');
gettext('Reject');
gettext('withdrawed');
gettext('Withdraw');
gettext('adjourned');
gettext('Adjourn');
gettext('not concerned');
gettext('Do not concern');
gettext('commited a bill');
gettext('Commit a bill');
gettext('needs review');
gettext('Needs review');
gettext('rejected (not authorized)');
gettext('Reject (not authorized)');
}
]);
}());