Merge pull request #1732 from emanuelschuetze/fixTranslations

Fixed gettext strings in JavaScript.
This commit is contained in:
Oskar Hahn 2015-12-01 13:38:21 +01:00
commit 3dd3a2f4fd
9 changed files with 222 additions and 145 deletions

View File

@ -6,11 +6,12 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
.config([ .config([
'mainMenuProvider', 'mainMenuProvider',
function (mainMenuProvider) { 'gettext',
function (mainMenuProvider, gettext) {
mainMenuProvider.register({ mainMenuProvider.register({
'ui_sref': 'agenda.item.list', 'ui_sref': 'agenda.item.list',
'img_class': 'calendar-o', 'img_class': 'calendar-o',
'title': 'Agenda', 'title': gettext('Agenda'),
'weight': 200, 'weight': 200,
'perm': 'agenda.can_see', 'perm': 'agenda.can_see',
}); });

View File

@ -6,11 +6,12 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
.config([ .config([
'mainMenuProvider', 'mainMenuProvider',
function (mainMenuProvider) { 'gettext',
function (mainMenuProvider, gettext) {
mainMenuProvider.register({ mainMenuProvider.register({
'ui_sref': 'assignments.assignment.list', 'ui_sref': 'assignments.assignment.list',
'img_class': 'pie-chart', 'img_class': 'pie-chart',
'title': 'Elections', 'title': gettext('Elections'),
'weight': 400, 'weight': 400,
'perm': 'assignments.can_see' 'perm': 'assignments.can_see'
}); });
@ -64,8 +65,8 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
// Provide generic assignment form fields for create and update view // Provide generic assignment form fields for create and update view
.factory('AssignmentFormFieldFactory', [ .factory('AssignmentFormFieldFactory', [
'gettext', 'gettextCatalog',
function (gettext) { function (gettextCatalog) {
return { return {
getFormFields: function () { getFormFields: function () {
return [ return [
@ -73,7 +74,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'title', key: 'title',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Title'), label: gettextCatalog.getString('Title'),
required: true required: true
} }
}, },
@ -81,14 +82,14 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'description', key: 'description',
type: 'textarea', type: 'textarea',
templateOptions: { templateOptions: {
label: gettext('Description') label: gettextCatalog.getString('Description')
} }
}, },
{ {
key: 'open_posts', key: 'open_posts',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Number of members to be elected'), label: gettextCatalog.getString('Number of members to be elected'),
type: 'number', type: 'number',
required: true required: true
} }
@ -97,7 +98,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'poll_description_default', key: 'poll_description_default',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Default comment on the ballot paper') label: gettextCatalog.getString('Default comment on the ballot paper')
} }
}]; }];
} }
@ -107,8 +108,8 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
// Provide generic assignmentpoll form fields for create and update view // Provide generic assignmentpoll form fields for create and update view
.factory('AssignmentPollFormFieldFactory', [ .factory('AssignmentPollFormFieldFactory', [
'gettext', 'gettextCatalog',
function (gettext) { function (gettextCatalog) {
return { return {
getFormFields: function () { getFormFields: function () {
return [ return [
@ -116,14 +117,14 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'description', key: 'description',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Comment on the ballot paper') label: gettextCatalog.getString('Comment on the ballot paper')
} }
}, },
{ {
key: 'yes', key: 'yes',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Yes'), label: gettextCatalog.getString('Yes'),
type: 'number', type: 'number',
required: true required: true
} }
@ -132,7 +133,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'poll_description_default', key: 'poll_description_default',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Default comment on the ballot paper') label: gettextCatalog.getString('Default comment on the ballot paper')
} }
}]; }];
} }
@ -394,11 +395,11 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
.controller('AssignmentPollUpdateCtrl', [ .controller('AssignmentPollUpdateCtrl', [
'$scope', '$scope',
'$state', '$state',
'gettext', 'gettextCatalog',
'AssignmentPoll', 'AssignmentPoll',
'assignmentpoll', 'assignmentpoll',
'ballot', 'ballot',
function($scope, $state, gettext, AssignmentPoll, assignmentpoll, ballot) { function($scope, $state, gettextCatalog, AssignmentPoll, assignmentpoll, ballot) {
// set initial values for form model // set initial values for form model
$scope.model = assignmentpoll; $scope.model = assignmentpoll;
$scope.ballot = ballot; $scope.ballot = ballot;
@ -415,7 +416,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'yes_' + option.candidate_id, key: 'yes_' + option.candidate_id,
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Yes'), label: gettextCatalog.getString('Yes'),
type: 'number', type: 'number',
required: true required: true
} }
@ -424,7 +425,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'no_' + option.candidate_id, key: 'no_' + option.candidate_id,
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('No'), label: gettextCatalog.getString('No'),
type: 'number', type: 'number',
required: true required: true
} }
@ -433,7 +434,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key:'abstain_' + option.candidate_id, key:'abstain_' + option.candidate_id,
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Abstain'), label: gettextCatalog.getString('Abstain'),
type: 'number', type: 'number',
required: true required: true
} }
@ -457,7 +458,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'votesvalid', key: 'votesvalid',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Votes valid'), label: gettextCatalog.getString('Votes valid'),
type: 'number' type: 'number'
} }
}, },
@ -465,7 +466,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'votesinvalid', key: 'votesinvalid',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Votes invalid'), label: gettextCatalog.getString('Votes invalid'),
type: 'number' type: 'number'
} }
}, },
@ -473,7 +474,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'votescast', key: 'votescast',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Votes cast'), label: gettextCatalog.getString('Votes cast'),
type: 'number' type: 'number'
} }
}, },
@ -483,7 +484,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
key: 'description', key: 'description',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Comment on the ballot paper') label: gettextCatalog.getString('Comment on the ballot paper')
} }
} }
); );

