Browse Source

Merge branch 'settings'

* settings:
  rename service methods
  rename service methods
  remove duplicated functions
  custom columns for persons registered at an event
  custom fields in person edit form
  custom fields in persons list
Davide Alberani 9 years ago
parent
commit
852a7a3aa2

+ 12 - 1
angular_app/event-info.html

@@ -49,6 +49,9 @@
                                 <tr>
                                     <th>{{'Person' | translate}}</th>
                                     <th>{{'Attended' | translate}}</th>
+                                    <td ng-repeat="col in customFields">
+                                        <strong>{{col.label | translate}}</strong>
+                                    </td>
                                     <th>{{'Delete' | translate}}</th>
                                 </tr>
                             </thead>
@@ -59,8 +62,16 @@
                                         <p ng-if="person.company || person.job"><i ng-if="person.job">{{person.job}}</i><span ng-if="person.company && person.job">&nbsp;@&nbsp;</span><i ng-if="person.company">{{person.company}}</i></p>
                                     </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>
+                                        <button class="btn btn-link" name="switch-attended" ng-click="setPersonAttribute(person, 'attended', !person.attended)"><span class="glyphicon {{(person.attended) && 'glyphicon-ok-sign text-success' || 'glyphicon-remove-sign text-danger'}}"></span></button>
                                     </td>
+                                <td ng-repeat="col in customFields">
+                                    <span ng-if="col.type == 'boolean'">
+                                        <button class="btn btn-link" ng-click="setPersonAttribute(person, col.key, !person[col.key])"><span class="glyphicon {{(person[col.key]) && 'glyphicon-ok-sign text-success' || 'glyphicon-remove-sign text-danger'}}"></span></button>
+                                    </span>
+                                    <span ng-if="col.type != 'boolean'">
+                                        {{person[col.key]}}
+                                    </span>
+                                </td>
                                     <td>
                                         <button ng-click="removeAttendee(person)" type="button" class="btn btn-link glyphicon glyphicon-trash"></button>
                                     </td>

+ 43 - 35
angular_app/js/controllers.js

