<commit_before>/*
 * https://nutty.io
 * Copyright (c) 2014 krishna.srinivas@gmail.com All rights reserved.
 * GPLv3 License <http://www.gnu.org/licenses/gpl.txt>
 */

angular.module('nuttyapp')
    .directive('recordButtons', function() {
        return {
            templateUrl: "templates/recordButtons.html",
            scope: true,
            restrict: 'E',
            replace: true,
            link: function(scope, element, attrs, Ctrl) {},
            controller: ['$scope', 'Recorder', 'NuttyConnection', 'alertBox', 'NuttySession',
                function($scope, Recorder, NuttyConnection, alertBox, NuttySession) {
                    var _uploaderr = false;
                    var record = Session.get("record");
                    var upload = false;
                    var _upload = false;
                    var submitted = false;
                    var filename = Session.get("recordfilename");

                    if (record && filename) {
                        Recorder.start(filename, false, function() {});
                    } else {
                        record = false;
                    }

                    $scope.btnactive = function() {
                        if (record)
                            return "active";
                        else
                            return "";
                    }
                    $scope.recordcolor = function() {
                        if (record)
                            return "red";
                        else
                            return "";
                    }
                    $scope.play = function() {
                        if (filename) {
                            mixpanel.track("localplay");
                            window.open("https://nutty.io/localrecord/" + filename);
                        } else
                            alertBox.alert("danger", "No recording available");
                    }

                    function uploaderror(event) {
                        alertBox.alert("danger", "Error during upload");
                        _upload = false;
                        _uploaderr = true;
                        $scope.uploadprogressbarshow = false;
                        $scope.$apply();
                    }

                    function uploadprogressupdate(event) {
                        if (event.lengthComputable) {
                            var percent = event.loaded / event.total * 100;
                            $scope.uploadprogress = Math.floor(percent);
                            $scope.$apply();
                        }
                    }

                    $scope.upload = function() {
                        submitted = true;
                        setTimeout(function() {
                            term.focus();
                        }, 0);
                        _upload = true;
                        // if (_upload) {
                        if (!Recorder.file) {
                            alertBox.alert("danger", "No recording available");
                            $scope.uploaddescshow = false;
                            _upload = false;
                            return;
                        } else if (!Meteor.userId()) {
                            alertBox.alert("danger", "Please signin to upload");
                            $scope.uploaddescshow = false;
                            _upload = false;
                            return;
                        }
                        $scope.uploaddescshow = false;
                        $scope.uploadprogressbarshow = true;
                        $scope.uploadprogress = 10;
                        Meteor.call('s3uploadinfo', NuttySession.sessionid, NuttySession.clientid, function(err, data) {
                            if (err) {
                                alertBox.alert("danger", "Server err during upload");
                                mixpanel.track("upload", {
                                    state: "gets3uploadinfofail"
                                });
                                $scope.$apply();
                            } else {
                                var xhr = new XMLHttpRequest();
                                var fd = new FormData();
                                _uploaderr = false;
                                fd.append('key', data.key);
                                fd.append('AWSAccessKeyId', data.AWSAccessKeyId);
                                fd.append('acl', data.acl);
                                //fd.append('success_action_redirect', data.success_action_redirect);
                                fd.append('policy', data.policy);
                                fd.append('signature', data.signature);
                                fd.append('Content-Type', data.ContentType);

                                // This file object is retrieved from a file input.
                                fd.append('file', Recorder.file);

                                xhr.upload.addEventListener("error", uploaderror);
                                xhr.upload.addEventListener("progress", uploadprogressupdate);
                                // xhr.upload.addEventListener("readystatechange", uploadreadystatechange);
                                xhr.open('POST', 'https://nutty.s3.amazonaws.com', true);

                                xhr.onreadystatechange = function() {
                                    if (xhr.readyState != 4) {
                                        return;
                                    }
                                    if (!_uploaderr) {
                                        alertBox.alert("success", "upload done! check https://nutty.io/uploads");
                                        var userId = Meteor.userId();
                                        mixpanel.track("upload", {
                                            state: "success"
                                        });
                                        if (userId) {
                                            NuttySession.insertrecording({
                                                userId: userId,
                                                filename: data.key,
                                                sessionid: NuttySession.sessionid,
                                                desc: $scope.uploaddesc,
                                                createdAt: new Date
                                            });
                                        } else {
                                            mixpanel.track("upload", {
                                                state: "fail"
                                            });
                                            alertBox.alert("danger", "Upload failed, Please signin during upload");
                                        }
                                    }
                                    $scope.uploadprogressbarshow = false;
                                    _upload = false;
                                    $scope.uploadprogress = 0;
                                    $scope.$apply();
                                };
                                xhr.send(fd);
                            }
                        });
                        // }
                    }

                    $scope._upload = function() {
                        if (!_upload) {
                            if (!Recorder.file) {
                                alertBox.alert("danger", "No recording available");
                                return;
                            } else if (!Meteor.userId()) {
                                alertBox.alert("danger", "Please signin to upload");
                                return;
                            }
                            _upload = true;
                            $scope.uploaddescshow = true;
                            setTimeout(function() {
                                $("#inputid").focus();
                            }, 100);
                        }
                    }

                    $scope._uploadactive = function() {
                        if (_upload)
                            return "active";
                        else
                            return "";
                    }

                    $scope.canceldesc = function() {
                        _upload = false;
                        $scope.uploaddescshow = false;
                        alertBox.alert("danger", "Upload cancelled")
                    }

                    $scope.uploaddescblur = function() {
                        if (!submitted)
                            _upload = false;
                        submitted = false;
                        $scope.uploaddescshow = false;
                    }

                    $scope.record = function() {
                        record = !record;
                        if (record) {
                            mixpanel.track("record");
                            filename = Random.hexString(16);
                            Session.set("recordfilename", filename);
                            Session.set("record", true);
                            Recorder.start(filename, true, function() {
                                Recorder.write({
                                    rowcol: 1,
                                    row: term.screenSize.height,
                                    col: term.screenSize.width
                                });
                                Recorder.write({
                                    termshot: term.document_.body.firstChild.firstChild.innerHTML
                                });
                                Recorder.write({
                                    cursorposition: true,
                                    row: term.getCursorRow(),
                                    col: term.getCursorColumn()
                                });
                            });
                        } else {
                            Session.set("record", false);
                            Recorder.stop();
                        }
                        term.focus();
                    }
                    $scope.recordbtntooltip = function() {
                        if (record)
                            return "stop recording"
                        else
                            return "start recording"
                    }
                }
            ]
        }
    });
<commit_msg>Play button open window using $location instead of hardcoding<commit_after>/*
 * https://nutty.io
 * Copyright (c) 2014 krishna.srinivas@gmail.com All rights reserved.
 * GPLv3 License <http://www.gnu.org/licenses/gpl.txt>
 */

angular.module('nuttyapp')
    .directive('recordButtons', function() {
        return {
            templateUrl: "templates/recordButtons.html",
            scope: true,
            restrict: 'E',
            replace: true,
            link: function(scope, element, attrs, Ctrl) {},
            controller: ['$scope', 'Recorder', 'NuttyConnection', 'alertBox', 'NuttySession', '$location',
                function($scope, Recorder, NuttyConnection, alertBox, NuttySession, $location) {
                    var _uploaderr = false;
                    var record = Session.get("record");
                    var upload = false;
                    var _upload = false;
                    var submitted = false;
                    var filename = Session.get("recordfilename");

                    if (record && filename) {
                        Recorder.start(filename, false, function() {});
                    } else {
                        record = false;
                    }

                    $scope.btnactive = function() {
                        if (record)
                            return "active";
                        else
                            return "";
                    }
                    $scope.recordcolor = function() {
                        if (record)
                            return "red";
                        else
                            return "";
                    }
                    $scope.play = function() {
                        if (filename) {
                            mixpanel.track("localplay");
                            window.open($location.protocol() + "://" + $location.host() + ":" + $location.port() + "/localrecord/" + filename);
                        } else
                            alertBox.alert("danger", "No recording available");
                    }

                    function uploaderror(event) {
                        alertBox.alert("danger", "Error during upload");
                        _upload = false;
                        _uploaderr = true;
                        $scope.uploadprogressbarshow = false;
                        $scope.$apply();
                    }

                    function uploadprogressupdate(event) {
                        if (event.lengthComputable) {
                            var percent = event.loaded / event.total * 100;
                            $scope.uploadprogress = Math.floor(percent);
                            $scope.$apply();
                        }
                    }

                    $scope.upload = function() {
                        submitted = true;
                        setTimeout(function() {
                            term.focus();
                        }, 0);
                        _upload = true;
                        // if (_upload) {
                        if (!Recorder.file) {
                            alertBox.alert("danger", "No recording available");
                            $scope.uploaddescshow = false;
                            _upload = false;
                            return;
                        } else if (!Meteor.userId()) {
                            alertBox.alert("danger", "Please signin to upload");
                            $scope.uploaddescshow = false;
                            _upload = false;
                            return;
                        }
                        $scope.uploaddescshow = false;
                        $scope.uploadprogressbarshow = true;
                        $scope.uploadprogress = 10;
                        Meteor.call('s3uploadinfo', NuttySession.sessionid, NuttySession.clientid, function(err, data) {
                            if (err) {
                                alertBox.alert("danger", "Server err during upload");
                                mixpanel.track("upload", {
                                    state: "gets3uploadinfofail"
                                });
                                $scope.$apply();
                            } else {
                                var xhr = new XMLHttpRequest();
                                var fd = new FormData();
                                _uploaderr = false;
                                fd.append('key', data.key);
                                fd.append('AWSAccessKeyId', data.AWSAccessKeyId);
                                fd.append('acl', data.acl);
                                //fd.append('success_action_redirect', data.success_action_redirect);
                                fd.append('policy', data.policy);
                                fd.append('signature', data.signature);
                                fd.append('Content-Type', data.ContentType);

                                // This file object is retrieved from a file input.
                                fd.append('file', Recorder.file);

                                xhr.upload.addEventListener("error", uploaderror);
                                xhr.upload.addEventListener("progress", uploadprogressupdate);
                                // xhr.upload.addEventListener("readystatechange", uploadreadystatechange);
                                xhr.open('POST', 'https://nutty.s3.amazonaws.com', true);

                                xhr.onreadystatechange = function() {
                                    if (xhr.readyState != 4) {
                                        return;
                                    }
                                    if (!_uploaderr) {
                                        alertBox.alert("success", "upload done! check https://nutty.io/uploads");
                                        var userId = Meteor.userId();
                                        mixpanel.track("upload", {
                                            state: "success"
                                        });
                                        if (userId) {
                                            NuttySession.insertrecording({
                                                userId: userId,
                                                filename: data.key,
                                                sessionid: NuttySession.sessionid,
                                                desc: $scope.uploaddesc,
                                                createdAt: new Date
                                            });
                                        } else {
                                            mixpanel.track("upload", {
                                                state: "fail"
                                            });
                                            alertBox.alert("danger", "Upload failed, Please signin during upload");
                                        }
                                    }
                                    $scope.uploadprogressbarshow = false;
                                    _upload = false;
                                    $scope.uploadprogress = 0;
                                    $scope.$apply();
                                };
                                xhr.send(fd);
                            }
                        });
                        // }
                    }

                    $scope._upload = function() {
                        if (!_upload) {
                            if (!Recorder.file) {
                                alertBox.alert("danger", "No recording available");
                                return;
                            } else if (!Meteor.userId()) {
                                alertBox.alert("danger", "Please signin to upload");
                                return;
                            }
                            _upload = true;
                            $scope.uploaddescshow = true;
                            setTimeout(function() {
                                $("#inputid").focus();
                            }, 100);
                        }
                    }

                    $scope._uploadactive = function() {
                        if (_upload)
                            return "active";
                        else
                            return "";
                    }

                    $scope.canceldesc = function() {
                        _upload = false;
                        $scope.uploaddescshow = false;
                        alertBox.alert("danger", "Upload cancelled")
                    }

                    $scope.uploaddescblur = function() {
                        if (!submitted)
                            _upload = false;
                        submitted = false;
                        $scope.uploaddescshow = false;
                    }

                    $scope.record = function() {
                        record = !record;
                        if (record) {
                            mixpanel.track("record");
                            filename = Random.hexString(16);
                            Session.set("recordfilename", filename);
                            Session.set("record", true);
                            Recorder.start(filename, true, function() {
                                Recorder.write({
                                    rowcol: 1,
                                    row: term.screenSize.height,
                                    col: term.screenSize.width
                                });
                                Recorder.write({
                                    termshot: term.document_.body.firstChild.firstChild.innerHTML
                                });
                                Recorder.write({
                                    cursorposition: true,
                                    row: term.getCursorRow(),
                                    col: term.getCursorColumn()
                                });
                            });
                        } else {
                            Session.set("record", false);
                            Recorder.stop();
                        }
                        term.focus();
                    }
                    $scope.recordbtntooltip = function() {
                        if (record)
                            return "stop recording"
                        else
                            return "start recording"
                    }
                }
            ]
        }
    });