View File

@ -82,6 +82,16 @@ img {
color: #999; color: #999;
} }
#header a.headerlink {
text-decoration: none;
}
#header a.headerlink {
color: #999;
}
#header a.headerlink:hover, #header a.headerlink:active, #header a.headerlink.active {
color: #e8eaed;
}
#header .title { #header .title {
float: left; float: left;
margin: 2px 0 0 -5px; margin: 2px 0 0 -5px;
@ -716,4 +726,9 @@ tr.selected td {
#nav .navbar .button i { padding-top: 15px;} #nav .navbar .button i { padding-top: 15px;}
#nav .searchbar { margin-top: 15px; } #nav .searchbar { margin-top: 15px; }
.searchbar .input-medium { width: 150px; } .searchbar .input-medium { width: 150px; }
#chatbox { width: 100%; top: 130px; }
.optional { /* hide optional column */
display: none;
}
} }

View File

@ -63,20 +63,33 @@ angular.module('OpenSlidesApp.core.site', [
} }
]) ])
// set browser language as default language for OpenSlides
.run([
'gettextCatalog',
'Languages',
function(gettextCatalog, Languages) {
// set detected browser language as default language (fallback: 'en')
Languages.setCurrentLanguage(Languages.getBrowserLanguage());
//TODO: for debug only! (helps to find untranslated strings by adding "[MISSING]:")
gettextCatalog.debug = false;
}
])
.config([ .config([
'mainMenuProvider', 'mainMenuProvider',
function (mainMenuProvider) { 'gettext',
function (mainMenuProvider, gettext) {
mainMenuProvider.register({ mainMenuProvider.register({
'ui_sref': 'dashboard', 'ui_sref': 'dashboard',
'img_class': 'home', 'img_class': 'home',
'title': 'Home', 'title': gettext('Home'),
'weight': 100, 'weight': 100,
}); });
mainMenuProvider.register({ mainMenuProvider.register({
'ui_sref': 'config', 'ui_sref': 'config',
'img_class': 'cog', 'img_class': 'cog',
'title': 'Settings', 'title': gettext('Settings'),
'weight': 1000, 'weight': 1000,
'perm': 'core.can_manage_config', 'perm': 'core.can_manage_config',
}); });
@ -340,17 +353,62 @@ angular.module('OpenSlidesApp.core.site', [
} }
]) ])
.controller("LanguageCtrl", function ($scope, gettextCatalog) { // gets all in OpenSlides available languages
// controller to switch app language .factory('Languages', [
// TODO: detect browser language for default language 'gettext',
gettextCatalog.setCurrentLanguage('en'); 'gettextCatalog',
//TODO: for debug only! (helps to find untranslated strings by adding "[MISSING]:") function (gettext, gettextCatalog) {
gettextCatalog.debug = true; return {
$scope.switchLanguage = function (lang) { // get all available languages
gettextCatalog.setCurrentLanguage(lang); getLanguages: function () {
if (lang != 'en') { var current = gettextCatalog.getCurrentLanguage();
gettextCatalog.loadRemote("static/i18n/" + lang + ".json"); // Define here new languages...
var languages = [
{ code: 'en', name: gettext('English') },
{ code: 'de', name: gettext('German') },
{ code: 'fr', name: gettext('French') }
];
angular.forEach(languages, function (language) {
if (language.code == current)
language.selected = true;
});
return languages
},
// get detected browser language code
getBrowserLanguage: function () {
var lang = navigator.language || navigator.userLanguage;
if (lang.indexOf('-') !== -1)
lang = lang.split('-')[0];
if (lang.indexOf('_') !== -1)
lang = lang.split('_')[0];
return lang;
},
// set current language and return updated languages object array
setCurrentLanguage: function (lang) {
var languages = this.getLanguages();
angular.forEach(languages, function (language) {
language.selected = false;
if (language.code == lang) {
language.selected = true;
gettextCatalog.setCurrentLanguage(lang);
if (lang != 'en') {
gettextCatalog.loadRemote("static/i18n/" + lang + ".json");
}
}
});
return languages;
}
} }
}
])
.controller("LanguageCtrl", function ($scope, gettextCatalog, Languages, filterFilter) {
$scope.languages = Languages.getLanguages();
$scope.selectedLanguage = filterFilter($scope.languages, {selected: true});
// controller to switch app language
$scope.switchLanguage = function (lang) {
$scope.languages = Languages.setCurrentLanguage(lang);
$scope.selectedLanguage = filterFilter($scope.languages, {selected: true});
}; };
}) })

View File