@@ -53,11 +53,14 @@ eventManControllers.controller('EventsListCtrl', ['$scope', 'Event',
 );
 
 
-eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', 'Person', '$stateParams', '$log',
-    function ($scope, Event, Person, $stateParams, $log) {
+eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', 'Person', '$stateParams', 'Setting', '$log',
+    function ($scope, Event, Person, $stateParams, Setting, $log) {
         $scope.personsOrderProp = 'name';
         $scope.eventsOrderProp = '-begin-date';
         $scope.countAttendees = 0;
+        $scope.customFields = Setting.query({setting: 'person_custom_field',
+            in_event_details: true});
+
         if ($stateParams.id) {
             $scope.event = Event.get($stateParams, function() {
                 $scope.$watchCollection(function() {
@@ -68,6 +71,7 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', 'Person',
             });
             $scope.allPersons = Person.all();
         }
+
         // store a new Event or update an existing one
         $scope.save = function() {
                 // avoid override of event.persons list.
@@ -97,11 +101,11 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', 'Person',
             $scope.countAttendees = attendees;
         };
 
-        $scope._addAttendee = function(person_data) {
+        $scope._addPerson = function(person_data) {
             person_data.person_id = person_data._id;
             person_data._id = $stateParams.id;
             person_data.attended = true;
-            Event.addAttendee(person_data, function() {
+            Event.addPerson(person_data, function() {
                 $scope.event = Event.get($stateParams);
                 $scope.allPersons = Person.all();
                 $scope.newPerson = {};
@@ -114,31 +118,29 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', 'Person',
             if (isNew) {
                 var personObj = new Person(person);
                 personObj.$save(function(p) {
-                    $scope._addAttendee(angular.copy(p));
+                    $scope._addPerson(angular.copy(p));
                 });
             } else {
-                $scope._addAttendee(angular.copy(person));
+                $scope._addPerson(angular.copy(person));
             }
         };
 
-        $scope.updateAttendee = function(person, attended) {
-            $log.debug('EventDetailsCtrl.event_id: ' + $stateParams.id);
-            $log.debug('EventDetailsCtrl.person_id: ' + person.person_id);
-            $log.debug('EventDetailsCtrl.attended: ' + attended);
-            Event.personAttended({
-                    _id: $stateParams.id,
-                    person_id: person.person_id,
-                    'attended': attended
-                },
+        $scope.setPersonAttribute = function(person, key, value) {
+            $log.debug('EventDetailsCtrl.setPersonAttribute.event_id: ' + $stateParams.id);
+            $log.debug('EventDetailsCtrl.setPersonAttribute.person_id: ' + person.person_id);
+            $log.debug('EventDetailsCtrl.setPersonAttribute.key: ' + key + ' value: ' + value);
+            var data = {_id: $stateParams.id, person_id: person.person_id};
+            data[key] = value;
+            Event.updatePerson(data,
                 function(data) {
-                    $log.debug('EventDetailsCtrl.personAttended.data');
+                    $log.debug('EventDetailsCtrl.setPersonAttribute.data');
                     $log.debug(data);
                     $scope.event.persons = data;
             });
         };
-                
+
         $scope.removeAttendee = function(person) {
-            Event.deleteAttendee({
+            Event.deletePerson({
                     _id: $stateParams.id,
                     person_id: person.person_id
                 },
@@ -151,11 +153,21 @@ eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', 'Person',
 );
 
 
-eventManControllers.controller('PersonsListCtrl', ['$scope', 'Person',
-    function ($scope, Person) {
+eventManControllers.controller('PersonsListCtrl', ['$scope', 'Person', 'Setting',
+    function ($scope, Person, Setting) {
         $scope.persons = Person.all();
         $scope.personsOrderProp = 'name';
         $scope.eventsOrderProp = '-begin-date';
+        $scope.customFields = Setting.query({setting: 'person_custom_field',
+            in_persons_list: true});
+
+        $scope.setAttribute = function(person, key, value) {
+            var data = {_id: person._id};
+            data[key] = value;
+            Person.update(data, function() {
+                $scope.persons = Person.all();
+            });
+        };
 
         $scope.remove = function(_id) {
             Person.remove({'id': _id}, function() {
@@ -166,11 +178,12 @@ eventManControllers.controller('PersonsListCtrl', ['$scope', 'Person',
 );
 
 
-eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$stateParams', 'Person', 'Event', '$log',
-    function ($scope, $stateParams, Person, Event, $log) {
+eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$stateParams', 'Person', 'Event', 'Setting', '$log',
+    function ($scope, $stateParams, Person, Event, Setting, $log) {
         $scope.personsOrderProp = 'name';
         $scope.eventsOrderProp = '-begin-date';
         $scope.addToEvent = '';
+        $scope.customFields = Setting.query({setting: 'person_custom_field'});
 
         if ($stateParams.id) {
             $scope.person = Person.get($stateParams);
@@ -188,7 +201,7 @@ eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$stateParams', '
                         data.person_id = data._id;
                         data._id = $scope.addToEvent;
                         data.attended = false;
-                        Event.addAttendee(data);
+                        Event.addPerson(data);
                     }
                 });
             } else {
@@ -198,22 +211,17 @@ eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$stateParams', '
                         data._id = $scope.addToEvent;
                         data.person_id = $scope.person._id;
                         data.attended = false;
-                        Event.addAttendee(data);
+                        Event.addPerson(data);
                     }
                 });
             }
             $scope.personForm.$dirty = false;
         };
 
-        $scope.updateAttendee = function(event, attended) {
-            $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: $stateParams.id,
-                    'attended': attended
-                },
+        $scope.setPersonAttributeAtEvent = function(evnt, key, value) {
+            var attrs = {_id: evnt._id, person_id: $stateParams.id};
+            attrs[key] = value;
+            Event.updatePerson(attrs,
                 function(data) {
                     $scope.events = Person.getEvents({_id: $stateParams.id, all: true});
                 }
@@ -229,13 +237,13 @@ eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$stateParams', '
                 data._id = evnt._id;
                 data.person_id = person._id;
                 data.attended = false;
-                Event.addAttendee(data,
+                Event.addPerson(data,
                     function(data) {
                         $scope.events = Person.getEvents({_id: $stateParams.id, all: true});
                     }
                 );
             } else {
-                Event.deleteAttendee({_id: evnt._id, person_id: person._id},
+                Event.deletePerson({_id: evnt._id, person_id: person._id},
                     function(data) {
                         $scope.events = Person.getEvents({_id: $stateParams.id, all: true});
                     }

+ 48 - 3
angular_app/js/services.js

@@ -31,7 +31,7 @@ eventManServices.factory('Event', ['$resource',
 
             update: {method: 'PUT'},
 
-            personAttended: {
+            updatePerson: {
                 method: 'PUT',
                 isArray: true,
                 url: 'events/:id/persons/:person_id',
@@ -40,7 +40,7 @@ eventManServices.factory('Event', ['$resource',
                 }
             },
 
-            addAttendee: {
+            addPerson: {
                 method: 'POST',
                 isArray: true,
                 url: 'events/:id/persons/:person_id',
@@ -49,7 +49,7 @@ eventManServices.factory('Event', ['$resource',
                 }
             },
 
-            deleteAttendee: {
+            deletePerson: {
                 method: 'DELETE',
                 isArray: true,
                 url: 'events/:_id/persons/:person_id',
@@ -88,3 +88,48 @@ eventManServices.factory('Person', ['$resource',
     }]
 );
 
+
+eventManServices.factory('Person', ['$resource',
+    function($resource) {
+        return $resource('persons/:id', {id: '@_id'}, {
+
+            all: {
+                method: 'GET',
+                isArray: true,
+                transformResponse: function(data, headers) {
+                    return angular.fromJson(data).persons;
+                }
+            },
+
+            update: {method: 'PUT'},
+
+            getEvents: {
+                method: 'GET',
+                url: 'persons/:_id/events',
+                isArray: true,
+                transformResponse: function(data, headers) {
+                    return angular.fromJson(data).events;
+                }
+            }
+        });
+    }]
+);
+
+
+eventManServices.factory('Setting', ['$resource',
+    function($resource) {
+        return $resource('settings/', {}, {
+
+            query: {
+                method: 'GET',
+                isArray: true,
+                transformResponse: function(data, headers) {
+                    return angular.fromJson(data).settings;
+                }
+            },
+
+            update: {method: 'PUT'},
+        });
+    }]
+);
+

+ 6 - 0
angular_app/person-edit.html

@@ -47,6 +47,12 @@
                 <tr ng-repeat="event in events | splittedFilter:query | orderBy:eventsOrderProp">
         </div>
 
+        <div ng-repeat="custom in customFields" class="form-group top5">
+            <label for="custom_{{custom['key']}}">{{custom.label | translate}}</span>
+            <input ng-if="custom.type == 'boolean'" id="custom_{{custm['key']}}" type="checkbox" class="form-control" placeholder="{{custom.label | translate}}" ng-model="person[custom.key]">
+            <input ng-if="custom.type != 'boolean'" id="custom_{{custm['key']}}" type="text" class="form-control" placeholder="{{custom.label | translate}}" ng-model="person[custom.key]">
+        </div>
+
         <input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
     </form>
 </div>

+ 1 - 1
angular_app/person-info.html

@@ -39,7 +39,7 @@
                             <button class="btn btn-link" name="switch-registered" ng-click="switchRegistered(event, person, !event.person_data.person_id)"><span class="glyphicon {{(event.person_data.person_id) && 'glyphicon-ok-sign text-success' || 'glyphicon-remove-sign text-danger'}}"></span></button>
                         </td>
                         <td>
-                            <button ng-disabled="!event.person_data.person_id" 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>
+                            <button ng-disabled="!event.person_data.person_id" class="btn btn-link" name="switch-attended" ng-click="setPersonAttributeAtEvent(event, 'attended', !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>

+ 11 - 0
angular_app/persons-list.html

@@ -33,6 +33,9 @@
                 <thead>
                     <tr>
                         <td><strong>{{'Name' | translate}}</strong></td>
+                        <td ng-repeat="col in customFields">
+                            <strong>{{col.label | translate}}</strong>
+                        </td>
                         <td><strong>{{'Delete' | translate}}</strong></td>
                     </tr>
                 </thead>
@@ -42,6 +45,14 @@
                         <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"><i ng-if="person.job">{{person.job}}</i><span ng-if="person.company && person.job">&nbsp;@&nbsp;</span><i ng-if="person.company">{{person.company}}</i></p>
                     </td>
+                    <td ng-repeat="col in customFields">
+                        <span ng-if="col.type == 'boolean'">
+                            <button class="btn btn-link" ng-click="setAttribute(person, col.key, !person[col.key])"><span class="glyphicon {{(person[col.key]) && 'glyphicon-ok-sign text-success' || 'glyphicon-remove-sign text-danger'}}"></span></button>
+                        </span>
+                        <span ng-if="col.type != 'boolean'">
+                            {{person[col.key]}}
+                        </span>
+                    </td>
                     <td>
                         <button ng-click="remove(person._id)" type="button" class="btn btn-link glyphicon glyphicon-trash"></button>
                     </td>

+ 2 - 0
backend.py

@@ -73,6 +73,8 @@ class EventManDB(object):
         """
         if obj is None:
             return None
+        if isinstance(obj, bool):
+            return obj
         try:
             return ObjectId(obj)
         except:

+ 25 - 6
eventman_server.py

@@ -39,13 +39,23 @@ PROCESS_TIMEOUT = 60
 
 class BaseHandler(tornado.web.RequestHandler):
     """Base class for request handlers."""
+    # A property to access the first value of each argument.
+    arguments = property(lambda self: dict([(k, v[0])
+        for k, v in self.request.arguments.iteritems()]))
+
     _bool_convert = {
         '0': False,
         'n': False,
         'f': False,
         'no': False,
         'off': False,
-        'false': False
+        'false': False,
+        '1': True,
+        'y': True,
+        't': True,
+        'on': True,
+        'yes': True,
+        'true': True
     }
 
     def tobool(self, obj):
@@ -53,7 +63,10 @@ class BaseHandler(tornado.web.RequestHandler):
             obj = obj[0]
         if isinstance(obj, (str, unicode)):
             obj = obj.lower()
-        return bool(self._bool_convert.get(obj, obj))
+        return self._bool_convert.get(obj, obj)
+
+    def _arguments_tobool(self):
+        return dict([(k, self.tobool(v)) for k, v in self.arguments.iteritems()])
 
     def initialize(self, **kwargs):
         """Add every passed (key, value) as attributes of the instance."""
@@ -101,10 +114,6 @@ class CollectionHandler(BaseHandler):
                 filtered.append(result)
         return filtered
 
-    # A property to access the first value of each argument.
-    arguments = property(lambda self: dict([(k, v[0])
-        for k, v in self.request.arguments.iteritems()]))
-
     def _dict2env(self, data):
         """Convert a dictionary into a form suitable to be passed as environment variables."""
         ret = {}
@@ -399,6 +408,15 @@ class EbCSVImportPersonsHandler(BaseHandler):
         self.write(reply)
 
 
+class SettingsHandler(BaseHandler):
+    """Handle requests for Settings."""
+    @gen.coroutine
+    def get(self, **kwds):
+        query = self._arguments_tobool()
+        settings = self.db.query('settings', query)
+        self.write({'settings': settings})
+
+
 def run():
     """Run the Tornado web application."""
     # command line arguments; can also be written in a configuration file,
@@ -428,6 +446,7 @@ def run():
             (r"/events/?(?P<id_>\w+)?/?(?P<resource>\w+)?/?(?P<resource_id>\w+)?", EventsHandler, init_params),
             (r"/(?:index.html)?", RootHandler, init_params),
             (r"/ebcsvpersons", EbCSVImportPersonsHandler, init_params),
+            (r"/settings", SettingsHandler, init_params),
             (r'/(.*)', tornado.web.StaticFileHandler, {"path": "angular_app"})
         ],
         template_path=os.path.join(os.path.dirname(__file__), "templates"),