<|endoftext|>


<commit_before>function viewPublish() {
var manual = '[manual collection]';

  $.ajax({
    url: "/zebedee/collections",
    type: "get",
    crossDomain: true,
    success: function (collections) {
    $(collections).each(function (i) {
      if (!collections[i].publishDate) {
        collections[i].publishDate = manual;
      }
    });
      populatePublishTable(collections);
    },
    error: function (response) {
      handleApiError(response);
    }
  });

  var result = [];
  function populatePublishTable(collections) {

    var collectionsByDate = _.chain(collections)
      .filter( function(collection) { return collection.approvedStatus; })
      .sortBy('publishDate')
      .groupBy('publishDate')
      .value();

    for (var key in collectionsByDate) {
      var response = [];
      if (key === manual) {
        var formattedDate = manual;
      } else {
        var formattedDate = StringUtils.formatIsoFullDateString(key);
      }
      $(collectionsByDate[key]).each(function (n) {
        var id = collectionsByDate[key][n].id;
        response.push(id);
      });
      result.push({date: formattedDate, ids: response});
    }

    var publishList = templates.publishList(result);
    $('.section').html(publishList);

    $('.publish-select-table tbody tr').click(function(){
      var collections = $(this).attr('data-collections').split(',');
      Florence.collectionToPublish.publishDate = $(this).find('td').html();
      viewPublishDetails(collections);

      $('.publish-select-table tbody tr').removeClass('selected');
      $(this).addClass('selected');
      $('.publish-selected').animate({right: "0%"}, 800);
      $('.publish-select').animate({marginLeft: "0%"}, 500);
    });
  }
}

<commit_msg>Showing date and time on publish screen.<commit_after>function viewPublish() {
var manual = '[manual collection]';

  $.ajax({
    url: "/zebedee/collections",
    type: "get",
    crossDomain: true,
    success: function (collections) {
    $(collections).each(function (i) {
      if (!collections[i].publishDate) {
        collections[i].publishDate = manual;
      }
    });
      populatePublishTable(collections);
    },
    error: function (response) {
      handleApiError(response);
    }
  });

  var result = [];
  function populatePublishTable(collections) {

    var collectionsByDate = _.chain(collections)
      .filter( function(collection) { return collection.approvedStatus; })
      .sortBy('publishDate')
      .groupBy('publishDate')
      .value();

    for (var key in collectionsByDate) {
      var response = [];
      if (key === manual) {
        var formattedDate = manual;
      } else {
        var formattedDate = StringUtils.formatIsoFull(key);
      }
      $(collectionsByDate[key]).each(function (n) {
        var id = collectionsByDate[key][n].id;
        response.push(id);
      });
      result.push({date: formattedDate, ids: response});
    }

    var publishList = templates.publishList(result);
    $('.section').html(publishList);

    $('.publish-select-table tbody tr').click(function(){
      var collections = $(this).attr('data-collections').split(',');
      Florence.collectionToPublish.publishDate = $(this).find('td').html();
      viewPublishDetails(collections);

      $('.publish-select-table tbody tr').removeClass('selected');
      $(this).addClass('selected');
      $('.publish-selected').animate({right: "0%"}, 800);
      $('.publish-select').animate({marginLeft: "0%"}, 500);
    });
  }
}

<|endoftext|>


