Add Pagination and improve import.

- Use Pagination for users and item list and users import table.
- Improve agenda import: Allow to define agenda item stuff like
  duration, comment, type.
This commit is contained in:
Emanuel Schuetze 2016-02-02 20:54:03 +01:00
parent 8b72f6d821
commit 8ae3e1d468
7 changed files with 103 additions and 28 deletions

View File

@ -86,6 +86,14 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
}); });
$scope.alert = {}; $scope.alert = {};
// pagination
$scope.currentPage = 1;
$scope.itemsPerPage = 100;
$scope.limitBegin = 0;
$scope.pageChanged = function() {
$scope.limitBegin = ($scope.currentPage - 1) * $scope.itemsPerPage;
};
// check open permission // check open permission
$scope.isAllowedToSeeOpenLink = function (item) { $scope.isAllowedToSeeOpenLink = function (item) {
var collection = item.content_object.collection; var collection = item.content_object.collection;
@ -356,17 +364,26 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
function($scope, gettext, Agenda, Customslide) { function($scope, gettext, Agenda, Customslide) {
// import from textarea // import from textarea
$scope.importByLine = function () { $scope.importByLine = function () {
if ($scope.itemlist) {
$scope.titleItems = $scope.itemlist[0].split("\n"); $scope.titleItems = $scope.itemlist[0].split("\n");
$scope.importcounter = 0; $scope.importcounter = 0;
$scope.titleItems.forEach(function(title) { $scope.titleItems.forEach(function(title, index) {
var item = {title: title}; var item = {title: title};
// TODO: create all items in bulk mode // TODO: create all items in bulk mode
Customslide.create(item).then( Customslide.create(item).then(
function(success) { function(success) {
// find related agenda item
Agenda.find(success.agenda_item_id).then(function(item) {
// import all items as type AGENDA_ITEM = 1
item.type = 1;
item.weight = 1000 + index;
Agenda.save(item);
});
$scope.importcounter++; $scope.importcounter++;
} }
); );
}); });
}
}; };
// *** CSV import *** // *** CSV import ***
@ -397,7 +414,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
$scope.$watch('csv.result', function () { $scope.$watch('csv.result', function () {
$scope.items = []; $scope.items = [];
var quotionRe = /^"(.*)"$/; var quotionRe = /^"(.*)"$/;
angular.forEach($scope.csv.result, function (item) { angular.forEach($scope.csv.result, function (item, index) {
// title // title
if (item.title) { if (item.title) {
item.title = item.title.replace(quotionRe, '$1'); item.title = item.title.replace(quotionRe, '$1');
@ -410,6 +427,29 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
if (item.text) { if (item.text) {
item.text = item.text.replace(quotionRe, '$1'); item.text = item.text.replace(quotionRe, '$1');
} }
// duration
if (item.duration) {
item.duration = item.duration.replace(quotionRe, '$1');
}
// comment
if (item.comment) {
item.comment = item.comment.replace(quotionRe, '$1');
}
// is_hidden
if (item.is_hidden) {
item.is_hidden = item.is_hidden.replace(quotionRe, '$1');
if (item.is_hidden == '1') {
item.type = 2;
} else {
item.type = 1;
}
} else {
item.type = 1;
}
// set weight for right csv row order
// (Use 1000+ to protect existing items and prevent collision
// with new items which use weight 10000 as default.)
item.weight = 1000 + index;
$scope.items.push(item); $scope.items.push(item);
}); });
}); });
@ -422,6 +462,14 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
Customslide.create(item).then( Customslide.create(item).then(
function(success) { function(success) {
item.imported = true; item.imported = true;
// find related agenda item
Agenda.find(success.agenda_item_id).then(function(agendaItem) {
agendaItem.duration = item.duration;
agendaItem.comment = item.comment;
agendaItem.type = item.type;
agendaItem.weight = item.weight;
Agenda.save(agendaItem);
});
} }
); );
} }
@ -436,10 +484,11 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
var element = document.getElementById('downloadLink'); var element = document.getElementById('downloadLink');
var csvRows = [ var csvRows = [
// column header line // column header line
['title', 'text'], ['title', 'text', 'duration', 'comment', 'is_hidden'],
// example entries // example entries
['Demo 1', 'Demo text 1'], ['Demo 1', 'Demo text 1', '1:00', 'test comment', ''],
['Demo 2', 'Demo text 2'] ['Break', '', '0:10', '', '1'],
['Demo 2', 'Demo text 2', '1:30', '', '']
]; ];
var csvString = csvRows.join("%0A"); var csvString = csvRows.join("%0A");

View File

@ -66,21 +66,24 @@ Keep each item in a single line.</p>
<h4 translate>Please note:</h4> <h4 translate>Please note:</h4>
<ul> <ul>
<li><translate>Required comma or semicolon separated values with these column header names in the first row</translate>:<br> <li><translate>Required comma or semicolon separated values with these column header names in the first row</translate>:<br>
<code>title, text</code> <code>title, text, duration, comment, is_hidden</code>
<li translate>Text is optional and may be empty. <li translate>Title is required. All other fields are optional and may be empty.
<li translate>Only double quotes are accepted as text delimiter (no single quotes). <li translate>Only double quotes are accepted as text delimiter (no single quotes).
<li><a id="downloadLink" href="" ng-click="downloadCSVExample()" translate>Download CSV example file</a> <li><a id="downloadLink" href="" ng-click="downloadCSVExample()" translate>Download CSV example file</a>
</ul> </ul>
<div ng-if="csv.result"> <div ng-if="csv.result">
<h3 translate>Preview</h3> <h3 translate>Preview</h3>
<table class="table table-striped table-bordered table-condensed"> <table ng-if="!csvImporting" class="table table-striped table-bordered table-condensed">
<thead> <thead>
<tr> <tr>
<th> <th>
<th># <th>#
<th translate>Title <th translate>Title
<th translate>Text</th> <th translate>Text
<th translate>Duration
<th translate>Comment
<th translate>Is hidden</th>
<tbody ng-repeat="item in items"> <tbody ng-repeat="item in items">
<tr> <tr>
<td class="minimum" <td class="minimum"
@ -94,13 +97,16 @@ Keep each item in a single line.</p>
<span ng-if="item.imported"> <span ng-if="item.imported">
<i class="fa fa-check-circle fa-lg"></i> <i class="fa fa-check-circle fa-lg"></i>
</span> </span>
<td>{{ $index + 1 }} <td class="minimum">{{ $index + 1 }}
<td ng-class="{ 'text-danger': item.title_error }"> <td ng-class="{ 'text-danger': item.title_error }">
<span ng-if="item.title_error" title="{{ item.title_error | translate }}"> <span ng-if="item.title_error" title="{{ item.title_error | translate }}">
<i class="fa fa-exclamation-triangle"></i> <i class="fa fa-exclamation-triangle"></i>
</span> </span>
{{ item.getTitle() }} {{ item.title }}
<td>{{ item.text | limitTo:80 }}{{ item.text.length > 80 ? '...' : '' }} <td>{{ item.text | limitTo:80 }}{{ item.text.length > 80 ? '...' : '' }}
<td>{{ item.duration }}
<td>{{ item.comment }}
<td>{{ item.is_hidden }}
</table> </table>
<div class="text-danger"> <div class="text-danger">

View File

@ -117,7 +117,8 @@
<translate>Done</translate> <translate>Done</translate>
<tbody> <tbody>
<tr ng-repeat="item in itemsFiltered = (items | filter: filter.search | <tr ng-repeat="item in itemsFiltered = (items | filter: filter.search |
filter: {is_hidden: filter.showHiddenItems} | filter: {closed: filter.showClosedItems})" filter: {is_hidden: filter.showHiddenItems} | filter: {closed: filter.showClosedItems}) |
limitTo : itemsPerPage : limitBegin"
class="animate-item" class="animate-item"
ng-class="{ 'activeline': item.isProjected(), 'selected': item.selected, 'hiddenrow': item.is_hidden}"> ng-class="{ 'activeline': item.isProjected(), 'selected': item.selected, 'hiddenrow': item.is_hidden}">
<!-- projector column --> <!-- projector column -->
@ -206,4 +207,5 @@
</div> </div>
</form> </form>
</table> </table>
<uib-pagination total-items="itemsFiltered.length" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></uib-pagination>
</div> </div>

View File

@ -91,6 +91,7 @@ img {
border: 1px solid red; border: 1px solid red;
position: fixed; position: fixed;
width: 100%; width: 100%;
z-index: 1000;
} }
#header a.headerlink { #header a.headerlink {
text-decoration: none; text-decoration: none;

View File

@ -390,6 +390,14 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
$scope.sortColumn = column; $scope.sortColumn = column;
}; };
// pagination
$scope.currentPage = 1;
$scope.itemsPerPage = 100;
$scope.limitBegin = 0;
$scope.pageChanged = function() {
$scope.limitBegin = ($scope.currentPage - 1) * $scope.itemsPerPage;
};
// open new/edit dialog // open new/edit dialog
$scope.openDialog = function (user) { $scope.openDialog = function (user) {
ngDialog.open(UserForm.getDialog(user)); ngDialog.open(UserForm.getDialog(user));
@ -643,6 +651,13 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
$scope.setSeparator = function () { $scope.setSeparator = function () {
$scope.csv.separator = $scope.separator; $scope.csv.separator = $scope.separator;
}; };
// pagination
$scope.currentPage = 1;
$scope.itemsPerPage = 100;
$scope.limitBegin = 0;
$scope.pageChanged = function() {
$scope.limitBegin = ($scope.currentPage - 1) * $scope.itemsPerPage;
};
// detect if csv file is loaded // detect if csv file is loaded
$scope.$watch('csv.result', function () { $scope.$watch('csv.result', function () {
$scope.users = []; $scope.users = [];

View File

@ -77,9 +77,9 @@
<li><a id="downloadLink" href="" ng-click="downloadCSVExample()" translate>Download CSV example file</a> <li><a id="downloadLink" href="" ng-click="downloadCSVExample()" translate>Download CSV example file</a>
</ul> </ul>
<div ng-if="csv.result"> <div ng-show="csv.result">
<h3 translate>Preview</h3> <h3 translate>Preview</h3>
<table class="table table-striped table-bordered table-condensed"> <table ng-if="!csvImporting" class="table table-striped table-bordered table-condensed">
<thead> <thead>
<tr> <tr>
<th> <th>
@ -91,8 +91,8 @@
<th translate>Groups <th translate>Groups
<th translate>Comment <th translate>Comment
<th translate>Is active</th> <th translate>Is active</th>
<tbody ng-repeat="user in users"> <tbody>
<tr> <tr ng-repeat="user in users | limitTo : itemsPerPage : limitBegin">
<td class="minimum" <td class="minimum"
ng-class="{ 'text-danger': user.importerror, 'text-success': user.imported }"> ng-class="{ 'text-danger': user.importerror, 'text-success': user.imported }">
<span ng-if="user.importerror"> <span ng-if="user.importerror">
@ -129,6 +129,7 @@
<td> <td>
<i ng-if="user.is_active" class="fa fa-check-square-o"></i> <i ng-if="user.is_active" class="fa fa-check-square-o"></i>
</table> </table>
<uib-pagination total-items="users.length" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></uib-pagination>
<div class="text-danger"> <div class="text-danger">
<div ng-repeat="user in usersFailed = (users | filter:{importerror:true})"></div> <div ng-repeat="user in usersFailed = (users | filter:{importerror:true})"></div>
@ -151,7 +152,7 @@
</div> </div>
<div class="spacer"> <div class="spacer">
<button ng-click="clear()" class="btn btn-default" translate> <button ng-if="!csvImporting" ng-click="clear()" class="btn btn-default" translate>
Clear preview Clear preview
</button> </button>
<button ng-if="!csvImporting" ng-click="import()" class="btn btn-primary" translate> <button ng-if="!csvImporting" ng-click="import()" class="btn btn-primary" translate>

View File

@ -125,7 +125,7 @@
</i> </i>
<tbody> <tbody>
<tr ng-repeat="user in usersFiltered = (users | filter: filter.search | filter: {groups: groupFilter} | <tr ng-repeat="user in usersFiltered = (users | filter: filter.search | filter: {groups: groupFilter} |
filter: {is_present: filterPresent} | orderBy: sortColumn:reverse)" filter: {is_present: filterPresent} | orderBy: sortColumn:reverse) | limitTo : itemsPerPage : limitBegin"
class="animate-item" class="animate-item"
ng-class="{ 'activeline': user.isProjected(), 'selected': user.selected }"> ng-class="{ 'activeline': user.isProjected(), 'selected': user.selected }">
<!-- projector column --> <!-- projector column -->
@ -163,4 +163,5 @@
</span> </span>
<input os-perms="users.can_manage" type="checkbox" ng-model="user.is_present" ng-click="save(user)"> <input os-perms="users.can_manage" type="checkbox" ng-model="user.is_present" ng-click="save(user)">
</table> </table>
<uib-pagination total-items="usersFiltered.length" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></uib-pagination>
</div> </div>