Merge pull request #1815 from emanuelschuetze/candidateElected
Mark candidate as elected. Updated assignment detail.
This commit is contained in:
commit
c30116f5c1
@ -189,7 +189,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
|
|||||||
function ($scope, $filter, $http, Agenda, User, item) {
|
function ($scope, $filter, $http, Agenda, User, item) {
|
||||||
Agenda.bindOne(item.id, $scope, 'item');
|
Agenda.bindOne(item.id, $scope, 'item');
|
||||||
User.bindAll({}, $scope, 'users');
|
User.bindAll({}, $scope, 'users');
|
||||||
$scope.speaker = {};
|
$scope.speakerSelectBox = {};
|
||||||
$scope.alert = {};
|
$scope.alert = {};
|
||||||
$scope.speakers = $filter('orderBy')(item.speakers, 'weight');
|
$scope.speakers = $filter('orderBy')(item.speakers, 'weight');
|
||||||
$scope.$watch(function () {
|
$scope.$watch(function () {
|
||||||
@ -208,9 +208,11 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
|
|||||||
.success(function(data){
|
.success(function(data){
|
||||||
$scope.alert.show = false;
|
$scope.alert.show = false;
|
||||||
$scope.speakers = item.speakers;
|
$scope.speakers = item.speakers;
|
||||||
|
$scope.speakerSelectBox = {};
|
||||||
})
|
})
|
||||||
.error(function(data){
|
.error(function(data){
|
||||||
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
||||||
|
$scope.speakerSelectBox = {};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// delete speaker(!) from list of speakers
|
// delete speaker(!) from list of speakers
|
||||||
|
@ -89,7 +89,7 @@
|
|||||||
{{alert.msg}}
|
{{alert.msg}}
|
||||||
</alert>
|
</alert>
|
||||||
<div os-perms="agenda.can_manage" class="input-group">
|
<div os-perms="agenda.can_manage" class="input-group">
|
||||||
<ui-select ng-model="speaker.selected" ng-change="addSpeaker(speaker.selected.id)">
|
<ui-select ng-model="speakerSelectBox.selected" ng-change="addSpeaker(speakerSelectBox.selected.id)">
|
||||||
<ui-select-match placeholder="{{ 'Select or search a participant ...' | translate }}">
|
<ui-select-match placeholder="{{ 'Select or search a participant ...' | translate }}">
|
||||||
{{ $select.selected.get_full_name() }}
|
{{ $select.selected.get_full_name() }}
|
||||||
</ui-select-match>
|
</ui-select-match>
|
||||||
@ -98,7 +98,7 @@
|
|||||||
</ui-select-choices>
|
</ui-select-choices>
|
||||||
</ui-select>
|
</ui-select>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<a ng-click="speaker={}" class="btn btn-default">
|
<a ng-click="speakerSelectBox={}" class="btn btn-default">
|
||||||
<i class="fa fa-times-circle"></i>
|
<i class="fa fa-times-circle"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
@ -7,6 +7,7 @@ from openslides.utils.rest_api import (
|
|||||||
ListField,
|
ListField,
|
||||||
ListSerializer,
|
ListSerializer,
|
||||||
ModelSerializer,
|
ModelSerializer,
|
||||||
|
SerializerMethodField,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,10 +48,17 @@ class AssignmentOptionSerializer(ModelSerializer):
|
|||||||
Serializer for assignment.models.AssignmentOption objects.
|
Serializer for assignment.models.AssignmentOption objects.
|
||||||
"""
|
"""
|
||||||
votes = AssignmentVoteSerializer(many=True, read_only=True)
|
votes = AssignmentVoteSerializer(many=True, read_only=True)
|
||||||
|
is_elected = SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AssignmentOption
|
model = AssignmentOption
|
||||||
fields = ('id', 'candidate', 'votes', 'poll')
|
fields = ('id', 'candidate', 'is_elected', 'votes', 'poll')
|
||||||
|
|
||||||
|
def get_is_elected(self, obj):
|
||||||
|
"""
|
||||||
|
Returns the election status of the candidate of this option.
|
||||||
|
"""
|
||||||
|
return obj.poll.assignment.is_elected(obj.candidate)
|
||||||
|
|
||||||
|
|
||||||
class FilterPollListSerializer(ListSerializer):
|
class FilterPollListSerializer(ListSerializer):
|
||||||
@ -81,6 +89,7 @@ class AssignmentAllPollSerializer(ModelSerializer):
|
|||||||
child=IntegerField(min_value=-2)),
|
child=IntegerField(min_value=-2)),
|
||||||
write_only=True,
|
write_only=True,
|
||||||
required=False)
|
required=False)
|
||||||
|
has_votes = SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AssignmentPoll
|
model = AssignmentPoll
|
||||||
@ -94,9 +103,16 @@ class AssignmentAllPollSerializer(ModelSerializer):
|
|||||||
'votesinvalid',
|
'votesinvalid',
|
||||||
'votescast',
|
'votescast',
|
||||||
'votes',
|
'votes',
|
||||||
|
'has_votes',
|
||||||
'assignment') # js-data needs the assignment-id in the nested object to define relations.
|
'assignment') # js-data needs the assignment-id in the nested object to define relations.
|
||||||
read_only_fields = ('yesnoabstain',)
|
read_only_fields = ('yesnoabstain',)
|
||||||
|
|
||||||
|
def get_has_votes(self, obj):
|
||||||
|
"""
|
||||||
|
Returns True if this poll has some votes.
|
||||||
|
"""
|
||||||
|
return obj.has_votes()
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
"""
|
"""
|
||||||
@ -142,7 +158,7 @@ class AssignmentShortPollSerializer(AssignmentAllPollSerializer):
|
|||||||
"""
|
"""
|
||||||
Serializer for assignment.models.AssignmentPoll objects.
|
Serializer for assignment.models.AssignmentPoll objects.
|
||||||
|
|
||||||
Serializes only short polls.
|
Serializes only short polls (excluded unpublished polls).
|
||||||
"""
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
list_serializer_class = FilterPollListSerializer
|
list_serializer_class = FilterPollListSerializer
|
||||||
|
@ -245,16 +245,18 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
User.bindAll({}, $scope, 'users');
|
User.bindAll({}, $scope, 'users');
|
||||||
Assignment.bindOne(assignment.id, $scope, 'assignment');
|
Assignment.bindOne(assignment.id, $scope, 'assignment');
|
||||||
Assignment.loadRelations(assignment, 'agenda_item');
|
Assignment.loadRelations(assignment, 'agenda_item');
|
||||||
$scope.candidate = {};
|
$scope.candidateSelectBox = {};
|
||||||
$scope.alert = {};
|
$scope.alert = {};
|
||||||
// add (nominate) candidate
|
// add (nominate) candidate
|
||||||
$scope.addCandidate = function (userId) {
|
$scope.addCandidate = function (userId) {
|
||||||
$http.post('/rest/assignments/assignment/' + assignment.id + '/candidature_other/', {'user': userId})
|
$http.post('/rest/assignments/assignment/' + assignment.id + '/candidature_other/', {'user': userId})
|
||||||
.success(function(data){
|
.success(function(data){
|
||||||
$scope.alert.show = false;
|
$scope.alert.show = false;
|
||||||
|
$scope.candidateSelectBox = {};
|
||||||
})
|
})
|
||||||
.error(function(data){
|
.error(function(data){
|
||||||
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
||||||
|
$scope.candidateSelectBox = {};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// remove candidate
|
// remove candidate
|
||||||
@ -266,15 +268,6 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// remove blocked candidate from "block-list"
|
|
||||||
$scope.removeBlockedCandidate = function (userId) {
|
|
||||||
$http.delete('/rest/assignments/assignment/' + assignment.id + '/candidature_other/',
|
|
||||||
{headers: {'Content-Type': 'application/json'},
|
|
||||||
data: JSON.stringify({user: userId})})
|
|
||||||
.error(function(data){
|
|
||||||
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// add me (nominate self as candidate)
|
// add me (nominate self as candidate)
|
||||||
$scope.addMe = function () {
|
$scope.addMe = function () {
|
||||||
$http.post('/rest/assignments/assignment/' + assignment.id + '/candidature_self/', {})
|
$http.post('/rest/assignments/assignment/' + assignment.id + '/candidature_self/', {})
|
||||||
@ -316,7 +309,7 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// delete ballt
|
// delete ballot
|
||||||
$scope.deleteBallot = function (poll) {
|
$scope.deleteBallot = function (poll) {
|
||||||
poll.DSDestroy();
|
poll.DSDestroy();
|
||||||
}
|
}
|
||||||
@ -353,6 +346,18 @@ angular.module('OpenSlidesApp.assignments.site', ['OpenSlidesApp.assignments'])
|
|||||||
$scope.alert = { type: 'danger', msg: message, show: true };
|
$scope.alert = { type: 'danger', msg: message, show: true };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// mark candidate as (not) elected
|
||||||
|
$scope.markElected = function (user, reverse) {
|
||||||
|
if (reverse) {
|
||||||
|
$http.delete(
|
||||||
|
'/rest/assignments/assignment/' + assignment.id + '/mark_elected/',
|
||||||
|
{headers: {'Content-Type': 'application/json'},
|
||||||
|
data: JSON.stringify({user: user})})
|
||||||
|
} else {
|
||||||
|
$http.post('/rest/assignments/assignment/' + assignment.id + '/mark_elected/', {'user': user})
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Just mark some vote value strings for translation.
|
// Just mark some vote value strings for translation.
|
||||||
gettext('Yes'), gettext('No'), gettext('Abstain');
|
gettext('Yes'), gettext('No'), gettext('Abstain');
|
||||||
|
@ -42,8 +42,9 @@
|
|||||||
|
|
||||||
<h3 translate>Candidates</h3>
|
<h3 translate>Candidates</h3>
|
||||||
<ol>
|
<ol>
|
||||||
<li ng-repeat="related_user in assignment.assignment_related_users" ng-if="related_user.status == 1">
|
<li ng-repeat="related_user in assignment.assignment_related_users">
|
||||||
<a ui-sref="users.user.detail({id: related_user.user_id})">{{ related_user.user.get_full_name() }}</a>
|
<a ui-sref="users.user.detail({id: related_user.user_id})">{{ related_user.user.get_full_name() }}</a>
|
||||||
|
<i ng-if="related_user.elected" class="fa fa-star" title="{{ 'is elected' | translate }}"></i>
|
||||||
<button os-perms="assignments.can_manage" ng-click="removeCandidate(related_user.user_id)"
|
<button os-perms="assignments.can_manage" ng-click="removeCandidate(related_user.user_id)"
|
||||||
class="btn btn-default btn-xs">
|
class="btn btn-default btn-xs">
|
||||||
<i class="fa fa-times"></i>
|
<i class="fa fa-times"></i>
|
||||||
@ -55,7 +56,7 @@
|
|||||||
{{alert.msg}}
|
{{alert.msg}}
|
||||||
</alert>
|
</alert>
|
||||||
<div os-perms="assignments.can_nominate_other" class="input-group">
|
<div os-perms="assignments.can_nominate_other" class="input-group">
|
||||||
<ui-select ng-model="candidate.selected" ng-change="addCandidate(candidate.selected.id)">
|
<ui-select ng-model="candidateSelectBox.selected" ng-change="addCandidate(candidateSelectBox.selected.id)">
|
||||||
<ui-select-match placeholder="{{ 'Select or search a participant ...' | translate }}">
|
<ui-select-match placeholder="{{ 'Select or search a participant ...' | translate }}">
|
||||||
{{ $select.selected.get_full_name() }}
|
{{ $select.selected.get_full_name() }}
|
||||||
</ui-select-match>
|
</ui-select-match>
|
||||||
@ -64,7 +65,7 @@
|
|||||||
</ui-select-choices>
|
</ui-select-choices>
|
||||||
</ui-select>
|
</ui-select>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<a ng-click="candidate={}" class="btn btn-default">
|
<a ng-click="candidateSelectBox={}" class="btn btn-default">
|
||||||
<i class="fa fa-times-circle"></i>
|
<i class="fa fa-times-circle"></i>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
@ -89,21 +90,24 @@
|
|||||||
<uib-tabset class="spacer">
|
<uib-tabset class="spacer">
|
||||||
<uib-tab ng-repeat="poll in assignment.polls" heading="Ballot {{$index+1}}">
|
<uib-tab ng-repeat="poll in assignment.polls" heading="Ballot {{$index+1}}">
|
||||||
<div os-perms="assignments.can_manage" class="spacer">
|
<div os-perms="assignments.can_manage" class="spacer">
|
||||||
<button ng-click="editPollDialog(poll, $index+1)"
|
|
||||||
class="btn btn-default btn-sm">
|
|
||||||
<i class="fa fa-pencil"></i>
|
|
||||||
<translate>Edit</translate>
|
|
||||||
</button>
|
|
||||||
<!-- angular requires to open the link in new tab with "target='_blank'".
|
<!-- angular requires to open the link in new tab with "target='_blank'".
|
||||||
Otherwise the pdf url can't be open in same window; angular redirects to "/". -->
|
Otherwise the pdf url can't be open in same window; angular redirects to "/". -->
|
||||||
<a ui-sref="assignmentpoll_pdf({poll_pk: poll.id})" target="_blank"
|
<a ui-sref="assignmentpoll_pdf({poll_pk: poll.id})" target="_blank"
|
||||||
class="btn btn-default btn-sm">
|
class="btn btn-default btn-sm">
|
||||||
<i class="fa fa-file-pdf-o"></i> Ballot paper
|
<i class="fa fa-file-pdf-o"></i>
|
||||||
|
1. <translate>Print ballot paper</translate>
|
||||||
</a>
|
</a>
|
||||||
|
<i class="fa fa-arrow-right"></i>
|
||||||
|
<button ng-click="editPollDialog(poll, $index+1)"
|
||||||
|
class="btn btn-default btn-sm">
|
||||||
|
<i class="fa fa-pencil"></i>
|
||||||
|
2. <translate>Enter votes</translate>
|
||||||
|
</button>
|
||||||
|
<i class="fa fa-arrow-right"></i>
|
||||||
<button os-perms-lite="assignments.can_manage" ng-if="!poll.published" ng-click="publishBallot(poll, true)"
|
<button os-perms-lite="assignments.can_manage" ng-if="!poll.published" ng-click="publishBallot(poll, true)"
|
||||||
class="btn btn-default btn-sm">
|
class="btn btn-default btn-sm">
|
||||||
<i class="fa fa-toggle-off"></i>
|
<i class="fa fa-toggle-off"></i>
|
||||||
<translate>Not published</translate>
|
3. <translate>Publish ballot</translate>
|
||||||
</button>
|
</button>
|
||||||
<button os-perms-lite="assignments.can_manage" ng-if="poll.published" ng-click="publishBallot(poll, false)"
|
<button os-perms-lite="assignments.can_manage" ng-if="poll.published" ng-click="publishBallot(poll, false)"
|
||||||
class="btn btn-default btn-sm">
|
class="btn btn-default btn-sm">
|
||||||
@ -115,23 +119,49 @@
|
|||||||
<translate>Delete</translate>
|
<translate>Delete</translate>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="results">
|
<div class="results spacer">
|
||||||
<div ng-repeat="option in poll.options">
|
<table class="table table-bordered table-striped minimumTable">
|
||||||
<div ng-if="poll.yesnoabstain && option.votes.length > 0">
|
<tr>
|
||||||
<strong>{{ option.candidate.get_full_name() }}</strong><br>
|
<th translate>Elected
|
||||||
{{ option.votes[0].value | translate }}: {{ option.votes[0].weight }}<br>
|
<th translate>Candidates
|
||||||
{{ option.votes[1].value | translate }}: {{ option.votes[1].weight }}<br>
|
<th ng-if="poll.has_votes" translate>Votes
|
||||||
{{ option.votes[2].value | translate }}: {{ option.votes[2].weight }}
|
<tr ng-repeat="option in poll.options">
|
||||||
<hr class="smallhr">
|
<td class="minimum">
|
||||||
</div>
|
<button os-perms="assignments.can_manage"
|
||||||
<div ng-if="!poll.yesnoabstain && option.votes.length > 0">
|
ng-click="markElected(option.candidate_id, option.is_elected)" class="btn btn-default btn-xs">
|
||||||
{{ option.candidate.get_full_name() }}: {{ option.votes[0].weight}}
|
<i ng-if="option.is_elected" class="fa fa-star" title="{{ 'is elected' | translate }}"></i>
|
||||||
<hr class="smallhr">
|
<i ng-if="!option.is_elected" class="fa fa-star-o" title="{{ 'is not elected' | translate }}"></i>
|
||||||
</div>
|
</button>
|
||||||
</div>
|
<td>
|
||||||
Valid votes: {{ poll.votesvalid }}<br>
|
<a ui-sref="users.user.detail({id: option.candidate.id})">{{ option.candidate.get_full_name() }}</a>
|
||||||
Invalid votes: {{ poll.votesinvalid }}<br>
|
<td ng-if="poll.has_votes">
|
||||||
Votes cast: {{ poll.votescast }}
|
<span ng-if="poll.yesnoabstain && option.votes.length > 0">
|
||||||
|
{{ option.votes[0].value | translate }}: {{ option.votes[0].weight }}<br>
|
||||||
|
{{ option.votes[1].value | translate }}: {{ option.votes[1].weight }}<br>
|
||||||
|
{{ option.votes[2].value | translate }}: {{ option.votes[2].weight }}
|
||||||
|
</span>
|
||||||
|
<span ng-if="!poll.yesnoabstain && option.votes.length > 0">
|
||||||
|
{{ option.votes[0].weight}}
|
||||||
|
</span>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<td>
|
||||||
|
<translate>Valid votes</translate>
|
||||||
|
<td ng-if="poll.has_votes">
|
||||||
|
{{ poll.votesvalid }}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<td>
|
||||||
|
<translate>Invalid votes</translate>
|
||||||
|
<td ng-if="poll.has_votes">
|
||||||
|
{{ poll.votesinvalid }}
|
||||||
|
<tr class="total bg-info">
|
||||||
|
<td>
|
||||||
|
<td>
|
||||||
|
<translate>Votes cast</translate>
|
||||||
|
<td ng-if="poll.has_votes">
|
||||||
|
{{ poll.votescast }}
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</uib-tab>
|
</uib-tab>
|
||||||
</uib-tabset>
|
</uib-tabset>
|
||||||
|
@ -146,8 +146,6 @@ class AssignmentViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
user = self.get_user_from_request_data(request)
|
user = self.get_user_from_request_data(request)
|
||||||
assignment = self.get_object()
|
assignment = self.get_object()
|
||||||
if assignment.is_elected(user):
|
|
||||||
raise ValidationError({'detail': _('User %s is already elected.') % user})
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
message = self.nominate_other(request, user, assignment)
|
message = self.nominate_other(request, user, assignment)
|
||||||
else:
|
else:
|
||||||
@ -156,15 +154,14 @@ class AssignmentViewSet(ModelViewSet):
|
|||||||
return Response({'detail': message})
|
return Response({'detail': message})
|
||||||
|
|
||||||
def nominate_other(self, request, user, assignment):
|
def nominate_other(self, request, user, assignment):
|
||||||
|
if assignment.is_elected(user):
|
||||||
|
raise ValidationError({'detail': _('User %s is already elected.') % user})
|
||||||
if assignment.phase == assignment.PHASE_FINISHED:
|
if assignment.phase == assignment.PHASE_FINISHED:
|
||||||
detail = _('You can not nominate someone to this election because it is finished.')
|
detail = _('You can not nominate someone to this election because it is finished.')
|
||||||
raise ValidationError({'detail': detail})
|
raise ValidationError({'detail': detail})
|
||||||
if assignment.phase == assignment.PHASE_VOTING and not request.user.has_perm('assignments.can_manage'):
|
if assignment.phase == assignment.PHASE_VOTING and not request.user.has_perm('assignments.can_manage'):
|
||||||
# To nominate another user during voting you have to be a manager.
|
# To nominate another user during voting you have to be a manager.
|
||||||
self.permission_denied(request)
|
self.permission_denied(request)
|
||||||
if not request.user.has_perm('assignments.can_manage'):
|
|
||||||
if assignment.is_elected(user):
|
|
||||||
raise ValidationError({'detail': _('User %s is already elected.') % user})
|
|
||||||
if assignment.is_candidate(user):
|
if assignment.is_candidate(user):
|
||||||
raise ValidationError({'detail': _('User %s is already nominated.') % user})
|
raise ValidationError({'detail': _('User %s is already nominated.') % user})
|
||||||
assignment.set_candidate(user)
|
assignment.set_candidate(user)
|
||||||
@ -177,7 +174,7 @@ class AssignmentViewSet(ModelViewSet):
|
|||||||
if assignment.phase == assignment.PHASE_FINISHED:
|
if assignment.phase == assignment.PHASE_FINISHED:
|
||||||
detail = _('You can not delete someones candidature to this election because it is finished.')
|
detail = _('You can not delete someones candidature to this election because it is finished.')
|
||||||
raise ValidationError({'detail': detail})
|
raise ValidationError({'detail': detail})
|
||||||
if not assignment.is_candidate(user):
|
if not assignment.is_candidate(user) and not assignment.is_elected(user):
|
||||||
raise ValidationError({'detail': _('User %s has no status in this election.') % user})
|
raise ValidationError({'detail': _('User %s has no status in this election.') % user})
|
||||||
assignment.delete_related_user(user)
|
assignment.delete_related_user(user)
|
||||||
return _('Candidate %s was withdrawn successfully.') % user
|
return _('Candidate %s was withdrawn successfully.') % user
|
||||||
|
@ -659,6 +659,9 @@ img {
|
|||||||
.result_label {
|
.result_label {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
tr.total td {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
/* Chatbox */
|
/* Chatbox */
|
||||||
#chatbox {
|
#chatbox {
|
||||||
@ -685,6 +688,10 @@ img {
|
|||||||
width: 1px;
|
width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.minimumTable {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.deleteColumn {
|
.deleteColumn {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #ff9999 !important;
|
background-color: #ff9999 !important;
|
||||||
|
Loading…
Reference in New Issue
Block a user