<commit_before>angular.module('lisp.communication', [])

  // Declaring the lisp service, which will contain all the functions we'll use to communicate with Lisp
  .factory('lispService', ['$http', '$q', function($http, $q) {
    var serviceInstance = {};

    // Info of all rlocs
    var listOfRlocs = {};
    // Donat un RLOC, té tot els EIDs que estan connectats
    var RLOCLinktedToEID = {};
    // Donat un EID, té tots els RLOCs als que està connectat
    var EidRLOC = {};
    // List with all vn-identifier
    var listOfVNI = [];
    // All Json info
    var Json = [];

    serviceInstance.getAllInfo = function(jsonObj) {
      //jsonObj has JSON response
      var virtualNetworks = jsonObj["mapping-database"]["virtual-network-identifier"];
      Json = virtualNetworks;
      for (var j=0; j<virtualNetworks.length; j++)
      {
        var vni = virtualNetworks[j]["vni"];
        listOfVNI.push(vni);
        var eids = virtualNetworks[j]["mapping"];
        for (var i = 0; i<eids.length; i++)
        {
          var eidInfo = eids[i]["mapping-record"]["eid"];
          var eid_uri =eids[i]["eid"];
          var mappingRecord = eids[i]["mapping-record"];
          var rlocs = mappingRecord["LocatorRecord"];
          var listEidRloc = [];
          for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++)
          {
            serviceInstance.addRlocToRlocList(rlocs[rlocIt]);
            listEidRloc.push(rlocs[rlocIt]["locator-id"]);
            serviceInstance.addRLOCToListRLOCLinktedToEID(rlocs[rlocIt],eid_uri);
          }
          EidRLOC[eids[i]["eid-uri"]] = listEidRloc;

          var typeIP = eids[i]["eid-uri"].split(":")[0];
        }
      }
    };

    serviceInstance.addRlocToRlocList = function(rloc){
      //check if rloc exists on listOfRlocs
      listOfRlocs[rloc["locator-id"]] = rloc;
    };

    serviceInstance.getRLOCsFromEID = function (eidaddress)
    {
      var EidInfo = {};
      for (var i=0; i<Json.length; i++)
      {
          var vni = Json[i]["vni"];
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var eid_uri = eids[j]["eid-uri"];
            var obj = [];
            if(eidaddress == serviceInstance.getIP(eid_uri)){
              var rlocs = eids[j]["mapping-record"]["LocatorRecord"]
              for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++)
              {
                var typeIP = rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0];
                obj.push(rlocs[rlocIt]["locator-id"]);
              }
              EidInfo[vni] = obj;
            }

        }
      }
      return EidInfo;
    };

    serviceInstance.getAddressType = function (eidUri)
    {
      return "ietf-lisp-address-types:" + serviceInstance.getIPType(eidUri) + "-afi";
    };

    serviceInstance.getMappingEID = function (eidUri)
    {
      var addresType = serviceInstance.getAddressType(eidUri);
      var idType = serviceInstance.getIPType(eidUri);
      var ip = serviceInstance.getIP(eidUri);
    };

    serviceInstance.addRLOCToListRLOCLinktedToEID = function (rloc,eid)
    {
      //check if rloc exists on listOfRlocs
      if (RLOCLinktedToEID[rloc["locator-id"]] === undefined)
      {
        var aux = [];
      }
      else
      {
        var aux = RLOCLinktedToEID[rloc["locator-id"]];
      }
      aux.push(eid);
      RLOCLinktedToEID[rloc["locator-id"]] = aux;
    };

    serviceInstance.getEIDsFromRLOC = function(addressType, addressIP)
    {
      var eids = [];
      for (var i=0; i<Json.length; i++)
      {
        var mappingOfVNI = Json[i]["mapping"];
        for (var j=0; j<mappingOfVNI.length;j++)
        {
          var locatorRecords = mappingOfVNI[j]["mapping-record"]["LocatorRecord"];
          for (var z=0; z<locatorRecords.length;z++)
          {
            if (getIPTypeOfRLOC(locatorRecords[z]["rloc"]["address-type"]) == addressType)
            {
              if (locatorRecords[z]["rloc"][addressType] == addressIP)
              {
                eids.push(mappingOfVNI[j]["eid-uri"])
              }
            }
          }
        }
      }
      return eids;
    };

    // First function to call: gets all the lisp database content and stores it in the service
    serviceInstance.initialize = function()
    {
      var deferred = $q.defer();
      var auth64 = btoa('admin:admin');

      $http({
            url: 'http://odl2.cba.upc.edu:8181/restconf/config/odl-mappingservice:mapping-database/',
            method: "GET",
            withCredentials: true,
            headers: {
                'Authorization': 'Basic '+ auth64
            }
        })
      .success(function(data) {

        serviceInstance.getAllInfo(data);
        deferred.resolve();

      }).error(function(msg, code) {

        deferred.reject(msg);

        console.log(msg);

      });

      return deferred.promise;

    };

    // Returns all EID contained in the service

    serviceInstance.getEidInfo = function(eidaddress){
      var EidInfo = {};
      for (var i=0; i<Json.length; i++)
      {
          var vni = Json[i]["vni"];
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var eid_uri = eids[j]["eid-uri"];
            var obj = new Object();
            if(eidaddress == serviceInstance.getIP(eid_uri)){
              obj.xtr_id = eids[j]["mapping-record"]["xtr-id"];
              obj.address = serviceInstance.getIP(eid_uri);
              obj.address_type = serviceInstance.getIPType(eid_uri);
              obj.action = eids[j]["mapping-record"]["action"];
              EidInfo[vni] = obj;
            }

        }
      }
      return EidInfo;
    };

    serviceInstance.getAllVnIds = function() {
      return listOfVNI;
    };

    /* Function to get EIDs in VN
    ** Retun array with eid-uri of all EIDs in VN.
    ** Tip: Use getIPType and getIP functions to get info of eid-uri
    */
    serviceInstance.getEidsInVn = function(VnId)
    {
      var EIDinVN = [];
      for (var i=0; i<Json.length; i++)
      {
        if (Json[i]["vni"] == VnId)
        {
          var eids = Json[i]["mapping"];
          for (var i=0;i<eids.length;i++)
          {
            EIDinVN.push(eids[i]["eid-uri"]);
          }
        }
      }
      return EIDinVN;
    };

    serviceInstance.getAllEids = function()
    {
      var EidList = [];
      for (var i=0; i<Json.length; i++)
      {
          var eids = Json[i]["mapping"];
          var vni = Json[i]["vni"]
          var vectorEIds = [];
          for (var j = 0; j<eids.length; j++)
          {
            var obj = new Object();
            var eid_uri = eids[j]["eid-uri"];
            var xtr = eids[j]["mapping-record"]["xtr-id"];
            obj.vni = vni;
            obj.address = eid_uri;
            obj.xtr_id  = xtr;
            var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
            var RLocAdr = [];
            for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++)
            {
              var typeIP = rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0];
              RLocAdr.push(rlocs[rlocIt]["rloc"][typeIP]);
            }
            obj.rlocs = RLocAdr;
            EidList.push(obj);
          }
        }
      return EidList;
    };

    serviceInstance.getIPType = function (eidUri)
    {
      return eidUri.split(":")[0];
    };

    serviceInstance.getIP = function (eidUri)
    {
      return eidUri.substring(eidUri.split(":")[0].length+1, eidUri.length);
    };

    serviceInstance.getRLOCs = function (vni, eid)
    {
      var rlocs = Json[vni]["mapping"][eid]["mapping-record"]["LocatorRecord"]
      var rloc_iterator;
      var rlocsOfEID = [];
      for (rloc_iterator = 0; rloc_iterator < rlocs.length; ++rloc_iterator)
      {
        rlocsOfEID.push(rlocs[rloc_iterator]);
      }
      return rlocsOfEID;
    };

    serviceInstance.getAllxtrids = function() {
       var vectorXTR = {};
      for (var i=0; i<Json.length; i++)
      {
        var eids = Json[i]["mapping"];
        for (var j=0; j<eids.length; j++)
        {
          var obj = {};
          var xtrInfo_id = eids[j]["mapping-record"]["xtr-id"];
          if(typeof vectorXTR[xtrInfo_id] != "undefined") obj = vectorXTR[xtrInfo_id];
          var rlocs = serviceInstance.getRLOCs(i,j);
          for(var k=0;k<rlocs.length;k++){
            var address = rlocs[k]["rloc"][rlocs[k]["rloc"]["address-type"].split(":")[1].split("-")[0]];
            obj[rlocs[k]["locator-id"]]= address;
          }
          vectorXTR[xtrInfo_id] = obj;
        }
      }
      return vectorXTR;
    };

    serviceInstance.getAllRlocs = function() {
      var ListRlocs = {};
      var RlocId;
      var RlocIp;
      for (var i=0; i<Json.length; i++)
      {
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
            for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++) {
              RlocId = rlocs[rlocIt]["locator-id"];
              RlocIp = rlocs[rlocIt]["rloc"][rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0]];
              var obj = new Object;
              obj.address= RlocIp;
              ListRlocs[RlocId]= obj;

          }
        }
      }

      return ListRlocs;
    };

    serviceInstance.getRlocInfo = function (RLOC_ID)
    {
     var obj = new Object();
      for (var i=0; i<Json.length; i++)
      {
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
            for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++) {
              if(RLOC_ID == rlocs[rlocIt]["locator-id"]){
                obj.id = rlocs[rlocIt]["locator-id"];
                obj.address_type = rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0];
                obj.address = rlocs[rlocIt]["rloc"][obj.address_type];
                obj.weight = rlocs[rlocIt]["weight"];
                obj.priority = rlocs[rlocIt]["priority"];
                obj.multicastweight = rlocs[rlocIt]["multicastWeight"];
                obj.xtr_id = eids[j]["mapping-record"]["xtr-id"];
            }
          }
        }
      }
      return obj;
    };

    serviceInstance.getIPTypeOfRLOC = function(rlocAddressType)
    {
      return rlocAddressType.split(":")[1].split("-")[0];
    };

    serviceInstance.getXTRInfo = function(action, xtrId)
    {
      var xtrInfo = [];
      for (var i=0; i<Json.length; i++)
      {
        var obj = new Object();

        obj.vni = Json[i]["vni"];
        obj.info = []
        var eids = Json[i]["mapping"];
        switch(action)
        {
          case "EID":
            for (var j = 0; j<eids.length; j++)
            {
              var xtr = eids[j]["mapping-record"]["xtr-id"];
              if (xtr == xtrId)
              {
                var EID_RLOCS = new Object();
                EID_RLOCS.eid = eids[j]["eid-uri"];
                EID_RLOCS.rlocs = serviceInstance.getRLOCs(i, j);
                var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
                obj.info.push(EID_RLOCS);
                /*for (var rlocIt=0; rlocIt<rlocs.length; rlocIt++)
                {
                  EID_RLOCS.rlocs.push(rlocs[rlocIt]["rloc"][getIPTypeOfRLOC(rlocs[rlocIt]["rloc"]["address-type"])])
                  /*var rlocIP = rlocs[rlocIt]["rloc"][getIPType(rlocs[rlocIt]["rloc"]["address-type"])];
                  obj.info.push(rlocIP);*/
               /* }
                obj.info.push(EID_RLOCS);*/
              }
            }
            break;
          case "RLOC":
            var dictionaryRLOC = {}
            var rlocsList = [];
            for (var j = 0; j<eids.length; j++)
            {
              var xtr = eids[j]["mapping-record"]["xtr-id"];
              if (xtr == xtrId)
              {

                var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
                for (var rlocIt=0; rlocIt<rlocs.length; rlocIt++)
                {
                  var rlocIP = String(rlocs[rlocIt]["rloc"][serviceInstance.getIPTypeOfRLOC(rlocs[rlocIt]["rloc"]["address-type"])]);
                  if (rlocsList.indexOf(rlocIP) == -1) rlocsList.push(rlocIP);
                  if (dictionaryRLOC[rlocIP] == undefined) dictionaryRLOC[rlocIP] = []
                  dictionaryRLOC[rlocIP].push(eids[j]["eid-uri"]);
                  }
              }
            }

            for (var rloc_itList = 0; rloc_itList < rlocsList.length; rloc_itList++)
            {
              var RLOC_EID = new Object();
              RLOC_EID.rloc = rlocsList[rloc_itList]
              RLOC_EID.info = dictionaryRLOC[rlocsList[rloc_itList]];
              obj.info.push(RLOC_EID)
            }
            break;
        }
        xtrInfo[i] = obj;
      }
      return xtrInfo;
    };

    return serviceInstance;
  }])
