introduce the All tickets page
This commit is contained in:
parent
bee15ca088
commit
1fbc069890
6 changed files with 61 additions and 66 deletions
|
@ -57,7 +57,12 @@
|
||||||
<tr ng-repeat="person in (event.persons || []) | splittedFilter:query | registeredFilter | orderBy:personsOrder">
|
<tr ng-repeat="person in (event.persons || []) | splittedFilter:query | registeredFilter | orderBy:personsOrder">
|
||||||
<td class="text-right">{{$index+1}}</td>
|
<td class="text-right">{{$index+1}}</td>
|
||||||
<td>
|
<td>
|
||||||
<span><strong><a ui-sref="person.info({id: person.person_id})"><span class="fa fa-lg fa-user"></span></a> <a ui-sref="event.ticket.edit({id: event._id, ticket_id: person._id})" ng-if="person._id"><span>{{person.name}}</span> <span>{{person.surname}}</span></a></strong></span><span ng-if="!person._id"><span>{{person.name}}</span> <span>{{person.surname}}</span></a></strong></span></span><span ng-if="person.email"> <{{person.email}}></span>
|
<span>
|
||||||
|
<strong>
|
||||||
|
<a ui-sref="event.ticket.edit({id: event._id, ticket_id: person._id})"><span>{{person.name}}</span> <span>{{person.surname}}</span></a>
|
||||||
|
</strong>
|
||||||
|
</span>
|
||||||
|
<span ng-if="person.email"> <{{person.email}}></span>
|
||||||
<p ng-if="person.company || person.job_title"><i ng-if="person.job_title">{{person.job_title}}</i><span ng-if="person.company && person.job_title"> @ </span><i ng-if="person.company">{{person.company}}</i></p>
|
<p ng-if="person.company || person.job_title"><i ng-if="person.job_title">{{person.job_title}}</i><span ng-if="person.company && person.job_title"> @ </span><i ng-if="person.company">{{person.company}}</i></p>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
|
@ -95,7 +100,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="person in allPersons | splittedFilter:query | personRegistered:{event: event, present: false}">
|
<tr ng-repeat="person in allPersons | splittedFilter:query | personRegistered:{event: event, present: false}">
|
||||||
<td>
|
<td>
|
||||||
<strong><a ui-sref="person.info({id: person._id})">{{person.name}} {{person.surname}}</a></strong>
|
<strong>{{person.name}} {{person.surname}}</strong>
|
||||||
<br />
|
<br />
|
||||||
{{person.email}}
|
{{person.email}}
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -73,8 +73,8 @@
|
||||||
<div ng-if="logo.imgURL" class="navbar-brand"><a ng-if="logo.link" href="{{logo.link}}" target="_blank"><img src="{{logo.imgURL}}" /></a></div>
|
<div ng-if="logo.imgURL" class="navbar-brand"><a ng-if="logo.link" href="{{logo.link}}" target="_blank"><img src="{{logo.imgURL}}" /></a></div>
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li ng-class="{active: isActive('/events') || isActive('/event')}"><a ui-sref="events">{{'Events' | translate}}</a></li>
|
<li ng-class="{active: isActive('/events') || isActive('/event')}"><a ui-sref="events">{{'Events' | translate}}</a></li>
|
||||||
<li ng-if="hasPermission('admin|all')" ng-class="{active: isActive('/tickets')}"><a ui-sref="tickets">{{'Tickets' | translate}}</a></li>
|
<li ng-if="hasPermission('admin|all')" ng-class="{active: isActive('/tickets')}"><a ui-sref="tickets">{{'All tickets' | translate}}</a></li>
|
||||||
<li ng-if="hasPermission('admin|all')" ng-class="{active: isActive('/import/persons')}"><a ui-sref="import.persons">{{'Import persons' | translate}}</a></li>
|
<li ng-if="hasPermission('admin|all')" ng-class="{active: isActive('/import/persons')}"><a ui-sref="import.persons">{{'Import tickets' | translate}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse navbar-collapse">
|
<div class="collapse navbar-collapse">
|
||||||
|
|
2
angular_app/js/app.js
vendored
2
angular_app/js/app.js
vendored
|
@ -148,7 +148,7 @@ eventManApp.config(['$stateProvider', '$urlRouterProvider',
|
||||||
.state('tickets', {
|
.state('tickets', {
|
||||||
url: '/tickets',
|
url: '/tickets',
|
||||||
templateUrl: 'tickets-list.html',
|
templateUrl: 'tickets-list.html',
|
||||||
controller: 'EventTicketsCtrl'
|
controller: 'EventsListCtrl'
|
||||||
})
|
})
|
||||||
.state('import', {
|
.state('import', {
|
||||||
url: '/import',
|
url: '/import',
|
||||||
|
|
38
angular_app/js/controllers.js
vendored
38
angular_app/js/controllers.js
vendored
|
@ -66,10 +66,23 @@ eventManControllers.controller('ModalConfirmInstanceCtrl', ['$scope', '$uibModal
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
eventManControllers.controller('EventsListCtrl', ['$scope', 'Event', '$uibModal', '$log', '$translate', '$rootScope',
|
eventManControllers.controller('EventsListCtrl', ['$scope', 'Event', '$uibModal', '$log', '$translate', '$rootScope', '$state',
|
||||||
function ($scope, Event, $uibModal, $log, $translate, $rootScope) {
|
function ($scope, Event, $uibModal, $log, $translate, $rootScope, $state) {
|
||||||
$scope.events = Event.all();
|
$scope.tickets = [];
|
||||||
|
$scope.events = Event.all(function(events) {
|
||||||
|
if (events && $state.is('tickets')) {
|
||||||
|
angular.forEach(events, function(evt, idx) {
|
||||||
|
var evt_tickets = (evt.persons || []).slice(0);
|
||||||
|
angular.forEach(evt_tickets, function(obj, obj_idx) {
|
||||||
|
obj.event_title = evt.title;
|
||||||
|
obj.event_id = evt._id;
|
||||||
|
});
|
||||||
|
$scope.tickets.push.apply($scope.tickets, evt_tickets || []);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
$scope.eventsOrderProp = "-begin_date";
|
$scope.eventsOrderProp = "-begin_date";
|
||||||
|
$scope.ticketsOrderProp = ["name", "surname"];
|
||||||
|
|
||||||
$scope.confirm_delete = 'Do you really want to delete this event?';
|
$scope.confirm_delete = 'Do you really want to delete this event?';
|
||||||
$rootScope.$on('$translateChangeSuccess', function () {
|
$rootScope.$on('$translateChangeSuccess', function () {
|
||||||
|
@ -94,6 +107,25 @@ eventManControllers.controller('EventsListCtrl', ['$scope', 'Event', '$uibModal'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.updateOrded = function(key) {
|
||||||
|
var new_order = [key];
|
||||||
|
var inv_key;
|
||||||
|
if (key && key[0] === '-') {
|
||||||
|
inv_key = key.substring(1);
|
||||||
|
} else {
|
||||||
|
inv_key = '-' + key;
|
||||||
|
}
|
||||||
|
angular.forEach($scope.ticketsOrderProp,
|
||||||
|
function(value, idx) {
|
||||||
|
if (value !== key && value !== inv_key) {
|
||||||
|
new_order.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$scope.ticketsOrderProp = new_order;
|
||||||
|
};
|
||||||
|
|
||||||
}]
|
}]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,66 +1,49 @@
|
||||||
<!-- show the list of Persons -->
|
<!-- show the list of Tickets -->
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-7 col-xs-7 vcenter">
|
<div class="col-md-7 col-xs-7 vcenter">
|
||||||
<h1>{{'Persons' | translate}}
|
<h1>{{'All tickets' | translate}}</h1>
|
||||||
<button ng-click="$state.go('person.new')" class="btn btn-success">
|
|
||||||
<span class="fa fa-plus-circle vcenter"></span>
|
|
||||||
{{'Add person' | translate}}
|
|
||||||
</button>
|
|
||||||
<button ng-click="$state.go('import.persons')" class="btn btn-success">
|
|
||||||
<span class="fa fa-download vcenter"></span>
|
|
||||||
{{'Import persons' | translate}}
|
|
||||||
</button>
|
|
||||||
</h1>
|
|
||||||
</div><!--
|
</div><!--
|
||||||
--><div class="col-md-5 col-xs-5 vcenter">
|
--><div class="col-md-5 col-xs-5 vcenter">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h2><div class="label label-info vcenter">{{'Persons:' | translate}} {{persons.length || 0}}</div></h2>
|
<h2><div class="label label-info vcenter">{{'Tickets:' | translate}} {{tickets.length || 0}}</div></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-primary table-striped top5">
|
<div class="panel panel-primary table-striped top5">
|
||||||
<div class="panel-heading">{{'Persons' | translate}}</div>
|
<div class="panel-heading">{{'Tickets' | translate}}</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form class="form-inline">
|
<form class="form-inline">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="query-persons">{{'Search:' | translate}}</label>
|
<label for="query-tickets">{{'Search:' | translate}}</label>
|
||||||
<input eventman-focus type="text" id="query-persons" class="form-control" placeholder="{{'Name or email' | translate}}" ng-model="query" ng-model-options="{debounce: 600}">
|
<input eventman-focus type="text" id="query-tickets" class="form-control" placeholder="{{'Name or email' | translate}}" ng-model="query" ng-model-options="{debounce: 600}">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div ng-include=" 'modal-confirm-action.html' " class="hidden"></div>
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-right nowrap">#</th>
|
<th class="text-right nowrap">#</th>
|
||||||
<th class="nowrap">{{'Person' | translate}} <a ng-click="updateOrded('name')" href=""><i class="fa fa-caret-up"></i></a>{{'Name' | translate}}<a ng-click="updateOrded('-name')" href=""><i class="fa fa-caret-down"></i></a> <a ng-click="updateOrded('surname')" href=""><i class="fa fa-caret-up"></i></a>{{'Surname' | translate}}<a ng-click="updateOrded('-surname')" href=""><i class="fa fa-caret-down"></i></a></th>
|
<th class="nowrap"><a ng-click="updateOrded('name')" href=""><i class="fa fa-caret-up"></i></a>{{'Name' | translate}}<a ng-click="updateOrded('-name')" href=""><i class="fa fa-caret-down"></i></a> <a ng-click="updateOrded('surname')" href=""><i class="fa fa-caret-up"></i></a>{{'Surname' | translate}}<a ng-click="updateOrded('-surname')" href=""><i class="fa fa-caret-down"></i></a> <a ng-click="updateOrded('email')" href=""><i class="fa fa-caret-up"></i></a>{{'Email' | translate}}<a ng-click="updateOrded('-email')" href=""><i class="fa fa-caret-down"></i></a></th>
|
||||||
<th ng-repeat="col in customFields" class="text-center nowrap">
|
<th class="text-center nowrap"><strong>{{'Event' | translate}}</strong></th>
|
||||||
<a ng-click="updateOrded(col.key)" href=""><i class="fa fa-caret-up"></i></a>{{col.label | translate}}<a ng-click="updateOrded('-' + col.key)" href=""><i class="fa fa-caret-down"></i></a>
|
<th class="text-center nowrap"><strong>{{'Attended' | translate}}</strong></th>
|
||||||
</th>
|
|
||||||
<th class="text-center nowrap"><strong>{{'Delete' | translate}}</strong></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="person in tickets | splittedFilter:query | orderBy:personsOrder">
|
<tr ng-repeat="ticket in tickets | splittedFilter:query | orderBy:ticketsOrderProp">
|
||||||
<td class="text-right">{{$index+1}}</td>
|
<td class="text-right">{{$index+1}}</td>
|
||||||
<td>
|
<td>
|
||||||
<span><strong><a ui-sref="person.info({id: person._id})"><span>{{person.name}}</span> <span>{{person.surname}}</span></a></strong></span><span ng-if="person.email"> <{{person.email}}></span>
|
<span><strong><a ui-sref="event.ticket.edit({id: ticket.event_id, ticket_id: ticket._id})"><span>{{ticket.name}}</span> <span>{{ticket.surname}}</span></a></strong></span><span ng-if="ticket.email"> <{{ticket.email}}></span>
|
||||||
<p ng-if="person.company || person.job_title"><i ng-if="person.job_title">{{person.job_title}}</i><span ng-if="person.company && person.job_title"> @ </span><i ng-if="person.company">{{person.company}}</i></p>
|
<p ng-if="ticket.company || ticket.job_title"><i ng-if="ticket.job_title">{{ticket.job_title}}</i><span ng-if="ticket.company && ticket.job_title"> @ </span><i ng-if="ticket.company">{{ticket.company}}</i></p>
|
||||||
</td>
|
|
||||||
<td ng-repeat="col in customFields" class="text-center">
|
|
||||||
<span ng-if="col.type == 'boolean'">
|
|
||||||
<button class="btn btn-link" ng-click="setAttribute(person, col.key, !person[col.key])"><span class="fa fa-lg {{(person[col.key]) && 'fa-check-circle text-success' || 'fa-times-circle text-danger'}}"></span></button>
|
|
||||||
</span>
|
|
||||||
<span ng-if="col.type != 'boolean'">
|
|
||||||
{{person[col.key]}}
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<button ng-click="remove(person._id)" type="button" class="btn btn-link fa fa-trash fa-lg"></button>
|
<a ui-sref="event.view({id: ticket.event_id})">{{ticket.event_title}}</a>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<span class="fa fa-lg {{(ticket.attended) && 'fa-check-circle text-success' || 'fa-times-circle text-danger'}}"></span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -522,28 +522,6 @@ class CollectionHandler(BaseHandler):
|
||||||
self.logger.error('Error yielding WebSocket message: %s', e)
|
self.logger.error('Error yielding WebSocket message: %s', e)
|
||||||
|
|
||||||
|
|
||||||
class TicketsHandler(CollectionHandler):
|
|
||||||
"""Handle requests for Tickes."""
|
|
||||||
|
|
||||||
@gen.coroutine
|
|
||||||
@authenticated
|
|
||||||
def get(self, id_=None, resource=None, resource_id=None, acl=True, **kwargs):
|
|
||||||
query = {}
|
|
||||||
events = self.db.query('events', {})
|
|
||||||
persons = {}
|
|
||||||
for event in events:
|
|
||||||
id_ = str(event['_id'])
|
|
||||||
title = event['title']
|
|
||||||
for person in (event.get('persons') or []):
|
|
||||||
email = person.get('email')
|
|
||||||
if not email:
|
|
||||||
continue
|
|
||||||
if email not in persons:
|
|
||||||
persons[email] = person
|
|
||||||
persons[email].setdefault('events', {})[id_] = title
|
|
||||||
self.write({'persons': persons.values()})
|
|
||||||
|
|
||||||
|
|
||||||
class PersonsHandler(CollectionHandler):
|
class PersonsHandler(CollectionHandler):
|
||||||
"""Handle requests for Persons."""
|
"""Handle requests for Persons."""
|
||||||
|
|
||||||
|
@ -1018,7 +996,6 @@ def run():
|
||||||
_persons_path = r"/persons/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
_persons_path = r"/persons/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
||||||
_events_path = r"/events/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
_events_path = r"/events/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
||||||
_users_path = r"/users/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
_users_path = r"/users/?(?P<id_>[\w\d_-]+)?/?(?P<resource>[\w\d_-]+)?/?(?P<resource_id>[\w\d_-]+)?"
|
||||||
_tickets_path = r"/tickets"
|
|
||||||
application = tornado.web.Application([
|
application = tornado.web.Application([
|
||||||
(_persons_path, PersonsHandler, init_params),
|
(_persons_path, PersonsHandler, init_params),
|
||||||
(r'/v%s%s' % (API_VERSION, _persons_path), PersonsHandler, init_params),
|
(r'/v%s%s' % (API_VERSION, _persons_path), PersonsHandler, init_params),
|
||||||
|
@ -1026,8 +1003,6 @@ def run():
|
||||||
(r'/v%s%s' % (API_VERSION, _events_path), EventsHandler, init_params),
|
(r'/v%s%s' % (API_VERSION, _events_path), EventsHandler, init_params),
|
||||||
(_users_path, UsersHandler, init_params),
|
(_users_path, UsersHandler, init_params),
|
||||||
(r'/v%s%s' % (API_VERSION, _users_path), UsersHandler, init_params),
|
(r'/v%s%s' % (API_VERSION, _users_path), UsersHandler, init_params),
|
||||||
(_tickets_path, TicketsHandler, init_params),
|
|
||||||
(r'/v%s%s' % (API_VERSION, _tickets_path), TicketsHandler, init_params),
|
|
||||||
(r"/(?:index.html)?", RootHandler, init_params),
|
(r"/(?:index.html)?", RootHandler, init_params),
|
||||||
(r"/ebcsvpersons", EbCSVImportPersonsHandler, init_params),
|
(r"/ebcsvpersons", EbCSVImportPersonsHandler, init_params),
|
||||||
(r"/settings", SettingsHandler, init_params),
|
(r"/settings", SettingsHandler, init_params),
|
||||||
|
|
Loading…
Reference in a new issue