Merge pull request #1557 from emanuelschuetze/angular-motions
Updated motion list, form and detail views.
This commit is contained in:
commit
2d6cdfa168
@ -3,7 +3,29 @@ angular.module('OpenSlidesApp.motions', [])
|
||||
.factory('Motion', function(DS) {
|
||||
return DS.defineResource({
|
||||
name: 'motions/motion',
|
||||
endpoint: '/rest/motions/motion/'
|
||||
endpoint: '/rest/motions/motion/',
|
||||
methods: {
|
||||
getVersion: function(versionId) {
|
||||
versionId = versionId || this.active_version;
|
||||
if (versionId == -1) {
|
||||
index = this.versions.length - 1;
|
||||
} else {
|
||||
index = _.findIndex(this.versions, function(element) {
|
||||
return element.id == versionId
|
||||
});
|
||||
}
|
||||
return this.versions[index];
|
||||
},
|
||||
getTitle: function(versionId) {
|
||||
return this.getVersion(versionId).title;
|
||||
},
|
||||
getText: function(versionId) {
|
||||
return this.getVersion(versionId).text;
|
||||
},
|
||||
getReason: function(versionId) {
|
||||
return this.getVersion(versionId).reason;
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.factory('Category', function(DS) {
|
||||
@ -39,6 +61,12 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
||||
resolve: {
|
||||
motions: function(Motion) {
|
||||
return Motion.findAll();
|
||||
},
|
||||
categories: function(Category) {
|
||||
return Category.findAll();
|
||||
},
|
||||
users: function(User) {
|
||||
return User.findAll();
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -68,6 +96,12 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
||||
resolve: {
|
||||
motion: function(Motion, $stateParams) {
|
||||
return Motion.find($stateParams.id);
|
||||
},
|
||||
categories: function(Category) {
|
||||
return Category.findAll();
|
||||
},
|
||||
users: function(User) {
|
||||
return User.findAll();
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -128,8 +162,10 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
||||
})
|
||||
})
|
||||
|
||||
.controller('MotionListCtrl', function($scope, Motion) {
|
||||
.controller('MotionListCtrl', function($scope, Motion, Category, User) {
|
||||
Motion.bindAll({}, $scope, 'motions');
|
||||
Category.bindAll({}, $scope, 'categories');
|
||||
User.bindAll({}, $scope, 'users');
|
||||
|
||||
// setup table sorting
|
||||
$scope.sortColumn = 'identifier';
|
||||
@ -157,8 +193,10 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
||||
};
|
||||
})
|
||||
|
||||
.controller('MotionDetailCtrl', function($scope, Motion, motion) {
|
||||
.controller('MotionDetailCtrl', function($scope, Motion, Category, User, motion) {
|
||||
Motion.bindOne(motion.id, $scope, 'motion');
|
||||
Category.bindAll({}, $scope, 'categories');
|
||||
User.bindAll({}, $scope, 'users');
|
||||
})
|
||||
|
||||
.controller('MotionCreateCtrl',
|
||||
@ -174,6 +212,9 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
||||
$scope.save = function (motion) {
|
||||
motion.tags = []; // TODO: REST API should do it! (Bug in Django REST framework)
|
||||
motion.attachments = []; // TODO: REST API should do it! (Bug in Django REST framework)
|
||||
if (!motion.supporters) {
|
||||
motion.supporters = []; // TODO: REST API should do it! (Bug in Django REST framework)
|
||||
}
|
||||
Motion.create(motion).then(
|
||||
function(success) {
|
||||
$state.go('motions.motion.list');
|
||||
@ -192,6 +233,11 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
||||
Mediafile.bindAll({}, $scope, 'mediafiles');
|
||||
|
||||
$scope.motion = motion;
|
||||
// get latest version for edit
|
||||
$scope.motion.title = $scope.motion.getTitle(-1);
|
||||
$scope.motion.text = $scope.motion.getText(-1);
|
||||
$scope.motion.reason = $scope.motion.getReason(-1);
|
||||
|
||||
$scope.save = function (motion) {
|
||||
motion.tags = []; // TODO: REST API should do it! (Bug in Django REST framework)
|
||||
motion.attachments = []; // TODO: REST API should do it! (Bug in Django REST framework)
|
||||
|
@ -1,4 +1,10 @@
|
||||
<h1>{{ motion.identifier }}</h1>
|
||||
<h1>
|
||||
{{ motion.getTitle() }}
|
||||
<small>
|
||||
<translate>Motion</translate> {{ motion.identifier }}
|
||||
<span ng-if="motion.versions.length > 1" >| Version {{ (motion.versions | filter: {id: motion.active_version})[0].version_number }}</span>
|
||||
</small>
|
||||
</h1>
|
||||
|
||||
<div id="submenu">
|
||||
<a ui-sref="motions.motion.list" class="btn btn-sm btn-default">
|
||||
@ -14,16 +20,34 @@
|
||||
<i class="fa fa-video-camera"></i>
|
||||
</a>
|
||||
<!-- edit -->
|
||||
<a ui-sref="motion.detail.update({id: motion.id })" os-perms="motions.can_manage"
|
||||
<a ui-sref="motions.motion.detail.update({id: motion.id })" os-perms="motions.can_manage"
|
||||
class="btn btn-default btn-sm"
|
||||
title="{{ 'Edit' | translate}}">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<h3 translate>Text</h3>
|
||||
{{ motion.getText() }}
|
||||
|
||||
<h3 translate>Category</h3>
|
||||
{{ motion.category }}
|
||||
<h3 translate>Reason</h3>
|
||||
{{ motion.getReason() }}
|
||||
</div>
|
||||
|
||||
<h3 translate>Submitters</h3>
|
||||
<!-- TODO -->
|
||||
<div class="col-sm-4">
|
||||
<div class="well">
|
||||
<h3 translate>Submitters</h3>
|
||||
<div ng-repeat="submitter in motion.submitters">
|
||||
{{ (users | filter: {id: submitter})[0].get_full_name() }}<br>
|
||||
</div>
|
||||
|
||||
<h3 translate>Category</h3>
|
||||
{{ (categories | filter: {id: motion.category})[0].name }}</a>
|
||||
|
||||
<h3 translate>Voting result</h3>
|
||||
-
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -21,7 +21,11 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="selectSubmitter" translate>Submitter</label>
|
||||
<ui-select ng-model="motion.submitter" theme="bootstrap" name="selectSubmitter">
|
||||
<select multiple size="3" ng-options="user.id as user.get_short_name() for user in users"
|
||||
ng-model="motion.submitters" class="form-control" name="selectSubmitter" required>
|
||||
</select>
|
||||
<!-- TODO: use modern ui-select component with more information per user
|
||||
<ui-select multipe ng-model="motion.submitter" theme="bootstrap" name="selectSubmitter">
|
||||
<ui-select-match placeholder="{{ 'Select or search a participant...' | translate }}">
|
||||
{{ $select.selected.get_short_name() }}
|
||||
</ui-select-match>
|
||||
@ -29,15 +33,15 @@
|
||||
<div ng-bind-html="user.get_short_name() | highlight: $select.search"></div>
|
||||
<small ng-bind-html="user.structure_level | highlight: $select.search"></small>
|
||||
</ui-select-choices>
|
||||
</ui-select>
|
||||
</ui-select>-->
|
||||
</div>
|
||||
<div class="form-group" ng-class="{'has-error has-feedback': motionForm.inputTitle.$error.required}">
|
||||
<div class="form-group">
|
||||
<label for="inputName" translate>Title</label>
|
||||
<input type="text" ng-model="motion.title" class="form-control" name="inputTitle" ng-required="true">
|
||||
<input type="text" ng-model="motion.title" class="form-control" name="inputTitle" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="textText" translate>Text</label>
|
||||
<textarea ng-model="motion.text" class="form-control" name="textText" />
|
||||
<textarea ng-model="motion.text" class="form-control" name="textText" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="textReason" translate>Reason</label>
|
||||
|
@ -32,11 +32,27 @@
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th ng-click="toggleSort('identifier')" class="sortable">
|
||||
<!-- TODO: Add motion.agenda_item to rest api -->
|
||||
<th ng-click="toggleSort('agenda_item')" class="sortable minimum">
|
||||
<translate>Agenda item</translate>
|
||||
<i class="pull-right fa" ng-show="sortColumn === 'agenda_item' && header.sortable != false"
|
||||
ng-class="reverse ? 'fa-sort-desc' : 'fa-sort-asc'">
|
||||
</i>
|
||||
<th ng-click="toggleSort('identifier')" class="sortable minimum">
|
||||
<translate>Identifier</translate>
|
||||
<i class="pull-right fa" ng-show="sortColumn === 'identifier' && header.sortable != false"
|
||||
ng-class="reverse ? 'fa-sort-desc' : 'fa-sort-asc'">
|
||||
</i>
|
||||
<th ng-click="toggleSort('title')" class="sortable">
|
||||
<translate>Title</translate>
|
||||
<i class="pull-right fa" ng-show="sortColumn === 'title' && header.sortable != false"
|
||||
ng-class="reverse ? 'fa-sort-desc' : 'fa-sort-asc'">
|
||||
</i>
|
||||
<th ng-click="toggleSort('submitters')" class="sortable">
|
||||
<translate>Submitters</translate>
|
||||
<i class="pull-right fa" ng-show="sortColumn === 'submitters' && header.sortable != false"
|
||||
ng-class="reverse ? 'fa-sort-desc' : 'fa-sort-asc'">
|
||||
</i>
|
||||
<th ng-click="toggleSort('category')" class="sortable">
|
||||
<translate>Category</translate>
|
||||
<i class="pull-right fa" ng-show="sortColumn === 'category' && header.sortable != false"
|
||||
@ -47,8 +63,17 @@
|
||||
<tbody>
|
||||
<tr ng-repeat="motion in motions | filter: filter.search |
|
||||
orderBy: sortColumn:reverse">
|
||||
<td> <!--TOOD: add agenda item reference -->
|
||||
<td><a ui-sref="motions.motion.detail({id: motion.id})">{{ motion.identifier }}</a>
|
||||
<td class="optional">{{ motion.category }}
|
||||
<td><a ui-sref="motions.motion.detail({id: motion.id})">
|
||||
<!-- TODO: make it easier to get active version -->
|
||||
{{ (motion.versions | filter: {id: motion.active_version})[0].title }}</a>
|
||||
<td class="optional">
|
||||
<div ng-repeat="submitter in motion.submitters">
|
||||
{{ (users | filter: {id: submitter})[0].get_full_name() }}<br>
|
||||
</div>
|
||||
<td class="optional">
|
||||
{{ (categories | filter: {id: motion.category})[0].name }}</a>
|
||||
<td os-perms="motions.can_manage core.can_manage_projector" class="nobr">
|
||||
<!-- projector, TODO: add link to activate slide -->
|
||||
<a href="#TODO" os-perms="core.can_manage_projector" class="btn btn-default btn-sm"
|
||||
|
@ -19,6 +19,24 @@ angular.module('OpenSlidesApp.users', [])
|
||||
}
|
||||
return name;
|
||||
},
|
||||
get_full_name: function() {
|
||||
// should be the same as in the python user model.
|
||||
var firstName = _.trim(this.first_name),
|
||||
lastName = _.trim(this.last_name),
|
||||
structure_level = _.trim(this.structure_level),
|
||||
name;
|
||||
|
||||
if (firstName && lastName) {
|
||||
// TODO: check config
|
||||
name = [firstName, lastName].join(' ');
|
||||
} else {
|
||||
name = firstName || lastName || this.username;
|
||||
}
|
||||
if (structure_level) {
|
||||
name = name + " (" + structure_level + ")";
|
||||
}
|
||||
return name;
|
||||
},
|
||||
getPerms: function() {
|
||||
var allPerms = [];
|
||||
_.forEach(this.groups, function(groupId) {
|
||||
|
Loading…
Reference in New Issue
Block a user