<commit_msg><commit_after>angular.module('lisp.communication', [])

  // Declaring the lisp service, which will contain all the functions we'll use to communicate with Lisp
  .factory('lispService', ['$http', '$q', function($http, $q) {
    var serviceInstance = {};

    // Info of all rlocs
    var listOfRlocs = {};
    // Donat un RLOC, té tot els EIDs que estan connectats
    var RLOCLinktedToEID = {};
    // Donat un EID, té tots els RLOCs als que està connectat
    var EidRLOC = {};
    // List with all vn-identifier
    var listOfVNI = [];
    // All Json info
    var Json = [];

    serviceInstance.getAllInfo = function(jsonObj) {
      //jsonObj has JSON response
      var virtualNetworks = jsonObj["mapping-database"]["virtual-network-identifier"];
      Json = virtualNetworks;
      for (var j=0; j<virtualNetworks.length; j++)
      {
        var vni = virtualNetworks[j]["vni"];
        listOfVNI.push(vni);
        var eids = virtualNetworks[j]["mapping"];
        for (var i = 0; i<eids.length; i++)
        {
          var eidInfo = eids[i]["mapping-record"]["eid"];
          var eid_uri =eids[i]["eid"];
          var mappingRecord = eids[i]["mapping-record"];
          var rlocs = mappingRecord["LocatorRecord"];
          var listEidRloc = [];
          for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++)
          {
            serviceInstance.addRlocToRlocList(rlocs[rlocIt]);
            listEidRloc.push(rlocs[rlocIt]["locator-id"]);
            serviceInstance.addRLOCToListRLOCLinktedToEID(rlocs[rlocIt],eid_uri);
          }
          EidRLOC[eids[i]["eid-uri"]] = listEidRloc;

          var typeIP = eids[i]["eid-uri"].split(":")[0];
        }
      }
    };

    serviceInstance.addRlocToRlocList = function(rloc){
      //check if rloc exists on listOfRlocs
      listOfRlocs[rloc["locator-id"]] = rloc;
    };

    serviceInstance.getRLOCsFromEID = function (eidaddress)
    {
      var EidInfo = {};
      for (var i=0; i<Json.length; i++)
      {
          var vni = Json[i]["vni"];
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var eid_uri = eids[j]["eid-uri"];
            var obj = [];
            if(eidaddress == serviceInstance.getIP(eid_uri)){
              var rlocs = eids[j]["mapping-record"]["LocatorRecord"]
              for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++)
              {
                var typeIP = rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0];
                obj.push(rlocs[rlocIt]["locator-id"]);
              }
              EidInfo[vni] = obj;
            }

        }
      }
      return EidInfo;
    };

    serviceInstance.getAddressType = function (eidUri)
    {
      return "ietf-lisp-address-types:" + serviceInstance.getIPType(eidUri) + "-afi";
    };

    serviceInstance.getMappingEID = function (eidUri)
    {
      var addresType = serviceInstance.getAddressType(eidUri);
      var idType = serviceInstance.getIPType(eidUri);
      var ip = serviceInstance.getIP(eidUri);
    };

    serviceInstance.addRLOCToListRLOCLinktedToEID = function (rloc,eid)
    {
      //check if rloc exists on listOfRlocs
      if (RLOCLinktedToEID[rloc["locator-id"]] === undefined)
      {
        var aux = [];
      }
      else
      {
        var aux = RLOCLinktedToEID[rloc["locator-id"]];
      }
      aux.push(eid);
      RLOCLinktedToEID[rloc["locator-id"]] = aux;
    };

    serviceInstance.getEIDsFromRLOC = function(addressType, addressIP)
    {
      var eids = [];
      for (var i=0; i<Json.length; i++)
      {
        var mappingOfVNI = Json[i]["mapping"];
        for (var j=0; j<mappingOfVNI.length;j++)
        {
          var locatorRecords = mappingOfVNI[j]["mapping-record"]["LocatorRecord"];
          for (var z=0; z<locatorRecords.length;z++)
          {
            if (serviceInstance.getIPTypeOfRLOC(locatorRecords[z]["rloc"]["address-type"]) == addressType)
            {
              if (locatorRecords[z]["rloc"][addressType] == addressIP)
              {
                eids.push(mappingOfVNI[j]["eid-uri"])
              }
            }
          }
        }
      }
      return eids;
    };

    // First function to call: gets all the lisp database content and stores it in the service
    serviceInstance.initialize = function()
    {
      var deferred = $q.defer();
      var auth64 = btoa('admin:admin');

      $http({
            url: 'http://odl2.cba.upc.edu:8181/restconf/config/odl-mappingservice:mapping-database/',
            method: "GET",
            withCredentials: true,
            headers: {
                'Authorization': 'Basic '+ auth64
            }
        })
      .success(function(data) {

        serviceInstance.getAllInfo(data);
        deferred.resolve();

      }).error(function(msg, code) {

        deferred.reject(msg);

        console.log(msg);

      });

      return deferred.promise;

    };

    // Returns all EID contained in the service

    serviceInstance.getEidInfo = function(eidaddress){
      var EidInfo = {};
      for (var i=0; i<Json.length; i++)
      {
          var vni = Json[i]["vni"];
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var eid_uri = eids[j]["eid-uri"];
            var obj = new Object();
            if(eidaddress == serviceInstance.getIP(eid_uri)){
              obj.xtr_id = eids[j]["mapping-record"]["xtr-id"];
              obj.address = serviceInstance.getIP(eid_uri);
              obj.address_type = serviceInstance.getIPType(eid_uri);
              obj.action = eids[j]["mapping-record"]["action"];
              EidInfo[vni] = obj;
            }

        }
      }
      return EidInfo;
    };

    serviceInstance.getAllVnIds = function() {
      return listOfVNI;
    };

    /* Function to get EIDs in VN
    ** Retun array with eid-uri of all EIDs in VN.
    ** Tip: Use getIPType and getIP functions to get info of eid-uri
    */
    serviceInstance.getEidsInVn = function(VnId)
    {
      var EIDinVN = [];
      for (var i=0; i<Json.length; i++)
      {
        if (Json[i]["vni"] == VnId)
        {
          var eids = Json[i]["mapping"];
          for (var i=0;i<eids.length;i++)
          {
            EIDinVN.push(eids[i]["eid-uri"]);
          }
        }
      }
      return EIDinVN;
    };

    serviceInstance.getAllEids = function()
    {
      var EidList = [];
      for (var i=0; i<Json.length; i++)
      {
          var eids = Json[i]["mapping"];
          var vni = Json[i]["vni"]
          var vectorEIds = [];
          for (var j = 0; j<eids.length; j++)
          {
            var obj = new Object();
            var eid_uri = eids[j]["eid-uri"];
            var xtr = eids[j]["mapping-record"]["xtr-id"];
            obj.vni = vni;
            obj.address = eid_uri;
            obj.xtr_id  = xtr;
            var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
            var RLocAdr = [];
            for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++)
            {
              var typeIP = rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0];
              RLocAdr.push(rlocs[rlocIt]["rloc"][typeIP]);
            }
            obj.rlocs = RLocAdr;
            EidList.push(obj);
          }
        }
      return EidList;
    };

    serviceInstance.getIPType = function (eidUri)
    {
      return eidUri.split(":")[0];
    };

    serviceInstance.getIP = function (eidUri)
    {
      return eidUri.substring(eidUri.split(":")[0].length+1, eidUri.length);
    };

    serviceInstance.getRLOCs = function (vni, eid)
    {
      var rlocs = Json[vni]["mapping"][eid]["mapping-record"]["LocatorRecord"]
      var rloc_iterator;
      var rlocsOfEID = [];
      for (rloc_iterator = 0; rloc_iterator < rlocs.length; ++rloc_iterator)
      {
        rlocsOfEID.push(rlocs[rloc_iterator]);
      }
      return rlocsOfEID;
    };

    serviceInstance.getAllxtrids = function() {
       var vectorXTR = {};
      for (var i=0; i<Json.length; i++)
      {
        var eids = Json[i]["mapping"];
        for (var j=0; j<eids.length; j++)
        {
          var obj = {};
          var xtrInfo_id = eids[j]["mapping-record"]["xtr-id"];
          if(typeof vectorXTR[xtrInfo_id] != "undefined") obj = vectorXTR[xtrInfo_id];
          var rlocs = serviceInstance.getRLOCs(i,j);
          for(var k=0;k<rlocs.length;k++){
            var address = rlocs[k]["rloc"][rlocs[k]["rloc"]["address-type"].split(":")[1].split("-")[0]];
            obj[rlocs[k]["locator-id"]]= address;
          }
          vectorXTR[xtrInfo_id] = obj;
        }
      }
      return vectorXTR;
    };

    serviceInstance.getAllRlocs = function() {
      var ListRlocs = {};
      var RlocId;
      var RlocIp;
      for (var i=0; i<Json.length; i++)
      {
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
            for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++) {
              RlocId = rlocs[rlocIt]["locator-id"];
              RlocIp = rlocs[rlocIt]["rloc"][rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0]];
              var obj = new Object;
              obj.address= RlocIp;
              ListRlocs[RlocId]= obj;

          }
        }
      }

      return ListRlocs;
    };

    serviceInstance.getRlocInfo = function (RLOC_ID)
    {
     var obj = new Object();
      for (var i=0; i<Json.length; i++)
      {
          var eids = Json[i]["mapping"];
          for (var j = 0; j<eids.length; j++)
          {
            var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
            for (var rlocIt = 0; rlocIt <rlocs.length; rlocIt++) {
              if(RLOC_ID == rlocs[rlocIt]["locator-id"]){
                obj.id = rlocs[rlocIt]["locator-id"];
                obj.address_type = rlocs[rlocIt]["rloc"]["address-type"].split(":")[1].split("-")[0];
                obj.address = rlocs[rlocIt]["rloc"][obj.address_type];
                obj.weight = rlocs[rlocIt]["weight"];
                obj.priority = rlocs[rlocIt]["priority"];
                obj.multicastweight = rlocs[rlocIt]["multicastWeight"];
                obj.xtr_id = eids[j]["mapping-record"]["xtr-id"];
            }
          }
        }
      }
      return obj;
    };

    serviceInstance.getIPTypeOfRLOC = function(rlocAddressType)
    {
      return rlocAddressType.split(":")[1].split("-")[0];
    };

    serviceInstance.getXTRInfo = function(action, xtrId)
    {
      var xtrInfo = [];
      for (var i=0; i<Json.length; i++)
      {
        var obj = new Object();

        obj.vni = Json[i]["vni"];
        obj.info = []
        var eids = Json[i]["mapping"];
        switch(action)
        {
          case "EID":
            for (var j = 0; j<eids.length; j++)
            {
              var xtr = eids[j]["mapping-record"]["xtr-id"];
              if (xtr == xtrId)
              {
                var EID_RLOCS = new Object();
                EID_RLOCS.eid = eids[j]["eid-uri"];
                EID_RLOCS.rlocs = serviceInstance.getRLOCs(i, j);
                var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
                obj.info.push(EID_RLOCS);
                /*for (var rlocIt=0; rlocIt<rlocs.length; rlocIt++)
                {
                  EID_RLOCS.rlocs.push(rlocs[rlocIt]["rloc"][getIPTypeOfRLOC(rlocs[rlocIt]["rloc"]["address-type"])])
                  /*var rlocIP = rlocs[rlocIt]["rloc"][getIPType(rlocs[rlocIt]["rloc"]["address-type"])];
                  obj.info.push(rlocIP);*/
               /* }
                obj.info.push(EID_RLOCS);*/
              }
            }
            break;
          case "RLOC":
            var dictionaryRLOC = {}
            var rlocsList = [];
            for (var j = 0; j<eids.length; j++)
            {
              var xtr = eids[j]["mapping-record"]["xtr-id"];
              if (xtr == xtrId)
              {

                var rlocs = eids[j]["mapping-record"]["LocatorRecord"];
                for (var rlocIt=0; rlocIt<rlocs.length; rlocIt++)
                {
                  var rlocIP = String(rlocs[rlocIt]["rloc"][serviceInstance.getIPTypeOfRLOC(rlocs[rlocIt]["rloc"]["address-type"])]);
                  if (rlocsList.indexOf(rlocIP) == -1) rlocsList.push(rlocIP);
                  if (dictionaryRLOC[rlocIP] == undefined) dictionaryRLOC[rlocIP] = []
                  dictionaryRLOC[rlocIP].push(eids[j]["eid-uri"]);
                  }
              }
            }

            for (var rloc_itList = 0; rloc_itList < rlocsList.length; rloc_itList++)
            {
              var RLOC_EID = new Object();
              RLOC_EID.rloc = rlocsList[rloc_itList]
              RLOC_EID.info = dictionaryRLOC[rlocsList[rloc_itList]];
              obj.info.push(RLOC_EID)
            }
            break;
        }
        xtrInfo[i] = obj;
      }
      return xtrInfo;
    };

    return serviceInstance;
  }])