@ -31,13 +31,14 @@
<!-- chatbox --> <!-- chatbox -->
<div ng-controller="ChatMessageCtrl" os-perms="core.can_use_chat" class="inline"> <div ng-controller="ChatMessageCtrl" os-perms="core.can_use_chat" class="inline">
<button ng-click="openChatbox()" class="btn btn-sm btn-default"> <a href ng-click="openChatbox()" class="headerlink"
ng-class="{ 'active': !chatboxIsCollapsed }" uib-dropdown-toggle>
<i class="fa fa-comment"></i> <i class="fa fa-comment"></i>
<translate>Chat</translate> <translate>Chat</translate>
<span ng-if="unreadMessages > 0 && chatboxIsCollapsed" class="badge"> <span ng-if="unreadMessages > 0 && chatboxIsCollapsed" class="badge">
{{ unreadMessages }} {{ unreadMessages }}
</span> </span>
</button> </a> |
<div id="chatbox" class="well" uib-collapse="chatboxIsCollapsed"> <div id="chatbox" class="well" uib-collapse="chatboxIsCollapsed">
<div id="chatbox-text" scroll-glue> <div id="chatbox-text" scroll-glue>
<ul class="list-unstyled"> <ul class="list-unstyled">
@ -63,13 +64,12 @@
</div> </div>
<!-- user settings / logout button --> <!-- user settings / logout button -->
<div class="btn-group" uib-dropdown> <span uib-dropdown>
<button type="button" class="btn btn-sm btn-default" uib-dropdown-toggle> <a href class="headerlink" uib-dropdown-toggle>
<i class="fa fa-user"></i> <i class="fa fa-user"></i>
<span class="optional-small">{{ operator.user.get_short_name() }}</span> <span>{{ operator.user.get_short_name() }}</span>
<span class="caret"></span> </a>
</button> <ul class="uib-dropdown-menu pull-right" role="menu" aria-labelledby="simple-dropdown">
<ul class="uib-dropdown-menu pull-right" role="menu" aria-labelledby="single-button">
<li> <li>
<a ui-sref="users.user.detail.profile({ id: operator.user.id })"> <a ui-sref="users.user.detail.profile({ id: operator.user.id })">
<i class="fa fa-cog"></i> <i class="fa fa-cog"></i>
@ -87,41 +87,30 @@
<translate>Logout</translate> <translate>Logout</translate>
</a> </a>
</ul> </ul>
</div> </span>
</div> </div>
<!-- Login button --> <!-- Login button -->
<div ng-if="!operator.isAuthenticated()"> <div ng-if="!operator.isAuthenticated()">
<button class="btn btn-sm btn-default" ng-click="openLoginForm()"> <a href ng-click="openLoginForm()" class="headerlink" uib-dropdown-toggle>
<i class="fa fa-sign-in"></i> <i class="fa fa-sign-in"></i>
<translate>Login</translate> <translate>Login</translate>
</button> </a>
</div> </div>
</div> </div>
<!-- language switcher --> <!-- language switcher -->
<div class="btn-group" ng-controller="LanguageCtrl" uib-dropdown> <span ng-controller="LanguageCtrl" uib-dropdown>
<button class="btn btn-sm btn-default" uib-dropdown-toggle> | <a href class="headerlink" uib-dropdown-toggle>
<i class="fa fa-flag"></i> <i class="fa fa-flag"></i>
<span class="caret"></span> {{ selectedLanguage[0].name | translate }}
</button> </a>
<ul class="uib-dropdown-menu pull-right" role="menu" aria-labelledby="single-button"> <ul class="uib-dropdown-menu pull-right" role="menu" aria-labelledby="simple-dropdown">
<li> <li ng-repeat="language in languages">
<a href="" ng-click="switchLanguage('en')"> <a href="" ng-click="switchLanguage(language.code)">
<i class="fa fa-flag"></i> <i ng-if="language.selected" class="fa fa-check"></i>
<translate>English</translate> (EN) {{ language.name | translate }}
</a> </a>
<li> </span>
<a href="" ng-click="switchLanguage('de')">
<i class="fa fa-flag"></i>
<translate>German</translate> (DE)
</a>
<li>
<a href="" ng-click="switchLanguage('fr')">
<i class="fa fa-flag"></i>
<translate>French</translate> (FR)
</a>
</ul>
</div>
</div> </div>
</div> </div>
@ -137,7 +126,7 @@
<li ng-repeat="element in elements" ui-sref-active="active"> <li ng-repeat="element in elements" ui-sref-active="active">
<a ui-sref="{{ element.ui_sref }}"> <a ui-sref="{{ element.ui_sref }}">
<i class="fa fa-{{ element.img_class }}"></i> <i class="fa fa-{{ element.img_class }}"></i>
<translate>{{ element.title }}</translate> {{ element.title | translate }}
</a> </a>
</ul> </ul>
</div> </div>

View File

