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) {
|
.factory('Motion', function(DS) {
|
||||||
return DS.defineResource({
|
return DS.defineResource({
|
||||||
name: 'motions/motion',
|
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) {
|
.factory('Category', function(DS) {
|
||||||
@ -39,6 +61,12 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
|||||||
resolve: {
|
resolve: {
|
||||||
motions: function(Motion) {
|
motions: function(Motion) {
|
||||||
return Motion.findAll();
|
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: {
|
resolve: {
|
||||||
motion: function(Motion, $stateParams) {
|
motion: function(Motion, $stateParams) {
|
||||||
return Motion.find($stateParams.id);
|
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');
|
Motion.bindAll({}, $scope, 'motions');
|
||||||
|
Category.bindAll({}, $scope, 'categories');
|
||||||
|
User.bindAll({}, $scope, 'users');
|
||||||
|
|
||||||
// setup table sorting
|
// setup table sorting
|
||||||
$scope.sortColumn = 'identifier';
|
$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');
|
Motion.bindOne(motion.id, $scope, 'motion');
|
||||||
|
Category.bindAll({}, $scope, 'categories');
|
||||||
|
User.bindAll({}, $scope, 'users');
|
||||||
})
|
})
|
||||||
|
|
||||||
.controller('MotionCreateCtrl',
|
.controller('MotionCreateCtrl',
|
||||||
@ -174,6 +212,9 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
|||||||
$scope.save = function (motion) {
|
$scope.save = function (motion) {
|
||||||
motion.tags = []; // TODO: REST API should do it! (Bug in Django REST framework)
|
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)
|
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(
|
Motion.create(motion).then(
|
||||||
function(success) {
|
function(success) {
|
||||||
$state.go('motions.motion.list');
|
$state.go('motions.motion.list');
|
||||||
@ -192,6 +233,11 @@ angular.module('OpenSlidesApp.motions.site', ['OpenSlidesApp.motions'])
|
|||||||
Mediafile.bindAll({}, $scope, 'mediafiles');
|
Mediafile.bindAll({}, $scope, 'mediafiles');
|
||||||
|
|
||||||
$scope.motion = motion;
|
$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) {
|
$scope.save = function (motion) {
|
||||||
motion.tags = []; // TODO: REST API should do it! (Bug in Django REST framework)
|
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)
|
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">
|
<div id="submenu">
|
||||||
<a ui-sref="motions.motion.list" class="btn btn-sm btn-default">
|
<a ui-sref="motions.motion.list" class="btn btn-sm btn-default">
|
||||||
@ -14,16 +20,34 @@
|
|||||||
<i class="fa fa-video-camera"></i>
|
<i class="fa fa-video-camera"></i>
|
||||||
</a>
|
</a>
|
||||||
<!-- edit -->
|
<!-- 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"
|
class="btn btn-default btn-sm"
|
||||||
title="{{ 'Edit' | translate}}">
|
title="{{ 'Edit' | translate}}">
|
||||||
<i class="fa fa-pencil"></i>
|
<i class="fa fa-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<h3 translate>Text</h3>
|
||||||
|
{{ motion.getText() }}
|
||||||
|
|
||||||
<h3 translate>Category</h3>
|
<h3 translate>Reason</h3>
|
||||||
{{ motion.category }}
|
{{ motion.getReason() }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3 translate>Submitters</h3>
|
<div class="col-sm-4">
|
||||||
<!-- TODO -->
|
<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>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="selectSubmitter" translate>Submitter</label>
|
<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 }}">
|
<ui-select-match placeholder="{{ 'Select or search a participant...' | translate }}">
|
||||||
{{ $select.selected.get_short_name() }}
|
{{ $select.selected.get_short_name() }}
|
||||||
</ui-select-match>
|
</ui-select-match>
|
||||||
@ -29,15 +33,15 @@
|
|||||||
<div ng-bind-html="user.get_short_name() | highlight: $select.search"></div>
|
<div ng-bind-html="user.get_short_name() | highlight: $select.search"></div>
|
||||||
<small ng-bind-html="user.structure_level | highlight: $select.search"></small>
|
<small ng-bind-html="user.structure_level | highlight: $select.search"></small>
|
||||||
</ui-select-choices>
|
</ui-select-choices>
|
||||||
</ui-select>
|
</ui-select>-->
|
||||||
</div>
|
</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>
|
<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>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="textText" translate>Text</label>
|
<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>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="textReason" translate>Reason</label>
|
<label for="textReason" translate>Reason</label>
|
||||||
|
@ -32,11 +32,27 @@
|
|||||||
<table class="table table-striped table-bordered table-hover">
|
<table class="table table-striped table-bordered table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<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>
|
<translate>Identifier</translate>
|
||||||
<i class="pull-right fa" ng-show="sortColumn === 'identifier' && header.sortable != false"
|
<i class="pull-right fa" ng-show="sortColumn === 'identifier' && header.sortable != false"
|
||||||
ng-class="reverse ? 'fa-sort-desc' : 'fa-sort-asc'">
|
ng-class="reverse ? 'fa-sort-desc' : 'fa-sort-asc'">
|
||||||
</i>
|
</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">
|
<th ng-click="toggleSort('category')" class="sortable">
|
||||||
<translate>Category</translate>
|
<translate>Category</translate>
|
||||||
<i class="pull-right fa" ng-show="sortColumn === 'category' && header.sortable != false"
|
<i class="pull-right fa" ng-show="sortColumn === 'category' && header.sortable != false"
|
||||||
@ -47,8 +63,17 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="motion in motions | filter: filter.search |
|
<tr ng-repeat="motion in motions | filter: filter.search |
|
||||||
orderBy: sortColumn:reverse">
|
orderBy: sortColumn:reverse">
|
||||||
|
<td> <!--TOOD: add agenda item reference -->
|
||||||
<td><a ui-sref="motions.motion.detail({id: motion.id})">{{ motion.identifier }}</a>
|
<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">
|
<td os-perms="motions.can_manage core.can_manage_projector" class="nobr">
|
||||||
<!-- projector, TODO: add link to activate slide -->
|
<!-- projector, TODO: add link to activate slide -->
|
||||||
<a href="#TODO" os-perms="core.can_manage_projector" class="btn btn-default btn-sm"
|
<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;
|
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() {
|
getPerms: function() {
|
||||||
var allPerms = [];
|
var allPerms = [];
|
||||||
_.forEach(this.groups, function(groupId) {
|
_.forEach(this.groups, function(groupId) {
|
||||||
|
Loading…
Reference in New Issue
Block a user