From 99c3428267a147b97e5e31af9cbed5ef5f198a40 Mon Sep 17 00:00:00 2001
From: degygii <lukas.gygi@gmail.com>
Date: Mon, 9 May 2016 16:30:06 +0200
Subject: [PATCH] added stuff to event tool and groups tool

---
 admin/tools/events.tool | 1199 ++++++++++++++++++++-------------------
 admin/tools/groups.tool |   21 +-
 2 files changed, 621 insertions(+), 599 deletions(-)

diff --git a/admin/tools/events.tool b/admin/tools/events.tool
index d6b0f43..6aac268 100644
--- a/admin/tools/events.tool
+++ b/admin/tools/events.tool
@@ -1,638 +1,655 @@
 <div class="events-table-wrapper">
-  <div class="tools-full-height">
-    <table class="table table-hover events-table" id="events-table">
-      <thead>
-        <tr>
-          <th>Title</th>
-          <th>Date</th>
-          <th>on website</th>
-          <th>spots</th>
-        </tr>
-      </thead>
-      <tbody>
-      </tbody>
-    </table>
-  </div>
+    <div class="tools-full-height">
+        <table class="table table-hover events-table" id="events-table">
+            <thead>
+                <tr>
+                    <th>Title</th>
+                    <th>Date</th>
+                    <th>on website</th>
+                    <th>spots</th>
+                    <th>signups</th>
+                </tr>
+            </thead>
+            <tbody>
+            </tbody>
+        </table>
+    </div>
 </div>
 
 <!-- modal for creating new events, easier to do it this way than js-->
 
 <div class="modal fade" id="new-event-modal" role="dialog">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <button type="button" class="close" data-dismiss="modal">&times;</button>
-        <h4 class="modal-title">Create new Event</h4>
-      </div>
-      <div class="modal-body">
-        <form id="new-event">
-          <div class="form-group">
-            <label for="title_de">Title</label>
-            <input type="text" class="form-control" id="title_de"></input>
-          </div>
-          <div class="form-group">
-            <label for="description_de">Description</label>
-            <textarea type="text" class="form-control" rows="3" id="description_de"></textarea>
-          </div>
-          <div class="form-group">
-            <label for="catchphrase_de">Catchphrase</label>
-            <input type="text" class="form-control" id="catchphrase_de"></input>
-          </div>
-
-          <!-- <div class="container"> -->
-          <!-- <div class="col-md-3"> -->
-          <div class="form-group">
-            <label for="time_start">Start Time</label>
-            <div class="input-group date" id="time_start">
-              <input type="text" class="form-control" />
-              <span class="input-group-addon">
-                    <span class="glyphicon-calendar glyphicon"></span>
-              </span>
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal">&times;</button>
+                <h4 class="modal-title">Create new Event</h4>
             </div>
-          </div>
-          <!-- </div> -->
-          <!-- <div class="col-md-3"> -->
-          <div class="form-group">
-            <label for="time_end">End Time</label>
-            <div class="input-group date" id="time_end">
-              <input type="text" class="form-control" />
-              <span class="input-group-addon">
+            <div class="modal-body">
+                <form id="new-event">
+                    <div class="form-group">
+                        <label for="title_de">Title</label>
+                        <input type="text" class="form-control" id="title_de"></input>
+                    </div>
+                    <div class="form-group">
+                        <label for="description_de">Description</label>
+                        <textarea type="text" class="form-control" rows="3" id="description_de"></textarea>
+                    </div>
+                    <div class="form-group">
+                        <label for="catchphrase_de">Catchphrase</label>
+                        <input type="text" class="form-control" id="catchphrase_de"></input>
+                    </div>
+
+                    <!-- <div class="container"> -->
+                    <!-- <div class="col-md-3"> -->
+                    <div class="form-group">
+                        <label for="time_start">Start Time</label>
+                        <div class="input-group date" id="time_start">
+                            <input type="text" class="form-control" />
+                            <span class="input-group-addon">
                     <span class="glyphicon-calendar glyphicon"></span>
-              </span>
-            </div>
-          </div>
-          <!-- </div> -->
-          <!-- </div> -->
-
-          <label class="checkbox-inline">
-            <input type="checkbox" id="signup-required" value="">No Signup
-          </label>
-
-          <label class="checkbox-inline">
-            <input type="checkbox" id="no-signup-limit" value="">No Signup Limit
-          </label>
-
-          <div class="form-group">
-            <label for="spots">Spots</label>
-            <input type="number" class="form-control" min="-1" id="spots"></input>
-          </div>
-
-          <!-- <div class="container"> -->
-          <!-- <div class="col-md-3"> -->
-          <div class="form-group">
-            <label for="time_register_start">Start of Registration</label>
-            <div class="input-group date" id="time_register_start">
-              <input type="text" class="form-control" />
-              <span class="input-group-addon">
+                            </span>
+                        </div>
+                    </div>
+                    <!-- </div> -->
+                    <!-- <div class="col-md-3"> -->
+                    <div class="form-group">
+                        <label for="time_end">End Time</label>
+                        <div class="input-group date" id="time_end">
+                            <input type="text" class="form-control" />
+                            <span class="input-group-addon">
                     <span class="glyphicon-calendar glyphicon"></span>
-              </span>
-            </div>
-          </div>
-          <!-- </div> -->
-          <!-- <div class="col-md-3"> -->
-          <div class="form-group">
-            <label for="time_register_end">End of Registration</label>
-            <div class="input-group date" id="time_register_end">
-              <input type="text" class="form-control" />
-              <span class="input-group-addon">
+                            </span>
+                        </div>
+                    </div>
+                    <!-- </div> -->
+                    <!-- </div> -->
+
+                    <label class="checkbox-inline">
+                        <input type="checkbox" id="signup-required" value="">No Signup
+                    </label>
+
+                    <label class="checkbox-inline">
+                        <input type="checkbox" id="no-signup-limit" value="">No Signup Limit
+                    </label>
+
+                    <div class="form-group">
+                        <label for="spots">Spots</label>
+                        <input type="number" class="form-control" min="-1" id="spots"></input>
+                    </div>
+
+                    <!-- <div class="container"> -->
+                    <!-- <div class="col-md-3"> -->
+                    <div class="form-group">
+                        <label for="time_register_start">Start of Registration</label>
+                        <div class="input-group date" id="time_register_start">
+                            <input type="text" class="form-control" />
+                            <span class="input-group-addon">
                     <span class="glyphicon-calendar glyphicon"></span>
