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 = {};
// pagination
$scope.currentPage = 1;
$scope.itemsPerPage = 100;
$scope.limitBegin = 0;
$scope.pageChanged = function() {
$scope.limitBegin = ($scope.currentPage - 1) * $scope.itemsPerPage;
};
// check open permission
$scope.isAllowedToSeeOpenLink = function (item) {
var collection = item.content_object.collection;
@ -356,17 +364,26 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
function($scope, gettext, Agenda, Customslide) {
// import from textarea
$scope.importByLine = function () {
$scope.titleItems = $scope.itemlist[0].split("\n");
$scope.importcounter = 0;
$scope.titleItems.forEach(function(title) {
var item = {title: title};
// TODO: create all items in bulk mode
Customslide.create(item).then(
function(success) {
$scope.importcounter++;
}
);
});
if ($scope.itemlist) {
$scope.titleItems = $scope.itemlist[0].split("\n");
$scope.importcounter = 0;
$scope.titleItems.forEach(function(title, index) {
var item = {title: title};
// TODO: create all items in bulk mode
Customslide.create(item).then(
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++;
}
);
});
}
};
// *** CSV import ***
@ -397,7 +414,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
$scope.$watch('csv.result', function () {
$scope.items = [];
var quotionRe = /^"(.*)"$/;
angular.forEach($scope.csv.result, function (item) {
angular.forEach($scope.csv.result, function (item, index) {
// title
if (item.title) {
item.title = item.title.replace(quotionRe, '$1');
@ -410,6 +427,29 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
if (item.text) {
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);
});
});
@ -422,6 +462,14 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
Customslide.create(item).then(
function(success) {
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 csvRows = [
// column header line
['title', 'text'],
['title', 'text', 'duration', 'comment', 'is_hidden'],
// example entries
['Demo 1', 'Demo text 1'],
['Demo 2', 'Demo text 2']
['Demo 1', 'Demo text 1', '1:00', 'test comment', ''],
['Break', '', '0:10', '', '1'],
['Demo 2', 'Demo text 2', '1:30', '', '']
];
var csvString = csvRows.join("%0A");

View File

@ -66,21 +66,24 @@ Keep each item in a single line.</p>
<h4 translate>Please note:</h4>
<ul>
<li><translate>Required comma or semicolon separated values with these column header names in the first row</translate>:<br>
<code>title, text</code>
<li translate>Text is optional and may be empty.
<code>title, text, duration, comment, is_hidden</code>
<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><a id="downloadLink" href="" ng-click="downloadCSVExample()" translate>Download CSV example file</a>
</ul>
<div ng-if="csv.result">
<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>
<tr>
<th>
<th>#
<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">
<tr>
<td class="minimum"
@ -94,13 +97,16 @@ Keep each item in a single line.</p>
<span ng-if="item.imported">
<i class="fa fa-check-circle fa-lg"></i>
</span>
<td>{{ $index + 1 }}
<td class="minimum">{{ $index + 1 }}
<td ng-class="{ 'text-danger': item.title_error }">
<span ng-if="item.title_error" title="{{ item.title_error | translate }}">
<i class="fa fa-exclamation-triangle"></i>
</span>
{{ item.getTitle() }}
{{ item.title }}
<td>{{ item.text | limitTo:80 }}{{ item.text.length > 80 ? '...' : '' }}
<td>{{ item.duration }}
<td>{{ item.comment }}
<td>{{ item.is_hidden }}
</table>
<div class="text-danger">

View File

@ -117,7 +117,8 @@
<translate>Done</translate>
<tbody>
<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"
ng-class="{ 'activeline': item.isProjected(), 'selected': item.selected, 'hiddenrow': item.is_hidden}">
<!-- projector column -->
@ -206,4 +207,5 @@
</div>
</form>
</table>
<uib-pagination total-items="itemsFiltered.length" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></uib-pagination>
</div>

View File

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

View File

@ -390,6 +390,14 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
$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
$scope.openDialog = function (user) {
ngDialog.open(UserForm.getDialog(user));
@ -643,6 +651,13 @@ angular.module('OpenSlidesApp.users.site', ['OpenSlidesApp.users'])
$scope.setSeparator = function () {
$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
$scope.$watch('csv.result', function () {
$scope.users = [];

View File

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

View File

@ -125,7 +125,7 @@
</i>
<tbody>
<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"
ng-class="{ 'activeline': user.isProjected(), 'selected': user.selected }">
<!-- projector column -->
@ -163,4 +163,5 @@
</span>
<input os-perms="users.can_manage" type="checkbox" ng-model="user.is_present" ng-click="save(user)">
</table>
<uib-pagination total-items="usersFiltered.length" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></uib-pagination>
</div>