Changes for the voting plugin
- new-style template hooks. See changes in the template hook documentation - reordered user list view to get more space for extra things - added template hooks.
This commit is contained in:
parent
209ea70d75
commit
2256031184
@ -123,11 +123,14 @@
|
||||
</div>
|
||||
|
||||
<h3 translate>Election result</h3>
|
||||
<button os-perms="assignments.can_manage" ng-show="assignment.phase !== 2" ng-click="createBallot()"
|
||||
class="btn btn-default btn-sm">
|
||||
<i class="fa fa-bar-chart fa-lg"></i>
|
||||
<translate>New ballot</translate>
|
||||
</button>
|
||||
<template-hook hook-name="assignmentPollNewBallotButton">
|
||||
<button os-perms="assignments.can_manage" ng-show="assignment.phase !== 2" ng-click="createBallot()"
|
||||
class="btn btn-default btn-sm">
|
||||
<i class="fa fa-bar-chart fa-lg"></i>
|
||||
<translate>New ballot</translate>
|
||||
</button>
|
||||
</template-hook>
|
||||
|
||||
<uib-tabset ng-if="assignment.polls.length > 0" class="spacer ballot-tabs" active="$parent.activeTab">
|
||||
<uib-tab ng-repeat="poll in assignment.polls | orderBy:'id'"
|
||||
index="$index" heading="{{ 'Ballot' | translate }} {{ $index + 1 }}">
|
||||
@ -274,7 +277,7 @@
|
||||
</uib-tabset>
|
||||
|
||||
<!-- Workaround to prevent page scrolling up after autoupdate. -->
|
||||
<div style="height: 700px"><div>
|
||||
<div style="height: 700px"></div>
|
||||
</div>
|
||||
|
||||
<template-hook hook-name="assignmentDetailViewDetailContainer"></template-hook>
|
||||
|
@ -9,6 +9,7 @@
|
||||
<i class="fa fa-tags fa-lg"></i>
|
||||
<translate>Tags</translate>
|
||||
</a>
|
||||
<template-hook hook-name="assignmentListMenuButton"></template-hook>
|
||||
</div>
|
||||
<h1 translate>Elections</h1>
|
||||
</div>
|
||||
|
@ -553,27 +553,57 @@ angular.module('OpenSlidesApp.core', [
|
||||
])
|
||||
|
||||
// Template hooks
|
||||
// 2 possible uses:
|
||||
// - { Id: 'myHookId', template: '<button>click me</button>' }
|
||||
// - { Id: 'myHookId', templateUrl: '/static/templates/plugin_name/my-hook.html' }
|
||||
// It is possible to provide a scope, that is merged into the scope of the templateHook.
|
||||
// This overrides functions/values of the parent scope, but there may are conflicts
|
||||
// with other plugins defining the same function/value. E.g.:
|
||||
// Possible uses:
|
||||
// 1. { id: 'myHookId', template: '<button>click me</button>' }
|
||||
// 2. { id: 'myHookId', templateUrl: '/static/templates/plugin_name/my-hook.html' }
|
||||
// 3. { id: 'myHookId' }
|
||||
//
|
||||
// Deprecated: Give the id with 'Id'. Please use 'id'.
|
||||
//
|
||||
// Option 3 is for just changing the scope (see below), but not the original content. This
|
||||
// is usefull to alter a JS behavior, e.g. on a ng-click. In this case, override is false
|
||||
// for this template hook.
|
||||
//
|
||||
// It is possible to provide a scope, that is merged into the surrounding scope.
|
||||
// You can override functions or values of the surrounding scope by providing them:
|
||||
// { Id: 'hookId', template: '<button ng-click="customFn()">click me</button>',
|
||||
// scope: {
|
||||
// customFn: function () { /*Do something */ },
|
||||
// customOrOverwritten: function () { /*Do something */ },
|
||||
// },
|
||||
// }
|
||||
// Or you provide a function that returns an object of functions/values to overwrite to
|
||||
// get access to the scope merged in:
|
||||
// { Id: 'hookId', template: '<button ng-click="customFn()">click me</button>',
|
||||
// scope: function (scope) {
|
||||
// return {
|
||||
// customOrOverwritten: function () {
|
||||
// scope.value = /* change it */;
|
||||
// },
|
||||
// };
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// As a default, template hooks in flavour of option 1 and 2 override the content that was
|
||||
// originally there. Provide 'override: false', to prevent overriding the original content.
|
||||
.factory('templateHooks', [
|
||||
function () {
|
||||
var hooks = {};
|
||||
return {
|
||||
hooks: hooks,
|
||||
registerHook: function (hook) {
|
||||
if (hooks[hook.Id] === undefined) {
|
||||
hooks[hook.Id] = [];
|
||||
// Deprecated: Set the new style 'id', if 'Id' is given.
|
||||
if (hook.id === undefined) {
|
||||
hook.id = hook.Id;
|
||||
}
|
||||
hooks[hook.Id].push(hook);
|
||||
|
||||
if (hooks[hook.id] === undefined) {
|
||||
hooks[hook.id] = [];
|
||||
}
|
||||
// set override default
|
||||
if (hook.override === undefined) {
|
||||
hook.override = !!(hook.template || hook.templateUrl);
|
||||
}
|
||||
hooks[hook.id].push(hook);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -584,21 +614,41 @@ angular.module('OpenSlidesApp.core', [
|
||||
'$http',
|
||||
'$q',
|
||||
'$templateCache',
|
||||
'$timeout',
|
||||
'templateHooks',
|
||||
function ($compile, $http, $q, $templateCache, templateHooks) {
|
||||
function ($compile, $http, $q, $templateCache, $timeout, templateHooks) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '',
|
||||
link: function (scope, iElement, iAttr) {
|
||||
var hooks = templateHooks.hooks[iAttr.hookName];
|
||||
if (hooks) {
|
||||
var templates = _.map(hooks, function (hook) {
|
||||
// Populate scope
|
||||
_.forEach(hook.scope, function (value, key) {
|
||||
if (!scope.hasOwnProperty(key)) {
|
||||
scope[key] = value;
|
||||
}
|
||||
// Populate scopes
|
||||
_.forEach(hooks, function (hook) {
|
||||
var _scope = hook.scope;
|
||||
// If it is a function, get the scope from the function and provide
|
||||
// the original scope.
|
||||
if (typeof hook.scope === 'function') {
|
||||
_scope = hook.scope(scope);
|
||||
}
|
||||
|
||||
_.forEach(_scope, function (value, key) {
|
||||
scope[key] = value;
|
||||
});
|
||||
});
|
||||
|
||||
// Check, if at least one hook overrides the original content.
|
||||
var override = _.some(hooks, function (hook) {
|
||||
return hook.override;
|
||||
});
|
||||
|
||||
// filter hooks, that does actually have a template
|
||||
hooks = _.filter(hooks, function (hook) {
|
||||
return hook.template || hook.templateUrl;
|
||||
});
|
||||
|
||||
// Get all templates
|
||||
var templates = _.map(hooks, function (hook) {
|
||||
// Either a template (html given as string) or a templateUrl has
|
||||
// to be given. If a scope is provided, the schope of this templateHook
|
||||
// is populated with the given functions/values.
|
||||
@ -608,8 +658,17 @@ angular.module('OpenSlidesApp.core', [
|
||||
return $templateCache.get(hook.templateUrl);
|
||||
}
|
||||
});
|
||||
var html = templates.join('');
|
||||
iElement.append($compile(html)(scope));
|
||||
|
||||
// Wait for the dom to build up, so we can retrieve the inner html of iElement.
|
||||
$timeout(function () {
|
||||
var html = override ? '' : iElement.html();
|
||||
if (templates.length) {
|
||||
html += templates.join('');
|
||||
}
|
||||
|
||||
iElement.empty();
|
||||
iElement.append($compile(html)(scope));
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -468,10 +468,12 @@
|
||||
</table>
|
||||
</ol>
|
||||
|
||||
<button ng-if="motion.isAllowed('create_poll')" ng-click="create_poll()" class="btn btn-default btn-sm">
|
||||
<i class="fa fa-bar-chart fa-lg"></i>
|
||||
<translate>New vote</translate>
|
||||
</button>
|
||||
<template-hook hook-name="motionPollNewVoteButton">
|
||||
<button ng-if="motion.isAllowed('create_poll')" ng-click="create_poll()" class="btn btn-default btn-sm">
|
||||
<i class="fa fa-bar-chart fa-lg"></i>
|
||||
<translate>New vote</translate>
|
||||
</button>
|
||||
</template-hook>
|
||||
|
||||
<div class="spacer-top pull-right nobr">
|
||||
<a href ng-click="gotoPersonalNote()" translate>Personal note</a>
|
||||
|
@ -21,6 +21,7 @@
|
||||
<i class="fa fa-download fa-lg"></i>
|
||||
<translate>Import</translate>
|
||||
</a>
|
||||
<template-hook hook-name="motionListMenuButton"></template-hook>
|
||||
</div>
|
||||
<h1 translate>Motions</h1>
|
||||
</div>
|
||||
|
@ -447,13 +447,15 @@ class MotionViewSet(ModelViewSet):
|
||||
raise ValidationError({'detail': 'You can not create a poll in this motion state.'})
|
||||
try:
|
||||
with transaction.atomic():
|
||||
motion.create_poll(skip_autoupdate=True)
|
||||
poll = motion.create_poll(skip_autoupdate=True)
|
||||
except WorkflowError as e:
|
||||
raise ValidationError({'detail': e})
|
||||
motion.write_log([ugettext_noop('Vote created')], request.user, skip_autoupdate=True)
|
||||
|
||||
inform_changed_data(motion)
|
||||
return Response({'detail': _('Vote created successfully.')})
|
||||
return Response({
|
||||
'detail': _('Vote created successfully.'),
|
||||
'createdPollId': poll.pk})
|
||||
|
||||
|
||||
class MotionPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
|
@ -565,6 +565,9 @@ angular.module('OpenSlidesApp.users.site', [
|
||||
_.forEach($scope.users, function (user) {
|
||||
user.has_last_email_send = !!user.last_email_send;
|
||||
});
|
||||
if ($scope.updateUsers) {
|
||||
$scope.updateUsers();
|
||||
}
|
||||
});
|
||||
Group.bindAll({where: {id: {'>': 1}}}, $scope, 'groups');
|
||||
$scope.$watch(function () {
|
||||
|
@ -19,6 +19,7 @@
|
||||
<i class="fa fa-download fa-lg"></i>
|
||||
<translate>Import</translate>
|
||||
</a>
|
||||
<template-hook hook-name="userListMenuButtons"></template-hook>
|
||||
</div>
|
||||
<h1 translate>Participants</h1>
|
||||
</div>
|
||||
@ -69,6 +70,8 @@
|
||||
</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<template-hook hook-name="userListSubmenuRight"></template-hook>
|
||||
</div>
|
||||
</div>
|
||||
<div uib-collapse="!isSelectMode" class="row spacer">
|
||||
@ -146,6 +149,7 @@
|
||||
{{ usersFiltered.length }} /
|
||||
{{ users.length }} {{ "participants" | translate }}<span ng-if="(users|filter:{selected:true}).length > 0">,
|
||||
{{(users|filter:{selected:true}).length}} {{ "selected" | translate }}</span>
|
||||
<template-hook hook-name="userListTableStats"></template-hook>
|
||||
</div>
|
||||
<div class="col-md-6" ng-show="usersFiltered.length > pagination.itemsPerPage">
|
||||
<span class="pull-right">
|
||||
@ -340,7 +344,9 @@
|
||||
</div>
|
||||
<div os-perms="users.can_manage" ng-class="{'hiddenDiv': !user.hover}">
|
||||
<small>
|
||||
<a href="" ng-click="openDialog(user)" translate>Edit</a> ·
|
||||
<template-hook hook-name="userListEditButton">
|
||||
<a href="" ng-click="openDialog(user)" translate>Edit</a> ·
|
||||
</template-hook>
|
||||
<a ui-sref="users.user.change-password({id: user.id})" translate>Change password</a> ·
|
||||
<a href="" class="text-danger"
|
||||
ng-bootbox-confirm="{{ 'Are you sure you want to delete this entry?' | translate }}<br>
|
||||
@ -434,17 +440,20 @@
|
||||
</div>
|
||||
</small>
|
||||
</div>
|
||||
<div style="width: 40%;" class="pull-right" os-perms="users.can_see_extra_data">
|
||||
<div os-perms="users.can_manage" ng-show="user.hover || user.is_present">
|
||||
<div style="width: 40%;" class="pull-right">
|
||||
<div os-perms="users.can_see_extra_data users.can_manage"
|
||||
ng-style="{'visibility': (user.hover || user.is_present) ? 'visible' : 'hidden'}">
|
||||
<span class="pointer nobr" ng-click="user.is_present = !user.is_present; save(user);">
|
||||
<i class="fa" ng-class="user.is_present ? 'fa-check-square-o' : 'fa-square-o'"></i>
|
||||
<span class="spacer-left" translate>Present</span>
|
||||
</span>
|
||||
</div>
|
||||
<div os-perms="!users.can_manage" class="nobr" ng-show="user.is_present">
|
||||
<div os-perms="!users.can_manage" class="nobr"
|
||||
ng-style="{'visibility': user.is_present ? 'visible' : 'hidden'}">
|
||||
<i class="fa fa-check-square-o"></i>
|
||||
<span class="spacer-left" translate>Present</span>
|
||||
</div>
|
||||
<template-hook hook-name="userListExtraContent"></template-hook>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user