-              </span>
-            </div>
-          </div>
-          <!-- </div> -->
-          <!-- </div> -->
-
-          <label class="checkbox-inline">
-            <input type="checkbox" id="allow_email_signup" value="">Only amiv Members
-          </label>
-
-          <div class="form-group">
-            <label for="location">Location</label>
-            <input type="text" class="form-control" id="location"></input>
-          </div>
-
-          <div class="form-group">
-            <label for="price">Price</label>
-            <input type="number" class="form-control" min="0" id="price"></input>
-          </div>
-
-          <div>
-            <label class="checkbox-inline">
-              <input type="checkbox" id="show_website" value="">Show on Webstite (requires banner image and title)
-            </label>
-          </div>
-          <div>
-            <label class="checkbox-inline">
-              <input type="checkbox" id="show_infoscreen" value="">Show ond Infoscreen (requires infoscreen image)
-            </label>
-          </div>
-          <div>
-            <label class="checkbox-inline">
-              <input type="checkbox" id="show_announce" value="">Show in Announce (requires stuff)
-            </label>
-          </div>
-
-          <div class="form-group">
-            <label for="description_de">Additional Fields (JSON schema)</label>
-            <textarea type="text" class="form-control" rows="3" id="additional_fields"></textarea>
-          </div>
-
-          <button type="button" class "btn" data-toggle="collapse" data-target="#english-collapse">show english fields</button>
-
-          <div id="english-collapse" class="collapse">
-            <div class="form-group">
-              <label for="title_en">Title english</label>
-              <input type="text" class="form-control" id="title_en"></input>
-            </div>
-            <div class="form-group">
-              <label for="description_en">Description english</label>
-              <textarea type="text" class="form-control" rows="3" id="description_en"></textarea>
+                            </span>
+                        </div>
+                    </div>
+                    <!-- </div> -->
+                    <!-- <div class="col-md-3"> -->
+                    <div class="form-group">
+                        <label for="time_register_end">End of Registration</label>
+                        <div class="input-group date" id="time_register_end">
+                            <input type="text" class="form-control" />
+                            <span class="input-group-addon">
+                    <span class="glyphicon-calendar glyphicon"></span>
+                            </span>
+                        </div>
+                    </div>
+                    <!-- </div> -->
+                    <!-- </div> -->
+
+                    <label class="checkbox-inline">
+                        <input type="checkbox" id="allow_email_signup" value="">Only amiv Members
+                    </label>
+
+                    <div class="form-group">
+                        <label for="location">Location</label>
+                        <input type="text" class="form-control" id="location"></input>
+                    </div>
+
+                    <div class="form-group">
+                        <label for="price">Price</label>
+                        <input type="number" class="form-control" min="0" id="price"></input>
+                    </div>
+
+                    <div>
+                        <label class="checkbox-inline">
+                            <input type="checkbox" id="show_website" value="">Show on Webstite (requires banner image and title)
+                        </label>
+                    </div>
+                    <div>
+                        <label class="checkbox-inline">
+                            <input type="checkbox" id="show_infoscreen" value="">Show ond Infoscreen (requires infoscreen image)
+                        </label>
+                    </div>
+                    <div>
+                        <label class="checkbox-inline">
+                            <input type="checkbox" id="show_announce" value="">Show in Announce (requires stuff)
+                        </label>
+                    </div>
+
+                    <div class="form-group">
+                        <label for="description_de">Additional Fields (JSON schema)</label>
+                        <textarea type="text" class="form-control" rows="3" id="additional_fields"></textarea>
+                    </div>
+
+                    <button type="button" class "btn" data-toggle="collapse" data-target="#english-collapse">show english fields</button>
+
+                    <div id="english-collapse" class="collapse">
+                        <div class="form-group">
+                            <label for="title_en">Title english</label>
+                            <input type="text" class="form-control" id="title_en"></input>
+                        </div>
+                        <div class="form-group">
+                            <label for="description_en">Description english</label>
+                            <textarea type="text" class="form-control" rows="3" id="description_en"></textarea>
+                        </div>
+                        <div class="form-group">
+                            <label for="catchphrase_en">Catchphrase english</label>
+                            <input type="text" class="form-control" id="catchphrase_en"></input>
+                        </div>
+                    </div>
+                    <!-- <input type="submit"> -->
+                </form>
             </div>
-            <div class="form-group">
-              <label for="catchphrase_en">Catchphrase english</label>
-              <input type="text" class="form-control" id="catchphrase_en"></input>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+                <button type="button" class="btn btn-primary" onclick="events.submitNewEvent()">Submit</button>
             </div>
-          </div>
-          <!-- <input type="submit"> -->
-        </form>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary" onclick="events.submitNewEvent()">Submit</button>
-      </div>
+        </div>
     </div>
-  </div>
 </div>
 
 <style>
-  .events-table-wrapper {
-    position: relative;
-  }
-
-  .events-table-wrapper>div {
-    overflow: auto;
-  }
-
-  #new-event-modal {
-    overflow: auto;
-  }
-
-  #new-event-modal .checkbox-inline {
-    margin-bottom: 10px;
-  }
-
-  .users-sidebar {
-    background: #fff;
-  }
-
-  .tooltip-inner {
-    white-space: nowrap;
-    max-width: none;
-  }
+    .events-table-wrapper {
+        position: relative;
+    }
+
+    .events-table-wrapper>div {
+        overflow: auto;
+    }
+
+    #new-event-modal {
+        overflow: auto;
+    }
+
+    #new-event-modal .checkbox-inline {
+        margin-bottom: 10px;
+    }
+
+    .users-sidebar {
+        background: #fff;
+    }
+
+    .tooltip-inner {
+        white-space: nowrap;
+        max-width: none;
+    }
 </style>
 
 <script type="text/javascript">
