introduce the All tickets page

This commit is contained in:
Davide Alberani 2016-07-07 22:18:30 +02:00
rodzic bee15ca088
commit 1fbc069890
6 zmienionych plików z 61 dodań i 66 usunięć

Wyświetl plik

@ -57,7 +57,12 @@
<tr ng-repeat="person in (event.persons || []) | splittedFilter:query | registeredFilter | orderBy:personsOrder">
<td class="text-right">{{$index+1}}</td>
<td>
<span><strong><a ui-sref="person.info({id: person.person_id})"><span class="fa fa-lg fa-user"></span></a>&nbsp;<a ui-sref="event.ticket.edit({id: event._id, ticket_id: person._id})" ng-if="person._id"><span>{{person.name}}</span>&nbsp;<span>{{person.surname}}</span></a></strong></span><span ng-if="!person._id"><span>{{person.name}}</span>&nbsp;<span>{{person.surname}}</span></a></strong></span></span><span ng-if="person.email">&nbsp;&lt;{{person.email}}&gt;</span>
<span>
<strong>
<a ui-sref="event.ticket.edit({id: event._id, ticket_id: person._id})"><span>{{person.name}}</span>&nbsp;<span>{{person.surname}}</span></a>
</strong>
</span>
<span ng-if="person.email">&nbsp;&lt;{{person.email}}&gt;</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">&nbsp;@&nbsp;</span><i ng-if="person.company">{{person.company}}</i></p>
</td>
<td class="text-center">
@ -95,7 +100,7 @@
<tbody>
<tr ng-repeat="person in allPersons | splittedFilter:query | personRegistered:{event: event, present: false}">
<td>
<strong><a ui-sref="person.info({id: person._id})">{{person.name}} {{person.surname}}</a></strong>
<strong>{{person.name}} {{person.surname}}</strong>
<br />
{{person.email}}
</td>

Wyświetl plik

@ -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>
<ul class="nav navbar-nav">
<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('/import/persons')}"><a ui-sref="import.persons">{{'Import persons' | 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 tickets' | translate}}</a></li>
</ul>
</div>
<div class="collapse navbar-collapse">

2
angular_app/js/app.js dostarczono
Wyświetl plik

@ -148,7 +148,7 @@ eventManApp.config(['$stateProvider', '$urlRouterProvider',
.state('tickets', {
url: '/tickets',
templateUrl: 'tickets-list.html',
controller: 'EventTicketsCtrl'
controller: 'EventsListCtrl'
})
.state('import', {
url: '/import',

Wyświetl plik

@ -66,10 +66,23 @@ eventManControllers.controller('ModalConfirmInstanceCtrl', ['$scope', '$uibModal
);
eventManControllers.controller('EventsListCtrl', ['$scope', 'Event', '$uibModal', '$log', '$translate', '$rootScope',
function ($scope, Event, $uibModal, $log, $translate, $rootScope) {
$scope.events = Event.all();
eventManControllers.controller('EventsListCtrl', ['$scope', 'Event', '$uibModal', '$log', '$translate', '$rootScope', '$state',
function ($scope, Event, $uibModal, $log, $translate, $rootScope, $state) {
$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.ticketsOrderProp = ["name", "surname"];
$scope.confirm_delete = 'Do you really want to delete this event?';
$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;
};
}]
);

Wyświetl plik

@ -1,66 +1,49 @@
<!-- show the list of Persons -->
<!-- show the list of Tickets -->
<div class="container">
<div class="container">
<div class="row">
<div class="col-md-7 col-xs-7 vcenter">
<h1>{{'Persons' | translate}}
<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>
<h1>{{'All tickets' | translate}}</h1>
</div><!--
--><div class="col-md-5 col-xs-5 vcenter">
<div class="row">
<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 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">
<form class="form-inline">
<div class="form-group">
<label for="query-persons">{{'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}">
<label for="query-tickets">{{'Search:' | translate}}</label>
<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>
</form>
<div ng-include=" 'modal-confirm-action.html' " class="hidden"></div>
<table class="table table-striped">
<thead>
<tr>
<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 ng-repeat="col in customFields" class="text-center nowrap">
<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>
<th class="text-center nowrap"><strong>{{'Delete' | translate}}</strong></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 class="text-center nowrap"><strong>{{'Event' | translate}}</strong></th>
<th class="text-center nowrap"><strong>{{'Attended' | translate}}</strong></th>
</tr>
</thead>
<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>
<span><strong><a ui-sref="person.info({id: person._id})"><span>{{person.name}}</span>&nbsp;<span>{{person.surname}}</span></a></strong></span><span ng-if="person.email">&nbsp;&lt;{{person.email}}&gt;</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">&nbsp;@&nbsp;</span><i ng-if="person.company">{{person.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>
<span><strong><a ui-sref="event.ticket.edit({id: ticket.event_id, ticket_id: ticket._id})"><span>{{ticket.name}}</span>&nbsp;<span>{{ticket.surname}}</span></a></strong></span><span ng-if="ticket.email">&nbsp;&lt;{{ticket.email}}&gt;</span>
<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">&nbsp;@&nbsp;</span><i ng-if="ticket.company">{{ticket.company}}</i></p>
</td>
<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>
</tr>
</tbody>

Wyświetl plik

@ -522,28 +522,6 @@ class CollectionHandler(BaseHandler):
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):
"""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_-]+)?"
_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_-]+)?"
_tickets_path = r"/tickets"
application = tornado.web.Application([
(_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),
(_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"/ebcsvpersons", EbCSVImportPersonsHandler, init_params),
(r"/settings", SettingsHandler, init_params),