@ -20,13 +20,13 @@ msgstr ""
msgid "--- Select state ---" msgid "--- Select state ---"
msgstr "" msgstr ""
#: users/static/js/users/site.js:322 #: users/static/js/users/site.js:323
#: users/static/templates/users/user-detail-profile.html:39 #: users/static/templates/users/user-detail-profile.html:39
#: users/static/templates/users/user-detail.html:37 #: users/static/templates/users/user-detail.html:37
msgid "About me" msgid "About me"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:436 #: assignments/static/js/assignments/site.js:437
#: motions/static/templates/motions/motion-detail.html:135 #: motions/static/templates/motions/motion-detail.html:135
#: motions/static/templates/motions/motion-detail.html:136 #: motions/static/templates/motions/motion-detail.html:136
#: motions/static/templates/motions/motion-detail.html:186 #: motions/static/templates/motions/motion-detail.html:186
@ -64,6 +64,7 @@ msgstr ""
msgid "Administrative data" msgid "Administrative data"
msgstr "" msgstr ""
#: agenda/static/js/agenda/site.js:14
#: agenda/static/templates/agenda/item-list.html:25 #: agenda/static/templates/agenda/item-list.html:25
#: agenda/static/templates/agenda/item-list.html:47 #: agenda/static/templates/agenda/item-list.html:47
#: agenda/static/templates/agenda/slide-item-list.html:2 #: agenda/static/templates/agenda/slide-item-list.html:2
@ -177,14 +178,14 @@ msgid "Closed"
msgstr "" msgstr ""
#: agenda/static/templates/agenda/item-list.html:174 #: agenda/static/templates/agenda/item-list.html:174
#: users/static/js/users/site.js:315 #: users/static/js/users/site.js:316
#: users/static/templates/users/user-detail.html:45 #: users/static/templates/users/user-detail.html:45
#: users/static/templates/users/user-import.html:72 #: users/static/templates/users/user-import.html:72
msgid "Comment" msgid "Comment"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:119 #: assignments/static/js/assignments/site.js:120
#: assignments/static/js/assignments/site.js:486 #: assignments/static/js/assignments/site.js:487
msgid "Comment on the ballot paper" msgid "Comment on the ballot paper"
msgstr "" msgstr ""
@ -220,8 +221,8 @@ msgstr ""
msgid "Current value:" msgid "Current value:"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:100 #: assignments/static/js/assignments/site.js:101
#: assignments/static/js/assignments/site.js:135 #: assignments/static/js/assignments/site.js:136
msgid "Default comment on the ballot paper" msgid "Default comment on the ballot paper"
msgstr "" msgstr ""
@ -229,7 +230,7 @@ msgstr ""
msgid "Default groups" msgid "Default groups"
msgstr "" msgstr ""
#: users/static/js/users/site.js:303 #: users/static/js/users/site.js:304
msgid "Default password" msgid "Default password"
msgstr "" msgstr ""
@ -259,7 +260,7 @@ msgstr ""
msgid "Delete selected items" msgid "Delete selected items"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:84 #: assignments/static/js/assignments/site.js:85
#: assignments/static/templates/assignments/assignment-detail.html:37 #: assignments/static/templates/assignments/assignment-detail.html:37
#: core/static/templates/core/projector-controls.html:120 #: core/static/templates/core/projector-controls.html:120
msgid "Description" msgid "Description"
@ -360,10 +361,12 @@ msgstr ""
msgid "Election result" msgid "Election result"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:14
#: assignments/static/templates/assignments/assignment-list.html:17 #: assignments/static/templates/assignments/assignment-list.html:17
msgid "Elections" msgid "Elections"
msgstr "" msgstr ""
#: mediafiles/static/js/mediafiles/site.js:14
#: mediafiles/static/templates/mediafiles/mediafile-list.html:9 #: mediafiles/static/templates/mediafiles/mediafile-list.html:9
msgid "Files" msgid "Files"
msgstr "" msgstr ""
@ -386,7 +389,7 @@ msgstr ""
msgid "Filter" msgid "Filter"
msgstr "" msgstr ""
#: users/static/js/users/site.js:269 #: users/static/js/users/site.js:270
#: users/static/templates/users/user-detail-profile.html:26 #: users/static/templates/users/user-detail-profile.html:26
#: users/static/templates/users/user-import.html:68 #: users/static/templates/users/user-import.html:68
msgid "First name" msgid "First name"
@ -396,7 +399,7 @@ msgstr ""
msgid "Group" msgid "Group"
msgstr "" msgstr ""
#: users/static/js/users/site.js:290 #: users/static/js/users/site.js:291
#: users/static/templates/users/group-list.html:13 #: users/static/templates/users/group-list.html:13
#: users/static/templates/users/user-detail.html:33 #: users/static/templates/users/user-detail.html:33
#: users/static/templates/users/user-import.html:71 #: users/static/templates/users/user-import.html:71
@ -418,6 +421,10 @@ msgstr ""
msgid "Hide internal agenda items" msgid "Hide internal agenda items"
msgstr "" msgstr ""
#: core/static/js/core/site.js:93
msgid "Home"
msgstr ""
#: users/static/templates/users/group-list.html:34 #: users/static/templates/users/group-list.html:34
msgid "ID" msgid "ID"
msgstr "" msgstr ""
@ -455,11 +462,11 @@ msgstr ""
msgid "Import participants" msgid "Import participants"
msgstr "" msgstr ""
#: users/static/js/users/site.js:722 #: users/static/js/users/site.js:723
msgid "Important: Please change your password!" msgid "Important: Please change your password!"
msgstr "" msgstr ""
#: users/static/js/users/site.js:720 #: users/static/js/users/site.js:721
msgid "Installation was successfully." msgid "Installation was successfully."
msgstr "" msgstr ""
@ -469,11 +476,11 @@ msgstr ""
msgid "Invalid votes" msgid "Invalid votes"
msgstr "" msgstr ""
#: users/static/js/users/site.js:337 #: users/static/js/users/site.js:338
msgid "Is active" msgid "Is active"
msgstr "" msgstr ""
#: users/static/js/users/site.js:330 #: users/static/js/users/site.js:331
#: users/static/templates/users/user-list.html:70 #: users/static/templates/users/user-list.html:70
msgid "Is present" msgid "Is present"
msgstr "" msgstr ""
@ -482,7 +489,7 @@ msgstr ""
msgid "Item number" msgid "Item number"
msgstr "" msgstr ""
#: users/static/js/users/site.js:276 #: users/static/js/users/site.js:277
#: users/static/templates/users/user-detail-profile.html:30 #: users/static/templates/users/user-detail-profile.html:30
#: users/static/templates/users/user-import.html:69 #: users/static/templates/users/user-import.html:69
msgid "Last name" msgid "Last name"
@ -597,14 +604,14 @@ msgstr ""
msgid "Next speakers:" msgid "Next speakers:"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:427 #: assignments/static/js/assignments/site.js:428
#: motions/static/templates/motions/motion-detail.html:130 #: motions/static/templates/motions/motion-detail.html:130
#: motions/static/templates/motions/motion-detail.html:131 #: motions/static/templates/motions/motion-detail.html:131
#: motions/static/templates/motions/motion-detail.html:177 #: motions/static/templates/motions/motion-detail.html:177
msgid "No" msgid "No"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:91 #: assignments/static/js/assignments/site.js:92
#: assignments/static/templates/assignments/assignment-list.html:144 #: assignments/static/templates/assignments/assignment-list.html:144
msgid "Number of members to be elected" msgid "Number of members to be elected"
msgstr "" msgstr ""
@ -634,6 +641,7 @@ msgstr ""
msgid "Participant" msgid "Participant"
msgstr "" msgstr ""
#: users/static/js/users/site.js:14
#: users/static/templates/users/user-list.html:35 #: users/static/templates/users/user-list.html:35
msgid "Participants" msgid "Participants"
msgstr "" msgstr ""
@ -826,7 +834,7 @@ msgstr ""
msgid "Select or search a category..." msgid "Select or search a category..."
msgstr "" msgstr ""
#: users/static/js/users/site.js:296 #: users/static/js/users/site.js:297
msgid "Select or search a group..." msgid "Select or search a group..."
msgstr "" msgstr ""
@ -858,6 +866,10 @@ msgstr ""
msgid "Select or search an attachment..." msgid "Select or search an attachment..."
msgstr "" msgstr ""
#: core/static/js/core/site.js:100
msgid "Settings"
msgstr ""
#: mediafiles/static/templates/mediafiles/mediafile-list.html:65 #: mediafiles/static/templates/mediafiles/mediafile-list.html:65
#: motions/static/templates/motions/category-list.html:44 #: motions/static/templates/motions/category-list.html:44
msgid "Show" msgid "Show"
@ -909,7 +921,7 @@ msgstr ""
msgid "Stop current speaker" msgid "Stop current speaker"
msgstr "" msgstr ""
#: users/static/js/users/site.js:283 #: users/static/js/users/site.js:284
#: users/static/templates/users/user-detail-profile.html:35 #: users/static/templates/users/user-detail-profile.html:35
#: users/static/templates/users/user-detail.html:31 #: users/static/templates/users/user-detail.html:31
#: users/static/templates/users/user-import.html:70 #: users/static/templates/users/user-import.html:70
@ -953,7 +965,7 @@ msgid "Tags"
msgstr "" msgstr ""
#: agenda/static/templates/agenda/item-import.html:64 #: agenda/static/templates/agenda/item-import.html:64
#: core/static/js/core/site.js:413 #: core/static/js/core/site.js:430
#: motions/static/js/motions/site.js:158 #: motions/static/js/motions/site.js:158
#: motions/static/templates/motions/motion-detail.html:232 #: motions/static/templates/motions/motion-detail.html:232
msgid "Text" msgid "Text"
@ -971,15 +983,15 @@ msgstr ""
#. academic degree #. academic degree
#: agenda/static/templates/agenda/item-import.html:63 #: agenda/static/templates/agenda/item-import.html:63
#: agenda/static/templates/agenda/item-list.html:170 #: agenda/static/templates/agenda/item-list.html:170
#: assignments/static/js/assignments/site.js:76 #: assignments/static/js/assignments/site.js:77
#: assignments/static/templates/assignments/assignment-list.html:140 #: assignments/static/templates/assignments/assignment-list.html:140
#: assignments/static/templates/assignments/assignment-list.html:84 #: assignments/static/templates/assignments/assignment-list.html:84
#: core/static/js/core/site.js:405 #: core/static/js/core/site.js:422
#: mediafiles/static/templates/mediafiles/mediafile-form.html:25 #: mediafiles/static/templates/mediafiles/mediafile-form.html:25
#: mediafiles/static/templates/mediafiles/mediafile-list.html:25 #: mediafiles/static/templates/mediafiles/mediafile-list.html:25
#: motions/static/js/motions/site.js:150 #: motions/static/js/motions/site.js:150
#: motions/static/templates/motions/motion-list.html:91 #: motions/static/templates/motions/motion-list.html:91
#: users/static/js/users/site.js:262 #: users/static/js/users/site.js:263
#: users/static/templates/users/user-detail-profile.html:22 #: users/static/templates/users/user-detail-profile.html:22
#: users/static/templates/users/user-import.html:67 #: users/static/templates/users/user-import.html:67
msgid "Title" msgid "Title"
@ -1007,7 +1019,7 @@ msgstr ""
msgid "Uploaded by" msgid "Uploaded by"
msgstr "" msgstr ""
#: users/static/js/users/site.js:721 #: users/static/js/users/site.js:722
msgid "Use <strong>admin</strong> and <strong>admin</strong> for first login." msgid "Use <strong>admin</strong> and <strong>admin</strong> for first login."
msgstr "" msgstr ""
@ -1022,7 +1034,7 @@ msgstr ""
msgid "Username" msgid "Username"
msgstr "" msgstr ""
#: users/static/js/users/site.js:742 #: users/static/js/users/site.js:743
msgid "Username or password was not correct." msgid "Username or password was not correct."
msgstr "" msgstr ""
@ -1036,18 +1048,18 @@ msgstr ""
msgid "Vote" msgid "Vote"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:476 #: assignments/static/js/assignments/site.js:477
#: motions/static/templates/motions/motion-detail.html:150 #: motions/static/templates/motions/motion-detail.html:150
#: motions/static/templates/motions/motion-detail.html:151 #: motions/static/templates/motions/motion-detail.html:151
#: motions/static/templates/motions/motion-detail.html:214 #: motions/static/templates/motions/motion-detail.html:214
msgid "Votes cast" msgid "Votes cast"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:468 #: assignments/static/js/assignments/site.js:469
msgid "Votes invalid" msgid "Votes invalid"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:460 #: assignments/static/js/assignments/site.js:461
msgid "Votes valid" msgid "Votes valid"
msgstr "" msgstr ""
@ -1059,8 +1071,8 @@ msgstr ""
msgid "Workflow" msgid "Workflow"
msgstr "" msgstr ""
#: assignments/static/js/assignments/site.js:126 #: assignments/static/js/assignments/site.js:127
#: assignments/static/js/assignments/site.js:418 #: assignments/static/js/assignments/site.js:419
#: motions/static/templates/motions/motion-detail.html:125 #: motions/static/templates/motions/motion-detail.html:125
#: motions/static/templates/motions/motion-detail.html:126 #: motions/static/templates/motions/motion-detail.html:126
#: motions/static/templates/motions/motion-detail.html:168 #: motions/static/templates/motions/motion-detail.html:168