-  var events = {
-    showInTable: ['title_de', 'time_start', 'show_website', 'spots'],
-    curEventData: null,
-
-    // Page
-    page: {
-      max: Number.MAX_VALUE,
-      cur: function() {
-        return parseInt(tools.mem.session.get('curPage'));
-      },
-      set: function(num) {
-        num = parseInt(num);
-        if (num > 0 && num < events.page.max + 1)
-          tools.mem.session.set('curPage', num);
-        $('.events-cur-page-cont').html(events.page.cur());
-        events.get();
-      },
-      inc: function() {
-        events.page.set(events.page.cur() + 1);
-      },
-      dec: function() {
-        events.page.set(events.page.cur() - 1);
-      }
-    },
-
-    //Sorting
-    sort: {
-      cur: function() {
-        return tools.mem.session.get('curSort');
-      },
-      set: function(sort) {
-        tools.mem.session.set('curSort', sort);
-        events.get();
-      },
-      inv: function() {
-        var tmp = events.sort.cur();
-        if (tmp.charAt(0) == '-')
-          events.sort.set(tmp.slice(1));
-        else
-          events.sort.set('-' + tmp);
-      }
-    },
-
-    //Searching
-    search: {
-      cur: function() {
-        return tools.mem.session.get('search');
-      },
-      set: function(dom, val) {
-        tools.mem.session.set('search', dom + '==' + val);
-        events.page.set(1);
-      },
-      clr: function() {
-        tools.mem.session.set('search', '');
-        events.page.set(1);
-      },
-    },
-
-    get: function() {
-      $('#wheel-logo').css('transform', 'rotate(360deg)');
-      console.log('getting events...');
-      amivcore.events.GET({
-        data: {
-          'max_results': '50',
-          page: events.page.cur(),
-          sort: events.sort.cur(),
-          where: events.search.cur(),
-        }
-      }, function(ret) {
+    var events = {
+        showInTable: ['title_de', 'time_start', 'show_website', 'spots', 'signup_count'],
+        curEventData: null,
+
+        // Page
+        page: {
+            max: Number.MAX_VALUE,
+            cur: function() {
+                return parseInt(tools.mem.session.get('curPage'));
+            },
+            set: function(num) {
+                num = parseInt(num);
+                if (num > 0 && num < events.page.max + 1)
+                    tools.mem.session.set('curPage', num);
+                $('.events-cur-page-cont').html(events.page.cur());
+                events.get();
+            },
+            inc: function() {
+                events.page.set(events.page.cur() + 1);
+            },
+            dec: function() {
+                events.page.set(events.page.cur() - 1);
+            }
+        },
 
-        if (ret === undefined || ret['_items'].length == 0) {
-          tools.log('No Data', 'w');
-          return;
-        }
-        events.meta = ret['_meta'];
-        events.page.max = Math.ceil(events.meta.total / events.meta.max_results);
-        $('.events-page-max-cont').html(events.page.max);
-
-        // Clear table from previous contentent
-        $('.events-table tbody').html('');
-
-        for (var n in ret['_items']) {
-          var tmp = '';
-          events.showInTable.forEach(function(i) {
-            tmp += '<td>' + ret['_items'][n][i] + '</td>';
-          });
-          $('.events-table tbody').append('<tr data-id="' + ret['_items'][n]['id'] + '">' + tmp + '</tr>');
-        }
-        $('.events-table tbody tr').click(events.showDetails);
-        $('#wheel-logo').css('transform', 'rotate(0deg)');
-      });
+        //Sorting
+        sort: {
+            cur: function() {
+                return tools.mem.session.get('curSort');
+            },
+            set: function(sort) {
+                tools.mem.session.set('curSort', sort);
+                events.get();
+            },
+            inv: function() {
+                var tmp = events.sort.cur();
+                if (tmp.charAt(0) == '-')
+                    events.sort.set(tmp.slice(1));
+                else
+                    events.sort.set('-' + tmp);
+            }
+        },
 
-    },
+        //Searching
+        search: {
+            cur: function() {
+                return tools.mem.session.get('search');
+            },
+            set: function(dom, val) {
+                tools.mem.session.set('search', dom + '==' + val);
+                events.page.set(1);
+            },
+            clr: function() {
+                tools.mem.session.set('search', '');
+                events.page.set(1);
+            },
+        },
+
+        get: function() {
+            $('#wheel-logo').css('transform', 'rotate(360deg)');
+            console.log('getting events...');
+            amivcore.events.GET({
+                data: {
+                    'max_results': '50',
+                    page: events.page.cur(),
+                    sort: events.sort.cur(),
+                    where: events.search.cur(),
+                }
+            }, function(ret) {
+                console.log(ret);
+                if (ret === undefined || ret['_items'].length == 0) {
+                    tools.log('No Data', 'w');
+                    // Clear table from previous contentent
+                    $('.events-table tbody').html('');
+                    return;
+                }
+                events.meta = ret['_meta'];
+                events.page.max = Math.ceil(events.meta.total / events.meta.max_results);
+                $('.events-page-max-cont').html(events.page.max);
+
+                // Clear table from previous contentent
+                $('.events-table tbody').html('');
+
+                for (var n in ret['_items']) {
+                    var tmp = '';
+                    events.showInTable.forEach(function(i) {
+                        tmp += '<td>' + ret['_items'][n][i] + '</td>';
+                    });
+                    $('.events-table tbody').append('<tr data-id="' + ret['_items'][n]['id'] + '">' + tmp + '</tr>');
+                }
+                $('.events-table tbody tr').click(events.showDetails);
+                $('#wheel-logo').css('transform', 'rotate(0deg)');
+            });
 
+        },
 
 
-    showDetails: function() {
-      amivcore.events.GET({
-        id: $(this).attr('data-id')
-      }, function(ret) {
-        curEventData = ret;
-        console.log(curEventData);
-        var tmp = '<table class="table table-hover events-edit-table" data-etag="' + ret['_etag'] + '"><tbody>';
-        for (var cur in ret) {
-          if (cur.charAt(0) != '_' && cur != 'signups')
-            tmp += '<tr><td>' + cur + '</td><td contenteditable>' + ret[cur] + '</td></tr>'
-        }
-        tmp += '</tbody></table>';
-
-        tools.modal({
-          head: ret.title_de,
-          body: tmp,
-          button: {
-            'Delete': {
-              type: 'danger',
-              close: false,
-              callback: function() {
-                if (confirm("Delete " + ret.title_de + "?") == true) {
-                  amivcore.events.DELETE({
+
+        showDetails: function() {
+            amivcore.events.GET({
+                id: $(this).attr('data-id')
+            }, function(ret) {
+                curEventData = ret;
+                console.log(curEventData);
+                var tmp = '<table class="table table-hover events-edit-table" data-etag="' + ret['_etag'] + '"><tbody>';
+                for (var cur in ret) {
+                    if (cur.charAt(0) != '_' && cur != 'signups')
+                        tmp += '<tr><td>' + cur + '</td><td contenteditable>' + ret[cur] + '</td></tr>'
+                }
+                tmp += '</tbody></table>';
+
+                tools.modal({
+                    head: ret.title_de,
+                    body: tmp,
+                    button: {
+                        'Delete': {
+                            type: 'danger',
+                            close: false,
+                            callback: function() {
+                                if (confirm("Delete " + ret.title_de + "?") == true) {
+                                    amivcore.events.DELETE({
+                                        id: curEventData.id,
+                                        header: {
+                                            'If-Match': $('.events-edit-table').attr('data-etag')
+                                        }
+                                    }, function(response) {
+                                        console.log(response);
+                                    });
+                                    events.get();
+                                    tools.log('Event deleted', 'w');
+                                    tools.modalClose();
+                                } else {
+                                    tools.log('Event not Deleted', 'i');
+                                }
+                            }
+                        },
+                        'Signups': {
+                            type: 'info',
+                            close: false,
+                            callback: function() {
+                                events.showSignups(curEventData);
+                            }
+                        },
+                        'Update': {
+                            type: 'success',
+                            close: false,
+                            callback: events.inspectEvent
+                        }
+                    }
+                });
+            });
+        },
+
+        /*showDetails: function() {
+            amivcore.events.GET({
+                id: $(this).attr('data-id')
+            }, function(ret) {
+                curEventData = ret;
+                console.log(curEventData);
+                for (var attr in curEventData) {
+                  $('#' + attr).val(curEventData[attr]);
+                }
+                $('#new-event-modal').modal('show');
+            });
+        },*/
+
+        showSignups: function(curEventData) {
+            var tmp = '<table class="table table-hover events-edit-table" data-etag="' + curEventData['_etag'] + '"><tbody>';
+            for (var user in curEventData['signups']) {
+                tmp += '<tr><td>' + user + '</td><td contenteditable>' + curEventData['signups'][cur] + '</td></tr>';
+            }
+            tmp += '</tbody></table>';
+            tools.modal({
+                head: curEventData.title_de,
+                body: tmp,
+                button: {
+                    'Update': {
+                        type: 'success',
+                        close: false
+                            //callback
+                    }
+                }
+            });
+        },
+
+        inspectEvent: function() {
+            var newEventData = {};
+            $('.events-edit-table tr').each(function() {
+                newEventData[$(this).children('td:nth-child(1)').html()] = $(this).children('td:nth-child(2)').html();
+            });
+            var changed = false,
+                curEventDataChanged = {};
+            for (var i in newEventData) {
+                if (newEventData[i] != String(curEventData[i])) {
+                    changed = true;
+                    curEventDataChanged[i] = newEventData[i];
+                }
+            }
+            console.log(curEventDataChanged);
+            if (changed) {
+                //workaround to get booleans and ints working
+                for (var i in curEventDataChanged) {
+                    if (!isNaN(curEventDataChanged[i])) curEventDataChanged[i] = parseInt(curEventDataChanged[i]);
+                    if (curEventDataChanged[i] === 'null' || curEventDataChanged[i] === '') curEventDataChanged[i] = null;
+                    if (curEventDataChanged[i] === 'true') curEventDataChanged[i] = true;
+                    if (curEventDataChanged[i] === 'false') curEventDataChanged[i] = false;
+
+                }
+                console.log(curEventDataChanged);
+                amivcore.events.PATCH({
                     id: curEventData.id,
                     header: {
-                      'If-Match': $('.events-edit-table').attr('data-etag')
+                        'If-Match': $('.events-edit-table').attr('data-etag')
+                    },
+                    data: curEventDataChanged
+                }, function(ret) {
+                    if (!ret.hasOwnProperty('_status') || ret['_status'] != 'OK')
+                        tools.log(JSON.stringify(ret.responseJSON['_issues']), 'e');
+                    else {
+                        // console.log(ret);
+                        tools.log('Event Updated', 's');
+                        events.get();
+                        tools.modalClose();
                     }
-                  }, function(response) {
-                    console.log(response);
-                  });
-                  events.get();
-                  tools.log('Event deleted', 'w');
-                  tools.modalClose();
+                });
+            }
+        },
+
+        submitNewEvent: function() {
+            console.log("submitting new event");
+            var newEvent = {
+                data: {}
+            };
+            newEvent["data"]["title_de"] = setNullIfEmpty($("#title_de").val());
+            newEvent["data"]["description_de"] = setNullIfEmpty($("#description_de").val());
+            newEvent["data"]["catchphrase_de"] = setNullIfEmpty($("#catchphrase_de").val());
+
+            if (!($("#time_start").data("DateTimePicker").date() == null)) {
+                //for now, because the api rejects .toISOString format
+                newEvent["data"]["time_start"] = $("#time_start").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
+            }
+            if (!($("#time_end").data("DateTimePicker").date() == null)) {
+                //for now, because the api rejects .toISOString format
+                newEvent["data"]["time_end"] = $("#time_end").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
+            }
+
+            if (!$("#signup-required").is(":checked")) {
+                if ($("#no-signup-limit").is(":checked")) {
+                    newEvent["data"]["spots"] = 0;
                 } else {
-                  tools.log('Event not Deleted', 'i');
+                    if ($("#spots").val() === "") {
+                        tools.log("Please specify a number of Spots", "e");
+                        return;
+                    }
+                    newEvent["data"]["spots"] = parseInt($("#spots").val());
+
                 }
-              }
-            },
-            'Signups': {
-              type: 'info',
-              close: false,
-              callback: function() {
-                events.showSignups(curEventData);
-              }
-            },
-            'Update': {
-              type: 'success',
-              close: false,
-              callback: events.inspectEvent
+                if (!($("#time_register_start").data("DateTimePicker").date() == null)) {
+                    //for now, because the api rejects .toISOString format
+                    newEvent["data"]["time_register_start"] = $("#time_register_start").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
+                } else {
+                    tools.log('field "Start of Registration" required', 'e');
+                    return;
+                }
+                if (!($("#time_register_end").data("DateTimePicker").date() == null)) {
+                    //for now, because the api rejects .toISOString format
+                    newEvent["data"]["time_register_end"] = $("#time_register_end").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
+                } else {
+                    tools.log('field "End of Registration" required', 'e');
+                    return;
+                }
+            } else {
+                newEvent["data"]["spots"] = -1;
             }
-          }
-        });
-      });
-    },
-
-    showSignups: function(curEventData) {
-      var tmp = '<table class="table table-hover events-edit-table" data-etag="' + curEventData['_etag'] + '"><tbody>';
-      for (var user in curEventData['signups']) {
-        tmp += '<tr><td>' + user + '</td><td contenteditable>' + curEventData['signups'][cur] + '</td></tr>';
-      }
-      tmp += '</tbody></table>';
-      tools.modal({
-        head: curEventData.title_de,
-        body: tmp,
-        button: {
-          'Update': {
-            type: 'success',
-            close: false
-              //callback
-          }
-        }
-      });
-    },
-
-    inspectEvent: function() {
-      var newEventData = {};
-      $('.events-edit-table tr').each(function() {
-        newEventData[$(this).children('td:nth-child(1)').html()] = $(this).children('td:nth-child(2)').html();
-      });
-      var changed = false,
-        curEventDataChanged = {};
-      for (var i in newEventData) {
-        if (newEventData[i] != String(curEventData[i])) {
-          changed = true;
-          curEventDataChanged[i] = newEventData[i];
-        }
-      }
-      console.log(curEventDataChanged);
-      if (changed) {
-        //workaround to get booleans and ints working
-        for (var i in curEventDataChanged) {
-          if (!isNaN(curEventDataChanged[i])) curEventDataChanged[i] = parseInt(curEventDataChanged[i]);
-          if (curEventDataChanged[i] === 'null' || curEventDataChanged[i] === '') curEventDataChanged[i] = null;
-          if (curEventDataChanged[i] === 'true') curEventDataChanged[i] = true;
-          if (curEventDataChanged[i] === 'false') curEventDataChanged[i] = false;
 
-        }
-        console.log(curEventDataChanged);
-        amivcore.events.PATCH({
-          id: curEventData.id,
-          header: {
-            'If-Match': $('.events-edit-table').attr('data-etag')
-          },
-          data: curEventDataChanged
-        }, function(ret) {
-          if (!ret.hasOwnProperty('_status') || ret['_status'] != 'OK')
-            tools.log(JSON.stringify(ret.responseJSON['_issues']), 'e');
-          else {
-            // console.log(ret);
-            tools.log('Event Updated', 's');
-            events.get();
-            tools.modalClose();
-          }
-        });
-      }
-    },
-
-    submitNewEvent: function() {
-      console.log("submitting new event");
-      var newEvent = {
-        data: {}
-      };
-      newEvent["data"]["title_de"] = setNullIfEmpty($("#title_de").val());
-      newEvent["data"]["description_de"] = setNullIfEmpty($("#description_de").val());
-      newEvent["data"]["catchphrase_de"] = setNullIfEmpty($("#catchphrase_de").val());
-
-      if (!($("#time_start").data("DateTimePicker").date() == null)) {
-        //for now, because the api rejects .toISOString format
-        newEvent["data"]["time_start"] = $("#time_start").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
-      }
-      if (!($("#time_end").data("DateTimePicker").date() == null)) {
-        //for now, because the api rejects .toISOString format
-        newEvent["data"]["time_end"] = $("#time_end").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
-      }
-
-      if (!$("#signup-required").is(":checked")) {
-        if ($("#no-signup-limit").is(":checked")) {
-          newEvent["data"]["spots"] = 0;
-        } else {
-          if ($("#spots").val() === "") {
-            tools.log("Please specify a number of Spots", "e");
-            return;
-          }
-          newEvent["data"]["spots"] = parseInt($("#spots").val());
+            newEvent["data"]["allow_email_signup"] = $("#allow_email_signup").is(':checked');
 
+            newEvent["data"]["location"] = setNullIfEmpty($("#location").val());
+
+            if (!($("#price").val() === "")) {
+                newEvent["data"]["price"] = Math.floor((parseFloat($("#price").val()) * 100));
+            }
+
+            newEvent["data"]["show_website"] = $("#show_website").is(':checked');
+            newEvent["data"]["show_infoscreen"] = $("#show_infoscreen").is(':checked');
+            newEvent["data"]["show_announce"] = $("#show_announce").is(':checked');
+            newEvent["data"]["additional_fields"] = setNullIfEmpty($("additional_fields".val()));
+
+            newEvent["data"]["title_en"] = setNullIfEmpty($("#title_en").val());
+            newEvent["data"]["description_en"] = setNullIfEmpty($("#description_en").val());
+            newEvent["data"]["catchphrase_en"] = setNullIfEmpty($("#catchphrase_en").val());
+
+            console.log(newEvent);
+            console.log(JSON.stringify(newEvent));
+            var response = amivcore.events.POST(newEvent, function(ret) {
+                if (!ret.hasOwnProperty('_status') || ret['_status'] != 'OK')
+                    tools.log(JSON.stringify(ret.responseJSON['_issues']), 'e');
+                else {
+                    tools.log('Event Added', 's');
+                    $('#new-event-modal').modal('hide');
+                    $("#new-event").trigger('reset');
+                    events.get();
+                }
+            });
+            console.log(response);
         }
-        if (!($("#time_register_start").data("DateTimePicker").date() == null)) {
-          //for now, because the api rejects .toISOString format
-          newEvent["data"]["time_register_start"] = $("#time_register_start").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
-        } else {
-          tools.log('field "Start of Registration" required', 'e');
-          return;
-        }
-        if (!($("#time_register_end").data("DateTimePicker").date() == null)) {
-          //for now, because the api rejects .toISOString format
-          newEvent["data"]["time_register_end"] = $("#time_register_end").data("DateTimePicker").date().format("YYYY-MM-DDThh:mm:ss") + "Z";
-        } else {
-          tools.log('field "End of Registration" required', 'e');
-          return;
-        }
-      } else {
-        newEvent["data"]["spots"] = -1;
-      }
-
-      newEvent["data"]["allow_email_signup"] = $("#allow_email_signup").is(':checked');
-
-      newEvent["data"]["location"] = setNullIfEmpty($("#location").val());
-
-      if (!($("#price").val() === "")) {
-        newEvent["data"]["price"] = Math.floor((parseFloat($("#price").val()) * 100));
-      }
-
-      newEvent["data"]["show_website"] = $("#show_website").is(':checked');
-      newEvent["data"]["show_infoscreen"] = $("#show_infoscreen").is(':checked');
-      newEvent["data"]["show_announce"] = $("#show_announce").is(':checked');
-      newEvent["data"]["additional_fields"] = setNullIfEmpty($("additional_fields".val()));
-
-      newEvent["data"]["title_en"] = setNullIfEmpty($("#title_en").val());
-      newEvent["data"]["description_en"] = setNullIfEmpty($("#description_en").val());
-      newEvent["data"]["catchphrase_en"] = setNullIfEmpty($("#catchphrase_en").val());
-
-      console.log(newEvent);
-      console.log(JSON.stringify(newEvent));
-      var response = amivcore.events.POST(newEvent, function(ret) {
-        if (!ret.hasOwnProperty('_status') || ret['_status'] != 'OK')
-          tools.log(JSON.stringify(ret.responseJSON['_issues']), 'e');
-        else {
-          tools.log('Event Added', 's');
-          $('#new-event-modal').modal('hide');
-          $("#new-event").trigger('reset');
-          events.get();
-        }
-      });
-      console.log(response);
     }
-  }
 
 
-  //setting up the date time picker
-  $(function() {
-    $('#time_start').datetimepicker({
-      locale: "de"
-    });
-    $('#time_end').datetimepicker({
-      locale: "de",
-      useCurrent: false //Important! See issue #1075
-    });
-    $('#time_register_start').datetimepicker({
-      locale: "de"
-    });
-    $('#time_register_end').datetimepicker({
-      locale: "de",
-      useCurrent: false //Important! See issue #1075
+    //setting up the date time picker
+    $(function() {
+        $('#time_start').datetimepicker({
+            locale: "de"
+        });
+        $('#time_end').datetimepicker({
+            locale: "de",
+            useCurrent: false //Important! See issue #1075aa
+        });
+        $('#time_register_start').datetimepicker({
+            locale: "de"
+        });
+        $('#time_register_end').datetimepicker({
+            locale: "de",
+            useCurrent: false //Important! See issue #107534
+        });
+        $("#time_register_start").on("dp.change", function(e) {
+            $('#time_register_end').data("DateTimePicker").minDate(e.date);
+        });
+        $("#time_register_end").on("dp.change", function(e) {
+            $('#time_register_start').data("DateTimePicker").maxDate(e.date);
+        });
+        $("#time_start").on("dp.change", function(e) {
+            $('#time_end').data("DateTimePicker").minDate(e.date);
+        });
+        $("#time_end").on("dp.change", function(e) {
+            $('#time_start').data("DateTimePicker").maxDate(e.date);
+        });
     });
-    $("#time_register_start").on("dp.change", function(e) {
-      $('#time_register_end').data("DateTimePicker").minDate(e.date);
+
+    $('#signup-required').click(function() {
+        $('#no-signup-limit').attr('disabled', this.checked);
+        $('#spots').attr('disabled', this.checked);
+        $('#time_register_end>input').attr('disabled', this.checked);
+        $('#time_register_start>input').attr('disabled', this.checked);
     });
-    $("#time_register_end").on("dp.change", function(e) {
-        $('#time_register_start').data("DateTimePicker").maxDate(e.date);
-      });
-      $("#time_start").on("dp.change", function(e) {
-        $('#time_end').data("DateTimePicker").minDate(e.date);
-      });
-      $("#time_end").on("dp.change", function(e) {
-      $('#time_start').data("DateTimePicker").maxDate(e.date);
+
+    $('#no-signup-limit').click(function() {
+        $('#spots').attr('disabled', this.checked);
     });
-  });
-
-  $('#signup-required').click(function() {
-    $('#no-signup-limit').attr('disabled', this.checked);
-    $('#spots').attr('disabled', this.checked);
-    $('#time_register_end>input').attr('disabled', this.checked);
-    $('#time_register_start>input').attr('disabled', this.checked);
-  });
-
-  $('#no-signup-limit').click(function() {
-    $('#spots').attr('disabled', this.checked);
-  });
-
-
-  tools.ui.menu({
-    '<span class="glyphicon glyphicon-plus"  data-toggle="tooltip" aria-hidden="true" title="Create new Event" data-placement="bottom"></span>': {
-      callback: function() {
-        $('#new-event-modal').modal('show');
-      }
-    },
-    '<span class="glyphicon glyphicon-refresh" aria-hidden="true"  data-toggle="tooltip" title="Refresh" data-placement="bottom"></span>': {
-      callback: events.get
-    },
-    '<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>': {
-      callback: events.page.dec
-    },
-    '<span class="events-cur-page-cont" aria-hidden="true"></span> / <span class="events-page-max-cont" aria-hidden="true"></span>': {
-      callback: function() {
-        tools.modal({
-          head: 'Go To Page:',
-          body: '<div class="form-group"><input type="number" value="' + events.page.cur() + '" class="form-control events-go-page"></div>',
-          button: {
-            'Go': {
-              type: 'success',
-              close: true,
-              callback: function() {
-                events.page.set($('.events-go-page').val());
-              },
+
+
+    tools.ui.menu({
+        '<span class="glyphicon glyphicon-plus"  data-toggle="tooltip" aria-hidden="true" title="Create new Event" data-placement="bottom"></span>': {
+            callback: function() {
+                $('#new-event-modal').modal('show');
             }
-          }
-        });
-      }
-    },
-    '<span class="glyphicon glyphicon-arrow-right" aria-hidden="true"></span>': {
-      callback: events.page.inc
-    },
-    '<span class="glyphicon glyphicon-sort" aria-hidden="true" data-toggle="tooltip" title="Sort" data-placement="bottom"></span>': {
-      callback: function() {
-        var tmp = '<div class="form-group"><select class="form-control events-sort-select">';
-        var cur = events.sort.cur();
-        ['id', 'title_de', 'description_de', 'time_start', 'time_register_start', 'time_end', 'time_register_end', 'show_website', 'show_announce', 'show_infoscreen', 'price', '_updated', 'location'].forEach(function(i) {
-          tmp += '<option value="' + i + '"' + ((i == cur) ? ' selected' : '') + '>&#8673; ' + i + '</option>';
-          tmp += '<option value="-' + i + '"' + (('-' + i == cur) ? ' selected' : '') + '>&#8675; ' + i + '</option>';
-        });
-        tmp += '</select></div>';
-        tools.modal({
-          head: 'Sort',
-          body: tmp,
-          button: {
-            'Sort': {
-              type: 'success',
-              close: true,
-              callback: function() {
-                events.sort.set($('.events-sort-select').val());
-              }
+        },
+        '<span class="glyphicon glyphicon-refresh" aria-hidden="true"  data-toggle="tooltip" title="Refresh" data-placement="bottom"></span>': {
+            callback: events.get
+        },
+        '<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>': {
+            callback: events.page.dec
+        },
+        '<span class="events-cur-page-cont" aria-hidden="true"></span> / <span class="events-page-max-cont" aria-hidden="true"></span>': {
+            callback: function() {
+                tools.modal({
+                    head: 'Go To Page:',
+                    body: '<div class="form-group"><input type="number" value="' + events.page.cur() + '" class="form-control events-go-page"></div>',
+                    button: {
+                        'Go': {
+                            type: 'success',
+                            close: true,
+                            callback: function() {
+                                events.page.set($('.events-go-page').val());
+                            },
+                        }
+                    }
+                });
             }
-          }
+        },
+        '<span class="glyphicon glyphicon-arrow-right" aria-hidden="true"></span>': {
+            callback: events.page.inc
+        },
+        '<span class="glyphicon glyphicon-sort" aria-hidden="true" data-toggle="tooltip" title="Sort" data-placement="bottom"></span>': {
+            callback: function() {
+                var tmp = '<div class="form-group"><select class="form-control events-sort-select">';
+                var cur = events.sort.cur();
+                ['id', 'title_de', 'description_de', 'time_start', 'time_register_start', 'time_end', 'time_register_end', 'show_website', 'show_announce', 'show_infoscreen', 'price', '_updated', 'location'].forEach(function(i) {
+                    tmp += '<option value="' + i + '"' + ((i == cur) ? ' selected' : '') + '>&#8673; ' + i + '</option>';
+                    tmp += '<option value="-' + i + '"' + (('-' + i == cur) ? ' selected' : '') + '>&#8675; ' + i + '</option>';
+                });
+                tmp += '</select></div>';
+                tools.modal({
+                    head: 'Sort',
+                    body: tmp,
+                    button: {
+                        'Sort': {
+                            type: 'success',
+                            close: true,
+                            callback: function() {
+                                events.sort.set($('.events-sort-select').val());
+                            }
+                        }
+                    }
 
-        });
-      }
-    },
-    '<span class="glyphicon glyphicon-search" aria-hidden="true" data-toggle="tooltip" title="Search" data-placement="bottom"></span>': {
-      callback: function() {
-        var tmp = '<div class="form-group"><select class="form-control events-search-select">';
-        var cur = events.search.cur();
-        if (cur === null || cur == '')
-          cur = '';
-        else
-          cur = cur.split('==')[1];
-        ['id', 'title_de', 'description_de', 'title_en', 'description_en', 'time_start', 'time_register_start', 'time_end', 'time_register_end', 'show_website', 'show_announce', 'show_infoscreen', 'price', '_updated', 'location'].forEach(
-          function(i) {
-            tmp += '<option value="' + i + '"' + ((i == cur) ? ' selected' : '') + '>' + i + '</option>';
-          });
-        tmp += '</select><br><input type="text" value="' + cur + '" class="form-control events-search-val"></div>';
-        tools.modal({
-          head: 'Search',
-          body: tmp,
-          button: {
-            'Clear': {
-              type: 'warning',
-              close: true,
-              callback: events.search.clr,
-            },
-            'Search': {
-              type: 'success',
-              close: true,
-              callback: function() {
-                events.search.set($('.events-search-select').val(), $('.events-search-val').val());
-              }
-            },
-          }
-        })
-      }
-    }
-  });
+                });
+            }
+        },
+        '<span class="glyphicon glyphicon-search" aria-hidden="true" data-toggle="tooltip" title="Search" data-placement="bottom"></span>': {
+            callback: function() {
+                var tmp = '<div class="form-group"><select class="form-control events-search-select">';
+                var cur = events.search.cur();
+                if (cur === null || cur == '')
+                    cur = '';
+                else
+                    cur = cur.split('==')[1];
+                ['id', 'title_de', 'description_de', 'title_en', 'description_en', 'time_start', 'time_register_start', 'time_end', 'time_register_end', 'show_website', 'show_announce', 'show_infoscreen', 'price', '_updated', 'location']
+                .forEach(
+                    function(i) {
+                        tmp += '<option value="' + i + '"' + ((i == cur) ? ' selected' : '') + '>' + i + '</option>';
+                    });
+                tmp += '</select><br><input type="text" value="' + cur + '" class="form-control events-search-val"></div>';
+                tools.modal({
+                    head: 'Search',
+                    body: tmp,
+                    button: {
+                        'Clear': {
+                            type: 'warning',
+                            close: true,
+                            callback: events.search.clr,
+                        },
+                        'Search': {
+                            type: 'success',
+                            close: true,
+                            callback: function() {
+                                events.search.set($('.events-search-select').val(), $('.events-search-val').val());
+                            }
+                        },
+                    }
+                })
+            }
+        }
+    });
 
-  if (events.page.cur() === null || isNaN(events.page.cur()))
-    events.page.set(1);
-  else
-    events.page.set(events.page.cur());
+    if (events.page.cur() === null || isNaN(events.page.cur()))
+        events.page.set(1);
+    else
+        events.page.set(events.page.cur());
 
-  $(document).ready(function() {
-    $('[data-toggle="tooltip"]').tooltip();
-  });
+    $(document).ready(function() {
+        $('[data-toggle="tooltip"]').tooltip();
+    });
 
-  function setNullIfEmpty(formData) {
-    if (formData === "") {
-      return null;
+    function setNullIfEmpty(formData) {
+        if (formData === "") {
+            return null;
+        }
+        return formData;
     }
-    return formData;
-  }
 </script>
diff --git a/admin/tools/groups.tool b/admin/tools/groups.tool
index 16e4fb0..f67ed6f 100644
--- a/admin/tools/groups.tool
+++ b/admin/tools/groups.tool
@@ -18,7 +18,8 @@
 </style>
 <script type="text/javascript">
 	var groups = {
-		showInTable: ['firstname', 'lastname', 'nethz', 'legi', 'membership'],
+		tableTitles: ['Name', 'Zoidberg', 'self enrollment', '# Of Subscribers'],
+		showInTable: ['name', 'has_zoidberg_share', 'allow_self_enrollment'],
 		curgroupData: null,
 
 		// Page
@@ -77,20 +78,22 @@
 
 		// Get groups
 		get: function() {
+			$('#wheel-logo').css('transform', 'rotate(360deg)');
 			amivcore.groups.GET({
 				data: {
 					'max_results': '50',
-					//page: groups.page.cur(),
-					//sort: groups.sort.cur(),
-					//where: groups.search.cur(),
+					page: groups.page.cur(),
+					sort: groups.sort.cur(),
+					where: groups.search.cur(),
 				}
 			}, function(ret) {
+				console.log(ret);
 
 				if (ret === undefined || ret['_items'].length == 0) {
 					tools.log('No Data', 'w');
+					$('#wheel-logo').css('transform', 'rotate(0deg)');
 					return;
 				}
-
 				groups.meta = ret['_meta'];
 				groups.page.max = Math.ceil(groups.meta.total / groups.meta.max_results);
 				$('.groups-page-max-cont').html(groups.page.max);
@@ -98,7 +101,7 @@
 				// Clear table from previous contentent
 				$('.groups-table thead tr, .groups-table tbody').html('');
 
-				groups.showInTable.forEach(function(i) {
+				groups.tableTitles.forEach(function(i) {
 					$('.groups-table thead tr').append('<th>' + i + '</th>');
 				});
 
@@ -107,8 +110,10 @@
 					groups.showInTable.forEach(function(i) {
 						tmp += '<td>' + ret['_items'][n][i] + '</td>';
 					});
+					tmp += '<td>' + ret['_items'][n]['user_subscribers'].length + '</td>';
 					$('.groups-table tbody').append('<tr data-id="' + ret['_items'][n]['id'] + '">' + tmp + '</tr>');
 				}
+				$('#wheel-logo').css('transform', 'rotate(0deg)');
 				$('.groups-table tbody tr').click(groups.showDetails);
 			});
 		},
@@ -236,7 +241,7 @@
 			callback: function() {
 				var tmp = '<div class="form-group"><select class="form-control groups-sort-select">';
 				var cur = groups.sort.cur();
-				['id', 'firstname', 'lastname', 'membership', 'nethz'].forEach(function(i) {
+				['id', 'name', 'has_zoidberg_share', 'allow_self_enrollment'].forEach(function(i) {
 					tmp += '<option value="' + i + '"' + ((i == cur) ? ' selected' : '') + '>&#8673; ' + i + '</option>';
 					tmp += '<option value="-' + i + '"' + (('-' + i == cur) ? ' selected' : '') + '>&#8675; ' + i + '</option>';
 				});
@@ -265,7 +270,7 @@
 					cur = '';
 				else
 					cur = cur.split('==')[1];
-				['id', 'firstname', 'lastname'].forEach(function(i) {
+				['id', 'name', 'has_zoidberg_share', 'allow_self_enrollment'].forEach(function(i) {
 					tmp += '<option value="' + i + '"' + ((i == cur) ? ' selected' : '') + '>' + i + '</option>';
 				});
 				tmp += '</select><br><input type="text" value="' + cur + '" class="form-control groups-search-val"></div>';
-- 
GitLab