<|endoftext|>


<commit_before>import _ from 'lodash'

import { insert, set, setAll, getAll, getOriginals, find } from '..'
import createCollection from './util/createCollection'

test('insert/create/set, originals will be persist', async () => {
  const users = createCollection({ onFetch: _.noop })

  set(users, 'a', 'A')
  const state = users.getState()
  expect(_.keys(state.originals)).toEqual(['a'])

  const persistedState = JSON.parse(JSON.stringify(state))
  expect(_.keys(persistedState.originals)).toEqual(['a'])
})

test('setAll', async () => {
  const table = createCollection({ onFetch: _.noop, initState: { byId: { old: { _id: 'old', name: 'old' } } } })
  expect(getAll(table)).toEqual({ old: { _id: 'old', name: 'old' } })

  // first set
  setAll(table, { a: 1, old: { _id: 'old', name: 'new' } })
  expect(getAll(table)).toEqual({ a: 1, old: { _id: 'old', name: 'new' } })
  expect(getOriginals(table)).toEqual({ a: null, old: { _id: 'old', name: 'old' } })

  // set again
  setAll(table, { a: 2, old: { _id: 'old', name: 'new2' } })
  expect(getAll(table)).toEqual({ a: 2, old: { _id: 'old', name: 'new2' } })
  // originals will keep as first change
  expect(getOriginals(table)).toEqual({ a: null, old: { _id: 'old', name: 'old' } })
})

test('insert & find', async () => {
  const collection = createCollection({})

  const inserted = insert(collection, [{ name: 'A' }, { name: 'B' }])
  expect(_.map(inserted, 'name')).toEqual(['A', 'B'])
  expect(_.map(getAll(collection), 'name')).toEqual(['A', 'B'])

  expect(find(collection, _.map(inserted, '_id'))).toEqual(inserted)
})
<commit_msg>test: mutate()<commit_after>import _ from 'lodash'

import { insert, set, setAll, getAll, getOriginals, find, mutate } from '..'
import createCollection from './util/createCollection'

test('setAll', async () => {
  const table = createCollection({
    onFetch: _.noop,
    initState: { byId: { old: { _id: 'old', name: 'old' } } },
  })

  // mutate to root
  mutate(table, { a: { $set: 1 }, old: { $set: { _id: 'old', name: 'new' } } })
  expect(getAll(table)).toEqual({ a: 1, old: { _id: 'old', name: 'new' } })

  // mutate by string
  mutate(table, 'a', { $set: 2 })
  expect(getAll(table).a).toEqual(2)

  // mutate by array of string
  mutate(table, ['old', 'name'], { $set: 'new 2' })
  expect(getAll(table).old.name).toEqual('new 2')
})

test('insert/create/set, originals will be persist', async () => {
  const users = createCollection({ onFetch: _.noop })

  set(users, 'a', 'A')
  const state = users.getState()
  expect(_.keys(state.originals)).toEqual(['a'])

  const persistedState = JSON.parse(JSON.stringify(state))
  expect(_.keys(persistedState.originals)).toEqual(['a'])
})

test('setAll', async () => {
  const table = createCollection({
    onFetch: _.noop,
    initState: { byId: { old: { _id: 'old', name: 'old' } } },
  })
  expect(getAll(table)).toEqual({ old: { _id: 'old', name: 'old' } })

  // first set
  setAll(table, { a: 1, old: { _id: 'old', name: 'new' } })
  expect(getAll(table)).toEqual({ a: 1, old: { _id: 'old', name: 'new' } })
  expect(getOriginals(table)).toEqual({
    a: null,
    old: { _id: 'old', name: 'old' },
  })

  // set again
  setAll(table, { a: 2, old: { _id: 'old', name: 'new2' } })
  expect(getAll(table)).toEqual({ a: 2, old: { _id: 'old', name: 'new2' } })
  // originals will keep as first change
  expect(getOriginals(table)).toEqual({
    a: null,
    old: { _id: 'old', name: 'old' },
  })
})

test('insert & find', async () => {
  const collection = createCollection({})

  const inserted = insert(collection, [{ name: 'A' }, { name: 'B' }])
  expect(_.map(inserted, 'name')).toEqual(['A', 'B'])
  expect(_.map(getAll(collection), 'name')).toEqual(['A', 'B'])

  expect(find(collection, _.map(inserted, '_id'))).toEqual(inserted)
})
<|endoftext|>


<commit_before>// View model for the page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetNameRapport");}, gvm);
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("HomeRapportTitle");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetRapportManual");}, gvm);

    gvm.formequip = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FormEquip");}, gvm);
    gvm.formmethod = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FormMethod");}, gvm);

    gvm.userId = null;
    gvm.availableModules = ko.observableArray([]);

    gvm.updateModules = function(courseid) {
        $.getJSON('/api/coursestructure/' + courseid, function(data) {
            if (!$.isEmptyObject(data)) {
                gvm.availableModules.removeAll();

                $.each(data, function(i, item) {
                    var tblObject = {modid: item.id, modname: item.name, competences: new Array()};
                    if (item.doelstellingen[Object.keys(item.doelstellingen)[0]].id !== null) {
                        gvm.updateCompetences(item.doelstellingen, tblObject.competences);
                    }
                    gvm.availableModules.push(tblObject);
                });
                makeChecklist();
            }
        });
    }

    gvm.updateCompetences = function(data, competences) {
        $.each(data, function(i, item) {
            var tblObject = {comid: item.id, comname: item.name, criterias: new Array()}
            if (item.criterias[Object.keys(item.criterias)[0]] !== null) {
                gvm.updateCriteria(item.criterias, tblObject.criterias);
            }
            competences.push(tblObject);
        });
        makeChecklist();
    }

    gvm.updateCriteria = function(data, criteria) {
        $.each(data, function(i, item){
            var tblObject = {critid: item.id, critname: item.name};
            criteria.push(tblObject);
        });
        makeChecklist();
    }
}

function addWorksheetProperties(serialData, wid, callback) {
    var collection = getCheckedFields();
    $.ajax({
        url: "/api/worksheetproperties/" + wid,
        type: "PUT",
        data: serialData,
        success: function(data) {
            console.log(data);
            callback(false);
        },
        error: function(data) {
            callback(true);
        }
    });
    $.ajax({
        url: "/api/worksheetmodules",
        type: "POST",
        data: {id: wid, modules: collection[0], competences: collection[1], criteria: collection[2]},
        success: function(data) {
            console.log('Success');
        },
        error: function(data) {
            console.log('Failure');
        }
    });
}

function makeChecklist() {
    $('.list-group.checked-list-box .list-group-item').each(function () {

        // Settings
        var $widget = $(this),
            $checkbox = $('<input type="checkbox" class="checkbox" />'),
            color = ($widget.data('color') ? $widget.data('color') : "primary"),
            style = ($widget.data('style') == "button" ? "btn-" : "list-group-item-"),
            settings = {
                on: {
                    icon: 'glyphicon glyphicon-check'
                },
                off: {
                    icon: 'glyphicon glyphicon-unchecked'
                }
            };

        $widget.css('cursor', 'pointer');
        $widget.append($checkbox);

        // Event Handlers
        $widget.on('click', function () {
            $checkbox.prop('checked', !$checkbox.is(':checked'));
            $checkbox.triggerHandler('change');
            /* Expansion */

            /* Expansion */
            updateDisplay();
        });
        $checkbox.on('change', function () {
            updateDisplay();
        });

        // Actions
        function updateDisplay() {
            var isChecked = $checkbox.is(':checked');

            // Set the button's state
            $widget.data('state', (isChecked) ? "on" : "off");

            // Set the button's icon
            $widget.find('.state-icon')
                .removeClass()
                .addClass('state-icon ' + settings[$widget.data('state')].icon);

            // Update the button's color
            if (isChecked) {
                $widget.addClass(style + color + ' active');
            } else {
                $widget.removeClass(style + color + ' active');
            }
        }

        // Initialization
        function init() {

            if ($widget.data('checked') == true) {
                $checkbox.prop('checked', !$checkbox.is(':checked'));
            }

            updateDisplay();

            // Inject the icon if applicable
            if ($widget.find('.state-icon').length == 0) {
                $widget.prepend('');
            }
        }
        init();
    });
}

function getCheckedFields() {
    var checkedItems = [], counter = 0;
    $("#check-list-box li.active").each(function(idx, li) {
        checkedItems[counter] = $(li).text();
        counter++;
    });
    return filterModules(checkedItems);
}

function filterModules(data) {
    var collection = [];
    var modules = [];
    var comps = [];
    var criteria = [];
    $.each(viewModel.availableModules(), function(i, item) {
        if (data.indexOf(item.modname) > -1) {
            modules.push(item.modid);
        }
        $.each(item.competences, function(i, item) {
            if (data.indexOf(item.comname) > -1) {
                comps.push(item.comid);
            }
            $.each(item.criterias, function(i, item) {
                if (data.indexOf(item.critname) > -1) {
                    criteria.push(item.critid);
                }
            });
        });
    });
    collection.push(modules);
    collection.push(comps);
    collection.push(criteria);
    return collection;
}

