Add checkbox 'show as agenda item'. (Fixes #1783)

Used for customslide, motion and assignment forms.
Changed default value of agenda.type to HIDDEN_ITEM (=2) in model.py.
This commit is contained in:
Emanuel Schuetze 2016-01-22 23:19:41 +01:00
parent 48781b95ba
commit 9ddc558085
6 changed files with 138 additions and 12 deletions

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agenda', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='item',
name='type',
field=models.IntegerField(default=2, choices=[(1, 'Agenda item'), (2, 'Hidden item')]),
),
]

View File

@ -181,7 +181,7 @@ class Item(RESTModelMixin, models.Model):
type = models.IntegerField( type = models.IntegerField(
choices=ITEM_TYPE, choices=ITEM_TYPE,
default=AGENDA_ITEM) default=HIDDEN_ITEM)
""" """
Type of the agenda item. Type of the agenda item.

View File

@ -72,7 +72,11 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
closeByEscape: false, closeByEscape: false,
closeByDocument: false, closeByDocument: false,
resolve: { resolve: {
assignment: function() {return Assignment.find($stateParams.id)} assignment: function() {
return Assignment.find($stateParams.id).then(function(assignment) {
return Assignment.loadRelations(assignment, 'agenda_item');
});
},
}, },
preCloseCallback: function() { preCloseCallback: function() {
$state.go('assignments.assignment.detail', {assignment: $stateParams.id}); $state.go('assignments.assignment.detail', {assignment: $stateParams.id});
@ -88,13 +92,19 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
// Service for generic assignment form (create and update) // Service for generic assignment form (create and update)
.factory('AssignmentForm', [ .factory('AssignmentForm', [
'gettextCatalog', 'gettextCatalog',
function (gettextCatalog) { 'operator',
function (gettextCatalog, operator) {
return { return {
// ngDialog for assignment form // ngDialog for assignment form
getDialog: function (assignment) { getDialog: function (assignment) {
if (assignment) { if (assignment) {
var resolve = { var resolve = {
assignment: function(Assignment) {return Assignment.find(assignment.id);} assignment: function() {
return assignment;
},
agenda_item: function(Assignment) {
return Assignment.loadRelations(assignment, 'agenda_item');
}
}; };
} }
return { return {
@ -139,6 +149,15 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
templateOptions: { templateOptions: {
label: gettextCatalog.getString('Default comment on the ballot paper') label: gettextCatalog.getString('Default comment on the ballot paper')
} }
},
{
key: 'showAsAgendaItem',
type: 'checkbox',
templateOptions: {
label: gettextCatalog.getString('Show as agenda item'),
description: gettextCatalog.getString('If deactivated the election appears as internal item on agenda.')
},
hide: !operator.hasPerms('assignments.can_manage')
}]; }];
} }
} }
@ -385,7 +404,8 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
'$state', '$state',
'Assignment', 'Assignment',
'AssignmentForm', 'AssignmentForm',
function($scope, $state, Assignment, AssignmentForm) { 'Agenda',
function($scope, $state, Assignment, AssignmentForm, Agenda) {
$scope.model = {}; $scope.model = {};
// set default value for open posts form field // set default value for open posts form field
$scope.model.open_posts = 1; $scope.model.open_posts = 1;
@ -396,6 +416,16 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
$scope.save = function(assignment) { $scope.save = function(assignment) {
Assignment.create(assignment).then( Assignment.create(assignment).then(
function(success) { function(success) {
// find related agenda item
Agenda.find(success.agenda_item_id).then(function(item) {
// check form element and set item type (AGENDA_ITEM = 1, HIDDEN_ITEM = 2)
var type = assignment.showAsAgendaItem ? 1 : 2;
// save only if agenda item type is modified
if (item.type != type) {
item.type = type;
Agenda.save(item);
}
});
$scope.closeThisDialog(); $scope.closeThisDialog();
} }
); );
@ -408,22 +438,36 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
'$state', '$state',
'Assignment', 'Assignment',
'AssignmentForm', 'AssignmentForm',
'Agenda',
'assignment', 'assignment',
function($scope, $state, Assignment, AssignmentForm, assignment) { function($scope, $state, Assignment, AssignmentForm, Agenda, assignment) {
$scope.alert = {}; $scope.alert = {};
// set initial values for form model by create deep copy of assignment object // set initial values for form model by create deep copy of assignment object
// so list/detail view is not updated while editing // so list/detail view is not updated while editing
$scope.model = angular.copy(assignment); $scope.model = angular.copy(assignment);
// get all form fields // get all form fields
$scope.formFields = AssignmentForm.getFormFields(); $scope.formFields = AssignmentForm.getFormFields();
for (var i = 0; i < $scope.formFields.length; i++) {
if ($scope.formFields[i].key == "showAsAgendaItem") {
// get state from agenda item (hidden/internal or agenda item)
$scope.formFields[i].defaultValue = !assignment.agenda_item.is_hidden;
}
}
// save assignment // save assignment
$scope.save = function (assignment) { $scope.save = function (assignment) {
// inject the changed assignment (copy) object back into DS store // inject the changed assignment (copy) object back into DS store
Assignment.inject(assignment); Assignment.inject(assignment);
// save change motion object on server // save change assignment object on server
Assignment.save(assignment).then( Assignment.save(assignment).then(
function(success) { function(success) {
// check form element and set item type (AGENDA_ITEM = 1, HIDDEN_ITEM = 2)
var type = assignment.showAsAgendaItem ? 1 : 2;
// save only if agenda item type is modified
if (assignment.agenda_item.type != type) {
assignment.agenda_item.type = type;
Agenda.save(assignment.agenda_item);
}
$scope.closeThisDialog(); $scope.closeThisDialog();
}, },
function (error) { function (error) {

View File

@ -504,6 +504,14 @@ angular.module('OpenSlidesApp.core.site', [
placeholder: gettextCatalog.getString('Select or search an attachment ...') placeholder: gettextCatalog.getString('Select or search an attachment ...')
} }
}, },
{
key: 'showOnAgenda',
type: 'checkbox',
templateOptions: {
label: gettextCatalog.getString('Show on agenda'),
description: gettextCatalog.getString('If deactivated it appears as internal item.')
}
},
]; ];
} }
} }
@ -729,7 +737,8 @@ angular.module('OpenSlidesApp.core.site', [
'$state', '$state',
'Customslide', 'Customslide',
'CustomslideForm', 'CustomslideForm',
function($scope, $state, Customslide, CustomslideForm) { 'Agenda',
function($scope, $state, Customslide, CustomslideForm, Agenda) {
$scope.customslide = {}; $scope.customslide = {};
// get all form fields // get all form fields
$scope.formFields = CustomslideForm.getFormFields(); $scope.formFields = CustomslideForm.getFormFields();
@ -738,6 +747,14 @@ angular.module('OpenSlidesApp.core.site', [
$scope.save = function (customslide) { $scope.save = function (customslide) {
Customslide.create(customslide).then( Customslide.create(customslide).then(
function(success) { function(success) {
// show as agenda item
if (customslide.showOnAgenda) {
Agenda.find(success.agenda_item_id).then(function(item) {
// set item type to AGENDA_ITEM = 1 (default is HIDDEN_ITEM = 2)
item.type = 1;
Agenda.save(item);
});
}
$scope.closeThisDialog(); $scope.closeThisDialog();
} }
); );

View File

@ -83,7 +83,11 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
closeByEscape: false, closeByEscape: false,
closeByDocument: false, closeByDocument: false,
resolve: { resolve: {
motion: function() {return Motion.find($stateParams.id)} motion: function() {
return Motion.find($stateParams.id).then(function(motion) {
return Motion.loadRelations(motion, 'agenda_item');
});
},
}, },
preCloseCallback: function() { preCloseCallback: function() {
$state.go('motions.motion.detail', {motion: $stateParams.id}); $state.go('motions.motion.detail', {motion: $stateParams.id});
@ -153,7 +157,12 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
getDialog: function (motion) { getDialog: function (motion) {
if (motion) { if (motion) {
var resolve = { var resolve = {
motion: function(Motion) { return Motion.find(motion.id); } motion: function() {
return motion;
},
agenda_item: function(Motion) {
return Motion.loadRelations(motion, 'agenda_item');
}
}; };
} }
return { return {
@ -224,6 +233,15 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
}, },
hide: true hide: true
}, },
{
key: 'showAsAgendaItem',
type: 'checkbox',
templateOptions: {
label: gettextCatalog.getString('Show as agenda item'),
description: gettextCatalog.getString('If deactivated the motion appears as internal item on agenda.')
},
hide: !operator.hasPerms('motions.can_manage')
},
{ {
key: 'more', key: 'more',
type: 'checkbox', type: 'checkbox',
@ -595,7 +613,8 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
'Tag', 'Tag',
'User', 'User',
'Workflow', 'Workflow',
function($scope, $state, gettext, Motion, MotionForm, Category, Config, Mediafile, Tag, User, Workflow) { 'Agenda',
function($scope, $state, gettext, Motion, MotionForm, Category, Config, Mediafile, Tag, User, Workflow, Agenda) {
Category.bindAll({}, $scope, 'categories'); Category.bindAll({}, $scope, 'categories');
Mediafile.bindAll({}, $scope, 'mediafiles'); Mediafile.bindAll({}, $scope, 'mediafiles');
Tag.bindAll({}, $scope, 'tags'); Tag.bindAll({}, $scope, 'tags');
@ -614,6 +633,16 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
$scope.save = function (motion) { $scope.save = function (motion) {
Motion.create(motion).then( Motion.create(motion).then(
function(success) { function(success) {
// find related agenda item
Agenda.find(success.agenda_item_id).then(function(item) {
// check form element and set item type (AGENDA_ITEM = 1, HIDDEN_ITEM = 2)
var type = motion.showAsAgendaItem ? 1 : 2;
// save only if agenda item type is modified
if (item.type != type) {
item.type = type;
Agenda.save(item);
}
});
$scope.closeThisDialog(); $scope.closeThisDialog();
} }
); );
@ -632,8 +661,9 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
'Tag', 'Tag',
'User', 'User',
'Workflow', 'Workflow',
'Agenda',
'motion', 'motion',
function($scope, $state, Motion, Category, Config, Mediafile, MotionForm, Tag, User, Workflow, motion) { function($scope, $state, Motion, Category, Config, Mediafile, MotionForm, Tag, User, Workflow, Agenda, 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');
@ -673,6 +703,10 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
$scope.formFields[i].hide = false; $scope.formFields[i].hide = false;
} }
} }
if ($scope.formFields[i].key == "showAsAgendaItem") {
// get state from agenda item (hidden/internal or agenda item)
$scope.formFields[i].defaultValue = !motion.agenda_item.is_hidden;
}
if ($scope.formFields[i].key == "workflow_id") { if ($scope.formFields[i].key == "workflow_id") {
// get saved workflow id from state // get saved workflow id from state
$scope.formFields[i].defaultValue = motion.state.workflow_id; $scope.formFields[i].defaultValue = motion.state.workflow_id;
@ -686,6 +720,13 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
// save change motion object on server // save change motion object on server
Motion.save(motion, { method: 'PATCH' }).then( Motion.save(motion, { method: 'PATCH' }).then(
function(success) { function(success) {
// check form element and set item type (AGENDA_ITEM = 1, HIDDEN_ITEM = 2)
var type = motion.showAsAgendaItem ? 1 : 2;
// save only if agenda item type is modified
if (motion.agenda_item.type != type) {
motion.agenda_item.type = type;
Agenda.save(motion.agenda_item);
}
$scope.closeThisDialog(); $scope.closeThisDialog();
}, },
function (error) { function (error) {

View File

@ -243,13 +243,18 @@ class Numbering(TestCase):
self.client = APIClient() self.client = APIClient()
self.client.login(username='admin', password='admin') self.client.login(username='admin', password='admin')
self.item_1 = CustomSlide.objects.create(title='test_title_thuha8eef7ohXar3eech').agenda_item self.item_1 = CustomSlide.objects.create(title='test_title_thuha8eef7ohXar3eech').agenda_item
self.item_1.type = Item.AGENDA_ITEM
self.item_1.save()
self.item_2 = CustomSlide.objects.create(title='test_title_eisah7thuxa1eingaeLo').agenda_item self.item_2 = CustomSlide.objects.create(title='test_title_eisah7thuxa1eingaeLo').agenda_item
self.item_2.type = Item.AGENDA_ITEM
self.item_2.weight = 2 self.item_2.weight = 2
self.item_2.save() self.item_2.save()
self.item_2_1 = CustomSlide.objects.create(title='test_title_Qui0audoaz5gie1phish').agenda_item self.item_2_1 = CustomSlide.objects.create(title='test_title_Qui0audoaz5gie1phish').agenda_item
self.item_2_1.type = Item.AGENDA_ITEM
self.item_2_1.parent = self.item_2 self.item_2_1.parent = self.item_2
self.item_2_1.save() self.item_2_1.save()
self.item_3 = CustomSlide.objects.create(title='test_title_ah7tphisheineisgaeLo').agenda_item self.item_3 = CustomSlide.objects.create(title='test_title_ah7tphisheineisgaeLo').agenda_item
self.item_3.type = Item.AGENDA_ITEM
self.item_3.weight = 3 self.item_3.weight = 3
self.item_3.save() self.item_3.save()