Merge pull request #3404 from FinnStutzenstein/Improvements

Goto top link, improved title, stylistic changes, and more
This commit is contained in:
Emanuel Schütze 2017-09-15 11:16:46 +02:00 committed by GitHub
commit 8e15b5dafe
16 changed files with 173 additions and 48 deletions

View File

@ -15,7 +15,7 @@ Agenda:
Motions: Motions:
- New export dialog [#3185]. - New export dialog [#3185].
- New feature: Personal notes for motions [#3190, #3267]. - New feature: Personal notes for motions [#3190, #3267, #3404].
- Fixed issue when creating/deleting motion comment fields in the - Fixed issue when creating/deleting motion comment fields in the
settings [#3187]. settings [#3187].
- Fixed empty motion comment field in motion update form [#3194]. - Fixed empty motion comment field in motion update form [#3194].
@ -80,6 +80,8 @@ Core:
- Updated CKEditor to 4.7 [#3375]. - Updated CKEditor to 4.7 [#3375].
- Reduced ckeditor toolbar for inline editing [#3368]. - Reduced ckeditor toolbar for inline editing [#3368].
- Added custom translations in config [#3383]. - Added custom translations in config [#3383].
- Added dynamic webpage title [#3404].
- Added 'go to top'-link [#3404].
Mediafiles: Mediafiles:
- Fixed reloading of PDF on page change [#3274]. - Fixed reloading of PDF on page change [#3274].

View File

@ -391,14 +391,19 @@ angular.module('OpenSlidesApp.agenda.site', [
'itemId', 'itemId',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
'gettextCatalog',
'WebpageTitle',
'ErrorMessage', 'ErrorMessage',
function ($scope, $filter, Agenda, itemId, Projector, ProjectionDefault, ErrorMessage) { function ($scope, $filter, Agenda, itemId, Projector, ProjectionDefault, gettextCatalog, WebpageTitle,
ErrorMessage) {
$scope.alert = {}; $scope.alert = {};
$scope.$watch(function () { $scope.$watch(function () {
return Agenda.lastModified(itemId); return Agenda.lastModified(itemId);
}, function () { }, function () {
$scope.item = Agenda.get(itemId); $scope.item = Agenda.get(itemId);
WebpageTitle.updateTitle(gettextCatalog.getString('List of speakers') + ' ' +
gettextCatalog.getString('of') + ' ' + $scope.item.getTitle());
// all speakers // all speakers
$scope.speakers = $filter('orderBy')($scope.item.speakers, 'weight'); $scope.speakers = $filter('orderBy')($scope.item.speakers, 'weight');
// next speakers // next speakers

View File

@ -406,7 +406,10 @@ angular.module('OpenSlidesApp.assignments', [])
return isProjectedIds; return isProjectedIds;
}, },
isRelatedProjected: function () { isRelatedProjected: function () {
var listOfSpeakers = this.agenda_item.isListOfSpeakersProjected(); var listOfSpeakers = [];
if (this.agenda_item) {
listOfSpeakers = this.agenda_item.isListOfSpeakersProjected();
}
return listOfSpeakers.concat(this.isProjected(null, true)); return listOfSpeakers.concat(this.isProjected(null, true));
}, },
}, },

View File

@ -418,10 +418,11 @@ angular.module('OpenSlidesApp.assignments.site', [
'gettextCatalog', 'gettextCatalog',
'AssignmentPhases', 'AssignmentPhases',
'AssignmentPdfExport', 'AssignmentPdfExport',
'WebpageTitle',
'ErrorMessage', 'ErrorMessage',
function($scope, $http, $filter, $timeout, filterFilter, gettext, ngDialog, AssignmentForm, operator, function($scope, $http, $filter, $timeout, filterFilter, gettext, ngDialog, AssignmentForm, operator,
Assignment, User, assignmentId, Projector, ProjectionDefault, gettextCatalog, AssignmentPhases, Assignment, User, assignmentId, Projector, ProjectionDefault, gettextCatalog, AssignmentPhases,
AssignmentPdfExport, ErrorMessage) { AssignmentPdfExport, WebpageTitle, ErrorMessage) {
User.bindAll({}, $scope, 'users'); User.bindAll({}, $scope, 'users');
var assignment = Assignment.get(assignmentId); var assignment = Assignment.get(assignmentId);
Assignment.loadRelations(assignment, 'agenda_item'); Assignment.loadRelations(assignment, 'agenda_item');
@ -447,6 +448,7 @@ angular.module('OpenSlidesApp.assignments.site', [
$scope.activeTab = $scope.assignment.polls.length - 1; $scope.activeTab = $scope.assignment.polls.length - 1;
updateBallotTabsFlag = false; updateBallotTabsFlag = false;
} }
WebpageTitle.updateTitle(gettextCatalog.getString('Election') + ' ' + $scope.assignment.title);
}); });
$scope.candidateSelectBox = {}; $scope.candidateSelectBox = {};
$scope.phases = AssignmentPhases; $scope.phases = AssignmentPhases;

View File

@ -296,6 +296,24 @@ img {
color: #555; color: #555;
} }
/** Goto top link **/
#goto-top {
position: fixed;
bottom: 15px;
right: 30px;
padding: 10px 30px;
background: white;
opacity: 0.6;
transition: opacity 250ms ease-out;
z-index: 100;
}
#goto-top:hover {
opacity: 1;
transition: opacity 250ms ease-in;
}
#goto-top a:hover {
text-decoration: none;
}
/** Content **/ /** Content **/

View File

@ -818,7 +818,7 @@ angular.module('OpenSlidesApp.core.pdf', [])
// If this element is inside a list (happens if copied from word), do not set spaces // If this element is inside a list (happens if copied from word), do not set spaces
// and margins. Just leave the paragraph there.. // and margins. Just leave the paragraph there..
if (!isInsideAList(element)) { if (!isInsideAList(element)) {
currentParagraph.margin = [20, 0, 0, 0]; currentParagraph.margin = [0, 0, 0, 0];
if (classes.indexOf('os-split-before') === -1) { if (classes.indexOf('os-split-before') === -1) {
currentParagraph.margin[1] = 8; currentParagraph.margin[1] = 8;
} }

View File

@ -134,20 +134,30 @@ angular.module('OpenSlidesApp.core.site', [
} }
]) ])
// Set up the activeAppTitle for the title from the webpage .factory('WebpageTitle', [
'$rootScope',
function ($rootScope) {
$rootScope.activeAppTitle = '';
return {
updateTitle: function (text) {
$rootScope.activeAppTitle = text || '';
},
};
}
])
// Watch for the basePerm on a stateChange and initialize the WebpageTitle factory
.run([ .run([
'$rootScope', '$rootScope',
'gettextCatalog',
'operator', 'operator',
function ($rootScope, gettextCatalog, operator) { 'WebpageTitle',
$rootScope.activeAppTitle = ''; function ($rootScope, operator, WebpageTitle) {
$rootScope.$on('$stateChangeSuccess', function(event, toState) { $rootScope.$on('$stateChangeSuccess', function(event, toState) {
WebpageTitle.updateTitle(toState.data ? toState.data.title : '');
if (toState.data) { if (toState.data) {
$rootScope.activeAppTitle = toState.data.title || '';
$rootScope.baseViewPermissionsGranted = toState.data.basePerm ? $rootScope.baseViewPermissionsGranted = toState.data.basePerm ?
operator.hasPerms(toState.data.basePerm) : true; operator.hasPerms(toState.data.basePerm) : true;
} else { } else {
$rootScope.activeAppTitle = '';
$rootScope.baseViewPermissionsGranted = true; $rootScope.baseViewPermissionsGranted = true;
} }
}); });
@ -987,6 +997,23 @@ angular.module('OpenSlidesApp.core.site', [
} }
]) ])
.controller('GotoTopCtrl', [
'$scope',
'$window',
'$timeout',
function ($scope, $window, $timeout) {
$scope.show = false;
angular.element($window).bind('scroll', function () {
$timeout(function () {
$scope.show = ($window.pageYOffset >= 150);
});
});
$scope.gotoTop = function () {
$window.scrollTo(0, 0);
};
}
])
// Projector Sidebar Controller // Projector Sidebar Controller
.controller('ProjectorSidebarCtrl', [ .controller('ProjectorSidebarCtrl', [
'$scope', '$scope',

View File

@ -4,7 +4,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<base href="/"> <base href="/">
<title ng-if="!activeAppTitle">OpenSlides</title> <!-- avoid {{ ... }} in title while angular is not loaded --> <title ng-if="!activeAppTitle">OpenSlides</title> <!-- avoid {{ ... }} in title while angular is not loaded -->
<title ng-if="activeAppTitle">OpenSlides &ndash; {{ activeAppTitle | translate }}</title> <title ng-if="activeAppTitle">{{ activeAppTitle | translate }} &ndash; OpenSlides</title>
<meta name="description" content=""> <meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="static/css/openslides-libs.css"> <link rel="stylesheet" href="static/css/openslides-libs.css">
@ -258,6 +258,14 @@
<messaging></messaging> <messaging></messaging>
<div ng-controller="GotoTopCtrl">
<div id="goto-top" class="pointer" ng-click="gotoTop()" ng-if="show">
<a>
<i class="fa fa-lg fa-arrow-up"></i>
</a>
</div>
</div>
</div><!--end wrapper--> </div><!--end wrapper-->
<script src="/webclient/site/"></script> <script src="/webclient/site/"></script>

View File

@ -144,9 +144,18 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
'motionBlockId', 'motionBlockId',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
'WebpageTitle',
'gettextCatalog',
'ErrorMessage', 'ErrorMessage',
function($scope, $http, ngDialog, Motion, MotionBlockForm, MotionBlock, motionBlockId, Projector, ProjectionDefault, ErrorMessage) { function($scope, $http, ngDialog, Motion, MotionBlockForm, MotionBlock, motionBlockId, Projector,
MotionBlock.bindOne(motionBlockId, $scope, 'motionBlock'); ProjectionDefault, WebpageTitle, gettextCatalog, ErrorMessage) {
$scope.$watch(function () {
return MotionBlock.lastModified(motionBlockId);
}, function () {
$scope.motionBlock = MotionBlock.get(motionBlockId);
WebpageTitle.updateTitle(gettextCatalog.getString('Motion block') + ' ' +
$scope.motionBlock.agenda_item.getTitle());
});
Motion.bindAll({}, $scope, 'motions'); Motion.bindAll({}, $scope, 'motions');
$scope.$watch(function () { $scope.$watch(function () {
return Projector.lastModified(); return Projector.lastModified();

View File

@ -134,7 +134,7 @@ angular.module('OpenSlidesApp.motions.motionservices', ['OpenSlidesApp.motions',
editors: [] editors: []
}; };
var options = Editor.getOptions('inline', 'YOffset'); var options = Editor.getOptions('inline', 'YOffset');
_.forEach($scope.noSpecialCommentsFields, function (field, id) { _.forEachRight($scope.noSpecialCommentsFields, function (field, id) {
var inlineEditing = MotionInlineEditing.createInstance($scope, motion, var inlineEditing = MotionInlineEditing.createInstance($scope, motion,
'view-original-comment-inline-editor-' + id, false, options, 'view-original-comment-inline-editor-' + id, false, options,
function (obj) { function (obj) {

View File

@ -121,7 +121,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
text: gettextCatalog.getString('Category') + ':', text: gettextCatalog.getString('Category') + ':',
style: ['bold', 'grey'] }, style: ['bold', 'grey'] },
{ {
text: motion.category.name, text: motion.category.prefix + ' - ' + motion.category.name,
style: 'grey' style: 'grey'
} }
]); ]);
@ -484,7 +484,7 @@ angular.module('OpenSlidesApp.motions.pdf', ['OpenSlidesApp.core.pdf'])
text: gettextCatalog.getString('Category') + ':', text: gettextCatalog.getString('Category') + ':',
style: ['bold', 'grey'] }, style: ['bold', 'grey'] },
{ {
text: motion.category.name, text: motion.category.prefix + ' - ' + motion.category.name,
style: 'grey' style: 'grey'
} }
]); ]);

View File

@ -902,6 +902,7 @@ angular.module('OpenSlidesApp.motions.site', [
motion.personalNote = PersonalNoteManager.getNote(motion); motion.personalNote = PersonalNoteManager.getNote(motion);
// For filtering, we cannot filter for .personalNote.star // For filtering, we cannot filter for .personalNote.star
motion.star = motion.personalNote ? motion.personalNote.star : false; motion.star = motion.personalNote ? motion.personalNote.star : false;
motion.hasPersonalNote = motion.personalNote ? !!motion.personalNote.note : false;
if (motion.star === undefined) { if (motion.star === undefined) {
motion.star = false; motion.star = false;
} }
@ -967,9 +968,13 @@ angular.module('OpenSlidesApp.motions.site', [
$scope.filter.booleanFilters = { $scope.filter.booleanFilters = {
isFavorite: { isFavorite: {
value: undefined, value: undefined,
displayName: gettext('Favorite'), choiceYes: gettext('Marked as favorite'),
choiceYes: gettext('Is favorite'), choiceNo: gettext('Not marked as favorite'),
choiceNo: gettext('Is not favorite'), },
hasPersonalNote: {
value: undefined,
choiceYes: gettext('Personal note set'),
choiceNo: gettext('Personal note not set'),
}, },
}; };
} }
@ -1213,12 +1218,13 @@ angular.module('OpenSlidesApp.motions.site', [
'MotionBlock', 'MotionBlock',
'MotionPdfExport', 'MotionPdfExport',
'PersonalNoteManager', 'PersonalNoteManager',
'WebpageTitle',
'EditingWarning', 'EditingWarning',
function($scope, $http, $timeout, operator, ngDialog, gettextCatalog, MotionForm, function($scope, $http, $timeout, operator, ngDialog, gettextCatalog, MotionForm,
ChangeRecommmendationCreate, ChangeRecommmendationView, MotionChangeRecommendation, ChangeRecommmendationCreate, ChangeRecommmendationView, MotionChangeRecommendation,
Motion, MotionComment, Category, Mediafile, Tag, User, Workflow, Config, motionId, MotionInlineEditing, Motion, MotionComment, Category, Mediafile, Tag, User, Workflow, Config, motionId, MotionInlineEditing,
MotionCommentsInlineEditing, Editor, Projector, ProjectionDefault, MotionBlock, MotionPdfExport, MotionCommentsInlineEditing, Editor, Projector, ProjectionDefault, MotionBlock, MotionPdfExport,
PersonalNoteManager, EditingWarning) { PersonalNoteManager, WebpageTitle, EditingWarning) {
var motion = Motion.get(motionId); var motion = Motion.get(motionId);
Category.bindAll({}, $scope, 'categories'); Category.bindAll({}, $scope, 'categories');
Mediafile.bindAll({}, $scope, 'mediafiles'); Mediafile.bindAll({}, $scope, 'mediafiles');
@ -1254,6 +1260,13 @@ angular.module('OpenSlidesApp.motions.site', [
$scope.motion = Motion.get(motionId); $scope.motion = Motion.get(motionId);
MotionComment.populateFields($scope.motion); MotionComment.populateFields($scope.motion);
$scope.motion.personalNote = PersonalNoteManager.getNote($scope.motion); $scope.motion.personalNote = PersonalNoteManager.getNote($scope.motion);
var webpageTitle = gettextCatalog.getString('Motion') + ' ';
if ($scope.motion.identifier) {
webpageTitle += $scope.motion.identifier + ' - ';
}
webpageTitle += $scope.motion.getTitle();
WebpageTitle.updateTitle(webpageTitle);
}); });
$scope.projectionModes = [ $scope.projectionModes = [
{mode: 'original', {mode: 'original',
@ -1537,7 +1550,7 @@ angular.module('OpenSlidesApp.motions.site', [
if (editingStoppedCallback) { if (editingStoppedCallback) {
editingStoppedCallback(); editingStoppedCallback();
} }
if ($scope.motion.getReason($scope.version)) { if ($scope.motion && $scope.motion.getReason($scope.version)) {
$scope.reasonInlineEditing.disable(); $scope.reasonInlineEditing.disable();
} }
$scope.inlineEditing.disable(); $scope.inlineEditing.disable();

View File

@ -238,13 +238,13 @@
<li ng-repeat="category in categories"> <li ng-repeat="category in categories">
<a href ng-click="toggleCategory(category)"> <a href ng-click="toggleCategory(category)">
<i class="fa fa-check" ng-if="category.id == motion.category.id"></i> <i class="fa fa-check" ng-if="category.id == motion.category.id"></i>
{{ category.name }} {{ category.prefix }} &ndash; {{ category.name }}
</a> </a>
</li> </li>
</ul> </ul>
</span> </span>
</div> </div>
{{ motion.category.name }} {{ motion.category.prefix }} &ndash; {{ motion.category.name }}
<!-- Motion block --> <!-- Motion block -->
<h3 class="heading" os-perms="!motions.can_manage" ng-show="motion.motionBlock" translate>Motion block</h3> <h3 class="heading" os-perms="!motions.can_manage" ng-show="motion.motionBlock" translate>Motion block</h3>
@ -424,6 +424,13 @@
<i class="fa fa-bar-chart fa-lg"></i> <i class="fa fa-bar-chart fa-lg"></i>
<translate>New vote</translate> <translate>New vote</translate>
</button> </button>
<div class="spacer-top pull-right nobr">
<a href="#personalNote" translate>Personal note</a>
<span ng-click="pinPersonalNote()" class="spacer-left pointer" title="{{ 'Pin personal note' || translate }}">
<i class="fa fa-thumb-tack" ng-class="{'rotate-45-deg-right': !personalNotePinned}"></i>
</span>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -86,7 +86,7 @@
<select ng-show="selectedAction == 'setCategory'" ng-model="selectedCategory" class="form-control input-sm"> <select ng-show="selectedAction == 'setCategory'" ng-model="selectedCategory" class="form-control input-sm">
<option value="" translate>--- Select category ---</option> <option value="" translate>--- Select category ---</option>
<option ng-repeat="category in categories" value="{{ category.id }}"> <option ng-repeat="category in categories" value="{{ category.id }}">
{{ category.name }} {{ category.prefix }} &ndash; {{ category.name }}
</option> </option>
<option value="no_category_selected" translate>No category</option> <option value="no_category_selected" translate>No category</option>
</select> </select>
@ -162,7 +162,7 @@
<li class="divider"></li> <li class="divider"></li>
<li> <li>
<a href ng-click="operateStateFilter(-1, isSelectMode)"> <a href ng-click="operateStateFilter(-1, isSelectMode)">
<i class="fa fa-check" ng-if="filter.multiselectFilters.category.indexOf(-1) > -1"></i> <i class="fa fa-check" ng-if="filter.multiselectFilters.state.indexOf(-1) > -1"></i>
<translate>done</translate> <translate>done</translate>
</a> </a>
</li> </li>
@ -232,7 +232,7 @@
<li ng-repeat="category in categories"> <li ng-repeat="category in categories">
<a href ng-click="filter.operateMultiselectFilter('category', category.id, isSelectMode)"> <a href ng-click="filter.operateMultiselectFilter('category', category.id, isSelectMode)">
<i class="fa fa-check" ng-if="filter.multiselectFilters.category.indexOf(category.id) > -1"></i> <i class="fa fa-check" ng-if="filter.multiselectFilters.category.indexOf(category.id) > -1"></i>
{{ category.name }} {{ category.prefix }} &ndash; {{ category.name }}
</a> </a>
</li> </li>
<li class="divider"></li> <li class="divider"></li>
@ -292,26 +292,39 @@
</li> </li>
</ul> </ul>
</span> </span>
<!-- boolean Filters --> <!-- boolean Filters (customized!) -->
<span ng-repeat="(name, booleanFilter) in filter.booleanFilters" <span ng-if="operator.user.id" uib-dropdown>
ng-if="operator.user.id" uib-dropdown> <span class="pointer" id="dropdownPrivate" uib-dropdown-toggle
<span class="pointer" id="dropdown{{ name }}" uib-dropdown-toggle ng-class="{'bold': (filter.booleanFilters.isFavorite.value !== undefined) ||
ng-class="{'bold': booleanFilter.value !== undefined, 'disabled': isSelectMode}" (filter.booleanFilters.hasPersonalNote.value !== undefined), 'disabled': isSelectMode}"
ng-disabled="isSelectMode"> ng-disabled="isSelectMode">
{{ booleanFilter.displayName | translate }} <translate>Private</translate>
<span class="caret"></span> <span class="caret"></span>
</span> </span>
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdown{{ name }}"> <ul class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownPrivate">
<li> <li>
<a href ng-click="booleanFilter.value = (booleanFilter.value ? undefined : true); filter.save();"> <a href ng-click="filter.booleanFilters.isFavorite.value = (filter.booleanFilters.isFavorite.value ? undefined : true); filter.save();">
<i class="fa" ng-class="{'fa-check': booleanFilter.value === true}"></i> <i class="fa" ng-class="{'fa-check': filter.booleanFilters.isFavorite.value === true}"></i>
{{ booleanFilter.choiceYes | translate }} {{ filter.booleanFilters.isFavorite.choiceYes | translate }}
</a> </a>
</li> </li>
<li> <li>
<a href ng-click="booleanFilter.value = (booleanFilter.value === false) ? undefined : false; filter.save();"> <a href ng-click="filter.booleanFilters.isFavorite.value = (filter.booleanFilters.isFavorite.value === false) ? undefined : false; filter.save();">
<i class="fa" ng-class="{'fa-check': booleanFilter.value === false}"></i> <i class="fa" ng-class="{'fa-check': filter.booleanFilters.isFavorite.value === false}"></i>
{{ booleanFilter.choiceNo | translate }} {{ filter.booleanFilters.isFavorite.choiceNo | translate }}
</a>
</li>
<li class="divider"></li>
<li>
<a href ng-click="filter.booleanFilters.hasPersonalNote.value = (filter.booleanFilters.hasPersonalNote.value ? undefined : true); filter.save();">
<i class="fa" ng-class="{'fa-check': filter.booleanFilters.hasPersonalNote.value === true}"></i>
{{ filter.booleanFilters.hasPersonalNote.choiceYes | translate }}
</a>
</li>
<li>
<a href ng-click="filter.booleanFilters.hasPersonalNote.value = (filter.booleanFilters.hasPersonalNote.value === false) ? undefined : false; filter.save();">
<i class="fa" ng-class="{'fa-check': filter.booleanFilters.hasPersonalNote.value === false}"></i>
{{ filter.booleanFilters.hasPersonalNote.choiceNo | translate }}
</a> </a>
</li> </li>
</ul> </ul>
@ -400,7 +413,7 @@
ng-class="{'disabled': isSelectMode}"> ng-class="{'disabled': isSelectMode}">
<span class="nobr"> <span class="nobr">
<i class="fa fa-times-circle"></i> <i class="fa fa-times-circle"></i>
{{ category.name }} {{ category.prefix }} &ndash; {{ category.name }}
</span> </span>
</span> </span>
<span ng-if="filter.multiselectFilters.category.indexOf(-1) > -1" class="pointer spacer-left-lg" <span ng-if="filter.multiselectFilters.category.indexOf(-1) > -1" class="pointer spacer-left-lg"
@ -480,6 +493,7 @@
| MultiselectFilter: filter.multiselectFilters.recommendation : getItemId.recommendation | MultiselectFilter: filter.multiselectFilters.recommendation : getItemId.recommendation
| MultiselectFilter: filter.multiselectFilters.tag : getItemId.tag | MultiselectFilter: filter.multiselectFilters.tag : getItemId.tag
| filter: {star: filter.booleanFilters.isFavorite.value} | filter: {star: filter.booleanFilters.isFavorite.value}
| filter: {hasPersonalNote: filter.booleanFilters.hasPersonalNote.value}
| toArray | toArray
| orderBy: sort.column : sort.reverse) | orderBy: sort.column : sort.reverse)
| limitTo : itemsPerPage : limitBegin"> | limitTo : itemsPerPage : limitBegin">
@ -606,7 +620,7 @@
</span> </span>
<span ng-if="motion.category != null"> <span ng-if="motion.category != null">
<i class="fa fa-sitemap spacer-right"></i> <i class="fa fa-sitemap spacer-right"></i>
{{ motion.category.name }} {{ motion.category.prefix }} &ndash; {{ motion.category.name }}
<i class="fa fa-cog fa-lg spacer-left" ng-show="motion.categoryHover"></i> <i class="fa fa-cog fa-lg spacer-left" ng-show="motion.categoryHover"></i>
</span> </span>
</span> </span>
@ -614,7 +628,7 @@
<li ng-repeat="category in categories"> <li ng-repeat="category in categories">
<a href ng-click="toggleCategory(motion, category)"> <a href ng-click="toggleCategory(motion, category)">
<i class="fa fa-check" ng-if="category.id == motion.category.id"></i> <i class="fa fa-check" ng-if="category.id == motion.category.id"></i>
{{ category.name }} {{ category.prefix }} &ndash; {{ category.name }}
</a> </a>
</li> </li>
</ul> </ul>
@ -623,7 +637,7 @@
<!-- Category string for normal user --> <!-- Category string for normal user -->
<div os-perms="!motions.can_manage" ng-show="motion.category != null"> <div os-perms="!motions.can_manage" ng-show="motion.category != null">
<i class="fa fa-sitemap spacer-right"></i> <i class="fa fa-sitemap spacer-right"></i>
{{ motion.category.name }} {{ motion.category.prefix }} &ndash; {{ motion.category.name }}
</div> </div>
<!-- Motion block dropdown for manage user --> <!-- Motion block dropdown for manage user -->

View File

@ -155,8 +155,17 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics', 'OpenSlides
'topicId', 'topicId',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
function($scope, ngDialog, TopicForm, Topic, topicId, Projector, ProjectionDefault) { 'WebpageTitle',
Topic.bindOne(topicId, $scope, 'topic'); 'gettextCatalog',
function($scope, ngDialog, TopicForm, Topic, topicId, Projector, ProjectionDefault, WebpageTitle,
gettextCatalog) {
$scope.$watch(function () {
return Topic.lastModified(topicId);
}, function () {
$scope.topic = Topic.get(topicId);
WebpageTitle.updateTitle(gettextCatalog.getString('Topic') + ' ' +
$scope.topic.agenda_item.getTitle());
});
$scope.$watch(function () { $scope.$watch(function () {
return Projector.lastModified(); return Projector.lastModified();
}, function () { }, function () {

View File

@ -749,9 +749,17 @@ angular.module('OpenSlidesApp.users.site', [
'Group', 'Group',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
function($scope, ngDialog, UserForm, User, userId, Group, Projector, ProjectionDefault) { 'gettextCatalog',
User.bindOne(userId, $scope, 'user'); 'WebpageTitle',
function($scope, ngDialog, UserForm, User, userId, Group, Projector, ProjectionDefault, gettextCatalog,
WebpageTitle) {
Group.bindAll({where: {id: {'>': 1}}}, $scope, 'groups'); Group.bindAll({where: {id: {'>': 1}}}, $scope, 'groups');
$scope.$watch(function () {
return User.lastModified(userId);
}, function () {
$scope.user = User.get(userId);
WebpageTitle.updateTitle(gettextCatalog.getString('Participant') + ' ' + $scope.user.get_short_name());
});
$scope.$watch(function () { $scope.$watch(function () {
return Projector.lastModified(); return Projector.lastModified();
}, function () { }, function () {