diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index 20274ee22..203c38b26 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -165,10 +165,8 @@ angular.module('OpenSlidesApp.core.site', [ } angular.forEach(views, function(config, name) { - - // Sets default values for templateUrl - var patterns = state.name.split('.'), - templateUrl, + // Sets additional default values for templateUrl + var templateUrl, controller, defaultControllers = { create: 'CreateCtrl', @@ -177,22 +175,43 @@ angular.module('OpenSlidesApp.core.site', [ detail: 'DetailCtrl', }; - // templateUrl - if (_.last(patterns).match(/(create|update)/)) { - // When state_patterns is in the form "app.module.create" or - // "app.module.update", use the form template. - templateUrl = 'static/templates/' + patterns[0] + '/' + patterns[1] + '-form.html'; - } else { - // Replaces the first point through a slash (the app name) - var appName = state.name.replace('.', '/'); - // Replaces any folowing points though a - - templateUrl = 'static/templates/' + appName.replace(/\./g, '-') + '.html'; + // Split up state name + // example: "motions.motion.detail.update" -> ['motions', 'motion', 'detail', 'update'] + var patterns = state.name.split('.') + + // set app and module name from state + // - appName: patterns[0] (e.g. "motions") + // - moduleNames: patterns without first element (e.g. ["motion", "detail", "update"]) + var appName = '' + var moduleName = ''; + var moduleNames = []; + if (patterns.length > 0) { + appName = patterns[0]; + moduleNames = patterns.slice(1); } + if (moduleNames.length > 0) { + // convert from camcelcase to dash notation + // example: ["motionBlock", "detail"] -> ["motion-block", "detail"] + for (var i = 0; i < moduleNames.length; i++) { + moduleNames[i] = moduleNames[i].replace(/([a-z\d])([A-Z])/g, '$1-$2').toLowerCase(); + }; + + // use special templateUrl for create and update view + // example: ["motion", "detail", "update"] -> "motion-form" + if (_.last(moduleNames).match(/(create|update)/)) { + moduleName = '/' + moduleNames[0] + '-form'; + } else { + // convert modelNames array to url string + // example: ["motion-block", "detail"] -> "motion-block-detail" + moduleName = '/' + moduleNames.join('-'); + } + } + templateUrl = 'static/templates/' + appName + moduleName + '.html'; config.templateUrl = state.templateUrl || templateUrl; // controller if (patterns.length >= 3) { - controller = _.capitalize(patterns[1]) + defaultControllers[_.last(patterns)]; + controller = _.upperFirst(patterns[1]) + defaultControllers[_.last(patterns)]; config.controller = state.controller || controller; } result[name] = config; @@ -1417,6 +1436,16 @@ angular.module('OpenSlidesApp.core.site', [ } ]) +.filter("toArray", function(){ + return function(obj) { + var result = []; + angular.forEach(obj, function(val, key) { + result.push(val); + }); + return result; + }; +}) + //Mark all core config strings for translation in Javascript .config([ 'gettext', diff --git a/openslides/motions/static/js/motions/motion-block.js b/openslides/motions/static/js/motions/motion-block.js index 9a88b0b23..ea45af12a 100644 --- a/openslides/motions/static/js/motions/motion-block.js +++ b/openslides/motions/static/js/motions/motion-block.js @@ -58,7 +58,7 @@ angular.module('OpenSlidesApp.motions.motionBlock', []) // Get ngDialog configuration. getDialog: function (motionBlock) { return { - template: 'static/templates/motions/motionBlock-form.html', + template: 'static/templates/motions/motion-block-form.html', controller: (motionBlock) ? 'MotionBlockUpdateCtrl' : 'MotionBlockCreateCtrl', className: 'ngdialog-theme-default wide-form', closeByEscape: false, @@ -104,8 +104,7 @@ angular.module('OpenSlidesApp.motions.motionBlock', []) } ]) -// TODO: Rename this to MotionBlockListCtrl after $stateProvider is fixed, see #2479. -.controller('MotionblockListCtrl', [ +.controller('MotionBlockListCtrl', [ '$scope', 'ngDialog', 'MotionBlock', @@ -123,22 +122,21 @@ angular.module('OpenSlidesApp.motions.motionBlock', []) $scope.delete = function (motionBlock) { MotionBlock.destroy(motionBlock.id); }; - - // TODO: In template we have filter toggleSort reverse sortColumn header. Use this stuff or remove it. } ]) -// TODO: Rename this to MotionBlockDetailCtrl after $stateProvider is fixed, see #2479. -.controller('MotionblockDetailCtrl', [ +.controller('MotionBlockDetailCtrl', [ '$scope', 'ngDialog', + 'Motion', 'MotionBlockForm', 'MotionBlock', 'motionBlock', 'Projector', 'ProjectionDefault', - function($scope, ngDialog, MotionBlockForm, MotionBlock, motionBlock, Projector, ProjectionDefault) { + function($scope, ngDialog, Motion, MotionBlockForm, MotionBlock, motionBlock, Projector, ProjectionDefault) { MotionBlock.bindOne(motionBlock.id, $scope, 'motionBlock'); + Motion.bindAll({}, $scope, 'motions'); $scope.$watch(function () { return Projector.lastModified(); }, function () { diff --git a/openslides/motions/static/js/motions/site.js b/openslides/motions/static/js/motions/site.js index 9626161e0..7bbd403f1 100644 --- a/openslides/motions/static/js/motions/site.js +++ b/openslides/motions/static/js/motions/site.js @@ -229,6 +229,9 @@ angular.module('OpenSlidesApp.motions.site', [ motionBlock: function(MotionBlock, $stateParams) { return MotionBlock.find($stateParams.id); }, + motions: function(Motion) { + return Motion.findAll(); + }, items: function(Agenda) { return Agenda.findAll().catch( function () { @@ -246,7 +249,7 @@ angular.module('OpenSlidesApp.motions.site', [ onEnter: ['$stateParams', '$state', 'ngDialog', 'MotionBlock', function($stateParams, $state, ngDialog, MotionBlock) { ngDialog.open({ - template: 'static/templates/motions/motionBlock-form.html', + template: 'static/templates/motions/motion-block-form.html', controller: 'MotionBlockUpdateCtrl', className: 'ngdialog-theme-default wide-form', closeByEscape: false, @@ -707,6 +710,7 @@ angular.module('OpenSlidesApp.motions.site', [ 'Workflow', 'User', 'Agenda', + 'MotionBlock', 'MotionDocxExport', 'MotionContentProvider', 'MotionCatalogContentProvider', @@ -716,11 +720,12 @@ angular.module('OpenSlidesApp.motions.site', [ 'HTMLValidizer', 'Projector', 'ProjectionDefault', - function($scope, $state, $http, ngDialog, MotionForm, Motion, Category, Tag, Workflow, User, Agenda, MotionDocxExport, - MotionContentProvider, MotionCatalogContentProvider, PdfMakeConverter, PdfMakeDocumentProvider, + function($scope, $state, $http, ngDialog, MotionForm, Motion, Category, Tag, Workflow, User, Agenda, MotionBlock, + MotionDocxExport, MotionContentProvider, MotionCatalogContentProvider, PdfMakeConverter, PdfMakeDocumentProvider, gettextCatalog, HTMLValidizer, Projector, ProjectionDefault) { Motion.bindAll({}, $scope, 'motions'); Category.bindAll({}, $scope, 'categories'); + MotionBlock.bindAll({}, $scope, 'motionBlocks'); Tag.bindAll({}, $scope, 'tags'); Workflow.bindAll({}, $scope, 'workflows'); User.bindAll({}, $scope, 'users'); @@ -743,11 +748,13 @@ angular.module('OpenSlidesApp.motions.site', [ $scope.multiselectFilter = { state: [], category: [], + motionBlock: [], tag: [] }; $scope.getItemId = { state: function (motion) {return motion.state_id;}, category: function (motion) {return motion.category_id;}, + motionBlock: function (motion) {return motion.motion_block_id;}, tag: function (motion) {return motion.tags_id;} }; // function to operate the multiselectFilter @@ -777,6 +784,10 @@ angular.module('OpenSlidesApp.motions.site', [ if (motion.category) { category = motion.category.name; } + var motionBlock = ''; + if (motion.motionBlock) { + motionBlock = motion.motionBlock.title; + } return [ motion.identifier, motion.getTitle(), @@ -802,6 +813,7 @@ angular.module('OpenSlidesApp.motions.site', [ } ).join(" "), category, + motionBlock ].join(" "); }; // for reset-button @@ -809,6 +821,7 @@ angular.module('OpenSlidesApp.motions.site', [ $scope.multiselectFilter = { state: [], category: [], + motionBlock: [], tag: [] }; if ($scope.filter) { @@ -818,6 +831,7 @@ angular.module('OpenSlidesApp.motions.site', [ $scope.are_filters_set = function () { return $scope.multiselectFilter.state.length > 0 || $scope.multiselectFilter.category.length > 0 || + $scope.multiselectFilter.motionBlock.length > 0 || $scope.multiselectFilter.tag.length > 0 || ($scope.filter ? $scope.filter.search : false); }; @@ -878,6 +892,14 @@ angular.module('OpenSlidesApp.motions.site', [ } save(motion); }; + $scope.toggle_motionBlock = function (motion, block) { + if (motion.motion_block_id == block.id) { + motion.motion_block_id = null; + } else { + motion.motion_block_id = block.id; + } + save(motion); + }; // open new/edit dialog $scope.openDialog = function (motion) { diff --git a/openslides/motions/static/templates/motions/motion-block-detail.html b/openslides/motions/static/templates/motions/motion-block-detail.html new file mode 100644 index 000000000..87d649fd0 --- /dev/null +++ b/openslides/motions/static/templates/motions/motion-block-detail.html @@ -0,0 +1,76 @@ +
+
+ +

{{ motionBlock.agenda_item.getTitle() }}

+

Motion block

+
+
+ +
+ + + + Set state for each motion according to their recommendation + + +
+
+ +
+
+ {{ motionsFiltered.length }} / + {{ motionBlock.motions.length }} {{ "motions" | translate }} +
+
+ + + + + + +
Motion + State + Recommendation +
+ + {{ motion.identifier }} {{ motion.getTitle() }} + + + +
+ {{ motion.state.name | translate }} +
+
+
+ {{ motion.recommendation.recommendation_label | translate }} +
+
+
diff --git a/openslides/motions/static/templates/motions/motionBlock-form.html b/openslides/motions/static/templates/motions/motion-block-form.html similarity index 100% rename from openslides/motions/static/templates/motions/motionBlock-form.html rename to openslides/motions/static/templates/motions/motion-block-form.html diff --git a/openslides/motions/static/templates/motions/motionBlock-list.html b/openslides/motions/static/templates/motions/motion-block-list.html similarity index 83% rename from openslides/motions/static/templates/motions/motionBlock-list.html rename to openslides/motions/static/templates/motions/motion-block-list.html index 966485938..abca205c8 100644 --- a/openslides/motions/static/templates/motions/motionBlock-list.html +++ b/openslides/motions/static/templates/motions/motion-block-list.html @@ -25,13 +25,9 @@ - - +
- Name - - + Name
{{ motionBlock.title }} diff --git a/openslides/motions/static/templates/motions/motion-detail.html b/openslides/motions/static/templates/motions/motion-detail.html index bf2e41f68..11cda9ea9 100644 --- a/openslides/motions/static/templates/motions/motion-detail.html +++ b/openslides/motions/static/templates/motions/motion-detail.html @@ -150,6 +150,12 @@

Category

{{ motion.category.name }} + +

Motion block

+ {{ motion.motionBlock.title }} + {{ motion.motionBlock.title }} +

Tags

@@ -160,10 +166,6 @@

Origin

{{ motion.origin }} - -

Motion block

- {{ motion.motionBlock }} -

Voting result

diff --git a/openslides/motions/static/templates/motions/motion-list.html b/openslides/motions/static/templates/motions/motion-list.html index 1265e05f1..49132380b 100644 --- a/openslides/motions/static/templates/motions/motion-list.html +++ b/openslides/motions/static/templates/motions/motion-list.html @@ -10,7 +10,7 @@ Categories - + Motion blocks @@ -109,7 +109,7 @@ Filter - + - + - + + + + Motion block + + + + +
  • -
    +
    Category + +
    +
  • +
  • + +
    + Motion block + +
    @@ -274,6 +304,15 @@ {{ category.name }} + + + + {{ motionBlock.title }} + + @@ -314,7 +355,7 @@