Merge pull request #1702 from emanuelschuetze/split-motions-js
Split motions.js into base, site and projector
This commit is contained in:
commit
78c7b2497f
@ -7,7 +7,7 @@ class MotionsAppConfig(AppConfig):
|
|||||||
verbose_name = 'OpenSlides Motion'
|
verbose_name = 'OpenSlides Motion'
|
||||||
angular_site_module = True
|
angular_site_module = True
|
||||||
angular_projector_module = True
|
angular_projector_module = True
|
||||||
js_files = ['js/motions/motions.js']
|
js_files = ['js/motions/base.js', 'js/motions/site.js', 'js/motions/projector.js']
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
# Load projector elements.
|
# Load projector elements.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
(function () {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
angular.module('OpenSlidesApp.motions', [])
|
angular.module('OpenSlidesApp.motions', ['OpenSlidesApp.users'])
|
||||||
|
|
||||||
.factory('WorkflowState', [
|
.factory('WorkflowState', [
|
||||||
'DS',
|
'DS',
|
||||||
@ -445,478 +447,4 @@ angular.module('OpenSlidesApp.motions', [])
|
|||||||
|
|
||||||
.run(['Motion', 'Category', function(Motion, Category) {}]);
|
.run(['Motion', 'Category', function(Motion, Category) {}]);
|
||||||
|
|
||||||
|
}());
|
||||||
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.create', {
|
|
||||||
resolve: {
|
|
||||||
categories: function(Category) {
|
|
||||||
return Category.findAll();
|
|
||||||
},
|
|
||||||
tags: function(Tag) {
|
|
||||||
return Tag.findAll();
|
|
||||||
},
|
|
||||||
users: function(User) {
|
|
||||||
return User.findAll();
|
|
||||||
},
|
|
||||||
mediafiles: function(Mediafile) {
|
|
||||||
return Mediafile.findAll();
|
|
||||||
},
|
|
||||||
workflows: function(Workflow) {
|
|
||||||
return Workflow.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', {
|
|
||||||
views: {
|
|
||||||
'@motions.motion': {}
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
categories: function(Category) {
|
|
||||||
return Category.findAll();
|
|
||||||
},
|
|
||||||
tags: function(Tag) {
|
|
||||||
return Tag.findAll();
|
|
||||||
},
|
|
||||||
users: function(User) {
|
|
||||||
return User.findAll();
|
|
||||||
},
|
|
||||||
mediafiles: function(Mediafile) {
|
|
||||||
return Mediafile.findAll();
|
|
||||||
},
|
|
||||||
workflows: function(Workflow) {
|
|
||||||
return Workflow.findAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.state('motions.motion.csv-import', {
|
|
||||||
url: '/csv-import',
|
|
||||||
controller: 'MotionCSVImportCtrl',
|
|
||||||
})
|
|
||||||
// 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': {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
.controller('MotionListCtrl', [
|
|
||||||
'$scope',
|
|
||||||
'$state',
|
|
||||||
'Motion',
|
|
||||||
'Category',
|
|
||||||
'Tag',
|
|
||||||
'Workflow',
|
|
||||||
'User',
|
|
||||||
function($scope, $state, Motion, Category, Tag, Workflow, User) {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// hover edit actions
|
|
||||||
$scope.hoverIn = function () {
|
|
||||||
$scope.showEditActions = true;
|
|
||||||
};
|
|
||||||
$scope.hoverOut = function () {
|
|
||||||
$scope.showEditActions = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// save changed motion
|
|
||||||
$scope.update = function (motion) {
|
|
||||||
// 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
|
|
||||||
$scope.delete = function () {
|
|
||||||
angular.forEach($scope.motions, function (motion) {
|
|
||||||
if (motion.selected)
|
|
||||||
Motion.destroy(motion.id);
|
|
||||||
});
|
|
||||||
$scope.isDeleteMode = false;
|
|
||||||
$scope.uncheckAll();
|
|
||||||
};
|
|
||||||
// delete single motion
|
|
||||||
$scope.deleteSingleMotion = function (motion) {
|
|
||||||
Motion.destroy(motion.id);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
.controller('MotionDetailCtrl', [
|
|
||||||
'$scope',
|
|
||||||
'$http',
|
|
||||||
'Motion',
|
|
||||||
'Category',
|
|
||||||
'Mediafile',
|
|
||||||
'Tag',
|
|
||||||
'User',
|
|
||||||
'Workflow',
|
|
||||||
'motion',
|
|
||||||
function($scope, $http, Motion, Category, Mediafile, Tag, User, Workflow, motion) {
|
|
||||||
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;
|
|
||||||
|
|
||||||
$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',
|
|
||||||
'operator',
|
|
||||||
'Motion',
|
|
||||||
'MotionFormFieldFactory',
|
|
||||||
'Category',
|
|
||||||
'Config',
|
|
||||||
'Mediafile',
|
|
||||||
'Tag',
|
|
||||||
'User',
|
|
||||||
'Workflow',
|
|
||||||
function($scope, $state, gettext, operator, Motion, MotionFormFieldFactory, Category, Config, Mediafile, Tag, User, Workflow) {
|
|
||||||
Category.bindAll({}, $scope, 'categories');
|
|
||||||
Mediafile.bindAll({}, $scope, 'mediafiles');
|
|
||||||
Tag.bindAll({}, $scope, 'tags');
|
|
||||||
User.bindAll({}, $scope, 'users');
|
|
||||||
Workflow.bindAll({}, $scope, 'workflows');
|
|
||||||
|
|
||||||
// get all form fields
|
|
||||||
$scope.formFields = MotionFormFieldFactory.getFormFields();
|
|
||||||
// override default values for create form
|
|
||||||
for (var i = 0; i < $scope.formFields.length; i++) {
|
|
||||||
if ($scope.formFields[i].key == "identifier") {
|
|
||||||
$scope.formFields[i].hide = true;
|
|
||||||
}
|
|
||||||
if ($scope.formFields[i].key == "text") {
|
|
||||||
// set preamble config value as default text
|
|
||||||
$scope.formFields[i].defaultValue = Config.get('motions_preamble').value;
|
|
||||||
}
|
|
||||||
if ($scope.formFields[i].key == "workflow_id") {
|
|
||||||
// preselect default workflow
|
|
||||||
$scope.formFields[i].defaultValue = Config.get('motions_workflow').value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$scope.save = function (motion) {
|
|
||||||
Motion.create(motion).then(
|
|
||||||
function(success) {
|
|
||||||
$state.go('motions.motion.list');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
.controller('MotionUpdateCtrl', [
|
|
||||||
'$scope',
|
|
||||||
'$state',
|
|
||||||
'gettext',
|
|
||||||
'Motion',
|
|
||||||
'Category',
|
|
||||||
'Config',
|
|
||||||
'Mediafile',
|
|
||||||
'MotionFormFieldFactory',
|
|
||||||
'Tag',
|
|
||||||
'User',
|
|
||||||
'Workflow',
|
|
||||||
'motion',
|
|
||||||
function($scope, $state, gettext, Motion, Category, Config, Mediafile, MotionFormFieldFactory, Tag, User, Workflow, motion) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// save form
|
|
||||||
$scope.save = function (model) {
|
|
||||||
Motion.save(model)
|
|
||||||
.then(function(success) {
|
|
||||||
$state.go('motions.motion.detail', {id: motion.id});
|
|
||||||
})
|
|
||||||
.catch(function(fallback) {
|
|
||||||
//TODO: show error in GUI
|
|
||||||
console.log(fallback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
.controller('MotionCSVImportCtrl', function($scope, Motion) {
|
|
||||||
// TODO
|
|
||||||
})
|
|
||||||
|
|
||||||
.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');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
angular.module('OpenSlidesApp.motions.projector', ['OpenSlidesApp.motions'])
|
|
||||||
|
|
||||||
.config(function(slidesProvider) {
|
|
||||||
slidesProvider.registerSlide('motions/motion', {
|
|
||||||
template: 'static/templates/motions/slide_motion.html',
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
.controller('SlideMotionCtrl', function($scope, Motion) {
|
|
||||||
// Attention! Each object that is used here has to be dealt on server side.
|
|
||||||
// Add it to the coresponding get_requirements method of the ProjectorElement
|
|
||||||
// class.
|
|
||||||
var id = $scope.element.id;
|
|
||||||
Motion.find(id);
|
|
||||||
Motion.bindOne(id, $scope, 'motion');
|
|
||||||
});
|
|
22
openslides/motions/static/js/motions/projector.js
Normal file
22
openslides/motions/static/js/motions/projector.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
(function () {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('OpenSlidesApp.motions.projector', ['OpenSlidesApp.motions'])
|
||||||
|
|
||||||
|
.config(function(slidesProvider) {
|
||||||
|
slidesProvider.registerSlide('motions/motion', {
|
||||||
|
template: 'static/templates/motions/slide_motion.html',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.controller('SlideMotionCtrl', function($scope, Motion) {
|
||||||
|
// Attention! Each object that is used here has to be dealt on server side.
|
||||||
|
// Add it to the coresponding get_requirements method of the ProjectorElement
|
||||||
|
// class.
|
||||||
|
var id = $scope.element.id;
|
||||||
|
Motion.find(id);
|
||||||
|
Motion.bindOne(id, $scope, 'motion');
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
462
openslides/motions/static/js/motions/site.js
Normal file
462
openslides/motions/static/js/motions/site.js
Normal file
@ -0,0 +1,462 @@
|
|||||||
|
(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.create', {
|
||||||
|
resolve: {
|
||||||
|
categories: function(Category) {
|
||||||
|
return Category.findAll();
|
||||||
|
},
|
||||||
|
tags: function(Tag) {
|
||||||
|
return Tag.findAll();
|
||||||
|
},
|
||||||
|
users: function(User) {
|
||||||
|
return User.findAll();
|
||||||
|
},
|
||||||
|
mediafiles: function(Mediafile) {
|
||||||
|
return Mediafile.findAll();
|
||||||
|
},
|
||||||
|
workflows: function(Workflow) {
|
||||||
|
return Workflow.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', {
|
||||||
|
views: {
|
||||||
|
'@motions.motion': {}
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
categories: function(Category) {
|
||||||
|
return Category.findAll();
|
||||||
|
},
|
||||||
|
tags: function(Tag) {
|
||||||
|
return Tag.findAll();
|
||||||
|
},
|
||||||
|
users: function(User) {
|
||||||
|
return User.findAll();
|
||||||
|
},
|
||||||
|
mediafiles: function(Mediafile) {
|
||||||
|
return Mediafile.findAll();
|
||||||
|
},
|
||||||
|
workflows: function(Workflow) {
|
||||||
|
return Workflow.findAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.state('motions.motion.csv-import', {
|
||||||
|
url: '/csv-import',
|
||||||
|
controller: 'MotionCSVImportCtrl',
|
||||||
|
})
|
||||||
|
// 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': {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
.controller('MotionListCtrl', [
|
||||||
|
'$scope',
|
||||||
|
'$state',
|
||||||
|
'Motion',
|
||||||
|
'Category',
|
||||||
|
'Tag',
|
||||||
|
'Workflow',
|
||||||
|
'User',
|
||||||
|
function($scope, $state, Motion, Category, Tag, Workflow, User) {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// hover edit actions
|
||||||
|
$scope.hoverIn = function () {
|
||||||
|
$scope.showEditActions = true;
|
||||||
|
};
|
||||||
|
$scope.hoverOut = function () {
|
||||||
|
$scope.showEditActions = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// save changed motion
|
||||||
|
$scope.update = function (motion) {
|
||||||
|
// 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
|
||||||
|
$scope.delete = function () {
|
||||||
|
angular.forEach($scope.motions, function (motion) {
|
||||||
|
if (motion.selected)
|
||||||
|
Motion.destroy(motion.id);
|
||||||
|
});
|
||||||
|
$scope.isDeleteMode = false;
|
||||||
|
$scope.uncheckAll();
|
||||||
|
};
|
||||||
|
// delete single motion
|
||||||
|
$scope.deleteSingleMotion = function (motion) {
|
||||||
|
Motion.destroy(motion.id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
.controller('MotionDetailCtrl', [
|
||||||
|
'$scope',
|
||||||
|
'$http',
|
||||||
|
'Motion',
|
||||||
|
'Category',
|
||||||
|
'Mediafile',
|
||||||
|
'Tag',
|
||||||
|
'User',
|
||||||
|
'Workflow',
|
||||||
|
'motion',
|
||||||
|
function($scope, $http, Motion, Category, Mediafile, Tag, User, Workflow, motion) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
$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',
|
||||||
|
function($scope, $state, gettext, Motion, MotionFormFieldFactory, Category, Config, Mediafile, Tag, User, Workflow) {
|
||||||
|
Category.bindAll({}, $scope, 'categories');
|
||||||
|
Mediafile.bindAll({}, $scope, 'mediafiles');
|
||||||
|
Tag.bindAll({}, $scope, 'tags');
|
||||||
|
User.bindAll({}, $scope, 'users');
|
||||||
|
Workflow.bindAll({}, $scope, 'workflows');
|
||||||
|
|
||||||
|
// get all form fields
|
||||||
|
$scope.formFields = MotionFormFieldFactory.getFormFields();
|
||||||
|
// override default values for create form
|
||||||
|
for (var i = 0; i < $scope.formFields.length; i++) {
|
||||||
|
if ($scope.formFields[i].key == "identifier") {
|
||||||
|
$scope.formFields[i].hide = true;
|
||||||
|
}
|
||||||
|
if ($scope.formFields[i].key == "text") {
|
||||||
|
// set preamble config value as default text
|
||||||
|
$scope.formFields[i].defaultValue = Config.get('motions_preamble').value;
|
||||||
|
}
|
||||||
|
if ($scope.formFields[i].key == "workflow_id") {
|
||||||
|
// preselect default workflow
|
||||||
|
$scope.formFields[i].defaultValue = Config.get('motions_workflow').value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$scope.save = function (motion) {
|
||||||
|
Motion.create(motion).then(
|
||||||
|
function(success) {
|
||||||
|
$state.go('motions.motion.list');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
.controller('MotionUpdateCtrl', [
|
||||||
|
'$scope',
|
||||||
|
'$state',
|
||||||
|
'gettext',
|
||||||
|
'Motion',
|
||||||
|
'Category',
|
||||||
|
'Config',
|
||||||
|
'Mediafile',
|
||||||
|
'MotionFormFieldFactory',
|
||||||
|
'Tag',
|
||||||
|
'User',
|
||||||
|
'Workflow',
|
||||||
|
'motion',
|
||||||
|
function($scope, $state, gettext, Motion, Category, Config, Mediafile, MotionFormFieldFactory, Tag, User, Workflow, motion) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save form
|
||||||
|
$scope.save = function (model) {
|
||||||
|
Motion.save(model)
|
||||||
|
.then(function(success) {
|
||||||
|
$state.go('motions.motion.detail', {id: motion.id});
|
||||||
|
})
|
||||||
|
.catch(function(fallback) {
|
||||||
|
//TODO: show error in GUI
|
||||||
|
console.log(fallback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
.controller('MotionCSVImportCtrl', function($scope, Motion) {
|
||||||
|
// TODO
|
||||||
|
})
|
||||||
|
|
||||||
|
.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');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
}());
|
@ -4,6 +4,55 @@
|
|||||||
|
|
||||||
angular.module('OpenSlidesApp.users', [])
|
angular.module('OpenSlidesApp.users', [])
|
||||||
|
|
||||||
|
.factory('operator', [
|
||||||
|
'User',
|
||||||
|
'Group',
|
||||||
|
'loadGlobalData',
|
||||||
|
function(User, Group, loadGlobalData) {
|
||||||
|
var operatorChangeCallbacks = [];
|
||||||
|
var operator = {
|
||||||
|
user: null,
|
||||||
|
perms: [],
|
||||||
|
isAuthenticated: function () {
|
||||||
|
return !!this.user;
|
||||||
|
},
|
||||||
|
onOperatorChange: function (func) {
|
||||||
|
operatorChangeCallbacks.push(func);
|
||||||
|
},
|
||||||
|
setUser: function(user_id) {
|
||||||
|
if (user_id) {
|
||||||
|
User.find(user_id).then(function(user) {
|
||||||
|
operator.user = user;
|
||||||
|
// TODO: load only the needed groups
|
||||||
|
Group.findAll().then(function() {
|
||||||
|
operator.perms = user.getPerms();
|
||||||
|
_.forEach(operatorChangeCallbacks, function (callback) {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
operator.user = null;
|
||||||
|
Group.find(1).then(function(group) {
|
||||||
|
operator.perms = group.permissions;
|
||||||
|
_.forEach(operatorChangeCallbacks, function (callback) {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Returns true if the operator has at least one perm of the perms-list.
|
||||||
|
hasPerms: function(perms) {
|
||||||
|
if (typeof perms == 'string') {
|
||||||
|
perms = perms.split(' ');
|
||||||
|
}
|
||||||
|
return _.intersection(perms, operator.perms).length > 0;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
.factory('User', ['DS', 'Group', 'jsDataModel', function(DS, Group, jsDataModel) {
|
.factory('User', ['DS', 'Group', 'jsDataModel', function(DS, Group, jsDataModel) {
|
||||||
var name = 'users/user';
|
var name = 'users/user';
|
||||||
return DS.defineResource({
|
return DS.defineResource({
|
||||||
|
@ -119,55 +119,6 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.factory('operator', [
|
|
||||||
'User',
|
|
||||||
'Group',
|
|
||||||
'loadGlobalData',
|
|
||||||
function(User, Group, loadGlobalData) {
|
|
||||||
var operatorChangeCallbacks = [];
|
|
||||||
var operator = {
|
|
||||||
user: null,
|
|
||||||
perms: [],
|
|
||||||
isAuthenticated: function () {
|
|
||||||
return !!this.user;
|
|
||||||
},
|
|
||||||
onOperatorChange: function (func) {
|
|
||||||
operatorChangeCallbacks.push(func);
|
|
||||||
},
|
|
||||||
setUser: function(user_id) {
|
|
||||||
if (user_id) {
|
|
||||||
User.find(user_id).then(function(user) {
|
|
||||||
operator.user = user;
|
|
||||||
// TODO: load only the needed groups
|
|
||||||
Group.findAll().then(function() {
|
|
||||||
operator.perms = user.getPerms();
|
|
||||||
_.forEach(operatorChangeCallbacks, function (callback) {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
operator.user = null;
|
|
||||||
Group.find(1).then(function(group) {
|
|
||||||
operator.perms = group.permissions;
|
|
||||||
_.forEach(operatorChangeCallbacks, function (callback) {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Returns true if the operator has at least one perm of the perms-list.
|
|
||||||
hasPerms: function(perms) {
|
|
||||||
if (typeof perms == 'string') {
|
|
||||||
perms = perms.split(' ');
|
|
||||||
}
|
|
||||||
return _.intersection(perms, operator.perms).length > 0;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return operator;
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
.run([
|
.run([
|
||||||
'operator',
|
'operator',
|
||||||
'$rootScope',
|
'$rootScope',
|
||||||
|
Loading…
Reference in New Issue
Block a user