function initPage() {
    $.getJSON('/api/currentuser', function(data) {
        var courseid = $('#storage').attr('data-value');
        viewModel.userId = data.id;
        viewModel.updateModules(courseid);
    });

    $('#submit').click(function() {
        var wid = $('#header').attr('data-value');
        addWorksheetProperties($('#worksheetform').serialize(), wid, function() {
            $('#worksheetform').prepend("
There was a problem submitting the form
");
        });
    });
}
<commit_msg>properties van worksheet invullen via formulier<commit_after>// View model for the page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetNameRapport");}, gvm);
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("HomeRapportTitle");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetRapportManual");}, gvm);

    gvm.formequip = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FormEquip");}, gvm);
    gvm.formmethod = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FormMethod");}, gvm);

    gvm.userId = null;
    gvm.availableModules = ko.observableArray([]);

    gvm.updateModules = function(courseid) {
        $.getJSON('/api/coursestructure/' + courseid, function(data) {
            if (!$.isEmptyObject(data)) {
                gvm.availableModules.removeAll();

                $.each(data, function(i, item) {
                    var tblObject = {modid: item.id, modname: item.name, competences: new Array()};
                    if (item.doelstellingen[Object.keys(item.doelstellingen)[0]].id !== null) {
                        gvm.updateCompetences(item.doelstellingen, tblObject.competences);
                    }
                    gvm.availableModules.push(tblObject);
                });
                makeChecklist();
            }
        });
    }

    gvm.updateCompetences = function(data, competences) {
        $.each(data, function(i, item) {
            var tblObject = {comid: item.id, comname: item.name, criterias: new Array()}
            if (item.criterias[Object.keys(item.criterias)[0]] !== null) {
                gvm.updateCriteria(item.criterias, tblObject.criterias);
            }
            competences.push(tblObject);
        });
        makeChecklist();
    }

    gvm.updateCriteria = function(data, criteria) {
        $.each(data, function(i, item){
            var tblObject = {critid: item.id, critname: item.name};
            criteria.push(tblObject);
        });
        makeChecklist();
    }
}

function addWorksheetProperties(serialData, wid, callback) {
    var collection = getCheckedFields();
    $.ajax({
        url: "/api/worksheetproperties/" + wid,
        type: "PUT",
        data: serialData,
        success: function(data) {
            console.log(data);
            callback(false);
        },
        error: function(data) {
            callback(true);
        }
    });
    $.ajax({
        url: "/api/worksheetmodules",
        type: "POST",
        data: {id: wid, modules: collection[0], competences: collection[1], criteria: collection[2]},
        success: function(data) {
            console.log('Success');
        },
        error: function(data) {
            console.log('Failure');
        }
    });
}

function makeChecklist() {
    $('.list-group.checked-list-box .list-group-item').each(function () {

        // Settings
        var $widget = $(this),
            $checkbox = $('<input type="checkbox" class="hidden" />'),
            color = ($widget.data('color') ? $widget.data('color') : "primary"),
            style = ($widget.data('style') == "button" ? "btn-" : "list-group-item-"),
            settings = {
                on: {
                    icon: 'glyphicon glyphicon-check'
                },
                off: {
                    icon: 'glyphicon glyphicon-unchecked'
                }
            };

        $widget.css('cursor', 'pointer');
        $widget.append($checkbox);

        // Event Handlers
        $widget.on('click', function () {
            $checkbox.prop('checked', !$checkbox.is(':checked'));
            $checkbox.triggerHandler('change');
            /* Expansion */

            /* Expansion */
            updateDisplay();
        });
        $checkbox.on('change', function () {
            updateDisplay();
        });

        // Actions
        function updateDisplay() {
            var isChecked = $checkbox.is(':checked');

            // Set the button's state
            $widget.data('state', (isChecked) ? "on" : "off");

            // Set the button's icon
            $widget.find('.state-icon')
                .removeClass()
                .addClass('state-icon ' + settings[$widget.data('state')].icon);

            // Update the button's color
            if (isChecked) {
                $widget.addClass(style + color + ' active');
            } else {
                $widget.removeClass(style + color + ' active');
            }
        }

        // Initialization
        function init() {

            if ($widget.data('checked') == true) {
                $checkbox.prop('checked', !$checkbox.is(':checked'));
            }

            updateDisplay();

            // Inject the icon if applicable
            if ($widget.find('.state-icon').length == 0) {
                $widget.prepend('');
            }
        }
        init();
    });
}

function getCheckedFields() {
    var checkedItems = [], counter = 0;
    $("#check-list-box li.active").each(function(idx, li) {
        checkedItems[counter] = $(li).text();
        counter++;
    });
    return filterModules(checkedItems);
}

function filterModules(data) {
    var collection = [];
    var modules = [];
    var comps = [];
    var criteria = [];
    $.each(viewModel.availableModules(), function(i, item) {
        if (data.indexOf(item.modname) > -1) {
            modules.push(item.modid);
        }
        $.each(item.competences, function(i, item) {
            if (data.indexOf(item.comname) > -1) {
                comps.push(item.comid);
            }
            $.each(item.criterias, function(i, item) {
                if (data.indexOf(item.critname) > -1) {
                    criteria.push(item.critid);
                }
            });
        });
    });
    collection.push(modules);
    collection.push(comps);
    collection.push(criteria);
    return collection;
}

