ui-router for events

This commit is contained in:
Davide Alberani 2015-04-05 16:57:21 +02:00
parent 5bff348f19
commit 5c3087410c
11 changed files with 208 additions and 114 deletions

View file

@ -1,19 +1,24 @@
<!-- show details of a single Event (editing also take place here) --> <!-- show details of a single Event (editing also take place here) -->
<div class="container"> <div class="container">
<h1>{{event.title}}&nbsp;
<button ng-if="event._id" ng-click="$state.go('event.info', {id: event._id})" class="btn btn-success">
<span class="glyphicon glyphicon-plus-sign"></span>
{{'Info' | translate}}
</button>
</h1>
<form name="eventForm" ng-model="eventdetails" ng-submit="save()"> <form name="eventForm" ng-model="eventdetails" ng-submit="save()">
<alert class="clearfix"> <alert class="clearfix">
<span>{{event.title}}</span> <button type="button" class="btn btn-default pull-right" ng-click="save($event)" ng-disabled="!eventForm.$dirty">{{'save' | translate}}</button>
<button type="button" class="btn btn-default pull-right" ng-click="save($event)" ng-disabled="!eventForm.$dirty">save</button>
</alert> </alert>
<div class="input-group input-group-lg"> <div class="input-group input-group-lg">
<span class="input-group-addon">Title</span> <span class="input-group-addon">{{'Title' | translate}}</span>
<input type="text" class="form-control" placeholder="Title" ng-model="event.title" ng-required="1"> <input type="text" class="form-control" placeholder="Title" ng-model="event.title" ng-required="1">
</div> </div>
<div class="input-group top5 well form-horizontal" ng-controller="DatetimePickerCtrl"> <div class="input-group top5 well form-horizontal" ng-controller="DatetimePickerCtrl">
<div class="form-group"> <div class="form-group">
<label for="begin-date" class="col-sm-3 control-label">begin date:</label> <label for="begin-date" class="col-sm-3 control-label">{{'begin date:' | translate}}</label>
<div id="begin-date" class="input-group col-sm-9"> <div id="begin-date" class="input-group col-sm-9">
<input type="text" class="form-control" datepicker-popup="dd-MMMM-yyyy" ng-model="event['begin-date']" is-open="opened" ng-required="true" /> <input type="text" class="form-control" datepicker-popup="dd-MMMM-yyyy" ng-model="event['begin-date']" is-open="opened" ng-required="true" />
<span class="input-group-btn"> <span class="input-group-btn">
@ -22,14 +27,14 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="begin-time" class="col-sm-3 control-label">begin time:</label> <label for="begin-time" class="col-sm-3 control-label">{{'begin time:' | translate}}</label>
<timepicker id="begin-time" class="input-group" ng-model="event['begin-time']" show-meridian="false"></timepicker> <timepicker id="begin-time" class="input-group" ng-model="event['begin-time']" show-meridian="false"></timepicker>
</div> </div>
</div> </div>
<div class="input-group top5 well form-horizontal" ng-controller="DatetimePickerCtrl"> <div class="input-group top5 well form-horizontal" ng-controller="DatetimePickerCtrl">
<div class="form-group"> <div class="form-group">
<label for="end-date" class="col-sm-3 control-label">End date:</label> <label for="end-date" class="col-sm-3 control-label">{{'End date:' | translate}}</label>
<div id="end-date" class="input-group col-sm-9"> <div id="end-date" class="input-group col-sm-9">
<input type="text" class="form-control" datepicker-popup="dd-MMMM-yyyy" ng-model="event['end-date']" is-open="opened" ng-required="true" /> <input type="text" class="form-control" datepicker-popup="dd-MMMM-yyyy" ng-model="event['end-date']" is-open="opened" ng-required="true" />
<span class="input-group-btn"> <span class="input-group-btn">
@ -38,50 +43,11 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="end-time" class="col-sm-3 control-label">End time:</label> <label for="end-time" class="col-sm-3 control-label">{{'End time:' | translate}}</label>
<timepicker id="end-time" class="input-group" ng-model="event['end-time']" show-meridian="false"></timepicker> <timepicker id="end-time" class="input-group" ng-model="event['end-time']" show-meridian="false"></timepicker>
</div> </div>
</div> </div>
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/> <input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
</form> </form>
<div class="panel panel-primary table-striped top5">
<div class="panel-heading">Persons</div>
<div class="panel-body">
<form class="form-inline">
<div class="form-group">
<label for="query-persons">Search:</label>
<input type="text" id="query-persons" class="form-control" placeholder="Name or email" ng-model="query">
</div>
<div class="form-group">
<label for="persons-order">Sort by:</label>
<select id="persons-order" class="form-control" ng-model="orderProp">
<option value="name" ng-selected="selected">Alphabetical</option>
<option value="_id">ID</option>
</select>
</div>
</form>
<table class="table table-striped">
<thead>
<tr>
<th>{{'Person' | translate}}</th>
<th>{{'Attended' | translate}}</th>
<th>{{'Actions' | translate}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in event.persons | filter:query | orderBy:orderProp">
<td><a href="/#/persons/{{person.person_id}}">{{person.name}} {{person.surname}}</a></td>
<td>
<button class="btn btn-link" name="switch-attended" ng-click="updateAttendee(person, !person.attended)"><span class="glyphicon {{(person.attended) && 'glyphicon-ok-sign text-success' || 'glyphicon-remove-sign text-danger'}}"></span></button>
</td>
<td>
<button ng-click="removeAttendee(person)" type="button" class="btn btn-link glyphicon glyphicon-trash"></button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div> </div>

View file

@ -0,0 +1,46 @@
<div class="container">
<h1>{{event.title}}
<button ng-if="event._id" ng-click="$state.go('event.edit', {id: event._id})" class="btn btn-success">
<span class="glyphicon glyphicon-plus-sign"></span>
{{'Edit' | translate}}
</button>
</h1>
<div class="panel panel-primary table-striped top5">
<div class="panel-heading">{{'Persons' | translate}}</div>
<div class="panel-body">
<form class="form-inline">
<div class="form-group">
<label for="query-persons">{{'Search:' | translate}}</label>
<input type="text" id="query-persons" class="form-control" placeholder="Name or email" ng-model="query">
</div>
<div class="form-group">
<label for="persons-order">{{'Sort by:' | translate}}</label>
<select id="persons-order" class="form-control" ng-model="orderProp">
<option value="name" ng-selected="selected">{{'Alphabetical' | translate}}</option>
<option value="_id">{{'ID' | translate}}</option>
</select>
</div>
</form>
<table class="table table-striped">
<thead>
<tr>
<th>{{'Person' | translate}}</th>
<th>{{'Attended' | translate}}</th>
<th>{{'Actions' | translate}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in event.persons | filter:query | orderBy:orderProp">
<td><a href="/#/persons/{{person.person_id}}">{{person.name}} {{person.surname}}</a></td>
<td>
<button class="btn btn-link" name="switch-attended" ng-click="updateAttendee(person, !person.attended)"><span class="glyphicon {{(person.attended) && 'glyphicon-ok-sign text-success' || 'glyphicon-remove-sign text-danger'}}"></span></button>
</td>
<td>
<button ng-click="removeAttendee(person)" type="button" class="btn btn-link glyphicon glyphicon-trash"></button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View file

@ -0,0 +1 @@
<div ui-view></div>

View file

@ -1,25 +1,25 @@
<!-- show a list of Events --> <!-- show a list of Events -->
<div class="container"> <div class="container">
<div class="row"> <form class="form-inline">
<div class="col-lg-12"> <div class="form-group">
<form class="form-inline"> <label for="query-events">Search:</label>
<div class="form-group"> <input type="text" id="query-events" class="form-control" placeholder="Event title" ng-model="query">
<label for="query-events">Search:</label>
<input type="text" id="query-events" class="form-control" placeholder="Event title" ng-model="query">
</div>
<div class="form-group">
<label for="events-order">Sort by:</label>
<select id="events-order" class="form-control" ng-model="orderProp">
<option value="title">Alphabetical</option>
<option value="begin-datetime">Date</option>
</select>
</div>
</form>
</div> </div>
</div> <div class="form-group">
</div> <label for="events-order">Sort by:</label>
<select id="events-order" class="form-control" ng-model="orderProp">
<option value="title">Alphabetical</option>
<option value="begin-datetime">Date</option>
</select>
</div>
<div class="form-group">
<button ng-click="$state.go('event.new')" class="btn btn-success">
<span class="glyphicon glyphicon-plus-sign"></span>
New event
</button>
</div>
</form>
<div class="container">
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
@ -30,7 +30,7 @@
<tbody> <tbody>
<tr ng-repeat="event in events | filter:query | orderBy:orderProp"> <tr ng-repeat="event in events | filter:query | orderBy:orderProp">
<td> <td>
<span><strong><a href="/#/events/{{event._id}}">{{event.title}}</a></strong></span> <span><strong><a ui-sref="event.info({id: event._id})">{{event.title}}</a></strong></span>
<p>Begins: {{event['begin-datetime']}}<br/> <p>Begins: {{event['begin-datetime']}}<br/>
Ends: {{event['end-datetime']}}</p> Ends: {{event['end-datetime']}}</p>
</td> </td>

View file

@ -10,6 +10,7 @@
<script src="/static/js/angular-resource.js"></script> <script src="/static/js/angular-resource.js"></script>
<script src="/static/js/angular-file-upload.min.js"></script> <script src="/static/js/angular-file-upload.min.js"></script>
<script src="/static/js/ui-bootstrap-tpls-0.12.1.js"></script> <script src="/static/js/ui-bootstrap-tpls-0.12.1.js"></script>
<script src="/static/js/angular-ui-router.min.js"></script>
<script src="/static/js/angular-translate.js"></script> <script src="/static/js/angular-translate.js"></script>
<script src="/static/js/eventman.js"></script> <script src="/static/js/eventman.js"></script>
<script src="/js/app.js"></script> <script src="/js/app.js"></script>
@ -42,11 +43,10 @@
<div class="container"> <div class="container">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li ng-class="{active: n.isActive('/events')}"><a ng-href="#/events">{{'Events' | translate}}</a></li> <li ng-class="{active: n.isActive('/events') || n.isActive('/event')}"><a ui-sref="events">{{'Events' | translate}}</a></li>
<li ng-class="{active: n.isActive('/new-event')}"><a ng-href="#/new-event">{{'Add event' | translate}}</a></li> <li ng-class="{active: n.isActive('/persons')}"><a ui-sref="persons.list">{{'Persons' | translate}}</a></li>
<li ng-class="{active: n.isActive('/persons')}"><a ng-href="#/persons">{{'Persons' | translate}}</a></li> <li ng-class="{active: n.isActive('/new-person')}"><a ui-sref="persons.new">{{'Add person' | translate}}</a></li>
<li ng-class="{active: n.isActive('/new-person')}"><a ng-href="#/new-person">{{'Add person' | translate}}</a></li> <li ng-class="{active: n.isActive('/import-persons')}"><a ui-sref="persons.import">{{'Import persons' | translate}}</a></li>
<li ng-class="{active: n.isActive('/import-persons')}"><a ng-href="#/import-persons">{{'Import persons' | translate}}</a></li>
</ul> </ul>
</div> </div>
</div> </div>
@ -57,7 +57,7 @@
<!-- all the magic takes place here: the content inside the next div <!-- all the magic takes place here: the content inside the next div
changes accordingly to the location you're visiting --> changes accordingly to the location you're visiting -->
<div ng-view></div> <div ui-view></div>
<div class="main-footer"> <div class="main-footer">
</div> </div>

77
angular_app/js/app.js vendored
View file

@ -20,11 +20,19 @@ var eventManApp = angular.module('eventManApp', [
'eventManServices', 'eventManServices',
'eventManControllers', 'eventManControllers',
'ui.bootstrap', 'ui.bootstrap',
'ui.router',
'pascalprecht.translate', 'pascalprecht.translate',
'angularFileUpload' 'angularFileUpload'
]); ]);
/* Add some utilities to the global scope. */
eventManApp.run(function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
});
/* Directive that can be used to make an input field react to the press of Enter. */ /* Directive that can be used to make an input field react to the press of Enter. */
eventManApp.directive('ngEnter', function () { eventManApp.directive('ngEnter', function () {
return function (scope, element, attrs) { return function (scope, element, attrs) {
@ -40,41 +48,56 @@ eventManApp.directive('ngEnter', function () {
}); });
/* Configure the routes. */ /* Configure the states. */
eventManApp.config(['$routeProvider', eventManApp.config(['$stateProvider', '$urlRouterProvider',
function($routeProvider) { function($stateProvider, $urlRouterProvider) {
$routeProvider. $urlRouterProvider.otherwise("/events");
when('/persons', { $stateProvider
templateUrl: 'persons-list.html', .state('events', {
controller: 'PersonsListCtrl' url: '/events',
}).
when('/persons/:id', {
templateUrl: 'person-detail.html',
controller: 'PersonDetailsCtrl'
}).
when('/events', {
templateUrl: 'events-list.html', templateUrl: 'events-list.html',
controller: 'EventsListCtrl' controller: 'EventsListCtrl'
}). })
when('/events/:id', { .state('event', {
templateUrl: 'event-detail.html', url: '/event',
templateUrl: 'event-main.html',
})
.state('event.new', {
url: '/new',
templateUrl: 'event-edit.html',
controller: 'EventDetailsCtrl' controller: 'EventDetailsCtrl'
}). })
when('/new-event', { .state('event.edit', {
templateUrl: 'event-detail.html', url: '/:id/edit',
templateUrl: 'event-edit.html',
controller: 'EventDetailsCtrl' controller: 'EventDetailsCtrl'
}). })
when('/new-person', { .state('event.info', {
url: '/:id',
templateUrl: 'event-info.html',
controller: 'EventDetailsCtrl'
})
.state('persons.list', {
url: '/persons',
templateUrl: 'persons-list.html',
controller: 'PersonsListCtrl'
})
.state('persons.info', {
url: '/persons/:id',
templateUrl: 'persons-detail.html',
controller: 'PersonDetailsCtrl'
})
.state('persons.new', {
url: '/new-person',
templateUrl: 'person-detail.html', templateUrl: 'person-detail.html',
controller: 'PersonDetailsCtrl' controller: 'PersonDetailsCtrl'
}). })
when('/import-persons', { .state('persons.import', {
url: '/personsaaa',
templateUrl: 'import-persons.html', templateUrl: 'import-persons.html',
controller: 'ImportPersonsCtrl' controller: 'ImportPersonsCtrl'
}). }
otherwise({ );
redirectTo: '/events'
});
} }
]); ]);

View file

@ -52,10 +52,10 @@ eventManControllers.controller('EventsListCtrl', ['$scope', 'Event',
); );
eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routeParams', '$log', eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$stateParams', '$log',
function ($scope, Event, $routeParams, $log) { function ($scope, Event, $stateParams, $log) {
if ($routeParams.id) { if ($stateParams.id) {
$scope.event = Event.get($routeParams); $scope.event = Event.get($stateParams);
} }
// store a new Event or update an existing one // store a new Event or update an existing one
$scope.save = function() { $scope.save = function() {
@ -73,11 +73,11 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routePa
}; };
$scope.updateAttendee = function(person, attended) { $scope.updateAttendee = function(person, attended) {
$log.debug('EventDetailsCtrl.event_id: ' + $routeParams.id); $log.debug('EventDetailsCtrl.event_id: ' + $stateParams.id);
$log.debug('EventDetailsCtrl.person_id: ' + person.person_id); $log.debug('EventDetailsCtrl.person_id: ' + person.person_id);
$log.debug('EventDetailsCtrl.attended: ' + attended); $log.debug('EventDetailsCtrl.attended: ' + attended);
Event.personAttended({ Event.personAttended({
_id: $routeParams.id, _id: $stateParams.id,
person_id: person.person_id, person_id: person.person_id,
'persons.$.attended': attended 'persons.$.attended': attended
}, },
@ -90,7 +90,7 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routePa
$scope.removeAttendee = function(person) { $scope.removeAttendee = function(person) {
Event.deleteAttendee({ Event.deleteAttendee({
_id: $routeParams.id, _id: $stateParams.id,
person_id: person.person_id person_id: person.person_id
}, },
function(data) { function(data) {
@ -115,11 +115,11 @@ eventManControllers.controller('PersonsListCtrl', ['$scope', 'Person',
); );
eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$routeParams', 'Person', 'Event', '$log', eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$stateParams', 'Person', 'Event', '$log',
function ($scope, $routeParams, Person, Event, $log) { function ($scope, $stateParams, Person, Event, $log) {
if ($routeParams.id) { if ($stateParams.id) {
$scope.person = Person.get($routeParams); $scope.person = Person.get($stateParams);
Person.getEvents($routeParams, function(data) { Person.getEvents($stateParams, function(data) {
$scope.events = data; $scope.events = data;
}); });
} }
@ -132,16 +132,16 @@ eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$routeParams', '
} }
}; };
$scope.updateAttendee = function(event, attended) { $scope.updateAttendee = function(event, attended) {
$log.debug('PersonDetailsCtrl.event_id: ' + $routeParams.id); $log.debug('PersonDetailsCtrl.event_id: ' + $stateParams.id);
$log.debug('PersonDetailsCtrl.event_id: ' + event.event_id); $log.debug('PersonDetailsCtrl.event_id: ' + event.event_id);
$log.debug('PersonDetailsCtrl.attended: ' + attended); $log.debug('PersonDetailsCtrl.attended: ' + attended);
Event.personAttended({ Event.personAttended({
_id: event._id, _id: event._id,
person_id: $routeParams.id, person_id: $stateParams.id,
'persons.$.attended': attended 'persons.$.attended': attended
}, },
function(data) { function(data) {
Person.getEvents($routeParams, function(data) { Person.getEvents($stateParams, function(data) {
$log.debug('PersonDetailsCtrl.personAttended.data'); $log.debug('PersonDetailsCtrl.personAttended.data');
$log.debug(data); $log.debug(data);
$scope.events = data; $scope.events = data;

View file

@ -0,0 +1,57 @@
<!-- show details of a single Person (editing also take place here) -->
<div class="container">
<form ng-model="persondetails" ng-submit="save()">
<div class="input-group input-group-lg">
<span class="input-group-addon">Name</span>
<input type="text" class="form-control" placeholder="Name" ng-model="person.name" ng-required="1">
</div>
<div class="input-group input-group-lg top5">
<span class="input-group-addon">Surname</span>
<input type="text" class="form-control" placeholder="Surname" ng-model="person.surname">
</div>
<div class="input-group top5">
<span class="input-group-addon">Email</span>
<input type="email" name="email" class="form-control" placeholder="root@example.com" ng-model="person.email">
</div>
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
</form>
<div class="panel panel-primary table-striped top5">
<div class="panel-heading">Events</div>
<div class="panel-body">
<form class="form-inline">
<div class="form-group">
<label for="query-persons">Search:</label>
<input type="text" id="query-persons" class="form-control" placeholder="Name or email" ng-model="query">
</div>
<div class="form-group">
<label for="events-order">Sort by:</label>
<select id="events-order" class="form-control" ng-model="orderProp">
<option value="name" ng-selected="selected">Alphabetical</option>
<option value="date">Date</option>
</select>
</div>
</form>
<table class="table">
<thead>
<tr>
<th>Event</th>
<th>Attended</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="event in events">
<td><a href="/#/events/{{event._id}}">{{event.title}}</a></td>
<td>
<button class="btn btn-link" name="switch-attended" ng-click="updateAttendee(event, !event.person_data.attended)"><span class="glyphicon {{(event.person_data.attended) && 'glyphicon-ok-sign text-success' || 'glyphicon-remove-sign text-danger'}}"></span></button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View file

@ -223,5 +223,6 @@ class EventManDB(object):
db = self.connect() db = self.connect()
if not isinstance(_id_or_query, dict): if not isinstance(_id_or_query, dict):
_id_or_query = {'_id': _id_or_query} _id_or_query = {'_id': _id_or_query}
_id_or_query = self.convert(_id_or_query)
db[collection].remove(_id_or_query) db[collection].remove(_id_or_query)

View file

@ -1,6 +1,6 @@
/* nav-bar padding */ /* nav-bar padding */
body { padding-top: 65px; } body { padding-top: 70px; }
/* fix styling for empty href */ /* fix styling for empty href */
.nav, .pagination, .carousel, .panel-title a { cursor: pointer; } .nav, .pagination, .carousel, .panel-title a { cursor: pointer; }