Added new motion state flags to show an additional fields
... to extend state name and recommendation label. Hide forState and forRecommendation fields in motion form and detail view (comment section).
This commit is contained in:
parent
b0ff8375a8
commit
78765ae9ed
25
openslides/motions/migrations/0007_auto_20161027_1406.py
Normal file
25
openslides/motions/migrations/0007_auto_20161027_1406.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.2 on 2016-10-27 12:06
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('motions', '0006_auto_20161017_2020'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='state',
|
||||||
|
name='show_recommendation_extension_field',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='state',
|
||||||
|
name='show_state_extension_field',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
@ -1085,6 +1085,20 @@ class State(RESTModelMixin, models.Model):
|
|||||||
this one, else it does.
|
this one, else it does.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
show_state_extension_field = models.BooleanField(default=False)
|
||||||
|
"""
|
||||||
|
If true, an additional input field (from motion comment) is visible
|
||||||
|
to extend the state name. The full state name is composed of the given
|
||||||
|
state name and the entered value of this input field.
|
||||||
|
"""
|
||||||
|
|
||||||
|
show_recommendation_extension_field = models.BooleanField(default=False)
|
||||||
|
"""
|
||||||
|
If true, an additional input field (from motion comment) is visible
|
||||||
|
to extend the recommendation label. The full recommendation string is
|
||||||
|
composed of the given recommendation label and the entered value of this input field.
|
||||||
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ()
|
default_permissions = ()
|
||||||
|
|
||||||
|
@ -71,6 +71,8 @@ class StateSerializer(ModelSerializer):
|
|||||||
'versioning',
|
'versioning',
|
||||||
'leave_old_version_active',
|
'leave_old_version_active',
|
||||||
'dont_set_identifier',
|
'dont_set_identifier',
|
||||||
|
'show_state_extension_field',
|
||||||
|
'show_recommendation_extension_field',
|
||||||
'next_states',
|
'next_states',
|
||||||
'workflow')
|
'workflow')
|
||||||
|
|
||||||
|
@ -147,11 +147,12 @@ angular.module('OpenSlidesApp.motions', [
|
|||||||
'MotionComment',
|
'MotionComment',
|
||||||
'jsDataModel',
|
'jsDataModel',
|
||||||
'gettext',
|
'gettext',
|
||||||
|
'gettextCatalog',
|
||||||
'operator',
|
'operator',
|
||||||
'Config',
|
'Config',
|
||||||
'lineNumberingService',
|
'lineNumberingService',
|
||||||
'diffService',
|
'diffService',
|
||||||
function(DS, MotionPoll, MotionChangeRecommendation, MotionComment, jsDataModel, gettext, operator, Config,
|
function(DS, MotionPoll, MotionChangeRecommendation, MotionComment, jsDataModel, gettext, gettextCatalog, operator, Config,
|
||||||
lineNumberingService, diffService) {
|
lineNumberingService, diffService) {
|
||||||
var name = 'motions/motion';
|
var name = 'motions/motion';
|
||||||
return DS.defineResource({
|
return DS.defineResource({
|
||||||
@ -288,6 +289,38 @@ angular.module('OpenSlidesApp.motions', [
|
|||||||
getReason: function (versionId) {
|
getReason: function (versionId) {
|
||||||
return this.getVersion(versionId).reason;
|
return this.getVersion(versionId).reason;
|
||||||
},
|
},
|
||||||
|
// full state name - optional with custom state name extension
|
||||||
|
// depended by state and provided by a custom comment field
|
||||||
|
getStateName: function () {
|
||||||
|
var additionalName = '';
|
||||||
|
if (this.state.show_state_extension_field) {
|
||||||
|
// check motion comment fields for flag 'forState'
|
||||||
|
var fields = Config.get('motions_comments').value;
|
||||||
|
var index = _.findIndex(fields, ['forState', true]);
|
||||||
|
if (index > -1) {
|
||||||
|
additionalName = ' ' + this.comments[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gettextCatalog.getString(this.state.name) + additionalName;
|
||||||
|
},
|
||||||
|
// full recommendation string - optional with custom recommendationextension
|
||||||
|
// depended by state and provided by a custom comment field
|
||||||
|
getRecommendationName: function () {
|
||||||
|
var recommendation = '';
|
||||||
|
var additionalName = '';
|
||||||
|
if (this.recommendation) {
|
||||||
|
recommendation = gettextCatalog.getString(this.recommendation.recommendation_label);
|
||||||
|
if (this.recommendation.show_recommendation_extension_field) {
|
||||||
|
// check motion comment fields for flag 'forRecommendation'
|
||||||
|
var fields = Config.get('motions_comments').value;
|
||||||
|
var index = _.findIndex(fields, ['forRecommendation', true]);
|
||||||
|
if (index > -1) {
|
||||||
|
additionalName = ' ' + this.comments[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return recommendation + additionalName;
|
||||||
|
},
|
||||||
// link name which is shown in search result
|
// link name which is shown in search result
|
||||||
getSearchResultName: function () {
|
getSearchResultName: function () {
|
||||||
return this.getTitle();
|
return this.getTitle();
|
||||||
@ -450,7 +483,7 @@ angular.module('OpenSlidesApp.motions', [
|
|||||||
getFormFields: function () {
|
getFormFields: function () {
|
||||||
var fields = Config.get('motions_comments').value;
|
var fields = Config.get('motions_comments').value;
|
||||||
return _.map(
|
return _.map(
|
||||||
fields,
|
_.filter(fields, function(element) { return !element.forState && !element.forRecommendation; }),
|
||||||
function (field) {
|
function (field) {
|
||||||
return {
|
return {
|
||||||
key: 'comment ' + field.name,
|
key: 'comment ' + field.name,
|
||||||
@ -484,7 +517,16 @@ angular.module('OpenSlidesApp.motions', [
|
|||||||
for (var i = 0; i < fields.length; i++) {
|
for (var i = 0; i < fields.length; i++) {
|
||||||
motion.comments.push(motion['comment ' + fields[i].name] || '');
|
motion.comments.push(motion['comment ' + fields[i].name] || '');
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
getFieldNameForFlag: function (flag) {
|
||||||
|
var fields = Config.get('motions_comments').value;
|
||||||
|
var fieldName = '';
|
||||||
|
var index = _.findIndex(fields, [flag, true]);
|
||||||
|
if (index > -1) {
|
||||||
|
fieldName = fields[index].name;
|
||||||
|
}
|
||||||
|
return fieldName;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -82,7 +82,7 @@ angular.module('OpenSlidesApp.motions.DOCX', [])
|
|||||||
}).join(', '),
|
}).join(', '),
|
||||||
signature_translation: signature_translation,
|
signature_translation: signature_translation,
|
||||||
status_translation: status_translation,
|
status_translation: status_translation,
|
||||||
status: gettextCatalog.getString(motion.state.name),
|
status: motion.getStateName(),
|
||||||
text: html2docx(motion.getText()),
|
text: html2docx(motion.getText()),
|
||||||
reason_translation: motion.getReason().length === 0 ? '' : reason_translation,
|
reason_translation: motion.getReason().length === 0 ? '' : reason_translation,
|
||||||
reason: html2docx(motion.getReason()),
|
reason: html2docx(motion.getReason()),
|
||||||
|
@ -42,7 +42,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
|
|||||||
// Generate text of signment
|
// Generate text of signment
|
||||||
var signment = function() {
|
var signment = function() {
|
||||||
var label = converter.createElement("text", gettextCatalog.getString('Submitter') + ':\nStatus:');
|
var label = converter.createElement("text", gettextCatalog.getString('Submitter') + ':\nStatus:');
|
||||||
var state = converter.createElement("text", User.get(motion.submitters_id[0]).full_name + '\n'+gettextCatalog.getString(motion.state.name));
|
var state = converter.createElement("text", User.get(motion.submitters_id[0]).full_name + '\n' + motion.getStateName());
|
||||||
state.width = "70%";
|
state.width = "70%";
|
||||||
label.width = "30%";
|
label.width = "30%";
|
||||||
label.bold = true;
|
label.bold = true;
|
||||||
|
@ -1013,6 +1013,7 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
'MotionChangeRecommendation',
|
'MotionChangeRecommendation',
|
||||||
'MotionPDFExport',
|
'MotionPDFExport',
|
||||||
'Motion',
|
'Motion',
|
||||||
|
'MotionComment',
|
||||||
'Category',
|
'Category',
|
||||||
'Mediafile',
|
'Mediafile',
|
||||||
'Tag',
|
'Tag',
|
||||||
@ -1026,9 +1027,8 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
'ProjectionDefault',
|
'ProjectionDefault',
|
||||||
function($scope, $http, operator, ngDialog, MotionForm,
|
function($scope, $http, operator, ngDialog, MotionForm,
|
||||||
ChangeRecommmendationCreate, ChangeRecommmendationView, MotionChangeRecommendation, MotionPDFExport,
|
ChangeRecommmendationCreate, ChangeRecommmendationView, MotionChangeRecommendation, MotionPDFExport,
|
||||||
Motion, Category, Mediafile, Tag, User, Workflow, Config, motion, MotionInlineEditing, gettextCatalog,
|
Motion, MotionComment, Category, Mediafile, Tag, User, Workflow, Config, motion, MotionInlineEditing, gettextCatalog,
|
||||||
Projector, ProjectionDefault) {
|
Projector, ProjectionDefault) {
|
||||||
Motion.bindOne(motion.id, $scope, 'motion');
|
|
||||||
Category.bindAll({}, $scope, 'categories');
|
Category.bindAll({}, $scope, 'categories');
|
||||||
Mediafile.bindAll({}, $scope, 'mediafiles');
|
Mediafile.bindAll({}, $scope, 'mediafiles');
|
||||||
Tag.bindAll({}, $scope, 'tags');
|
Tag.bindAll({}, $scope, 'tags');
|
||||||
@ -1041,10 +1041,17 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
}, function () {
|
}, function () {
|
||||||
$scope.defaultProjectorId = ProjectionDefault.filter({name: 'motions'})[0].projector_id;
|
$scope.defaultProjectorId = ProjectionDefault.filter({name: 'motions'})[0].projector_id;
|
||||||
});
|
});
|
||||||
|
$scope.$watch(function () {
|
||||||
|
return Motion.lastModified(motion.id);
|
||||||
|
}, function () {
|
||||||
|
$scope.motion = Motion.get(motion.id);
|
||||||
|
MotionComment.populateFields($scope.motion);
|
||||||
|
});
|
||||||
|
$scope.commentsFields = Config.get('motions_comments').value;
|
||||||
|
$scope.commentFieldForState = MotionComment.getFieldNameForFlag('forState');
|
||||||
|
$scope.commentFieldForRecommendation = MotionComment.getFieldNameForFlag('forRecommendation');
|
||||||
$scope.version = motion.active_version;
|
$scope.version = motion.active_version;
|
||||||
$scope.isCollapsed = true;
|
$scope.isCollapsed = true;
|
||||||
$scope.commentsFields = Config.get('motions_comments').value;
|
|
||||||
|
|
||||||
$scope.lineNumberMode = Config.get('motions_default_line_numbering').value;
|
$scope.lineNumberMode = Config.get('motions_default_line_numbering').value;
|
||||||
$scope.setLineNumberMode = function(mode) {
|
$scope.setLineNumberMode = function(mode) {
|
||||||
$scope.lineNumberMode = mode;
|
$scope.lineNumberMode = mode;
|
||||||
@ -1119,6 +1126,26 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
$scope.reset_state = function () {
|
$scope.reset_state = function () {
|
||||||
$http.put('/rest/motions/motion/' + motion.id + '/set_state/', {});
|
$http.put('/rest/motions/motion/' + motion.id + '/set_state/', {});
|
||||||
};
|
};
|
||||||
|
// save additional state field
|
||||||
|
$scope.saveAdditionalStateField = function (stateExtension) {
|
||||||
|
if (stateExtension) {
|
||||||
|
motion["comment " + $scope.commentFieldForState] = stateExtension;
|
||||||
|
motion.title = motion.getTitle(-1);
|
||||||
|
motion.text = motion.getText(-1);
|
||||||
|
motion.reason = motion.getReason(-1);
|
||||||
|
Motion.save(motion);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// save additional recommendation field
|
||||||
|
$scope.saveAdditionalRecommendationField = function (recommendationExtension) {
|
||||||
|
if (recommendationExtension) {
|
||||||
|
motion["comment " + $scope.commentFieldForRecommendation] = recommendationExtension;
|
||||||
|
motion.title = motion.getTitle(-1);
|
||||||
|
motion.text = motion.getText(-1);
|
||||||
|
motion.reason = motion.getReason(-1);
|
||||||
|
Motion.save(motion);
|
||||||
|
}
|
||||||
|
};
|
||||||
// update recommendation
|
// update recommendation
|
||||||
$scope.updateRecommendation = function (recommendation_id) {
|
$scope.updateRecommendation = function (recommendation_id) {
|
||||||
$http.put('/rest/motions/motion/' + motion.id + '/set_recommendation/', {'recommendation': recommendation_id});
|
$http.put('/rest/motions/motion/' + motion.id + '/set_recommendation/', {'recommendation': recommendation_id});
|
||||||
@ -1183,7 +1210,7 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
isAllowed = operator.hasPerms('motions.can_see_and_manage_comments') || _.find(
|
isAllowed = operator.hasPerms('motions.can_see_and_manage_comments') || _.find(
|
||||||
$scope.commentsFields,
|
$scope.commentsFields,
|
||||||
function(field) {
|
function(field) {
|
||||||
return field.public;
|
return field.public && !field.forState && !field.forRecommendation;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -65,11 +65,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<td>
|
<td>
|
||||||
<div class="label" ng-class="'label-'+motion.state.css_class">
|
<div class="label" ng-class="'label-'+motion.state.css_class">
|
||||||
{{ motion.state.name | translate }}
|
{{ motion.getStateName() }}
|
||||||
</div>
|
</div>
|
||||||
<td>
|
<td>
|
||||||
<div class="label" ng-class="'label-'+motion.recommendation.css_class">
|
<div class="label" ng-class="'label-'+motion.recommendation.css_class">
|
||||||
{{ motion.recommendation.recommendation_label | translate }}
|
{{ motion.getRecommendationName() }}
|
||||||
</div>
|
</div>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -115,7 +115,19 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="label" ng-class="'label-'+motion.state.css_class">
|
<div class="label" ng-class="'label-'+motion.state.css_class">
|
||||||
{{ motion.state.name | translate }}
|
{{ motion.getStateName() }}
|
||||||
|
</div>
|
||||||
|
<div os-perms="motions.can_manage" class="input-group spacer"
|
||||||
|
ng-show="motion.state.show_state_extension_field">
|
||||||
|
<label class="sr-only" for="stateExtensionField">{{ commentFieldForState }}</label>
|
||||||
|
<input type="text" ng-model="stateExtension"
|
||||||
|
id="stateNameExtensionField" class="form-control input-sm"
|
||||||
|
placeholder="{{ commentFieldForState }}">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button ng-click="saveAdditionalStateField(stateExtension)" class="btn btn-default btn-sm">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Recommendation -->
|
<!-- Recommendation -->
|
||||||
@ -142,7 +154,19 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="label" ng-class="'label-'+motion.recommendation.css_class">
|
<div class="label" ng-class="'label-'+motion.recommendation.css_class">
|
||||||
{{ motion.recommendation.recommendation_label | translate }}
|
{{ motion.getRecommendationName() }}
|
||||||
|
</div>
|
||||||
|
<div class="input-group spacer"
|
||||||
|
ng-show="motion.recommendation.show_recommendation_extension_field">
|
||||||
|
<label class="sr-only" for="recommendationExtensionField">{{ commentFieldForRecommendation }}</label>
|
||||||
|
<input type="text" ng-model="recommendationExtension"
|
||||||
|
id="recommendationExtensionField" class="form-control input-sm"
|
||||||
|
placeholder="{{ commentFieldForRecommendation }}">
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button ng-click="saveAdditionalRecommendationField(recommendationExtension)" class="btn btn-default btn-sm">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -405,9 +429,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="details" ng-if="isAllowedToSeeCommentField()">
|
<div class="details" ng-if="isAllowedToSeeCommentField()">
|
||||||
<h3>Motion Comments</h3>
|
<h3 translate>Comments</h3>
|
||||||
<div ng-repeat="field in commentsFields">
|
<div ng-repeat="field in commentsFields">
|
||||||
<div ng-if="field.public || operator.hasPerms('motions.can_see_and_manage_comments')">
|
<div ng-if="(field.public && !field.forState && !field.forRecommendation) ||
|
||||||
|
(operator.hasPerms('motions.can_see_and_manage_comments') && !field.forState && !field.forRecommendation)">
|
||||||
<h4>
|
<h4>
|
||||||
{{ field.name }}
|
{{ field.name }}
|
||||||
<span ng-if="!field.public" class="label label-warning" translate>internal</span>
|
<span ng-if="!field.public" class="label label-warning" translate>internal</span>
|
||||||
|
@ -389,7 +389,7 @@
|
|||||||
<i class="fa fa-paperclip" ng-if="motion.attachments_id.length > 0"></i>
|
<i class="fa fa-paperclip" ng-if="motion.attachments_id.length > 0"></i>
|
||||||
<span style="padding: 5px;" ng-mouseover="motion.stateHover=true" ng-mouseleave="motion.stateHover=false">
|
<span style="padding: 5px;" ng-mouseover="motion.stateHover=true" ng-mouseleave="motion.stateHover=false">
|
||||||
<span class="label" ng-class="'label-'+motion.state.css_class">
|
<span class="label" ng-class="'label-'+motion.state.css_class">
|
||||||
{{ motion.state.name | translate }}
|
{{ motion.getStateName() }}
|
||||||
</span>
|
</span>
|
||||||
<span os-perms="motions.can_manage" ng-class="{'hiddenDiv': !motion.stateHover}" uib-dropdown>
|
<span os-perms="motions.can_manage" ng-class="{'hiddenDiv': !motion.stateHover}" uib-dropdown>
|
||||||
<i class="fa fa-cog pointer" uib-dropdown-toggle id="state-dropdown{{ motion.id }}"></i>
|
<i class="fa fa-cog pointer" uib-dropdown-toggle id="state-dropdown{{ motion.id }}"></i>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div id="sidebox">
|
<div id="sidebox">
|
||||||
<!-- State -->
|
<!-- State -->
|
||||||
<h3 translate>State</h3>
|
<h3 translate>State</h3>
|
||||||
{{ motion.state.name | translate }}
|
{{ motion.getStateName() }}
|
||||||
|
|
||||||
<!-- Submitters -->
|
<!-- Submitters -->
|
||||||
<h3 ng-if="motion.submitters.length > 0" translate>Submitters</h3>
|
<h3 ng-if="motion.submitters.length > 0" translate>Submitters</h3>
|
||||||
|
Loading…
Reference in New Issue
Block a user