From bc72089973884979340e0ece1c51558d3f4ee9f4 Mon Sep 17 00:00:00 2001 From: Emanuel Schuetze Date: Fri, 30 Sep 2016 17:19:27 +0200 Subject: [PATCH] UI improvements - item list: reorder buttons - motion list: * move hover menu for edit/delete below submitters * limit submitters to one - motion detail: * show ol flush left * use 2 or 3 columns in meta box * use small buttons for line numbering controls * group line number controls in grey tool bar. * Show motion comments div only if user is allowed. - motion config: * Deativate comments by default. * Deactivate recommendations for motions by default. - item detail: Show needed buttons only. - assignment detail: Improve ballot tabs. - general: * move pdf button to right * move 'back to overview' button to left * update label vor countdown option --- openslides/agenda/static/js/agenda/site.js | 45 +++++-- .../agenda/current-list-of-speakers.html | 20 ++- .../static/templates/agenda/item-detail.html | 63 ++++----- .../static/templates/agenda/item-list.html | 111 ++++++++-------- .../assignments/static/js/assignments/site.js | 7 +- .../assignments/assignment-detail.html | 122 +++++++++++------- openslides/core/config_variables.py | 2 +- openslides/core/static/css/app.css | 56 +++++--- openslides/core/static/js/core/site.js | 2 +- .../core/static/templates/core/tag-list.html | 8 +- openslides/motions/config_variables.py | 4 +- openslides/motions/static/js/motions/site.js | 16 ++- .../templates/motions/category-list.html | 8 +- .../templates/motions/motion-detail.html | 58 +++++---- .../static/templates/motions/motion-list.html | 31 ++--- .../static/templates/users/group-list.html | 8 +- .../static/templates/users/user-list.html | 2 +- 17 files changed, 339 insertions(+), 224 deletions(-) diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index 7ca0ee866..5f1dca7d3 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -337,9 +337,21 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) $scope.defaultProjectorListOfSpeakersId = projectiondefaultListOfSpeakers.projector_id; } }); + + $scope.$watch(function () { + return Agenda.lastModified(); + }, function () { + // all speakers + $scope.speakers = $filter('orderBy')(item.speakers, 'weight'); + // next speakers + $scope.nextSpeakers = $filter('filter')($scope.speakers, {'begin_time': null}); + // current speaker + $scope.currentSpeaker = $filter('filter')($scope.speakers, {'begin_time': '!!', 'end_time': null}); + // last speakers + $scope.lastSpeakers = $filter('filter')($scope.speakers, {'end_time': '!!'}); + }); $scope.speakerSelectBox = {}; $scope.alert = {}; - $scope.speakers = $filter('orderBy')(item.speakers, 'weight'); $scope.$watch(function () { return Agenda.lastModified(); @@ -403,20 +415,31 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda']) $scope.speakers = item.speakers; }; - // check if user is allowed to see 'add me' / 'remove me' button + // Return true if the requested user is allowed to do a specific action + // and see the corresponding button (e.g. 'add me' or 'remove me'). $scope.isAllowed = function (action) { var nextUsers = []; - var nextSpeakers = $filter('filter')($scope.speakers, {'begin_time': null}); - angular.forEach(nextSpeakers, function (speaker) { + angular.forEach($scope.nextSpeakers, function (speaker) { nextUsers.push(speaker.user_id); }); - if (action == 'add') { - return (operator.hasPerms('agenda.can_be_speaker') && - !item.speaker_list_closed && - $.inArray(operator.user.id, nextUsers) == -1); - } - if (action == 'remove') { - return ($.inArray(operator.user.id, nextUsers) != -1); + switch (action) { + case 'add': + return (operator.hasPerms('agenda.can_be_speaker') && + !item.speaker_list_closed && + $.inArray(operator.user.id, nextUsers) == -1); + case 'remove': + return ($.inArray(operator.user.id, nextUsers) != -1); + case 'removeAll': + return (operator.hasPerms('agenda.can_manage') && + $scope.speakers.length > 0); + case 'beginNextSpeech': + return (operator.hasPerms('agenda.can_manage') && + $scope.nextSpeakers.length > 0); + case 'endCurrentSpeech': + return (operator.hasPerms('agenda.can_manage') && + $scope.currentSpeaker.length > 0); + case 'showLastSpeakers': + return $scope.lastSpeakers.length > 0; } }; diff --git a/openslides/agenda/static/templates/agenda/current-list-of-speakers.html b/openslides/agenda/static/templates/agenda/current-list-of-speakers.html index d9c84943e..c6c4a7923 100644 --- a/openslides/agenda/static/templates/agenda/current-list-of-speakers.html +++ b/openslides/agenda/static/templates/agenda/current-list-of-speakers.html @@ -1,7 +1,19 @@
-
+
+
-
-
- - -
+ + +
+ + +

+ The list of speakers is empty. +

-
-

Last speakers

-
-
    -
  1. +
      +
    1. {{ speaker.user.get_full_name() }} {{ getDuration(speaker) | osSecondsToTime }} minutes @@ -115,9 +119,8 @@
-

Current speaker

- +

+ {{ speaker.user.get_full_name() }} - +

-

Next speakers

-
+
    -
  1. +
  2. {{ $index + 1 }}. {{ speaker.user.get_full_name() }} +  
-
+
{{ alert.msg }}
diff --git a/openslides/agenda/static/templates/agenda/item-list.html b/openslides/agenda/static/templates/agenda/item-list.html index 2cd95ef20..0cf7a6871 100644 --- a/openslides/agenda/static/templates/agenda/item-list.html +++ b/openslides/agenda/static/templates/agenda/item-list.html @@ -1,26 +1,58 @@
@@ -31,58 +63,29 @@ diff --git a/openslides/assignments/static/js/assignments/site.js b/openslides/assignments/static/js/assignments/site.js index 275221df8..bb801614b 100644 --- a/openslides/assignments/static/js/assignments/site.js +++ b/openslides/assignments/static/js/assignments/site.js @@ -367,6 +367,8 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) $scope.candidateSelectBox = {}; $scope.phases = phases; $scope.alert = {}; + $scope.activeTab = 0; + // open edit dialog $scope.openDialog = function (assignment) { ngDialog.open(AssignmentForm.getDialog(assignment)); @@ -431,6 +433,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) }; // create new ballot $scope.createBallot = function () { + $scope.activeTab = 0; $http.post('/rest/assignments/assignment/' + assignment.id + '/create_poll/') .success(function(data){ $scope.alert.show = false; @@ -465,10 +468,10 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments']) }); }; // publish ballot - $scope.publishBallot = function (poll, isPublished) { + $scope.togglePublishBallot = function (poll) { poll.DSUpdate({ assignment_id: assignment.id, - published: isPublished, + published: !poll.published, }) .then(function(success) { $scope.alert.show = false; diff --git a/openslides/assignments/static/templates/assignments/assignment-detail.html b/openslides/assignments/static/templates/assignments/assignment-detail.html index f02456385..1918e3d1a 100644 --- a/openslides/assignments/static/templates/assignments/assignment-detail.html +++ b/openslides/assignments/static/templates/assignments/assignment-detail.html @@ -3,11 +3,7 @@

{{ assignment.agenda_item.getTitle() || assignment.title }}

@@ -117,76 +118,98 @@

Election result

- - + -
+ + + +
+ - 1. Print ballot paper + Print ballot paper - + - - - - + + additional-id="poll.id" content="{{ 'Project' | translate }}"> - - - Delete -
-
- +
+ + +
+ Candidates + + Election method
+ One vote per candidate + Yes/No/Abstain per candidate + Yes/No per candidate +
+ + +
- + - - - - -
Elected Candidates - VotesVotes
- + + + +   + {{ option.candidate.get_full_name() }} - +
{{ vote.label }}: @@ -199,25 +222,30 @@
Valid ballots - + {{ vote.value }} {{ vote.percentStr }}
Invalid ballots - + {{ vote.value }} {{ vote.percentStr }}
Casted ballots - + {{ vote.value }} {{ vote.percentStr }}
+ + + + + + New ballot + +
diff --git a/openslides/core/config_variables.py b/openslides/core/config_variables.py index 52bc715de..a84a0f7fc 100644 --- a/openslides/core/config_variables.py +++ b/openslides/core/config_variables.py @@ -153,7 +153,7 @@ def get_config_variables(): name='projector_default_countdown', default_value=60, input_type='integer', - label='Default countdown', + label='Predefined seconds of new countdowns', weight=185, group='Projector') diff --git a/openslides/core/static/css/app.css b/openslides/core/static/css/app.css index c412242c6..3cd72e6d2 100644 --- a/openslides/core/static/css/app.css +++ b/openslides/core/static/css/app.css @@ -275,7 +275,10 @@ img { float: left; margin-left: 5px; } - +.col1 .header .submenu > div.button { + float: none; + margin-left: 0; +} .col1 .meta .title { width: 100%; cursor: pointer; @@ -333,9 +336,23 @@ img { max-width: 100%; height: auto; } -.col1 ul, .col1 ol { - margin-left: 20px; +.col1 ol { + margin-left: 15px; } +.ballot-tabs ul { + margin-left: 0px; +} +.ballot-tabs li.active a { + background-color: #f5f5f5 !important; +} +.ballot-tabs .tab-content { + background-color: #f5f5f5; + border: 1px solid #ddd; + border-width: 0px 1px 1px 1px; + padding: 15px; + +} + /* Toolbar to save motion in inline editing mode */ .motion-save-toolbar { @@ -689,14 +706,26 @@ img { } #motion-table .data-row > div { - padding: 12px 0; + padding: 10px 0; } #motion-table .header-row { border-top: 1px solid #ddd; background-color: #f5f5f5; } +.linenumber-toolbar, .speakers-toolbar { + background-color: #f5f5f5; + border-bottom: 1px solid #ddd; + padding: 12px 0 10px 0; + height: 54px; + margin: -20px -5px 50px -5px; +} +.speakers-toolbar { + margin: -20px -20px 30px -20px; + padding: 12px 15px 10px 15px; + +} .header-row > div { padding: 10px; } @@ -733,7 +762,7 @@ img { } #motion-table .content > div > div { - margin-bottom: 5px; + margin-bottom: 3px; } #motion-table .content > div > div:last-child { @@ -948,16 +977,12 @@ img { white-space: pre-line; } -.slimlist { - padding-left: 20px; -} - .slimlabel.label { padding: 0px 10px; } .indentation, .indentation20 { - margin-left: 20px; + margin-left: 20px !important; } .indentation-lg { @@ -972,10 +997,6 @@ img { background-color: #f0ad4e; } -.listOfSpeakers h3 { - padding-bottom: 0; -} - .smallhr { margin-top: 5px; margin-bottom: 5px; @@ -1062,12 +1083,13 @@ img { .lastSpeakers { color: #9a9898; +} +.lastSpeakers .indentation { margin-left: 27px; } .currentSpeaker { font-weight: bold; - margin-left: 0px; } .currentSpeaker i { @@ -1275,6 +1297,10 @@ tr.selected td { h3 { font-size: 18px; padding-bottom: 10px; } + .col-md-4 { + float: left; + width: 50%; + } } diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index beb1694cf..a5735ee80 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -1884,7 +1884,7 @@ angular.module('OpenSlidesApp.core.site', [ gettext('Background color of projector header and footer'); gettext('Font color of projector header and footer'); gettext('Font color of projector headline'); - gettext('Default countdown'); + gettext('Predefined seconds of new countdowns'); } ]); diff --git a/openslides/core/static/templates/core/tag-list.html b/openslides/core/static/templates/core/tag-list.html index 5b6eceb09..4b583df56 100644 --- a/openslides/core/static/templates/core/tag-list.html +++ b/openslides/core/static/templates/core/tag-list.html @@ -1,14 +1,14 @@
diff --git a/openslides/motions/config_variables.py b/openslides/motions/config_variables.py index 30db67794..d20931614 100644 --- a/openslides/motions/config_variables.py +++ b/openslides/motions/config_variables.py @@ -100,7 +100,7 @@ def get_config_variables(): yield ConfigVariable( name='motions_recommendations_by', - default_value='Recommendation committee', + default_value='', label='Name of recommendation committee', help_text='Use an empty value to disable the recommendation system.', weight=332, @@ -161,7 +161,7 @@ def get_config_variables(): yield ConfigVariable( name='motions_comments', - default_value=[{'name': 'Comment', 'public': True}], + default_value=[], input_type='comments', label='Comment fields for motions', weight=353, diff --git a/openslides/motions/static/js/motions/site.js b/openslides/motions/static/js/motions/site.js index 5322c6f7e..aab2d957f 100644 --- a/openslides/motions/static/js/motions/site.js +++ b/openslides/motions/static/js/motions/site.js @@ -1185,6 +1185,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid .controller('MotionDetailCtrl', [ '$scope', '$http', + 'operator', 'ngDialog', 'MotionForm', 'Motion', @@ -1204,7 +1205,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid 'Projector', 'HTMLValidizer', 'ProjectionDefault', - function($scope, $http, ngDialog, MotionForm, Motion, Category, Mediafile, Tag, User, Workflow, Config, + function($scope, $http, operator, ngDialog, MotionForm, Motion, Category, Mediafile, Tag, User, Workflow, Config, motion, MotionContentProvider, PollContentProvider, PdfMakeConverter, PdfMakeDocumentProvider, MotionInlineEditing, gettextCatalog, Projector, HTMLValidizer, ProjectionDefault) { Motion.bindOne(motion.id, $scope, 'motion'); @@ -1374,6 +1375,19 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions', 'OpenSlid $scope.showVersion(motion.active_version); }); }; + // check if user is allowed to see at least one comment field + $scope.isAllowedToSeeCommentField = function () { + var isAllowed = false; + if ($scope.commentsFields.length > 0) { + isAllowed = operator.hasPerms('motions.can_see_and_manage_comments') || _.find( + $scope.commentsFields, + function(field) { + return field.public; + } + ); + } + return Boolean(isAllowed); + }; // Inline editing functions $scope.inlineEditing = MotionInlineEditing; diff --git a/openslides/motions/static/templates/motions/category-list.html b/openslides/motions/static/templates/motions/category-list.html index d9774e1ee..171b297fd 100644 --- a/openslides/motions/static/templates/motions/category-list.html +++ b/openslides/motions/static/templates/motions/category-list.html @@ -1,14 +1,14 @@
diff --git a/openslides/motions/static/templates/motions/motion-detail.html b/openslides/motions/static/templates/motions/motion-detail.html index 531f8c22f..9e3e64c74 100644 --- a/openslides/motions/static/templates/motions/motion-detail.html +++ b/openslides/motions/static/templates/motions/motion-detail.html @@ -3,11 +3,7 @@

{{ motion.agenda_item.getTitle() || motion.getTitle() }}

@@ -41,7 +42,7 @@

-
+
@@ -161,7 +162,7 @@

Voting result

-
    +
    1. Vote @@ -264,64 +265,71 @@
      +
      +
      +
      -
      +
      - - - + +
      - + - - -
      +
      +
      @@ -393,7 +401,7 @@
      -
      @@ -410,7 +418,7 @@
      -
      +

      Motion Comments

      diff --git a/openslides/motions/static/templates/motions/motion-list.html b/openslides/motions/static/templates/motions/motion-list.html index 86343d9d8..02b69adf4 100644 --- a/openslides/motions/static/templates/motions/motion-list.html +++ b/openslides/motions/static/templates/motions/motion-list.html @@ -312,19 +312,6 @@

      {{ motion.identifier }}:
      - -
      - - - - - -   - - -
      @@ -358,11 +345,25 @@
      by - - {{ submitter.get_full_name() }},, ... + + {{ submitter.get_full_name() }},, + ... [+{{ motion.submitters.length - 1 }}]
      + +
      + + + Edit + + · + Delete + + +
      diff --git a/openslides/users/static/templates/users/group-list.html b/openslides/users/static/templates/users/group-list.html index 7d450f415..53be75353 100644 --- a/openslides/users/static/templates/users/group-list.html +++ b/openslides/users/static/templates/users/group-list.html @@ -1,15 +1,15 @@
      diff --git a/openslides/users/static/templates/users/user-list.html b/openslides/users/static/templates/users/user-list.html index ff7e77ed2..6ce7a9ca7 100644 --- a/openslides/users/static/templates/users/user-list.html +++ b/openslides/users/static/templates/users/user-list.html @@ -2,7 +2,7 @@