View File

@ -6,11 +6,12 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp.
.config([ .config([
'mainMenuProvider', 'mainMenuProvider',
function (mainMenuProvider) { 'gettext',
function (mainMenuProvider, gettext) {
mainMenuProvider.register({ mainMenuProvider.register({
'ui_sref': 'mediafiles.mediafile.list', 'ui_sref': 'mediafiles.mediafile.list',
'img_class': 'paperclip', 'img_class': 'paperclip',
'title': 'Files', 'title': gettext('Files'),
'weight': 600, 'weight': 600,
'perm': 'mediafiles.can_see', 'perm': 'mediafiles.can_see',
}); });

View File

@ -109,7 +109,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
// Provide generic motion form fields for create and update view // Provide generic motion form fields for create and update view
.factory('MotionFormFieldFactory', [ .factory('MotionFormFieldFactory', [
'gettext', 'gettextCatalog',
'operator', 'operator',
'Category', 'Category',
'Config', 'Config',
@ -117,7 +117,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
'Tag', 'Tag',
'User', 'User',
'Workflow', 'Workflow',
function (gettext, operator, Category, Config, Mediafile, Tag, User, Workflow) { function (gettextCatalog, operator, Category, Config, Mediafile, Tag, User, Workflow) {
return { return {
getFormFields: function () { getFormFields: function () {
return [ return [
@ -125,7 +125,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'identifier', key: 'identifier',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Identifier') label: gettextCatalog.getString('Identifier')
}, },
hide: true hide: true
}, },
@ -133,13 +133,13 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'submitters_id', key: 'submitters_id',
type: 'ui-select-multiple', type: 'ui-select-multiple',
templateOptions: { templateOptions: {
label: gettext('Submitters'), label: gettextCatalog.getString('Submitters'),
optionsAttr: 'bs-options', optionsAttr: 'bs-options',
options: User.getAll(), options: User.getAll(),
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search', ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
valueProp: 'id', valueProp: 'id',
labelProp: 'full_name', labelProp: 'full_name',
placeholder: gettext('Select or search a submitter...') placeholder: gettextCatalog.getString('Select or search a submitter...')
}, },
hide: !operator.hasPerms('motions.can_manage') hide: !operator.hasPerms('motions.can_manage')
}, },
@ -147,7 +147,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'title', key: 'title',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Title'), label: gettextCatalog.getString('Title'),
required: true required: true
} }
}, },
@ -155,7 +155,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'text', key: 'text',
type: 'textarea', type: 'textarea',
templateOptions: { templateOptions: {
label: gettext('Text'), label: gettextCatalog.getString('Text'),
required: true required: true
}, },
ngModelElAttrs: {'ckeditor': 'CKEditorOptions'} ngModelElAttrs: {'ckeditor': 'CKEditorOptions'}
@ -164,7 +164,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'reason', key: 'reason',
type: 'textarea', type: 'textarea',
templateOptions: { templateOptions: {
label: gettext('Reason') label: gettextCatalog.getString('Reason')
}, },
ngModelElAttrs: {'ckeditor': 'CKEditorOptions'} ngModelElAttrs: {'ckeditor': 'CKEditorOptions'}
}, },
@ -172,7 +172,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'more', key: 'more',
type: 'checkbox', type: 'checkbox',
templateOptions: { templateOptions: {
label: gettext('Show extended fields') label: gettextCatalog.getString('Show extended fields')
}, },
hide: !operator.hasPerms('motions.can_manage') hide: !operator.hasPerms('motions.can_manage')
}, },
@ -180,13 +180,13 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'attachments_id', key: 'attachments_id',
type: 'ui-select-multiple', type: 'ui-select-multiple',
templateOptions: { templateOptions: {
label: gettext('Attachment'), label: gettextCatalog.getString('Attachment'),
optionsAttr: 'bs-options', optionsAttr: 'bs-options',
options: Mediafile.getAll(), options: Mediafile.getAll(),
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search', ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
valueProp: 'id', valueProp: 'id',
labelProp: 'title_or_filename', labelProp: 'title_or_filename',
placeholder: gettext('Select or search an attachment...') placeholder: gettextCatalog.getString('Select or search an attachment...')
}, },
hideExpression: '!model.more' hideExpression: '!model.more'
}, },
@ -194,13 +194,13 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'category_id', key: 'category_id',
type: 'ui-select-single', type: 'ui-select-single',
templateOptions: { templateOptions: {
label: gettext('Category'), label: gettextCatalog.getString('Category'),
optionsAttr: 'bs-options', optionsAttr: 'bs-options',
options: Category.getAll(), options: Category.getAll(),
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search', ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
valueProp: 'id', valueProp: 'id',
labelProp: 'name', labelProp: 'name',
placeholder: gettext('Select or search a category...') placeholder: gettextCatalog.getString('Select or search a category...')
}, },
hideExpression: '!model.more' hideExpression: '!model.more'
}, },
@ -208,13 +208,13 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'tags_id', key: 'tags_id',
type: 'ui-select-multiple', type: 'ui-select-multiple',
templateOptions: { templateOptions: {
label: gettext('Tags'), label: gettextCatalog.getString('Tags'),
optionsAttr: 'bs-options', optionsAttr: 'bs-options',
options: Tag.getAll(), options: Tag.getAll(),
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search', ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
valueProp: 'id', valueProp: 'id',
labelProp: 'name', labelProp: 'name',
placeholder: gettext('Select or search a tag...') placeholder: gettextCatalog.getString('Select or search a tag...')
}, },
hideExpression: '!model.more' hideExpression: '!model.more'
}, },
@ -222,13 +222,13 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'supporters_id', key: 'supporters_id',
type: 'ui-select-multiple', type: 'ui-select-multiple',
templateOptions: { templateOptions: {
label: gettext('Supporters'), label: gettextCatalog.getString('Supporters'),
optionsAttr: 'bs-options', optionsAttr: 'bs-options',
options: User.getAll(), options: User.getAll(),
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search', ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
valueProp: 'id', valueProp: 'id',
labelProp: 'full_name', labelProp: 'full_name',
placeholder: gettext('Select or search a supporter...') placeholder: gettextCatalog.getString('Select or search a supporter...')
}, },
hideExpression: '!model.more' hideExpression: '!model.more'
}, },
@ -236,13 +236,13 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
key: 'workflow_id', key: 'workflow_id',
type: 'ui-select-single', type: 'ui-select-single',
templateOptions: { templateOptions: {
label: gettext('Workflow'), label: gettextCatalog.getString('Workflow'),
optionsAttr: 'bs-options', optionsAttr: 'bs-options',
options: Workflow.getAll(), options: Workflow.getAll(),
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search', ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
valueProp: 'id', valueProp: 'id',
labelProp: 'name', labelProp: 'name',
placeholder: gettext('Select or search a workflow...') placeholder: gettextCatalog.getString('Select or search a workflow...')
}, },
hideExpression: '!model.more', hideExpression: '!model.more',
}]; }];
@ -504,7 +504,6 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
.controller('MotionUpdateCtrl', [ .controller('MotionUpdateCtrl', [
'$scope', '$scope',
'$state', '$state',
'gettext',
'Motion', 'Motion',
'Category', 'Category',
'Config', 'Config',
@ -514,7 +513,7 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
'User', 'User',
'Workflow', 'Workflow',
'motion', 'motion',
function($scope, $state, gettext, Motion, Category, Config, Mediafile, MotionFormFieldFactory, Tag, User, Workflow, motion) { function($scope, $state, Motion, Category, Config, Mediafile, MotionFormFieldFactory, Tag, User, Workflow, motion) {
Category.bindAll({}, $scope, 'categories'); Category.bindAll({}, $scope, 'categories');
Mediafile.bindAll({}, $scope, 'mediafiles'); Mediafile.bindAll({}, $scope, 'mediafiles');
Tag.bindAll({}, $scope, 'tags'); Tag.bindAll({}, $scope, 'tags');

View File

@ -6,11 +6,12 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
.config([ .config([
'mainMenuProvider', 'mainMenuProvider',
function (mainMenuProvider) { 'gettext',
function (mainMenuProvider, gettext) {
mainMenuProvider.register({ mainMenuProvider.register({
'ui_sref': 'users.user.list', 'ui_sref': 'users.user.list',
'img_class': 'user', 'img_class': 'user',
'title': 'Participants', 'title': gettext('Participants'),
'weight': 500, 'weight': 500,
'perm': 'users.can_see_name', 'perm': 'users.can_see_name',
}); });
@ -249,9 +250,9 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
// Provide generic user form fields for create and update view // Provide generic user form fields for create and update view
.factory('UserFormFieldFactory', [ .factory('UserFormFieldFactory', [
'$http', '$http',
'gettext', 'gettextCatalog',
'Group', 'Group',
function ($http, gettext, Group) { function ($http, gettextCatalog, Group) {
return { return {
getFormFields: function () { getFormFields: function () {
return [ return [
@ -259,48 +260,48 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
key: 'title', key: 'title',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Title'), label: gettextCatalog.getString('Title'),
} }
}, },
{ {
key: 'first_name', key: 'first_name',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('First name') label: gettextCatalog.getString('First name')
} }
}, },
{ {
key: 'last_name', key: 'last_name',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Last name') label: gettextCatalog.getString('Last name')
} }
}, },
{ {
key: 'structure_level', key: 'structure_level',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Structure level') label: gettextCatalog.getString('Structure level')
} }
}, },
{ {
key: 'groups', key: 'groups',
type: 'ui-select-multiple', type: 'ui-select-multiple',
templateOptions: { templateOptions: {
label: gettext('Groups'), label: gettextCatalog.getString('Groups'),
optionsAttr: 'bs-options', optionsAttr: 'bs-options',
options: Group.getAll(), options: Group.getAll(),
ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search', ngOptions: 'option[to.valueProp] as option in to.options | filter: $select.search',
valueProp: 'id', valueProp: 'id',
labelProp: 'name', labelProp: 'name',
placeholder: gettext('Select or search a group...') placeholder: gettextCatalog.getString('Select or search a group...')
} }
}, },
{ {
key: 'default_password', key: 'default_password',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Default password'), label: gettextCatalog.getString('Default password'),
addonRight: { text: 'Reset', class: 'fa fa-undo', onClick: function () { addonRight: { text: 'Reset', class: 'fa fa-undo', onClick: function () {
// TODO: find a way to get user.id // TODO: find a way to get user.id
//$http.post('/rest/users/user/' + model.id + '/reset_password/', {}) //$http.post('/rest/users/user/' + model.id + '/reset_password/', {})
@ -312,14 +313,14 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
key: 'comment', key: 'comment',
type: 'input', type: 'input',
templateOptions: { templateOptions: {
label: gettext('Comment') label: gettextCatalog.getString('Comment')
} }
}, },
{ {
key: 'about_me', key: 'about_me',
type: 'textarea', type: 'textarea',
templateOptions: { templateOptions: {
label: gettext('About me') label: gettextCatalog.getString('About me')
}, },
ngModelElAttrs: {'ckeditor': 'CKEditorOptions'} ngModelElAttrs: {'ckeditor': 'CKEditorOptions'}
}, },
@ -327,14 +328,14 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
key: 'is_present', key: 'is_present',
type: 'checkbox', type: 'checkbox',
templateOptions: { templateOptions: {
label: gettext('Is present') label: gettextCatalog.getString('Is present')
} }
}, },
{ {
key: 'is_active', key: 'is_active',
type: 'checkbox', type: 'checkbox',
templateOptions: { templateOptions: {
label: gettext('Is active') label: gettextCatalog.getString('Is active')
} }
}]; }];
} }
@ -709,17 +710,17 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
'$scope', '$scope',
'$http', '$http',
'operator', 'operator',
'gettext', 'gettextCatalog',
'Config', 'Config',
function ($scope, $http, operator, gettext, Config) { function ($scope, $http, operator, gettextCatalog, Config) {
$scope.alerts = []; $scope.alerts = [];
// TODO: add welcome message only on first time (or if admin password not changed) // TODO: add welcome message only on first time (or if admin password not changed)
$scope.alerts.push({ $scope.alerts.push({
type: 'success', type: 'success',
msg: gettext("Installation was successfully.") + "<br>" + msg: gettextCatalog.getString("Installation was successfully.") + "<br>" +
gettext("Use <strong>admin</strong> and <strong>admin</strong> for first login.") + "<br>" + gettextCatalog.getString("Use <strong>admin</strong> and <strong>admin</strong> for first login.") + "<br>" +
gettext("Important: Please change your password!") gettextCatalog.getString("Important: Please change your password!")
}); });
// close alert function // close alert function
$scope.closeAlert = function(index) { $scope.closeAlert = function(index) {
@ -739,7 +740,7 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
} else { } else {
$scope.alerts.push({ $scope.alerts.push({
type: 'danger', type: 'danger',
msg: gettext('Username or password was not correct.') msg: gettextCatalog.getString('Username or password was not correct.')
}); });
//Username or password is not correct. //Username or password is not correct.
} }