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:
parent
8b72f6d821
commit
8ae3e1d468
@ -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 () {
|
||||||
$scope.titleItems = $scope.itemlist[0].split("\n");
|
if ($scope.itemlist) {
|
||||||
$scope.importcounter = 0;
|
$scope.titleItems = $scope.itemlist[0].split("\n");
|
||||||
$scope.titleItems.forEach(function(title) {
|
$scope.importcounter = 0;
|
||||||
var item = {title: title};
|
$scope.titleItems.forEach(function(title, index) {
|
||||||
// TODO: create all items in bulk mode
|
var item = {title: title};
|
||||||
Customslide.create(item).then(
|
// TODO: create all items in bulk mode
|
||||||
function(success) {
|
Customslide.create(item).then(
|
||||||
$scope.importcounter++;
|
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 ***
|
// *** 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");
|
||||||
|
@ -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">
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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 = [];
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user