function initPage() {
    $.getJSON('/api/currentuser', function(data) {
        var courseid = $('#storage').attr('data-value');
        viewModel.userId = data.id;
        viewModel.updateModules(courseid);
    });

    $('#submit').click(function() {
        var wid = $('#header').attr('data-value');
        addWorksheetProperties($('#worksheetform').serialize(), wid, function() {
            $('#worksheetform').prepend("
There was a problem submitting the form
");
        });
    });
}
<|endoftext|>


<commit_before>
var vm = Npm.require('vm');
var Fiber = Npm.require('fibers');
var Future = Npm.require('fibers/future');

var chai, plugins = {};

if (Gagarin.isActive) {

  chai = Npm.require('chai');

  chai.should();
  chai.use(Npm.require('chai-things'));

  plugins.chai   = chai;
  plugins.Fiber  = Fiber;
  plugins.expect = chai.expect;
  plugins.assert = chai.assert;

  // TODO: also protect these methods with some authentication (user/password/token?)
  //       note that required data my be provided with GAGARIN_SETTINGS

  Meteor.methods({

    '/gagarin/execute': function (closure, code, args) {
      "use strict";

      args = args || [];

      check(code, String);
      check(args, Array);
      check(closure, Object);

      var func;

      try {
        func = vm.runInThisContext('(' + wrapSourceCode(code, args, closure, Object.keys(plugins)) + ')');
      } catch (err) {
        throw new Meteor.Error(400, err);
      }
      if (typeof func === 'function') {
        var feedback;
        try {
          feedback = func.apply({}, values(closure).concat(values(plugins)));
        } catch (err) {
          feedback = { error: err.message };
        }
        return feedback;
      }
    },

    '/gagarin/promise': function (closure, code, args) {
      "use strict";

      args = args || [];

      check(code, String);
      check(args, Array);
      check(closure, Object);

      var future = new Future();
      var chunks = [];

      var keys = Object.keys(closure).map(function (key) {
        return stringify(key) + ": " + key;
      }).join(',');

      args = args.map(stringify);

      args.unshift("(function (cb) {\n    return function ($) {\n      setTimeout(function () { cb({ error : $, closure: {" + keys + "}}); });\n    };\n  })(arguments[arguments.length-1])");
      args.unshift("(function (cb) {\n    return function ($) {\n      setTimeout(function () { cb({ value : $, closure: {" + keys + "}}); });\n    };\n  })(arguments[arguments.length-1])");

      chunks.push(
        "function (" + Object.keys(closure).concat(Object.keys(plugins)).join(', ') + ") {",
        "  'use strict';",
        "  var either = function (first) {",
        "    return {",
        "      or: function (second) {",
        "        return function (arg1, arg2) {",
        "          return arg1 ? first(arg1) : second(arg2);",
        "        };",
        "      }",
        "    };",
        "  };",
        "  try {",
        "    (" + code + ")(",
        "    " + args.join(', ') + ");",
        "  } catch ($) {",
        "    arguments[arguments.length-1]({",
        "      error   : $.message,",
        "      closure : { " + keys + " }",
        "    });",
        "  }",
        "}"
      );

      var func;

      try {
        func = vm.runInThisContext("(" + chunks.join('\n') + ")");
      } catch (err) {
        throw new Meteor.Error(err);
      }

      if (typeof func === 'function') {
        try {
          func.apply({}, values(closure).concat(values(plugins)).concat([ function (feedback) {
            if (feedback.error && typeof feedback.error === 'object') {
              feedback.error = feedback.error.message;
            }
            future['return'](feedback);
          } ]));
        } catch (err) {
          throw new Meteor.Error(err);
        }
        return future.wait();
      }
    },

    '/gagarin/wait': function (closure, timeout, message, code, args) {
      "use strict";

      args = args || [];

      check(timeout, Number);
      check(message, String);
      check(code, String);
      check(args, Array);
      check(closure, Object);

      var future  = new Future();
      var done    = false;
      var handle1 = null;
      var handle2 = null;

      function resolve (feedback) {
        // TODO: can we do away with this sentinel?
        if (done) {
          return;
        }
        done = true;
        if (!feedback.closure) {
          feedback.closure = closure;
        }
        if (feedback.error && typeof feedback.error === 'object') {
          feedback.error = feedback.error.message;
        }
        future['return'](feedback);
        //-------------------------
        clearTimeout(handle1);
        clearTimeout(handle2);
      }

      var func;

      try {
        func = vm.runInThisContext("(" + wrapSourceCode(code, args, closure, Object.keys(plugins)) + ")");
      } catch (err) {
        resolve({ error: err });
      }

      if (!done && typeof func === 'function') {

        // XXX this should be defined prior to the fist call to test, because
        //     the latter can return immediatelly

        handle2 = setTimeout(function () {
          resolve({ error: 'I have been waiting for ' + timeout + ' ms ' + message + ', but it did not happen.' });
        }, timeout);

        (function test() {
          var feedback;
          try {
            feedback = func.apply({}, values(closure).concat(values(plugins)));

            if (feedback.value || feedback.error) {
              resolve(feedback);
            }

            handle1 = setTimeout(Meteor.bindEnvironment(test), 50); // repeat after 1/20 sec.

            if (feedback.closure) {
              closure = feedback.closure;
            }

          } catch (err) {
            resolve({ error: err });
          }
        }());

      } else {
        resolve({ error: 'code has to be a function' })
      }

      return future.wait();
    },

  });

  Meteor.startup(function () {
    console.log('Поехали!'); // Let's ride! (Gagarin, during the Vostok 1 launch)
  });

}

/**
 * Creates a source code of another function, providing the given
 * arguments and injecting the given closure variables.
 *
 * @param {String} code
 * @param {Array} args
 * @param {Object} closure
 */
function wrapSourceCode(code, args, closure, listOfNames) {
  "use strict";

  var chunks = [];

  listOfNames = listOfNames || [];

  chunks.push(
    "function (" + Object.keys(closure).concat(listOfNames).join(', ') + ") {",
    "  'use strict';"
  );

  chunks.push(
    "  try {",
    "    return (function ($) {",
    "      return {",
    "        closure: {"
  );

  Object.keys(closure).forEach(function (key) {
    chunks.push("          " + stringify(key) + ": " + key + ",");
  });

  chunks.push(
    "        },",
    "        value: $,",
    "      };",
    "    })( (" + code + ")(" + args.map(stringify).join(',') + ") );",
    "  } catch (err) {",
    "    return {",
    "      closure: {"
  );

  Object.keys(closure).forEach(function (key) {
    chunks.push("        " + stringify(key) + ": " + key + ",");
  });

  chunks.push(
    "      },",
    "      error: err.message",
    "    };",
    "  }",
    "}"
  );

  return chunks.join('\n');
}

/**
 * Returns all values of the object, sorted
 * alphabetically by corresponding keys.
 *
 * @param {Object}
 */
function values(object) {
  "use strict";

  var values = Object.keys(object).map(function (key) {
    return object[key];
  });
  if (arguments.length > 1) {
    values.push.apply(values, Array.prototype.slice.call(arguments, 1));
  }
  return values;
}

/**
 * A thin wrapper around JSON.stringify:
 *
 *  - `undefined` gets evaluated to "undefined"
 *  - a function gets evaluated to source code
 *
 * @param {Object} value
 */
function stringify(value) {
  "use strict";

  if (typeof value === 'function') {
    return value.toString();
  }
  return value !== undefined ? JSON.stringify(value) : "undefined";
}

<commit_msg>Use cleaner patter for source code wrapping<commit_after>
var vm = Npm.require('vm');
var Fiber = Npm.require('fibers');
var Future = Npm.require('fibers/future');

var chai, plugins = {};

if (Gagarin.isActive) {

  chai = Npm.require('chai');

  chai.should();
  chai.use(Npm.require('chai-things'));

  plugins.chai   = chai;
  plugins.Fiber  = Fiber;
  plugins.expect = chai.expect;
  plugins.assert = chai.assert;
  plugins.either = function either (first) {
    return { or: function (second) {
        return function (arg1, arg2) { return arg1 ? first(arg1) : second(arg2) };
    }};
  };

  // TODO: also protect these methods with some authentication (user/password/token?)
  //       note that required data my be provided with GAGARIN_SETTINGS

  Meteor.methods({

    '/gagarin/execute': function (closure, code, args) {
      "use strict";

      args = args || [];

      check(code, String);
      check(args, Array);
      check(closure, Object);

      var code = providePlugins(isolateScope(code, closure)).join('\n');
      var func;

      try {
        func = vm.runInThisContext('(' + code + ')').apply({}, values(plugins));
      } catch (err) {
        throw new Meteor.Error(400, err);
      }

      return func.apply({}, values(closure, function (userFunc, getClosure) {
        return { value : userFunc.apply({}, args), closure : getClosure() };
      }));

    },

    '/gagarin/promise': function (closure, code, args) {
      "use strict";

      args = args || [];

      check(code, String);
      check(args, Array);
      check(closure, Object);

      var future = new Future();
      var chunks = [];

      var keys = Object.keys(closure).map(function (key) {
        return stringify(key) + ": " + key;
      }).join(',');

      args = args.map(stringify);

      args.unshift("(function (cb) {\n    return function ($) {\n      setTimeout(function () { cb({ error : $, closure: {" + keys + "}}); });\n    };\n  })(arguments[arguments.length-1])");
      args.unshift("(function (cb) {\n    return function ($) {\n      setTimeout(function () { cb({ value : $, closure: {" + keys + "}}); });\n    };\n  })(arguments[arguments.length-1])");

      chunks.push(
        "function (" + Object.keys(closure).concat(Object.keys(plugins)).join(', ') + ") {",
        "  'use strict';",
        "  var either = function (first) {",
        "    return {",
        "      or: function (second) {",
        "        return function (arg1, arg2) {",
        "          return arg1 ? first(arg1) : second(arg2);",
        "        };",
        "      }",
        "    };",
        "  };",
        "  try {",
        "    (" + code + ")(",
        "    " + args.join(', ') + ");",
        "  } catch ($) {",
        "    arguments[arguments.length-1]({",
        "      error   : $.message,",
        "      closure : { " + keys + " }",
        "    });",
        "  }",
        "}"
      );

      var func;

      try {
        func = vm.runInThisContext("(" + chunks.join('\n') + ")");
      } catch (err) {
        throw new Meteor.Error(err);
      }

      if (typeof func === 'function') {
        try {
          func.apply({}, values(closure).concat(values(plugins)).concat([ function (feedback) {
            if (feedback.error && typeof feedback.error === 'object') {
              feedback.error = feedback.error.message;
            }
            future['return'](feedback);
          } ]));
        } catch (err) {
          throw new Meteor.Error(err);
        }
        return future.wait();
      }
    },

    '/gagarin/wait': function (closure, timeout, message, code, args) {
      "use strict";

      args = args || [];

      check(timeout, Number);
      check(message, String);
      check(code, String);
      check(args, Array);
      check(closure, Object);

      var future  = new Future();
      var done    = false;
      var handle1 = null;
      var handle2 = null;

      function resolve (feedback) {
        // TODO: can we do away with this sentinel?
        if (done) {
          return;
        }
        done = true;
        if (!feedback.closure) {
          feedback.closure = closure;
        }
        if (feedback.error && typeof feedback.error === 'object') {
          feedback.error = feedback.error.message;
        }
        future['return'](feedback);
        //-------------------------
        clearTimeout(handle1);
        clearTimeout(handle2);
      }

      code = providePlugins(wrapSourceCode(code, args, closure)).join('\n');

      var func;

      try {
        func = vm.runInThisContext("(" + code + ")").apply({}, values(plugins));
      } catch (err) {
        resolve({ error: err });
      }

      if (!done) {

        // XXX this should be defined prior to the fist call to test, because
        //     the latter can return immediatelly

        handle2 = setTimeout(function () {
          resolve({ error: 'I have been waiting for ' + timeout + ' ms ' + message + ', but it did not happen.' });
        }, timeout);

        (function test() {
          var feedback;
          try {
            feedback = func.apply({}, values(closure));

            if (feedback.value || feedback.error) {
              resolve(feedback);
            }

            handle1 = setTimeout(Meteor.bindEnvironment(test), 50); // repeat after 1/20 sec.

            if (feedback.closure) {
              closure = feedback.closure;
            }

          } catch (err) {
            resolve({ error: err });
          }
        }());

      } else {
        resolve({ error: 'code has to be a function' })
      }

      return future.wait();
    },

  });

  Meteor.startup(function () {
    console.log('Поехали!'); // Let's ride! (Gagarin, during the Vostok 1 launch)
  });

}

function providePlugins(code) {
  var chunks = [];
  if (typeof code === 'string') {
    code = code.split('\n');
  }
  chunks.push("function (" + Object.keys(plugins).join(', ') + ") {");
  chunks.push("  return " + code[0]);

  code.forEach(function (line, index) {
    if (index === 0) return; // omit the first line
    chunks.push("  " + line);
  });
  chunks.push("}");
  return chunks;
}

function isolateScope(code, closure) {
  if (typeof code === 'string') {
    code = code.split('\n');
  }
  var keys = Object.keys(closure).map(function (key) {
    return stringify(key) + ": " + key;
  });
  var chunks = [];

  chunks.push(
    "function (" + Object.keys(closure).join(', ') + ") {",
    "  'use strict';",
    "  return (function (userFunc, getClosure, action) {",
    "    try {",
    "      return action(userFunc, getClosure);",
    "    } catch (err) {",
    "      return { error: err.message, closure: getClosure() };",
    "    }",
    "  })("
  );

  // the code provided by the user goes here
  align(code).forEach(function (line) {
    chunks.push("    " + line);
  });
  chunks[chunks.length-1] += ',';

  chunks.push(
    // the function returning current state of the closure
    "    function () {",
    "      return { " + keys.join(', ') + " };",
    "    },",

    // the custom action
    "    arguments[arguments.length-1]",
    "  );",
    "}"
  );

  return chunks;
}

function align(code) {
  if (typeof code === 'string') {
    code = code.split('\n');
  }
  var match = code[code.length-1].match(/^(\s+)\}/);
  var regex = null;
  if (match && code[0].match(/^function/)) {
    regex = new RegExp("^" + match[1]);
    return code.map(function (line) {
      return line.replace(regex, "");
    });
  }
  return code;
}

/**
 * Creates a source code of another function, providing the given
 * arguments and injecting the given closure variables.
 *
 * @param {String} code
 * @param {Array} args
 * @param {Object} closure
 */
function wrapSourceCode(code, args, closure) {
  "use strict";

  var chunks = [];

  chunks.push(
    "function (" + Object.keys(closure).join(', ') + ") {",
    "  'use strict';"
  );

  chunks.push(
    "  try {",
    "    return (function ($) {",
    "      return {",
    "        closure: {"
  );

  Object.keys(closure).forEach(function (key) {
    chunks.push("          " + stringify(key) + ": " + key + ",");
  });

  chunks.push(
    "        },",
    "        value: $,",
    "      };",
    "    })( (" + code + ")(" + args.map(stringify).join(',') + ") );",
    "  } catch (err) {",
    "    return {",
    "      closure: {"
  );

  Object.keys(closure).forEach(function (key) {
    chunks.push("        " + stringify(key) + ": " + key + ",");
  });

  chunks.push(
    "      },",
    "      error: err.message",
    "    };",
    "  }",
    "}"
  );

  return chunks;
}

/**
 * Returns all values of the object, sorted
 * alphabetically by corresponding keys.
 *
 * @param {Object}
 */
