Merge pull request #3341 from normanjaeckel/BetterAgenda

Supported server side setup of new agenda items (type and parent).
This commit is contained in:
Emanuel Schütze 2018-01-29 10:38:50 +01:00 committed by GitHub
commit ec2fcbdd73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 213 additions and 184 deletions

View File

@ -12,6 +12,7 @@ Agenda:
- Fixed wrong sorting of last speakers [#3193].
- Fixed issue when sorting a new inserted speaker [#3210].
- New permission for managing lists of speakers [#3366].
- Fixed multiple request on creation of agenda related items [#3341].
Motions:
- New export dialog [#3185].

View File

@ -14,16 +14,24 @@ def listen_to_related_object_post_save(sender, instance, created, **kwargs):
Receiver function to create agenda items. It is connected to the signal
django.db.models.signals.post_save during app loading.
Do not run caching and autoupdate if the instance as an attribute
skip_autoupdate (regardless of its truthy or falsy conent).
The agenda_item_update_information container may have fields like type,
parent_id, comment, duration, weight or skip_autoupdate.
Do not run caching and autoupdate if the instance has a key
skip_autoupdate in the agenda_item_update_information container.
"""
if hasattr(instance, 'get_agenda_title'):
if created:
attrs = {}
for attr in ('type', 'parent_id', 'comment', 'duration', 'weight'):
if instance.agenda_item_update_information.get(attr):
attrs[attr] = instance.agenda_item_update_information.get(attr)
Item.objects.create(content_object=instance, **attrs)
# If the object is created, the related_object has to be sent again.
Item.objects.create(content_object=instance)
if not hasattr(instance, 'skip_autoupdate'):
if not instance.agenda_item_update_information.get('skip_autoupdate'):
inform_changed_data(instance)
elif not hasattr(instance, 'skip_autoupdate'):
elif not instance.agenda_item_update_information.get('skip_autoupdate'):
# If the object has changed, then also the agenda item has to be sent.
inform_changed_data(instance.agenda_item)

View File

@ -21,32 +21,6 @@ angular.module('OpenSlidesApp.agenda', ['OpenSlidesApp.users'])
}
])
.factory('AgendaUpdate',[
'Agenda',
'operator',
function(Agenda, operator) {
return {
saveChanges: function (item_id, changes) {
// change agenda item only if user has the permission to do that
if (operator.hasPerms('agenda.can_manage agenda.can_see_hidden_items')) {
Agenda.find(item_id).then(function (item) {
var something = false;
_.each(changes, function(change) {
if (change.value !== item[change.key]) {
item[change.key] = change.value;
something = true;
}
});
if (something === true) {
Agenda.save(item);
}
});
}
}
};
}
])
.factory('Agenda', [
'$http',
'DS',

View File

@ -330,6 +330,11 @@ class Assignment(RESTModelMixin, models.Model):
vote_results_dict[candidate].append(votes)
return vote_results_dict
"""
Container for runtime information for agenda app (on create or update of this instance).
"""
agenda_item_update_information = {} # type: Dict[str, Any]
def get_agenda_title(self):
return str(self)

View File

@ -194,6 +194,8 @@ class AssignmentFullSerializer(ModelSerializer):
"""
assignment_related_users = AssignmentRelatedUserSerializer(many=True, read_only=True)
polls = AssignmentAllPollSerializer(many=True, read_only=True)
agenda_type = IntegerField(write_only=True, required=False, min_value=1, max_value=2)
agenda_parent_id = IntegerField(write_only=True, required=False, min_value=1)
class Meta:
model = Assignment
@ -207,6 +209,8 @@ class AssignmentFullSerializer(ModelSerializer):
'poll_description_default',
'polls',
'agenda_item_id',
'agenda_type',
'agenda_parent_id',
'tags',)
validators = (posts_validator,)
@ -215,6 +219,19 @@ class AssignmentFullSerializer(ModelSerializer):
data['description'] = validate_html(data['description'])
return data
def create(self, validated_data):
"""
Customized create method. Set information about related agenda item
into agenda_item_update_information container.
"""
agenda_type = validated_data.pop('agenda_type', None)
agenda_parent_id = validated_data.pop('agenda_parent_id', None)
assignment = Assignment(**validated_data)
assignment.agenda_item_update_information['type'] = agenda_type
assignment.agenda_item_update_information['parent_id'] = agenda_parent_id
assignment.save()
return assignment
class AssignmentShortSerializer(AssignmentFullSerializer):
"""

View File

@ -155,21 +155,21 @@ angular.module('OpenSlidesApp.assignments.site', [
templateOptions: {
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') && operator.hasPerms('agenda.can_manage'))
}];
// parent item
// show as agenda item + parent item
if (isCreateForm) {
formFields.push({
key: 'agenda_parent_item_id',
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') && operator.hasPerms('agenda.can_manage'))
});
formFields.push({
key: 'agenda_parent_id',
type: 'select-single',
templateOptions: {
label: gettextCatalog.getString('Parent item'),
@ -627,9 +627,8 @@ angular.module('OpenSlidesApp.assignments.site', [
'Assignment',
'AssignmentForm',
'Agenda',
'AgendaUpdate',
'ErrorMessage',
function($scope, $state, Assignment, AssignmentForm, Agenda, AgendaUpdate, ErrorMessage) {
function($scope, $state, Assignment, AssignmentForm, Agenda, ErrorMessage) {
$scope.model = {};
// set default value for open posts form field
$scope.model.open_posts = 1;
@ -637,13 +636,10 @@ angular.module('OpenSlidesApp.assignments.site', [
$scope.formFields = AssignmentForm.getFormFields(true);
// save assignment
$scope.save = function(assignment, gotoDetailView) {
assignment.agenda_type = assignment.showAsAgendaItem ? 1 : 2;
// The attribute assignment.agenda_parent_id is set by the form, see form definition.
Assignment.create(assignment).then(
function (success) {
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
// see openslides.agenda.models.Item.ITEM_TYPE.
var changes = [{key: 'type', value: (assignment.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: assignment.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id,changes);
if (gotoDetailView) {
$state.go('assignments.assignment.detail', {id: success.id});
}
@ -663,10 +659,9 @@ angular.module('OpenSlidesApp.assignments.site', [
'Assignment',
'AssignmentForm',
'Agenda',
'AgendaUpdate',
'assignmentId',
'ErrorMessage',
function($scope, $state, Assignment, AssignmentForm, Agenda, AgendaUpdate, assignmentId, ErrorMessage) {
function($scope, $state, Assignment, AssignmentForm, Agenda, assignmentId, ErrorMessage) {
var assignment = Assignment.get(assignmentId);
$scope.alert = {};
// set initial values for form model by create deep copy of assignment object
@ -674,26 +669,14 @@ angular.module('OpenSlidesApp.assignments.site', [
$scope.model = angular.copy(assignment);
// get all form fields
$scope.formFields = AssignmentForm.getFormFields();
var agenda_item = Agenda.get(assignment.agenda_item_id);
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;
} else if($scope.formFields[i].key == 'agenda_parent_item_id') {
$scope.formFields[i].defaultValue = agenda_item.parent_id;
}
}
// save assignment
$scope.save = function (assignment, gotoDetailView) {
// inject the changed assignment (copy) object back into DS store
Assignment.inject(assignment);
// save change assignment object on server
// save changed assignment object on server
Assignment.save(assignment).then(
function(success) {
var changes = [{key: 'type', value: (assignment.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: assignment.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id,changes);
if (gotoDetailView) {
$state.go('assignments.assignment.detail', {id: success.id});
}

View File

@ -1,3 +1,5 @@
from typing import Any, Dict # noqa
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
from django.core.exceptions import ImproperlyConfigured, ValidationError
@ -628,6 +630,11 @@ class Motion(RESTModelMixin, models.Model):
if self.recommendation is not None:
self.set_state(self.recommendation)
"""
Container for runtime information for agenda app (on create or update of this instance).
"""
agenda_item_update_information = {} # type: Dict[str, Any]
def get_agenda_title(self):
"""
Return a simple title string for the agenda.
@ -895,6 +902,11 @@ class MotionBlock(RESTModelMixin, models.Model):
id=self.pk)
return super().delete(skip_autoupdate=skip_autoupdate, *args, **kwargs) # type: ignore
"""
Container for runtime information for agenda app (on create or update of this instance).
"""
agenda_item_update_information = {} # type: Dict[str, Any]
@property
def agenda_item(self):
"""

View File

@ -49,9 +49,25 @@ class MotionBlockSerializer(ModelSerializer):
"""
Serializer for motion.models.Category objects.
"""
agenda_type = IntegerField(write_only=True, required=False, min_value=1, max_value=2)
agenda_parent_id = IntegerField(write_only=True, required=False, min_value=1)
class Meta:
model = MotionBlock
fields = ('id', 'title', 'agenda_item_id',)
fields = ('id', 'title', 'agenda_item_id', 'agenda_type', 'agenda_parent_id',)
def create(self, validated_data):
"""
Customized create method. Set information about related agenda item
into agenda_item_update_information container.
"""
agenda_type = validated_data.pop('agenda_type', None)
agenda_parent_id = validated_data.pop('agenda_parent_id', None)
motion_block = MotionBlock(**validated_data)
motion_block.agenda_item_update_information['type'] = agenda_type
motion_block.agenda_item_update_information['parent_id'] = agenda_parent_id
motion_block.save()
return motion_block
class StateSerializer(ModelSerializer):
@ -288,6 +304,8 @@ class MotionSerializer(ModelSerializer):
required=False,
validators=[validate_workflow_field],
write_only=True)
agenda_type = IntegerField(write_only=True, required=False, min_value=1, max_value=2)
agenda_parent_id = IntegerField(write_only=True, required=False, min_value=1)
class Meta:
model = Motion
@ -314,6 +332,8 @@ class MotionSerializer(ModelSerializer):
'attachments',
'polls',
'agenda_item_id',
'agenda_type',
'agenda_parent_id',
'log_messages',)
read_only_fields = ('state', 'recommendation',) # Some other fields are also read_only. See definitions above.
@ -332,6 +352,9 @@ class MotionSerializer(ModelSerializer):
def create(self, validated_data):
"""
Customized method to create a new motion from some data.
Set also information about related agenda item into
agenda_item_update_information container.
"""
motion = Motion()
motion.title = validated_data['title']
@ -344,6 +367,8 @@ class MotionSerializer(ModelSerializer):
motion.comments = validated_data.get('comments')
motion.parent = validated_data.get('parent')
motion.reset_state(validated_data.get('workflow_id'))
motion.agenda_item_update_information['type'] = validated_data.get('agenda_type')
motion.agenda_item_update_information['parent_id'] = validated_data.get('agenda_parent_id')
motion.save()
if validated_data.get('submitters'):
motion.submitters.add(*validated_data['submitters'])

View File

@ -69,8 +69,8 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
};
},
// Get angular-formly fields.
getFormFields: function () {
return [
getFormFields: function (isCreateForm) {
var formFields = [
{
key: 'title',
type: 'input',
@ -78,7 +78,11 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
label: gettextCatalog.getString('Title')
}
},
{
];
// show as agenda item + parent item
if (isCreateForm) {
formFields.push({
key: 'showAsAgendaItem',
type: 'checkbox',
templateOptions: {
@ -86,18 +90,21 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
description: gettextCatalog.getString('If deactivated it appears as internal item on agenda.')
},
hide: !(operator.hasPerms('motions.can_manage') && operator.hasPerms('agenda.can_manage'))
},
{
key: 'agenda_parent_item_id',
});
formFields.push({
key: 'agenda_parent_id',
type: 'select-single',
templateOptions: {
label: gettextCatalog.getString('Parent item'),
options: AgendaTree.getFlatTree(Agenda.getAll()),
ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id',
placeholder: gettextCatalog.getString('Select a parent item ...')
}
}
];
},
hide: !operator.hasPerms('agenda.can_manage')
});
}
return formFields;
}
};
}
@ -190,24 +197,20 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
'$scope',
'MotionBlock',
'MotionBlockForm',
'AgendaUpdate',
function($scope, MotionBlock, MotionBlockForm, AgendaUpdate) {
function($scope, MotionBlock, MotionBlockForm) {
// Prepare form.
$scope.model = {};
$scope.model.showAsAgendaItem = true;
// Get all form fields.
$scope.formFields = MotionBlockForm.getFormFields();
$scope.formFields = MotionBlockForm.getFormFields(true);
// Save form.
$scope.save = function (motionBlock) {
motionBlock.agenda_type = motionBlock.showAsAgendaItem ? 1 : 2;
// The attribute motionBlock.agenda_parent_id is set by the form, see form definition.
MotionBlock.create(motionBlock).then(
function (success) {
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
// see openslides.agenda.models.Item.ITEM_TYPE.
var changes = [{key: 'type', value: (motionBlock.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: motionBlock.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id, changes);
$scope.closeThisDialog();
},
function (error) {
@ -227,11 +230,8 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
'$state',
'MotionBlock',
'MotionBlockForm',
'AgendaUpdate',
'motionBlockId',
function($scope, $state, MotionBlock, MotionBlockForm, AgendaUpdate, motionBlockId) {
// TODO: Check #2486 and remove some agenda related code.
//MotionBlock.loadRelations(motionBlock, 'agenda_item');
function($scope, $state, MotionBlock, MotionBlockForm, motionBlockId) {
$scope.alert = {};
// Prepare form. Set initial values by creating a deep copy of
@ -241,23 +241,14 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
// Get all form fields.
$scope.formFields = MotionBlockForm.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 = !motionBlock.agenda_item.is_hidden;
} else if ($scope.formFields[i].key == 'agenda_parent_item_id') {
$scope.formFields[i].defaultValue = motionBlock.agenda_item.parent_id;
}
}
// Save form.
$scope.save = function (motionBlock) {
// inject the changed motionBlock (copy) object back into DS store
MotionBlock.inject(motionBlock);
// save changed motionBlock object on server
MotionBlock.create(motionBlock).then(
function (success) {
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
// see openslides.agenda.models.Item.ITEM_TYPE.
var changes = [{key: 'type', value: (motionBlock.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: motionBlock.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id,changes);
$scope.closeThisDialog();
},
function (error) {

View File

@ -376,21 +376,21 @@ angular.module('OpenSlidesApp.motions.site', [
description: gettextCatalog.getString("Don't create a new version.")
},
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') && operator.hasPerms('agenda.can_manage'))
}];
// parent item
// show as agenda item + parent item
if (isCreateForm) {
formFields.push({
key: 'agenda_parent_item_id',
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') && operator.hasPerms('agenda.can_manage'))
});
formFields.push({
key: 'agenda_parent_id',
type: 'select-single',
templateOptions: {
label: gettextCatalog.getString('Parent item'),
@ -1890,10 +1890,9 @@ angular.module('OpenSlidesApp.motions.site', [
'User',
'Workflow',
'Agenda',
'AgendaUpdate',
'ErrorMessage',
function($scope, $state, gettext, gettextCatalog, operator, Motion, MotionForm,
Category, Config, Mediafile, Tag, User, Workflow, Agenda, AgendaUpdate, ErrorMessage) {
Category, Config, Mediafile, Tag, User, Workflow, Agenda, ErrorMessage) {
Category.bindAll({}, $scope, 'categories');
Mediafile.bindAll({}, $scope, 'mediafiles');
Tag.bindAll({}, $scope, 'tags');
@ -1927,13 +1926,10 @@ angular.module('OpenSlidesApp.motions.site', [
// save motion
$scope.save = function (motion, gotoDetailView) {
motion.agenda_type = motion.showAsAgendaItem ? 1 : 2;
// The attribute motion.agenda_parent_id is set by the form, see form definition.
Motion.create(motion).then(
function(success) {
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
// see openslides.agenda.models.Item.ITEM_TYPE.
var changes = [{key: 'type', value: (motion.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: motion.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id, changes);
if (isAmendment || gotoDetailView) {
$state.go('motions.motion.detail', {id: success.id});
}
@ -1959,13 +1955,12 @@ angular.module('OpenSlidesApp.motions.site', [
'User',
'Workflow',
'Agenda',
'AgendaUpdate',
'motionId',
'operator',
'ErrorMessage',
'EditingWarning',
function($scope, $state, Motion, Category, Config, Mediafile, MotionForm,
Tag, User, Workflow, Agenda, AgendaUpdate, motionId, operator, ErrorMessage,
Tag, User, Workflow, Agenda, motionId, operator, ErrorMessage,
EditingWarning) {
Category.bindAll({}, $scope, 'categories');
Mediafile.bindAll({}, $scope, 'mediafiles');
@ -2007,18 +2002,10 @@ angular.module('OpenSlidesApp.motions.site', [
$scope.formFields[i].hide = false;
}
}
if ($scope.formFields[i].key == "showAsAgendaItem" && motion.agenda_item) {
// 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") {
// get saved workflow id from state
$scope.formFields[i].defaultValue = motion.state.workflow_id;
}
if ($scope.formFields[i].key == "agenda_parent_item_id") {
// get current parent_id of the agenda item
$scope.formFields[i].defaultValue = motion.agenda_item.parent_id;
}
}
// Displaying a warning, if other users edit this motion too
@ -2029,14 +2016,9 @@ angular.module('OpenSlidesApp.motions.site', [
$scope.save = function (motion, gotoDetailView) {
// inject the changed motion (copy) object back into DS store
Motion.inject(motion);
// save change motion object on server
// save changed motion object on server
Motion.save(motion).then(
function(success) {
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
// see openslides.agenda.models.Item.ITEM_TYPE.
var changes = [{key: 'type', value: (motion.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: motion.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id,changes);
if (gotoDetailView) {
$state.go('motions.motion.detail', {id: success.id});
}

View File

@ -596,7 +596,8 @@ class CategoryViewSet(ModelViewSet):
# Remove old identifiers
for motion in motions:
motion.identifier = None
motion.skip_autoupdate = True # This line is to skip agenda item autoupdate. See agenda/signals.py.
# This line is to skip agenda item autoupdate. See agenda/signals.py.
motion.agenda_item_update_information['skip_autoupdate'] = True
motion.save(skip_autoupdate=True)
# Set new identifers and change identifiers of amendments.
@ -615,7 +616,8 @@ class CategoryViewSet(ModelViewSet):
obj['new_identifier'],
child.identifier,
count=1)
child.skip_autoupdate = True # This line is to skip agenda item autoupdate. See agenda/signals.py.
# This line is to skip agenda item autoupdate. See agenda/signals.py.
child.agenda_item_update_information['skip_autoupdate'] = True
child.save(skip_autoupdate=True)
instances.append(child)
instances.append(child.agenda_item)

View File

@ -1,3 +1,5 @@
from typing import Any, Dict # noqa
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
@ -54,6 +56,11 @@ class Topic(RESTModelMixin, models.Model):
id=self.pk)
return super().delete(skip_autoupdate=skip_autoupdate, *args, **kwargs) # type: ignore
"""
Container for runtime information for agenda app (on create or update of this instance).
"""
agenda_item_update_information = {} # type: Dict[str, Any]
@property
def agenda_item(self):
"""

View File

@ -1,4 +1,4 @@
from openslides.utils.rest_api import ModelSerializer
from openslides.utils.rest_api import CharField, IntegerField, ModelSerializer
from openslides.utils.validate import validate_html
from .models import Topic
@ -8,11 +8,49 @@ class TopicSerializer(ModelSerializer):
"""
Serializer for core.models.Topic objects.
"""
agenda_type = IntegerField(write_only=True, required=False, min_value=1, max_value=2)
agenda_parent_id = IntegerField(write_only=True, required=False, min_value=1)
agenda_comment = CharField(write_only=True, required=False, allow_blank=True)
agenda_duration = IntegerField(write_only=True, required=False, min_value=1)
agenda_weight = IntegerField(write_only=True, required=False, min_value=1)
class Meta:
model = Topic
fields = ('id', 'title', 'text', 'attachments', 'agenda_item_id')
fields = (
'id',
'title',
'text',
'attachments',
'agenda_item_id',
'agenda_type',
'agenda_parent_id',
'agenda_comment',
'agenda_duration',
'agenda_weight',
)
def validate(self, data):
if 'text' in data:
data['text'] = validate_html(data['text'])
return data
def create(self, validated_data):
"""
Customized create method. Set information about related agenda item
into agenda_item_update_information container.
"""
agenda_type = validated_data.pop('agenda_type', None)
agenda_parent_id = validated_data.pop('agenda_parent_id', None)
agenda_comment = validated_data.pop('agenda_comment', None)
agenda_duration = validated_data.pop('agenda_duration', None)
agenda_weight = validated_data.pop('agenda_weight', None)
attachments = validated_data.pop('attachments', [])
topic = Topic(**validated_data)
topic.agenda_item_update_information['type'] = agenda_type
topic.agenda_item_update_information['parent_id'] = agenda_parent_id
topic.agenda_item_update_information['comment'] = agenda_comment
topic.agenda_item_update_information['duration'] = agenda_duration
topic.agenda_item_update_information['weight'] = agenda_weight
topic.save()
topic.attachments.add(*attachments)
return topic

View File

@ -116,28 +116,28 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
}
});
}
// show as agenda item
formFields.push({
key: 'showAsAgendaItem',
type: 'checkbox',
templateOptions: {
label: gettextCatalog.getString('Show as agenda item'),
description: gettextCatalog.getString('If deactivated it appears as internal item on agenda.')
},
hide: !operator.hasPerms('agenda.can_manage')
});
// parent item
// show as agenda item + parent item
if (isCreateForm) {
formFields.push({
key: 'agenda_parent_item_id',
key: 'showAsAgendaItem',
type: 'checkbox',
templateOptions: {
label: gettextCatalog.getString('Show as agenda item'),
description: gettextCatalog.getString('If deactivated it appears as internal item on agenda.')
},
hide: !operator.hasPerms('agenda.can_manage')
});
formFields.push({
key: 'agenda_parent_id',
type: 'select-single',
templateOptions: {
label: gettextCatalog.getString('Parent item'),
options: AgendaTree.getFlatTree(Agenda.getAll()),
ngOptions: 'item.id as item.getListViewTitle() for item in to.options | notself : model.agenda_item_id',
placeholder: gettextCatalog.getString('Select a parent item ...')
}
},
hide: !operator.hasPerms('agenda.can_manage')
});
}
@ -186,9 +186,8 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
'Topic',
'TopicForm',
'Agenda',
'AgendaUpdate',
'ErrorMessage',
function($scope, $state, Topic, TopicForm, Agenda, AgendaUpdate, ErrorMessage) {
function($scope, $state, Topic, TopicForm, Agenda, ErrorMessage) {
$scope.topic = {};
$scope.model = {};
$scope.model.showAsAgendaItem = true;
@ -196,13 +195,10 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
$scope.formFields = TopicForm.getFormFields(true);
// save form
$scope.save = function (topic) {
topic.agenda_type = topic.showAsAgendaItem ? 1 : 2;
// The attribute topic.agenda_parent_id is set by the form, see form definition.
Topic.create(topic).then(
function (success) {
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
// see openslides.agenda.models.Item.ITEM_TYPE.
var changes = [{key: 'type', value: (topic.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: topic.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id,changes);
$scope.closeThisDialog();
}, function (error) {
$scope.alert = ErrorMessage.forAlert(error);
@ -218,10 +214,9 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
'Topic',
'TopicForm',
'Agenda',
'AgendaUpdate',
'topicId',
'ErrorMessage',
function($scope, $state, Topic, TopicForm, Agenda, AgendaUpdate, topicId, ErrorMessage) {
function($scope, $state, Topic, TopicForm, Agenda, topicId, ErrorMessage) {
var topic = Topic.get(topicId);
$scope.alert = {};
// set initial values for form model by create deep copy of topic object
@ -229,25 +224,17 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
$scope.model = angular.copy(topic);
// get all form fields
$scope.formFields = TopicForm.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 = !topic.agenda_item.is_hidden;
} else if ($scope.formFields[i].key == "agenda_parent_item_id") {
$scope.formFields[i].defaultValue = topic.agenda_item.parent_id;
}
}
// save form
$scope.save = function (topic) {
Topic.create(topic).then(
// inject the changed topic (copy) object back into DS store
Topic.inject(topic);
// save changed topic object on server
Topic.save(topic).then(
function(success) {
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
// see openslides.agenda.models.Item.ITEM_TYPE.
var changes = [{key: 'type', value: (topic.showAsAgendaItem ? 1 : 2)},
{key: 'parent_id', value: topic.agenda_parent_item_id}];
AgendaUpdate.saveChanges(success.agenda_item_id,changes);
$scope.closeThisDialog();
}, function (error) {
},
function (error) {
// save error: revert all changes by restore
// (refresh) original topic object from server
Topic.refresh(topic);
@ -265,8 +252,7 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
'Topic',
'HumanTimeConverter',
'TopicsCsvExample',
'AgendaUpdate',
function($scope, gettext, Agenda, Topic, HumanTimeConverter, TopicsCsvExample, AgendaUpdate) {
function($scope, gettext, Agenda, Topic, HumanTimeConverter, TopicsCsvExample) {
// Big TODO: Change wording from "item" to "topic".
// import from textarea
$scope.importByLine = function () {
@ -275,12 +261,11 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
$scope.importcounter = 0;
$scope.titleItems.forEach(function(title, index) {
var item = {title: title};
item.agenda_type = 1; // The new topic is not hidden.
item.agenda_weight = 1000 + index;
// TODO: create all items in bulk mode
Topic.create(item).then(
function(success) {
var changes = [{key: 'type', value: 1},
{key: 'weight', value: 1000 + index}];
AgendaUpdate.saveChanges(success.agenda_item_id, changes);
$scope.importcounter++;
}
);
@ -363,13 +348,12 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
$scope.csvImporting = true;
angular.forEach($scope.items, function (item) {
if (item.selected && !item.importerror) {
item.agenda_type = item.type;
item.agenda_comment = item.comment;
item.agenda_duration = item.duration;
item.agenda_weight = item.weight;
Topic.create(item).then(
function(success) {
var changes = [{key: 'duration', value: item.duration},
{key: 'comment', value: item.comment},
{key: 'type', value: item.type},
{key: 'weight', value: item.weight}];
AgendaUpdate.saveChanges(success.agenda_item_id, changes);
item.imported = true;
}
);