2015-11-23 21:31:15 +01:00
|
|
|
(function () {
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
|
|
|
|
|
|
|
.config([
|
|
|
|
'mainMenuProvider',
|
|
|
|
'gettext',
|
|
|
|
function (mainMenuProvider, gettext) {
|
|
|
|
mainMenuProvider.register({
|
|
|
|
'ui_sref': 'motions.motion.list',
|
|
|
|
'img_class': 'file-text',
|
|
|
|
'title': gettext('Motions'),
|
|
|
|
'weight': 300,
|
|
|
|
'perm': 'motions.can_see',
|
|
|
|
});
|
|
|
|
}
|
|
|
|
])
|
|
|
|
|
|
|
|
.config(function($stateProvider) {
|
|
|
|
$stateProvider
|
|
|
|
.state('motions', {
|
|
|
|
url: '/motions',
|
|
|
|
abstract: true,
|
|
|
|
template: "<ui-view/>",
|
|
|
|
})
|
|
|
|
.state('motions.motion', {
|
|
|
|
abstract: true,
|
|
|
|
template: "<ui-view/>",
|
|
|
|
})
|
|
|
|
.state('motions.motion.list', {
|
|
|
|
resolve: {
|
|
|
|
motions: function(Motion) {
|
|
|
|
return Motion.findAll();
|
|
|
|
},
|
|
|
|
categories: function(Category) {
|
|
|
|
return Category.findAll();
|
|
|
|
},
|
|
|
|
tags: function(Tag) {
|
|
|
|
return Tag.findAll();
|
|
|
|
},
|
|
|
|
users: function(User) {
|
|
|
|
return User.findAll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.state('motions.motion.detail', {
|
|
|
|
resolve: {
|
|
|
|
motion: function(Motion, $stateParams) {
|
|
|
|
return Motion.find($stateParams.id);
|
|
|
|
},
|
|
|
|
categories: function(Category) {
|
|
|
|
return Category.findAll();
|
|
|
|
},
|
|
|
|
users: function(User) {
|
|
|
|
return User.findAll();
|
|
|
|
},
|
|
|
|
mediafiles: function(Mediafile) {
|
|
|
|
return Mediafile.findAll();
|
|
|
|
},
|
|
|
|
tags: function(Tag) {
|
|
|
|
return Tag.findAll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.state('motions.motion.detail.update', {
|
2015-11-27 23:09:38 +01:00
|
|
|
onEnter: ['$stateParams', 'ngDialog', 'Motion', function($stateParams, ngDialog, Motion) {
|
|
|
|
ngDialog.open({
|
|
|
|
template: 'static/templates/motions/motion-form.html',
|
|
|
|
controller: 'MotionUpdateCtrl',
|
|
|
|
className: 'ngdialog-theme-default wide-form',
|
|
|
|
resolve: { motion: function() {
|
|
|
|
return Motion.find($stateParams.id) }}
|
|
|
|
});
|
|
|
|
}]
|
2015-11-23 21:31:15 +01:00
|
|
|
})
|
2015-11-28 19:59:58 +01:00
|
|
|
.state('motions.motion.import', {
|
|
|
|
url: '/import',
|
|
|
|
controller: 'MotionImportCtrl',
|
|
|
|
resolve: {
|
|
|
|
motions: function(Motion) {
|
|
|
|
return Motion.findAll();
|
|
|
|
},
|
|
|
|
categories: function(Category) {
|
|
|
|
return Category.findAll();
|
|
|
|
},
|
|
|
|
users: function(User) {
|
|
|
|
return User.findAll();
|
|
|
|
}
|
|
|
|
}
|
2015-11-23 21:31:15 +01:00
|
|
|
})
|
|
|
|
// categories
|
|
|
|
.state('motions.category', {
|
|
|
|
url: '/category',
|
|
|
|
abstract: true,
|
|
|
|
template: "<ui-view/>",
|
|
|
|
})
|
|
|
|
.state('motions.category.list', {
|
|
|
|
resolve: {
|
|
|
|
categories: function(Category) {
|
|
|
|
return Category.findAll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.state('motions.category.create', {})
|
|
|
|
.state('motions.category.detail', {
|
|
|
|
resolve: {
|
|
|
|
category: function(Category, $stateParams) {
|
|
|
|
return Category.find($stateParams.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.state('motions.category.detail.update', {
|
|
|
|
views: {
|
|
|
|
'@motions.category': {}
|
|
|
|
}
|
2015-11-27 23:09:38 +01:00
|
|
|
});
|
2015-11-23 21:31:15 +01:00
|
|
|
})
|
|
|
|
|
2015-11-27 23:09:38 +01:00
|
|
|
// Provide generic motion form fields for create and update view
|
|
|
|
.factory('MotionFormFieldFactory', [
|
2015-11-30 23:52:42 +01:00
|
|
|
'gettextCatalog',
|
2015-11-27 23:09:38 +01:00
|
|
|
'operator',
|
|
|
|
'Category',
|
|
|
|
'Config',
|
|
|
|
'Mediafile',
|
|
|
|
'Tag',
|
|
|
|
'User',
|
|
|
|
'Workflow',
|
2015-11-30 23:52:42 +01:00
|
|
|
function (gettextCatalog, operator, Category, Config, Mediafile, Tag, User, Workflow) {
|
2015-11-27 23:09:38 +01:00
|
|
|
return {
|
|
|
|
getFormFields: function () {
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
key: 'identifier',
|
|
|
|
type: 'input',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Identifier')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hide: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'submitters_id',
|
|
|
|
type: 'ui-select-multiple',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Submitters'),
|
2015-11-27 23:09:38 +01:00
|
|
|
optionsAttr: 'bs-options',
|
|
|
|
options: User.getAll(),
|
|
|
|
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
|
|
|
|
valueProp: 'id',
|
|
|
|
labelProp: 'full_name',
|
2015-12-11 20:04:05 +01:00
|
|
|
placeholder: gettextCatalog.getString('Select or search a submitter ...')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hide: !operator.hasPerms('motions.can_manage')
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'title',
|
|
|
|
type: 'input',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Title'),
|
2015-11-27 23:09:38 +01:00
|
|
|
required: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'text',
|
|
|
|
type: 'textarea',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Text'),
|
2015-11-27 23:09:38 +01:00
|
|
|
required: true
|
|
|
|
},
|
|
|
|
ngModelElAttrs: {'ckeditor': 'CKEditorOptions'}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'reason',
|
|
|
|
type: 'textarea',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Reason')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
ngModelElAttrs: {'ckeditor': 'CKEditorOptions'}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'more',
|
|
|
|
type: 'checkbox',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Show extended fields')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hide: !operator.hasPerms('motions.can_manage')
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'attachments_id',
|
|
|
|
type: 'ui-select-multiple',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Attachment'),
|
2015-11-27 23:09:38 +01:00
|
|
|
optionsAttr: 'bs-options',
|
|
|
|
options: Mediafile.getAll(),
|
|
|
|
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
|
|
|
|
valueProp: 'id',
|
|
|
|
labelProp: 'title_or_filename',
|
2015-12-11 20:04:05 +01:00
|
|
|
placeholder: gettextCatalog.getString('Select or search an attachment ...')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hideExpression: '!model.more'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'category_id',
|
|
|
|
type: 'ui-select-single',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Category'),
|
2015-11-27 23:09:38 +01:00
|
|
|
optionsAttr: 'bs-options',
|
|
|
|
options: Category.getAll(),
|
|
|
|
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
|
|
|
|
valueProp: 'id',
|
|
|
|
labelProp: 'name',
|
2015-12-11 20:04:05 +01:00
|
|
|
placeholder: gettextCatalog.getString('Select or search a category ...')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hideExpression: '!model.more'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'tags_id',
|
|
|
|
type: 'ui-select-multiple',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Tags'),
|
2015-11-27 23:09:38 +01:00
|
|
|
optionsAttr: 'bs-options',
|
|
|
|
options: Tag.getAll(),
|
|
|
|
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
|
|
|
|
valueProp: 'id',
|
|
|
|
labelProp: 'name',
|
2015-12-11 20:04:05 +01:00
|
|
|
placeholder: gettextCatalog.getString('Select or search a tag ...')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hideExpression: '!model.more'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'supporters_id',
|
|
|
|
type: 'ui-select-multiple',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Supporters'),
|
2015-11-27 23:09:38 +01:00
|
|
|
optionsAttr: 'bs-options',
|
|
|
|
options: User.getAll(),
|
|
|
|
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
|
|
|
|
valueProp: 'id',
|
|
|
|
labelProp: 'full_name',
|
2015-12-11 20:04:05 +01:00
|
|
|
placeholder: gettextCatalog.getString('Select or search a supporter ...')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hideExpression: '!model.more'
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 'workflow_id',
|
|
|
|
type: 'ui-select-single',
|
|
|
|
templateOptions: {
|
2015-11-30 23:52:42 +01:00
|
|
|
label: gettextCatalog.getString('Workflow'),
|
2015-11-27 23:09:38 +01:00
|
|
|
optionsAttr: 'bs-options',
|
|
|
|
options: Workflow.getAll(),
|
|
|
|
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
|
|
|
|
valueProp: 'id',
|
|
|
|
labelProp: 'name',
|
2015-12-11 20:04:05 +01:00
|
|
|
placeholder: gettextCatalog.getString('Select or search a workflow ...')
|
2015-11-27 23:09:38 +01:00
|
|
|
},
|
|
|
|
hideExpression: '!model.more',
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
])
|
|
|
|
|
2015-11-23 21:31:15 +01:00
|
|
|
.controller('MotionListCtrl', [
|
|
|
|
'$scope',
|
|
|
|
'$state',
|
2015-11-27 23:09:38 +01:00
|
|
|
'ngDialog',
|
2015-11-23 21:31:15 +01:00
|
|
|
'Motion',
|
|
|
|
'Category',
|
|
|
|
'Tag',
|
|
|
|
'Workflow',
|
|
|
|
'User',
|
2015-11-27 23:09:38 +01:00
|
|
|
function($scope, $state, ngDialog, Motion, Category, Tag, Workflow, User) {
|
2015-11-23 21:31:15 +01:00
|
|
|
Motion.bindAll({}, $scope, 'motions');
|
|
|
|
Category.bindAll({}, $scope, 'categories');
|
|
|
|
Tag.bindAll({}, $scope, 'tags');
|
|
|
|
Workflow.bindAll({}, $scope, 'workflows');
|
|
|
|
User.bindAll({}, $scope, 'users');
|
|
|
|
$scope.alert = {};
|
|
|
|
|
|
|
|
// setup table sorting
|
|
|
|
$scope.sortColumn = 'identifier';
|
|
|
|
$scope.filterPresent = '';
|
|
|
|
$scope.reverse = false;
|
|
|
|
// function to sort by clicked column
|
|
|
|
$scope.toggleSort = function ( column ) {
|
|
|
|
if ( $scope.sortColumn === column ) {
|
|
|
|
$scope.reverse = !$scope.reverse;
|
|
|
|
}
|
|
|
|
$scope.sortColumn = column;
|
|
|
|
};
|
|
|
|
|
|
|
|
// collect all states of all workflows
|
|
|
|
// TODO: regard workflows only which are used by motions
|
|
|
|
$scope.states = [];
|
|
|
|
var workflows = Workflow.getAll();
|
|
|
|
angular.forEach(workflows, function (workflow) {
|
|
|
|
if (workflows.length > 1) {
|
|
|
|
var wf = {}
|
|
|
|
wf.name = "# "+workflow.name;
|
|
|
|
$scope.states.push(wf);
|
|
|
|
}
|
|
|
|
angular.forEach(workflow.states, function (state) {
|
|
|
|
$scope.states.push(state);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2015-11-27 23:09:38 +01:00
|
|
|
// open new dialog
|
|
|
|
$scope.newDialog = function () {
|
|
|
|
ngDialog.open({
|
|
|
|
template: 'static/templates/motions/motion-form.html',
|
|
|
|
controller: 'MotionCreateCtrl',
|
|
|
|
className: 'ngdialog-theme-default wide-form'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
// open edit dialog
|
|
|
|
$scope.editDialog = function (motion) {
|
|
|
|
ngDialog.open({
|
|
|
|
template: 'static/templates/motions/motion-form.html',
|
|
|
|
controller: 'MotionUpdateCtrl',
|
|
|
|
className: 'ngdialog-theme-default wide-form',
|
|
|
|
resolve: {
|
|
|
|
motion: function(Motion) {
|
|
|
|
return Motion.find(motion.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
2015-11-23 21:31:15 +01:00
|
|
|
// save changed motion
|
2015-11-27 23:09:38 +01:00
|
|
|
$scope.save = function (motion) {
|
2015-11-23 21:31:15 +01:00
|
|
|
// get (unchanged) values from latest version for update method
|
|
|
|
motion.title = motion.getTitle(-1);
|
|
|
|
motion.text = motion.getText(-1);
|
|
|
|
motion.reason = motion.getReason(-1);
|
|
|
|
Motion.save(motion).then(
|
|
|
|
function(success) {
|
|
|
|
motion.quickEdit = false;
|
|
|
|
$scope.alert.show = false;
|
|
|
|
},
|
|
|
|
function(error){
|
|
|
|
var message = '';
|
|
|
|
for (var e in error.data) {
|
|
|
|
message += e + ': ' + error.data[e] + ' ';
|
|
|
|
}
|
|
|
|
$scope.alert = { type: 'danger', msg: message, show: true };
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// *** delete mode functions ***
|
|
|
|
$scope.isDeleteMode = false;
|
|
|
|
// check all checkboxes
|
|
|
|
$scope.checkAll = function () {
|
|
|
|
angular.forEach($scope.motions, function (motion) {
|
|
|
|
motion.selected = $scope.selectedAll;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
// uncheck all checkboxes if isDeleteMode is closed
|
|
|
|
$scope.uncheckAll = function () {
|
|
|
|
if (!$scope.isDeleteMode) {
|
|
|
|
$scope.selectedAll = false;
|
|
|
|
angular.forEach($scope.motions, function (motion) {
|
|
|
|
motion.selected = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
// delete selected motions
|
2015-11-27 23:09:38 +01:00
|
|
|
$scope.deleteMultiple = function () {
|
2015-11-23 21:31:15 +01:00
|
|
|
angular.forEach($scope.motions, function (motion) {
|
|
|
|
if (motion.selected)
|
|
|
|
Motion.destroy(motion.id);
|
|
|
|
});
|
|
|
|
$scope.isDeleteMode = false;
|
|
|
|
$scope.uncheckAll();
|
|
|
|
};
|
|
|
|
// delete single motion
|
2015-11-27 23:09:38 +01:00
|
|
|
$scope.delete = function (motion) {
|
2015-11-23 21:31:15 +01:00
|
|
|
Motion.destroy(motion.id);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
])
|
|
|
|
|
|
|
|
.controller('MotionDetailCtrl', [
|
|
|
|
'$scope',
|
|
|
|
'$http',
|
2015-11-27 23:09:38 +01:00
|
|
|
'ngDialog',
|
2015-11-23 21:31:15 +01:00
|
|
|
'Motion',
|
|
|
|
'Category',
|
|
|
|
'Mediafile',
|
|
|
|
'Tag',
|
|
|
|
'User',
|
|
|
|
'Workflow',
|
|
|
|
'motion',
|
2015-11-27 23:09:38 +01:00
|
|
|
function($scope, $http, ngDialog, Motion, Category, Mediafile, Tag, User, Workflow, motion) {
|
2015-11-23 21:31:15 +01:00
|
|
|
Motion.bindOne(motion.id, $scope, 'motion');
|
|
|
|
Category.bindAll({}, $scope, 'categories');
|
|
|
|
Mediafile.bindAll({}, $scope, 'mediafiles');
|
|
|
|
Tag.bindAll({}, $scope, 'tags');
|
|
|
|
User.bindAll({}, $scope, 'users');
|
|
|
|
Workflow.bindAll({}, $scope, 'workflows');
|
|
|
|
Motion.loadRelations(motion, 'agenda_item');
|
|
|
|
// TODO: make 'motion.attachments' useable and itteratable in template
|
|
|
|
// Motion.loadRelations(motion, 'attachments');
|
|
|
|
|
|
|
|
$scope.alert = {};
|
|
|
|
$scope.isCollapsed = true;
|
|
|
|
|
2015-11-27 23:09:38 +01:00
|
|
|
// open edit dialog
|
|
|
|
$scope.editDialog = function (motion) {
|
|
|
|
ngDialog.open({
|
|
|
|
template: 'static/templates/motions/motion-form.html',
|
|
|
|
controller: 'MotionUpdateCtrl',
|
|
|
|
className: 'ngdialog-theme-default wide-form',
|
|
|
|
resolve: {
|
|
|
|
motion: function(Motion) {
|
|
|
|
return Motion.find(motion.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-11-23 21:31:15 +01:00
|
|
|
$scope.support = function () {
|
|
|
|
$http.post('/rest/motions/motion/' + motion.id + '/support/');
|
|
|
|
}
|
|
|
|
$scope.unsupport = function () {
|
|
|
|
$http.delete('/rest/motions/motion/' + motion.id + '/support/');
|
|
|
|
}
|
|
|
|
$scope.update_state = function (state) {
|
|
|
|
$http.put('/rest/motions/motion/' + motion.id + '/set_state/', {'state': state.id});
|
|
|
|
}
|
|
|
|
$scope.reset_state = function (state_id) {
|
|
|
|
$http.put('/rest/motions/motion/' + motion.id + '/set_state/', {});
|
|
|
|
}
|
|
|
|
$scope.create_poll = function () {
|
|
|
|
$http.post('/rest/motions/motion/' + motion.id + '/create_poll/', {})
|
|
|
|
.success(function(data){
|
|
|
|
$scope.alert.show = false;
|
|
|
|
})
|
|
|
|
.error(function(data){
|
|
|
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
|
|
|
});
|
|
|
|
}
|
|
|
|
$scope.delete_poll = function (poll) {
|
|
|
|
poll.DSDestroy();
|
|
|
|
}
|
|
|
|
$scope.update_poll = function (poll) {
|
|
|
|
poll.DSUpdate({
|
|
|
|
motion_id: motion.id,
|
|
|
|
votes: {"Yes": poll.yes, "No": poll.no, "Abstain": poll.abstain},
|
|
|
|
votesvalid: poll.votesvalid,
|
|
|
|
votesinvalid: poll.votesinvalid,
|
|
|
|
votescast: poll.votescast
|
|
|
|
})
|
|
|
|
.then(function(success) {
|
|
|
|
$scope.alert.show = false;
|
|
|
|
poll.isEditMode = false;
|
|
|
|
})
|
|
|
|
.catch(function(error) {
|
|
|
|
var message = '';
|
|
|
|
for (var e in error.data) {
|
|
|
|
message += e + ': ' + error.data[e] + ' ';
|
|
|
|
}
|
|
|
|
$scope.alert = { type: 'danger', msg: message, show: true };
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
])
|
|
|
|
|
|
|
|
.controller('MotionCreateCtrl', [
|
|
|
|
'$scope',
|
|
|
|
'$state',
|
|
|
|
'gettext',
|
|
|
|
'Motion',
|
|
|
|
'MotionFormFieldFactory',
|
|
|
|
'Category',
|
|
|
|
'Config',
|
|
|
|
'Mediafile',
|
|
|
|
'Tag',
|
|
|
|
'User',
|
|
|
|
'Workflow',
|
2015-11-23 22:01:30 +01:00
|
|
|
function($scope, $state, gettext, Motion, MotionFormFieldFactory, Category, Config, Mediafile, Tag, User, Workflow) {
|
2015-11-23 21:31:15 +01:00
|
|
|
Category.bindAll({}, $scope, 'categories');
|
|
|
|
Mediafile.bindAll({}, $scope, 'mediafiles');
|
|
|
|
Tag.bindAll({}, $scope, 'tags');
|
|
|
|
User.bindAll({}, $scope, 'users');
|
|
|
|
Workflow.bindAll({}, $scope, 'workflows');
|
|
|
|
|
2015-12-11 23:33:55 +01:00
|
|
|
$scope.model = {};
|
|
|
|
// set default values for create form
|
|
|
|
// ... set preamble config value as text
|
|
|
|
$scope.model.text = Config.get('motions_preamble').value;
|
|
|
|
// ... preselect default workflow
|
|
|
|
$scope.model.workflow_id = Config.get('motions_workflow').value;
|
2015-11-23 21:31:15 +01:00
|
|
|
// get all form fields
|
|
|
|
$scope.formFields = MotionFormFieldFactory.getFormFields();
|
|
|
|
for (var i = 0; i < $scope.formFields.length; i++) {
|
|
|
|
if ($scope.formFields[i].key == "identifier") {
|
|
|
|
$scope.formFields[i].hide = true;
|
|
|
|
}
|
|
|
|
}
|
2015-11-27 23:09:38 +01:00
|
|
|
// save motion
|
2015-11-23 21:31:15 +01:00
|
|
|
$scope.save = function (motion) {
|
|
|
|
Motion.create(motion).then(
|
|
|
|
function(success) {
|
2015-11-27 23:09:38 +01:00
|
|
|
$scope.closeThisDialog();
|
2015-11-23 21:31:15 +01:00
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
])
|
|
|
|
|
|
|
|
.controller('MotionUpdateCtrl', [
|
|
|
|
'$scope',
|
|
|
|
'$state',
|
|
|
|
'Motion',
|
|
|
|
'Category',
|
|
|
|
'Config',
|
|
|
|
'Mediafile',
|
|
|
|
'MotionFormFieldFactory',
|
|
|
|
'Tag',
|
|
|
|
'User',
|
|
|
|
'Workflow',
|
|
|
|
'motion',
|
2015-11-30 23:52:42 +01:00
|
|
|
function($scope, $state, Motion, Category, Config, Mediafile, MotionFormFieldFactory, Tag, User, Workflow, motion) {
|
2015-11-23 21:31:15 +01:00
|
|
|
Category.bindAll({}, $scope, 'categories');
|
|
|
|
Mediafile.bindAll({}, $scope, 'mediafiles');
|
|
|
|
Tag.bindAll({}, $scope, 'tags');
|
|
|
|
User.bindAll({}, $scope, 'users');
|
|
|
|
Workflow.bindAll({}, $scope, 'workflows');
|
|
|
|
|
|
|
|
// set initial values for form model
|
|
|
|
$scope.model = motion;
|
|
|
|
$scope.model.more = false;
|
|
|
|
// get all form fields
|
|
|
|
$scope.formFields = MotionFormFieldFactory.getFormFields();
|
|
|
|
// override default values for update form
|
|
|
|
for (var i = 0; i < $scope.formFields.length; i++) {
|
|
|
|
if ($scope.formFields[i].key == "identifier") {
|
|
|
|
// show identifier field
|
|
|
|
$scope.formFields[i].hide = false;
|
|
|
|
}
|
|
|
|
if ($scope.formFields[i].key == "title") {
|
|
|
|
// get title of latest version
|
|
|
|
$scope.formFields[i].defaultValue = motion.getTitle(-1);
|
|
|
|
}
|
|
|
|
if ($scope.formFields[i].key == "text") {
|
|
|
|
// get text of latest version
|
|
|
|
$scope.formFields[i].defaultValue = motion.getText(-1);
|
|
|
|
}
|
|
|
|
if ($scope.formFields[i].key == "reason") {
|
|
|
|
// get reason of latest version
|
|
|
|
$scope.formFields[i].defaultValue = motion.getReason(-1);
|
|
|
|
}
|
|
|
|
if ($scope.formFields[i].key == "workflow_id") {
|
|
|
|
// get saved workflow id from state
|
|
|
|
$scope.formFields[i].defaultValue = motion.state.workflow_id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-27 23:09:38 +01:00
|
|
|
// save motion
|
|
|
|
$scope.save = function (motion) {
|
|
|
|
Motion.save(motion).then(
|
|
|
|
function(success) {
|
|
|
|
$scope.closeThisDialog();
|
|
|
|
}
|
|
|
|
);
|
2015-11-23 21:31:15 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
])
|
|
|
|
|
2015-11-28 19:59:58 +01:00
|
|
|
.controller('MotionImportCtrl', [
|
|
|
|
'$scope',
|
|
|
|
'gettext',
|
|
|
|
'Category',
|
|
|
|
'Motion',
|
|
|
|
'User',
|
|
|
|
function($scope, gettext, Category, Motion, User) {
|
|
|
|
// set initial data for csv import
|
|
|
|
$scope.motions = []
|
|
|
|
$scope.separator = ',';
|
|
|
|
$scope.encoding = 'UTF-8';
|
|
|
|
$scope.encodingOptions = ['UTF-8', 'ISO-8859-1'];
|
|
|
|
$scope.csv = {
|
|
|
|
content: null,
|
|
|
|
header: true,
|
|
|
|
headerVisible: false,
|
|
|
|
separator: $scope.separator,
|
|
|
|
separatorVisible: false,
|
|
|
|
encoding: $scope.encoding,
|
|
|
|
encodingVisible: false,
|
|
|
|
result: null
|
|
|
|
};
|
|
|
|
// set csv file encoding
|
|
|
|
$scope.setEncoding = function () {
|
|
|
|
$scope.csv.encoding = $scope.encoding;
|
|
|
|
};
|
|
|
|
// set csv file encoding
|
|
|
|
$scope.setSeparator = function () {
|
|
|
|
$scope.csv.separator = $scope.separator;
|
|
|
|
};
|
|
|
|
// detect if csv file is loaded
|
|
|
|
$scope.$watch('csv.result', function () {
|
|
|
|
$scope.motions = [];
|
|
|
|
var quotionRe = /^"(.*)"$/;
|
|
|
|
angular.forEach($scope.csv.result, function (motion) {
|
|
|
|
if (motion.identifier) {
|
|
|
|
motion.identifier = motion.identifier.replace(quotionRe, '$1');
|
|
|
|
if (motion.identifier != '') {
|
|
|
|
// All motion objects are already loaded via the resolve statement from ui-router.
|
|
|
|
var motions = Motion.getAll();
|
|
|
|
if (_.find(motions, function (item) {
|
|
|
|
return item.identifier == motion.identifier;
|
|
|
|
})) {
|
|
|
|
motion.importerror = true;
|
|
|
|
motion.identifier_error = gettext('Error: Identifier already exists.');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// title
|
|
|
|
if (motion.title) {
|
|
|
|
motion.title = motion.title.replace(quotionRe, '$1');
|
|
|
|
}
|
|
|
|
if (!motion.title) {
|
|
|
|
motion.importerror = true;
|
|
|
|
motion.title_error = gettext('Error: Title is required.');
|
|
|
|
}
|
|
|
|
// text
|
|
|
|
if (motion.text) {
|
|
|
|
motion.text = motion.text.replace(quotionRe, '$1');
|
|
|
|
}
|
|
|
|
if (!motion.text) {
|
|
|
|
motion.importerror = true;
|
|
|
|
motion.text_error = gettext('Error: Text is required.');
|
|
|
|
}
|
|
|
|
// reason
|
|
|
|
if (motion.reason) {
|
|
|
|
motion.reason = motion.reason.replace(quotionRe, '$1');
|
|
|
|
}
|
|
|
|
// submitter
|
|
|
|
if (motion.submitter) {
|
|
|
|
motion.submitter = motion.submitter.replace(quotionRe, '$1');
|
|
|
|
if (motion.submitter != '') {
|
|
|
|
// All user objects are already loaded via the resolve statement from ui-router.
|
|
|
|
var users = User.getAll();
|
|
|
|
angular.forEach(users, function (user) {
|
|
|
|
if (user.short_name == motion.submitter) {
|
|
|
|
motion.submitters_id = [user.id];
|
|
|
|
motion.submitter = User.get(user.id).full_name;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (motion.submitter && motion.submitter != '' && !motion.submitters_id) {
|
|
|
|
motion.submitter_create = gettext('New participant will be created.');
|
|
|
|
}
|
|
|
|
// category
|
|
|
|
if (motion.category) {
|
|
|
|
motion.category = motion.category.replace(quotionRe, '$1');
|
|
|
|
if (motion.category != '') {
|
|
|
|
// All categore objects are already loaded via the resolve statement from ui-router.
|
|
|
|
var categories = Category.getAll();
|
|
|
|
angular.forEach(categories, function (category) {
|
|
|
|
// search for existing category
|
|
|
|
if (category.name == motion.category) {
|
|
|
|
motion.category_id = category.id;
|
|
|
|
motion.category = Category.get(category.id).name;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (motion.category && motion.category != '' && !motion.category_id) {
|
|
|
|
motion.category_create = gettext('New category will be created.');
|
|
|
|
}
|
|
|
|
$scope.motions.push(motion);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// import from csv file
|
|
|
|
$scope.import = function () {
|
|
|
|
$scope.csvImporting = true;
|
|
|
|
angular.forEach($scope.motions, function (motion) {
|
|
|
|
if (!motion.importerror) {
|
|
|
|
// create new user if not exist
|
|
|
|
if (!motion.submitters_id) {
|
|
|
|
var index = motion.submitter.indexOf(' ');
|
|
|
|
var user = {
|
|
|
|
first_name: motion.submitter.substr(0, index),
|
|
|
|
last_name: motion.submitter.substr(index+1),
|
|
|
|
groups: []
|
|
|
|
}
|
|
|
|
User.create(user).then(
|
|
|
|
function(success) {
|
|
|
|
// set new user id
|
|
|
|
motion.submitters_id = [success.id];
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// create new category if not exist
|
|
|
|
if (!motion.category_id) {
|
|
|
|
var category = {
|
|
|
|
name: motion.category,
|
|
|
|
prefix: motion.category.charAt(0)
|
|
|
|
}
|
|
|
|
Category.create(category).then(
|
|
|
|
function(success) {
|
|
|
|
// set new category id
|
|
|
|
motion.category_id = [success.id];
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
Motion.create(motion).then(
|
|
|
|
function(success) {
|
|
|
|
motion.imported = true;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
$scope.csvimported = true;
|
|
|
|
};
|
|
|
|
$scope.clear = function () {
|
|
|
|
$scope.csv.result = null;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
])
|
2015-11-23 21:31:15 +01:00
|
|
|
|
|
|
|
.controller('CategoryListCtrl', function($scope, Category) {
|
|
|
|
Category.bindAll({}, $scope, 'categories');
|
|
|
|
|
|
|
|
// delete selected category
|
|
|
|
$scope.delete = function (category) {
|
|
|
|
Category.destroy(category.id);
|
|
|
|
};
|
|
|
|
})
|
|
|
|
|
|
|
|
.controller('CategoryDetailCtrl', function($scope, Category, category) {
|
|
|
|
Category.bindOne(category.id, $scope, 'category');
|
|
|
|
})
|
|
|
|
|
|
|
|
.controller('CategoryCreateCtrl', function($scope, $state, Category) {
|
|
|
|
$scope.category = {};
|
|
|
|
$scope.save = function (category) {
|
|
|
|
Category.create(category).then(
|
|
|
|
function(success) {
|
|
|
|
$state.go('motions.category.list');
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
})
|
|
|
|
|
|
|
|
.controller('CategoryUpdateCtrl', function($scope, $state, Category, category) {
|
|
|
|
$scope.category = category;
|
|
|
|
$scope.save = function (category) {
|
|
|
|
Category.save(category).then(
|
|
|
|
function(success) {
|
|
|
|
$state.go('motions.category.list');
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
}());
|