function values(object) {
  "use strict";

  var values = Object.keys(object).map(function (key) {
    return object[key];
  });
  if (arguments.length > 1) {
    values.push.apply(values, Array.prototype.slice.call(arguments, 1));
  }
  return values;
}

/**
 * A thin wrapper around JSON.stringify:
 *
 *  - `undefined` gets evaluated to "undefined"
 *  - a function gets evaluated to source code
 *
 * @param {Object} value
 */
function stringify(value) {
  "use strict";

  if (typeof value === 'function') {
    return value.toString();
  }
  return value !== undefined ? JSON.stringify(value) : "undefined";
}

<|endoftext|>


<commit_before>import React from 'react'
import { Grid, Button, PageHeader, Panel, ListGroup, ListGroupItem, Label } from 'react-bootstrap'
import { Match, Miss, Link } from 'react-router';
import _ from 'lodash'
import { Loading } from '../shared/Loading'
import ghClient from '../shared/githubClient'
import { getCreator } from '../shared/requestUtils'
import NewRequest from './NewRequest'
import PanelIssue from './PanelIssue'
import moment from 'moment'

class Requests extends React.Component {
  constructor() {
    super()
    this.state = {
      isLoading: true,
      issues: [],
    }
    this.getIssues = this.getIssues.bind(this)
    this.findIssue = this.findIssue.bind(this)
  }

  componentDidMount() {
    const labels = ['user request']
    if (this.props.params.label !== this.props.params.repo)
      labels.push(this.props.params.label)
    this.getIssues({ labels: labels.join(), state: 'open' })
  }

  getIssues(issueOptions) {
    this.setState({
      isLoading: true
    });
    return ghClient.gh.getIssues(this.props.params.organisation, this.props.params.repo)
      .listIssues(issueOptions)
      .then(response => {
        this.setState({
          issues: response.data,
          isLoading: false
        });
      })
      .catch(err => console.log(err))
  }

  findIssue(issueNumber) {
    return _.find(this.state.issues, i => i.number === parseInt(issueNumber, 10))
  }

  render() {
    const {pathname, params, ...rest} = this.props
    const newRequestButton = params && (!params.issueNumber || params.issueNumber !== 'new') && (
      <Link to={`/requests/${params.organisation}/${params.repo}/${params.label}/new`}>{
        ({isActive, location, href, onClick, transition}) =>
          <Button onClick={onClick} bsStyle="default" bsSize="large">
            New Request
              </Button>
      }</Link>
    )

    return (
      <Grid>

          <PageHeader>
            <Match pattern={`/requests/:organisation/:repo/:label/:issueNumber`} exactly render={({params}) => <Link to={`/requests/${params.organisation}/${params.repo}/${params.label}`}></Link>} />
            <Match pattern={`/requests/:organisation/:repo/:label`} exactly render={() => <Link to="/requests"></Link>} />
            { }
            {this.props.project.name}

              {' '}
              {newRequestButton}
              {' '}
              {rest.isAdmin && <a href={`http://github.com/${params.organisation}/${params.repo}`} target="_blank">}
              {' '}

          </PageHeader>

        {
          (this.state.isLoading) ? (
            <Loading />
          ) : (

                <Match pattern={`/requests/:organisation/:repo/:label/:issueNumber`} exactly render={(matchProps) => (

                    <Match pattern={`${pathname}/new`} exactly render={(childProps) => (
                      <NewRequest
                        {...matchProps}
                        isAdmin={rest.isAdmin}
                        userProfile={rest.userProfile}
                        project={rest.project}
                        onIssueCreated={this.getIssues} />
                    )} />
                    <Miss render={() => (
                      <PanelIssue
                        {...matchProps}
                        isAdmin={rest.isAdmin}
                        userProfile={rest.userProfile}
                        project={rest.project}
                        issue={this.findIssue(matchProps.params.issueNumber)} />
                    )} />

                )} />
                <Match pattern={pathname} exactly render={() => (
                  <RequestPanel {...this.props} isAdmin={rest.isAdmin} userProfile={rest.userProfile} project={rest.project} issues={this.state.issues} />
                )} />

            )
        }
      </Grid >)
  }
}

Requests.defaultProps = {
  project: { name: '' }
}

export default Requests

const RequestPanel = props => (
  <Panel defaultExpanded header={`${props.issues.length} open issues`} bsStyle="default">
    <ListGroup fill>
      {props.issues.map(i => (
        <Link key={i.number} to={`${props.pathname}/${i.number}`}>{
          ({isActive, location, href, onClick, transition}) => (
            <ListGroupItem onClick={onClick} href={href}>
              <IssueInfo issue={i} />
            </ListGroupItem>
          )
        }</Link>
      )
      )}
    </ListGroup>
  </Panel>
)

const IssueInfo = (props) => (

    {props.issue.title} submitted {moment(props.issue.created_at).fromNow()} by {`${getCreator(props.issue).name || getCreator(props.issue).login}`}{props.issue.labels.map(l => <Tag key={l.name} label={l} />)}

)

const Tag = props => {
  const {label} = props
  if (label.name === "bug") return {label.name}
  if (label.name === "enhancement") return {label.name}

  return null
}
<commit_msg>Add ability to show closed issues<commit_after>import React from 'react'
import { Grid, Button, PageHeader, Panel, ListGroup, ListGroupItem, Label } from 'react-bootstrap'
import { Match, Miss, Link } from 'react-router';
import _ from 'lodash'
import { Loading } from '../shared/Loading'
import ghClient from '../shared/githubClient'
import { getCreator } from '../shared/requestUtils'
import NewRequest from './NewRequest'
import PanelIssue from './PanelIssue'
import moment from 'moment'

const issueVisibilityText = (showOpen) => showOpen ? 'open' : 'closed'

class Requests extends React.Component {
  constructor() {
    super()
    this.state = {
      isLoading: true,
      issues: [],
      showOpen: true
    }
    this.getIssues = this.getIssues.bind(this)
    this.findIssue = this.findIssue.bind(this)
    this.toggleShowOpen = this.toggleShowOpen.bind(this)
  }

  componentDidMount() {
    const labels = ['user request']
    if (this.props.params.label !== this.props.params.repo)
      labels.push(this.props.params.label)
    this.getIssues({ labels: labels.join(), state: 'all' })
  }

  getIssues(issueOptions) {
    this.setState({
      isLoading: true
    });
    return ghClient.gh.getIssues(this.props.params.organisation, this.props.params.repo)
      .listIssues(issueOptions)
      .then(response => {
        this.setState({
          issues: response.data,
          isLoading: false
        });
      })
      .catch(err => console.log(err))
  }

  findIssue(issueNumber) {
    return _.find(this.state.issues, i => i.number === parseInt(issueNumber, 10))
  }

  toggleShowOpen() {
    this.setState({ showOpen: !this.state.showOpen })
  }

  render() {
    const {pathname, params, ...rest} = this.props
    const newRequestButton = params && (!params.issueNumber || params.issueNumber !== 'new') && (
      <Link to={`/requests/${params.organisation}/${params.repo}/${params.label}/new`}>{
        ({isActive, location, href, onClick, transition}) =>
          <Button onClick={onClick} bsStyle="default" bsSize="large">
            New Request
              </Button>
      }</Link>
    )

    return (
      <Grid>

          <PageHeader>
            <Match pattern={`/requests/:organisation/:repo/:label/:issueNumber`} exactly render={({params}) => <Link to={`/requests/${params.organisation}/${params.repo}/${params.label}`}></Link>} />
            <Match pattern={`/requests/:organisation/:repo/:label`} exactly render={() => <Link to="/requests"></Link>} />
            {}
            {this.props.project.name}

              {' '}
              {newRequestButton}
              {' '}
              {rest.isAdmin && <a href={`http://github.com/${params.organisation}/${params.repo}`} target="_blank">}
              {' '}

          </PageHeader>

        {
          (this.state.isLoading) ? (
            <Loading />
          ) : (

                <Match pattern={`/requests/:organisation/:repo/:label/:issueNumber`} exactly render={(matchProps) => (

                    <Match pattern={`${pathname}/new`} exactly render={(childProps) => (
                      <NewRequest
                        {...matchProps}
                        isAdmin={rest.isAdmin}
                        userProfile={rest.userProfile}
                        project={rest.project}
                        onIssueCreated={this.getIssues} />
                    )} />
                    <Miss render={() => (
                      <PanelIssue
                        {...matchProps}
                        isAdmin={rest.isAdmin}
                        userProfile={rest.userProfile}
                        project={rest.project}
                        issue={this.findIssue(matchProps.params.issueNumber)} />
                    )} />

                )} />
                <Match pattern={pathname} exactly render={() => (
                  <RequestPanel
                    {...this.props}
                    isAdmin={rest.isAdmin}
                    userProfile={rest.userProfile}
                    project={rest.project}
                    issues={this.state.issues.filter(i => i.state == issueVisibilityText(this.state.showOpen))}
                    shown={issueVisibilityText(this.state.showOpen)}
                    hidden={issueVisibilityText(!this.state.showOpen)}
                    onVisibilityToggle={this.toggleShowOpen} />
                )} />

            )
        }
      </Grid >)
  }
}

Requests.defaultProps = {
  project: { name: '' }
}

export default Requests

const RequestPanel = props => {
  const header = {props.issues.length} {props.shown} issues Show {props.hidden} issues

  return (
    <Panel defaultExpanded header={header} bsStyle="default">
      <ListGroup fill>
        {props.issues.map(i => (
          <Link key={i.number} to={`${props.pathname}/${i.number}`}>{
            ({isActive, location, href, onClick, transition}) => (
              <ListGroupItem onClick={onClick} href={href}>
                <IssueInfo issue={i} />
              </ListGroupItem>
            )
          }</Link>
        )
        )}
      </ListGroup>
    </Panel>
  )
}

const IssueInfo = (props) => (

    {props.issue.title} submitted {moment(props.issue.created_at).fromNow()} by {`${getCreator(props.issue).name || getCreator(props.issue).login}`}{props.issue.labels.map(l => <Tag key={l.name} label={l} />)}

)

const Tag = props => {
  const {label} = props
  if (label.name === "bug") return {label.name}
  if (label.name === "enhancement") return {label.name}

  return null
}
<|endoftext|>