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) -->
<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()">
<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</button>
<button type="button" class="btn btn-default pull-right" ng-click="save($event)" ng-disabled="!eventForm.$dirty">{{'save' | translate}}</button>
</alert>
<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">
</div>
<div class="input-group top5 well form-horizontal" ng-controller="DatetimePickerCtrl">
<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">
<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">
@ -22,14 +27,14 @@
</div>
</div>
<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>
</div>
</div>
<div class="input-group top5 well form-horizontal" ng-controller="DatetimePickerCtrl">
<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">
<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">
@ -38,50 +43,11 @@
</div>
</div>
<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>
</div>
</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">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>

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 -->
<div class="container">
<div class="row">
<div class="col-lg-12">
<form class="form-inline">
<div class="form-group">
<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>
<form class="form-inline">
<div class="form-group">
<label for="query-events">Search:</label>
<input type="text" id="query-events" class="form-control" placeholder="Event title" ng-model="query">
</div>
</div>
</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>
<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">
<thead>
<tr>
@ -30,7 +30,7 @@
<tbody>
<tr ng-repeat="event in events | filter:query | orderBy:orderProp">
<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/>
Ends: {{event['end-datetime']}}</p>
</td>

View file

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

77
angular_app/js/app.js vendored
View file

@ -20,11 +20,19 @@ var eventManApp = angular.module('eventManApp', [
'eventManServices',
'eventManControllers',
'ui.bootstrap',
'ui.router',
'pascalprecht.translate',
'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. */
eventManApp.directive('ngEnter', function () {
return function (scope, element, attrs) {
@ -40,41 +48,56 @@ eventManApp.directive('ngEnter', function () {
});
/* Configure the routes. */
eventManApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/persons', {
templateUrl: 'persons-list.html',
controller: 'PersonsListCtrl'
}).
when('/persons/:id', {
templateUrl: 'person-detail.html',
controller: 'PersonDetailsCtrl'
}).
when('/events', {
/* Configure the states. */
eventManApp.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/events");
$stateProvider
.state('events', {
url: '/events',
templateUrl: 'events-list.html',
controller: 'EventsListCtrl'
}).
when('/events/:id', {
templateUrl: 'event-detail.html',
})
.state('event', {
url: '/event',
templateUrl: 'event-main.html',
})
.state('event.new', {
url: '/new',
templateUrl: 'event-edit.html',
controller: 'EventDetailsCtrl'
}).
when('/new-event', {
templateUrl: 'event-detail.html',
})
.state('event.edit', {
url: '/:id/edit',
templateUrl: 'event-edit.html',
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',
controller: 'PersonDetailsCtrl'
}).
when('/import-persons', {
})
.state('persons.import', {
url: '/personsaaa',
templateUrl: 'import-persons.html',
controller: 'ImportPersonsCtrl'
}).
otherwise({
redirectTo: '/events'
});
}
);
}
]);

View file

@ -52,10 +52,10 @@ eventManControllers.controller('EventsListCtrl', ['$scope', 'Event',
);
eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routeParams', '$log',
function ($scope, Event, $routeParams, $log) {
if ($routeParams.id) {
$scope.event = Event.get($routeParams);
eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$stateParams', '$log',
function ($scope, Event, $stateParams, $log) {
if ($stateParams.id) {
$scope.event = Event.get($stateParams);
}
// store a new Event or update an existing one
$scope.save = function() {
@ -73,11 +73,11 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routePa
};
$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.attended: ' + attended);
Event.personAttended({
_id: $routeParams.id,
_id: $stateParams.id,
person_id: person.person_id,
'persons.$.attended': attended
},
@ -90,7 +90,7 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routePa
$scope.removeAttendee = function(person) {
Event.deleteAttendee({
_id: $routeParams.id,
_id: $stateParams.id,
person_id: person.person_id
},
function(data) {
@ -115,11 +115,11 @@ eventManControllers.controller('PersonsListCtrl', ['$scope', 'Person',
);
eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$routeParams', 'Person', 'Event', '$log',
function ($scope, $routeParams, Person, Event, $log) {
if ($routeParams.id) {
$scope.person = Person.get($routeParams);
Person.getEvents($routeParams, function(data) {
eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$stateParams', 'Person', 'Event', '$log',
function ($scope, $stateParams, Person, Event, $log) {
if ($stateParams.id) {
$scope.person = Person.get($stateParams);
Person.getEvents($stateParams, function(data) {
$scope.events = data;
});
}
@ -132,16 +132,16 @@ eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$routeParams', '
}
};
$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.attended: ' + attended);
Event.personAttended({
_id: event._id,
person_id: $routeParams.id,
person_id: $stateParams.id,
'persons.$.attended': attended
},
function(data) {
Person.getEvents($routeParams, function(data) {
Person.getEvents($stateParams, function(data) {
$log.debug('PersonDetailsCtrl.personAttended.data');
$log.debug(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()
if not isinstance(_id_or_query, dict):
_id_or_query = {'_id': _id_or_query}
_id_or_query = self.convert(_id_or_query)
db[collection].remove(_id_or_query)

View file

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