<commit_before>//#!/bin/env node
/* Copyright 2014 Krzysztof Daniel

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

var logger = require('./util/log.js').getLogger('maps');

var constructSharingURL = function(req, mapId) {
    var protocol;
    if(req.headers.referer){
        protocol = req.headers.referer.split(':')[0];
    } else {
        protocol = 'http';
    }
    var url_main = protocol + '://' + req.headers.host;
    return url_main + '/anonymous/' + mapId + '/map.svg';
};

var mapmodule = function(db) {
    return {
        createNewMap : function (req, res) {

            var userId = req.user.href;
            logger.debug("new map creation requested for user", userId);

            var name = "";
            if (typeof req.body.name !== 'undefined') {
                name = req.body.name;
            }
            var description = "";
            if (typeof req.body.description !== 'undefined') {
                description = req.body.description;
            }

            var date = null;
            if (typeof req.body.description !== 'undefined') {
                date = req.body.date;
            }

            var stub = {
                name : name,
                description : description,
                userDate : date,
                serverDate : new Date(),
                nodes : [],
                connections : []
            };

            var meta = {
                deleted : false,
                userIdGoogle : userId,
                history : [ stub ]
            };

            logger.debug("creating map", meta);

            db.maps.save(meta, function(err, saved) {
                if (err !== null) {
                    logger.error(err);
                    res.setHeader('Content-Type', 'application/json');
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                    res.end();
                }
                if (saved) {
                    logger.debug("new map", saved._id, "created for user", userId);
                    var mapid = '' + saved._id;
                    db.collection('progress').save({
                        mapid : mapid,
                        progress : 0
                    }, function(err, savedprogress) {
                        if (err !== null) {
                            logger.error(err);
                            res.setHeader('Content-Type', 'application/json');
                            res.statusCode = 500;
                            res.send(JSON.stringify(err));
                            res.end();
                        }
                        if (savedprogress) {
                            logger.debug("progress created for map", saved._id);
                            // tell the client where is the map
                            res.redirect('/map/' + saved._id);
                        }
                    });
                }
            });
        },

        deleteMap : function(req, res, mapId, redirect) {

            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            logger.debug("deleting map", mapId, "for user", userId);

            var userDate = null; // TODO: if I will ever care what time was
                                    // in
            // the client when a map was deleted.

            db.maps.findAndModify({
                query : {
                    userIdGoogle : userId,
                    _id : mapId,
                    deleted : false
                },
                update : {
                    $set : {
                        deleted : true
                    },
                    $push : {
                        // null object in the history
                        history : {
                            userDate : userDate,
                            serverDate : new Date()
                        }
                    }
                },
                upsert : true,
            }, function(err, object) {
                if (err !== null) {
                    logger.error(err);
                    res.setHeader('Content-Type', 'application/json');
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                } else {
                    if (!redirect) {
                        res.writeHead(200, {
                            'content-type' : 'text/html'
                        });
                        res.end();
                    } else {
                        res.redirect(redirect);
                    }
                }
            });

        },

        updateMap : function (req, res, mapId) {
            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            logger.debug("updating map", mapId, "for user", userId);
            var historyEntry = req.body;
            // objectID there, replace
            historyEntry._id = mapId;
            historyEntry.userId = userId;
            historyEntry.serverDate = new Date();

            logger.debug('map', historyEntry);

            db.maps.findAndModify({
                query : {
                    userIdGoogle : userId,
                    _id : mapId,
                    deleted : false
                /* don't modify deleted maps */
                },
                update : {
                    $push : {
                        history : historyEntry
                    }
                },
            }, function(err, object) {
                if (err !== null) {
                    logger.error(err);
                    res.setHeader('Content-Type', 'application/json');
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                } else {
                    res.writeHead(200, {
                        'content-type' : 'text/html'
                    });
                    res.end();
                }
            });
        },

        partialMapUpdate : function (req, res, mapId) {
            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            var load = req.body;
            logger.debug("updating map partially", mapId, "for user", userId, " request" + JSON.stringify(load));

            db.maps.find({
                "userIdGoogle" : userId,
                "_id" : mapId,
                deleted : false
            /* don't return deleted maps */
            }, {
                history : {
                    $slice : -1
                }
            }).toArray(function(err, map) {
                res.setHeader('Content-Type', 'application/json');
                if (err !== null) {
                    logger.error(err);
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                } else {
                    // clone last history entry
                    var historyEntry = (JSON.parse(JSON.stringify(map[0].history[0])));
                    historyEntry.serverDate = new Date();
                    historyEntry[load.pk] = load.value;

                    db.maps.findAndModify({
                        query : {
                            userIdGoogle : userId,
                            _id : mapId,
                            deleted : false
                        /* don't modify deleted maps */
                        },
                        update : {
                            $push : {
                                history : historyEntry
                            }
                        },
                    }, function(err, object) {
                        if (err !== null) {
                            logger.error(err);
                            res.setHeader('Content-Type', 'application/json');
                            res.statusCode = 500;
                            res.send(JSON.stringify(err));
                        } else {
                            res.writeHead(200, {
                                'content-type' : 'text/html'
                            });
                            res.end();
                        }
                    });
                }
            });
        },

        getMap : function (req, mapId, callback) {

            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            logger.debug("getting map", mapId, "for user", userId);

            db.maps.find({
                "userIdGoogle" : userId,
                "_id" : mapId,
                deleted : false
            /* don't return deleted maps */
            }, {
                history : {
                    $slice : -1
                }
            }).toArray(function(err, maps) {
                if (err) {
                    logger.error(err);
                } else if (maps.length === 0) {
                    logger.warn('no map ' + mapId + ' for user ' + userId + ' found!');
                } else {
                    if (!maps[0].history[0].nodes) {
                        maps[0].history[0].nodes = [];
                    }
                    if (!maps[0].history[0].connections) {
                        maps[0].history[0].connections = [];
                    }
                    if (!maps[0].anonymousShare) {
                        maps[0].anonymousShare = false;
                    } else {
                        maps[0].anonymousShareLink = constructSharingURL(req, mapId);
                    }
                    callback(maps[0]);
                }
            });

        },

        getMaps : function (req, next) {
            var userId = req.user.href;

            logger.debug("getting maps for user", userId);

            db.maps.find({
                "userIdGoogle" : userId,
                deleted : false
            /* don't return deleted maps */
            }, {
                history : {
                    $slice : -1
                }
            }).toArray(function(err, maps) {
                if (err !== null) {
                    logger.error(err);
                } else {
                    // limit what goes with generic maps
                    var response = [];
                    for (var i = 0; i < maps.length; i++) {
                        var singleMap = {};
                        singleMap._id = maps[i]._id;
                        singleMap.name = maps[i].history[0].name;
                        singleMap.description = maps[i].history[0].description;
                        singleMap.userDate = maps[i].history[0].userDate;
                        singleMap.serverDate = maps[i].history[0].serverDate;
                        response.push(singleMap);
                    }
                    next(response);
                }
            });
        },

        getProgressState : function(req, mapId, finalCallback) {
            var async = require('async');
            async.waterfall([ function(clbck) {
                var userId = req.user.href;

                var objectIdmapId = db.ObjectId(mapId);

                db.maps.find({
                    "userIdGoogle" : userId,
                    "_id" : objectIdmapId,
                    deleted : false
                /* don't return deleted maps */
                }).toArray(function(err, maps) {
                    if (err || !maps || maps.length !== 1) {
                        clbck(err, false);
                        return;
                    }
                    if (maps.length === 1) {
                        clbck(err, true);
                        return;
                    }
                });
            }, function(allowed, clbck) {
                if (!allowed) {
                    clbck(null, {
                        progress : -1
                    });
                    return;
                }
                db.progress.findOne({
                    mapid : mapId
                }, function(err, state) {
                    clbck(err, {
                        progress : state.progress
                    });
                });
            } ], function(err, result) {
                if (err) {
                    logger.error(err);
                    finalCallback({
                        progress : -1
                    });
                } else {
                    finalCallback(result);
                }
            });
        },

        advanceProgressState : function(req, mapid, finalCallback) {
            var async = require('async');
            async.waterfall([ function(clbck) {
                var userId = req.user.href;

                var objectIdmapId = db.ObjectId(mapid);

                db.maps.find({
                    "userIdGoogle" : userId,
                    "_id" : objectIdmapId,
                    deleted : false
                /* don't return deleted maps */
                }).toArray(function(err, maps) {
                    if (err || !maps || maps.length !== 1) {
                        clbck(err, false);
                        return;
                    }
                    if (maps.length === 1) {
                        clbck(err, true);
                        return;
                    }
                });
            }, function(allowed, clbck) {
                if (!allowed) {
                    clbck(null, {
                        progress : -1
                    });
                    return;
                }
                db.progress.findAndModify({
                    query : {
                        mapid : mapid
                    },
                    update : {
                        $inc : {
                            progress : 1
                        }
                    }
                }, function(err, object) {
                    clbck(err, {
                        // this is updated in db
                        progress : object.progress + 1
                    });
                });
            } ], function(err, result) {
                if (err) {
                    logger.error(err);
                    finalCallback({
                        progress : -1
                    });
                } else {
                    finalCallback(result);
                }
            });
        },

        share : function (req, mapId, mode, callback) {
            var userId = req.user.href;
            mapId = db.ObjectId(mapId);

            logger.debug("sharing ", mapId, " for user ", userId, " mode ", mode);

            var anonymousShare = mode === 'anonymous';

            db.maps.findAndModify({
                query : {
                    "_id" : mapId,
                    "userIdGoogle" : userId,
                    deleted : false
                },
                update : {
                    $set : {
                        anonymousShare : anonymousShare
                    }
                }
            }, function(err, object) {
                if (err) {
                    logger.error(err);
                }
                callback(anonymousShare ? {
                    url : constructSharingURL(req, mapId)
                } : {});
            });
        }
    };
};
module.exports = mapmodule;
<commit_msg>fix a bug<commit_after>//#!/bin/env node
/* Copyright 2014 Krzysztof Daniel

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

var logger = require('./util/log.js').getLogger('maps');

var constructSharingURL = function(req, mapId) {
    var protocol;
    if(req.headers.referer){
        protocol = req.headers.referer.split(':')[0];
    } else {
        protocol = 'http';
    }
    var url_main = protocol + '://' + req.headers.host;
    return url_main + '/anonymous/' + mapId + '/map.svg';
};

var mapmodule = function(db) {
    return {
        createNewMap : function (req, res) {

            var userId = req.user.href;
            logger.debug("new map creation requested for user", userId);

            var name = "";
            if (typeof req.body.name !== 'undefined') {
                name = req.body.name;
            }
            var description = "";
            if (typeof req.body.description !== 'undefined') {
                description = req.body.description;
            }

            var date = null;
            if (typeof req.body.description !== 'undefined') {
                date = req.body.date;
            }

            var stub = {
                name : name,
                description : description,
                userDate : date,
                serverDate : new Date(),
                nodes : [],
                connections : []
            };

            var meta = {
                deleted : false,
                userIdGoogle : userId,
                history : [ stub ]
            };

            logger.debug("creating map", meta);

            db.maps.save(meta, function(err, saved) {
                if (err !== null) {
                    logger.error(err);
                    res.setHeader('Content-Type', 'application/json');
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                    res.end();
                }
                if (saved) {
                    logger.debug("new map", saved._id, "created for user", userId);
                    var mapid = '' + saved._id;
                    db.collection('progress').save({
                        mapid : mapid,
                        progress : 0
                    }, function(err, savedprogress) {
                        if (err !== null) {
                            logger.error(err);
                            res.setHeader('Content-Type', 'application/json');
                            res.statusCode = 500;
                            res.send(JSON.stringify(err));
                            res.end();
                        }
                        if (savedprogress) {
                            logger.debug("progress created for map", saved._id);
                            // tell the client where is the map
                            res.redirect('/map/' + saved._id);
                        }
                    });
                }
            });
        },

        deleteMap : function(req, res, mapId, redirect) {

            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            logger.debug("deleting map", mapId, "for user", userId);

            var userDate = null; // TODO: if I will ever care what time was
                                    // in
            // the client when a map was deleted.

            db.maps.findAndModify({
                query : {
                    userIdGoogle : userId,
                    _id : mapId,
                    deleted : false
                },
                update : {
                    $set : {
                        deleted : true
                    },
                    $push : {
                        // null object in the history
                        history : {
                            userDate : userDate,
                            serverDate : new Date()
                        }
                    }
                },
                upsert : true,
            }, function(err, object) {
                if (err !== null) {
                    logger.error(err);
                    res.setHeader('Content-Type', 'application/json');
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                } else {
                    if (!redirect) {
                        res.writeHead(200, {
                            'content-type' : 'text/html'
                        });
                        res.end();
                    } else {
                        res.redirect(redirect);
                    }
                }
            });

        },

        updateMap : function (req, res, mapId) {
            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            logger.debug("updating map", mapId, "for user", userId);
            var historyEntry = req.body;
            // objectID there, replace
            historyEntry._id = mapId;
            historyEntry.userId = userId;
            historyEntry.serverDate = new Date();

            logger.debug('map', historyEntry);

            db.maps.findAndModify({
                query : {
                    userIdGoogle : userId,
                    _id : mapId,
                    deleted : false
                /* don't modify deleted maps */
                },
                update : {
                    $push : {
                        history : historyEntry
                    }
                },
            }, function(err, object) {
                if (err !== null) {
                    logger.error(err);
                    res.setHeader('Content-Type', 'application/json');
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                } else {
                    res.writeHead(200, {
                        'content-type' : 'text/html'
                    });
                    res.end();
                }
            });
        },

        partialMapUpdate : function (req, res, mapId) {
            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            var load = req.body;
            logger.debug("updating map partially", mapId, "for user", userId, " request" + JSON.stringify(load));

            db.maps.find({
                "userIdGoogle" : userId,
                "_id" : mapId,
                deleted : false
            /* don't return deleted maps */
            }, {
                history : {
                    $slice : -1
                }
            }).toArray(function(err, map) {
                res.setHeader('Content-Type', 'application/json');
                if (err !== null) {
                    logger.error(err);
                    res.statusCode = 500;
                    res.send(JSON.stringify(err));
                } else {
                    // clone last history entry
                    var historyEntry = (JSON.parse(JSON.stringify(map[0].history[0])));
                    historyEntry.serverDate = new Date();
                    historyEntry[load.pk] = load.value;

                    db.maps.findAndModify({
                        query : {
                            userIdGoogle : userId,
                            _id : mapId,
                            deleted : false
                        /* don't modify deleted maps */
                        },
                        update : {
                            $push : {
                                history : historyEntry
                            }
                        },
                    }, function(err, object) {
                        if (err !== null) {
                            logger.error(err);
                            res.setHeader('Content-Type', 'application/json');
                            res.statusCode = 500;
                            res.send(JSON.stringify(err));
                        } else {
                            res.writeHead(200, {
                                'content-type' : 'text/html'
                            });
                            res.end();
                        }
                    });
                }
            });
        },

        getMap : function (req, mapId, callback) {

            var userId = req.user.href;

            mapId = db.ObjectId(mapId);
            logger.debug("getting map", mapId, "for user", userId);

            db.maps.find({
                "userIdGoogle" : userId,
                "_id" : mapId,
                deleted : false
            /* don't return deleted maps */
            }, {
                history : {
                    $slice : -1
                }
            }).toArray(function(err, maps) {
                if (err) {
                    logger.error(err);
                } else if (maps.length === 0) {
                    logger.warn('no map ' + mapId + ' for user ' + userId + ' found!');
                } else {
                    if (!maps[0].history[0].nodes) {
                        maps[0].history[0].nodes = [];
                    }
                    if (!maps[0].history[0].connections) {
                        maps[0].history[0].connections = [];
                    }
                    if (!maps[0].anonymousShare) {
                        maps[0].anonymousShare = false;
                    } else {
                        maps[0].anonymousShareLink = constructSharingURL(req, mapId);
                    }
                    callback(maps[0]);
                }
            });

        },

        getMaps : function (req, next) {
            var userId = req.user.href;

            logger.debug("getting maps for user", userId);

            db.maps.find({
                "userIdGoogle" : userId,
                deleted : false
            /* don't return deleted maps */
            }, {
                history : {
                    $slice : -1
                }
            }).toArray(function(err, maps) {
                if (err !== null) {
                    logger.error(err);
                } else {
                    // limit what goes with generic maps
                    var response = [];
                    for (var i = 0; i < maps.length; i++) {
                        var singleMap = {};
                        singleMap._id = maps[i]._id;
                        singleMap.name = maps[i].history[0].name;
                        singleMap.description = maps[i].history[0].description;
                        singleMap.userDate = maps[i].history[0].userDate;
                        singleMap.serverDate = maps[i].history[0].serverDate;
                        response.push(singleMap);
                    }
                    next(response);
                }
            });
        },

        getProgressState : function(req, mapId, finalCallback) {
            var async = require('async');
            async.waterfall([ function(clbck) {
                var userId = req.user.href;

                var objectIdmapId = db.ObjectId(mapId);

                db.maps.find({
                    "userIdGoogle" : userId,
                    "_id" : objectIdmapId,
                    deleted : false
                /* don't return deleted maps */
                }).toArray(function(err, maps) {
                    if (err || !maps || maps.length !== 1) {
                        clbck(err, false);
                        return;
                    }
                    if (maps.length === 1) {
                        clbck(err, true);
                        return;
                    }
                });
            }, function(allowed, clbck) {
                if (!allowed) {
                    clbck(null, {
                        progress : -1
                    });
                    return;
                }
                db.progress.findOne({
                    mapid : mapId
                }, function(err, state) {
                    if (state) {
                        clbck(err, {
                            progress : state.progress
                        });
                    } else {
                        clbck(err, {
                            progress : -1
                        });
                    }
                });
            } ], function(err, result) {
                if (err) {
                    logger.error(err);
                    finalCallback({
                        progress : -1
                    });
                } else {
                    finalCallback(result);
                }
            });
        },

        advanceProgressState : function(req, mapid, finalCallback) {
            var async = require('async');
            async.waterfall([ function(clbck) {
                var userId = req.user.href;

                var objectIdmapId = db.ObjectId(mapid);

                db.maps.find({
                    "userIdGoogle" : userId,
                    "_id" : objectIdmapId,
                    deleted : false
                /* don't return deleted maps */
                }).toArray(function(err, maps) {
                    if (err || !maps || maps.length !== 1) {
                        clbck(err, false);
                        return;
                    }
                    if (maps.length === 1) {
                        clbck(err, true);
                        return;
                    }
                });
            }, function(allowed, clbck) {
                if (!allowed) {
                    clbck(null, {
                        progress : -1
                    });
                    return;
                }
                db.progress.findAndModify({
                    query : {
                        mapid : mapid
                    },
                    update : {
                        $inc : {
                            progress : 1
                        }
                    }
                }, function(err, object) {
                    clbck(err, {
                        // this is updated in db
                        progress : object.progress + 1
                    });
                });
            } ], function(err, result) {
                if (err) {
                    logger.error(err);
                    finalCallback({
                        progress : -1
                    });
                } else {
                    finalCallback(result);
                }
            });
        },

        share : function (req, mapId, mode, callback) {
            var userId = req.user.href;
            mapId = db.ObjectId(mapId);

            logger.debug("sharing ", mapId, " for user ", userId, " mode ", mode);

            var anonymousShare = mode === 'anonymous';

            db.maps.findAndModify({
                query : {
                    "_id" : mapId,
                    "userIdGoogle" : userId,
                    deleted : false
                },
                update : {
                    $set : {
                        anonymousShare : anonymousShare
                    }
                }
            }, function(err, object) {
                if (err) {
                    logger.error(err);
                }
                callback(anonymousShare ? {
                    url : constructSharingURL(req, mapId)
                } : {});
            });
        }
    };
};
module.exports = mapmodule;
<|endoftext|>


<commit_before>var $$ = require('nodeca-lib').Utilities;

module.exports = (function (app, callback) {
  var store = {};

  store.preload = function (env, callback) {
    // grab user groups from user
    if (undefined == env.groups && env.user && env.user.groups) {
      env.groups = env.user.groups;
    }

    // env.grous was neither specified directly nor found in user
    if (!Array.isArray(env.groups) || 0 == env.groups.length) {
      callback(Error("Can't find list of groups"));
      return;
    }

    // got list of groups ids - preload objects
    if ('number' === typeof env.groups[0]) {
      app.model('usergroup')
      .where('_id').in(env.groups)
      .exec(function (err, groups) {
        env.groups = groups;
        callback(err);
      });
      return;
    }

    // everything is ready
    callback();
  };

  store.setter = function (data, env, callback) {
    var UserGroup = app.model('usergroup'),
        joint = new Promise.Joint(),
        settings = {};

    // prepare data to be set
    $$.each(data, function (key, val) { settings['settings.' + key] = val; });

    // call update for each group
    env.groups.forEach(function (g) {
      UserGroup.update({ _id: g._id }, settings, joint.promise().resolve);
    });

    // wait for all changes to be complete
    joint.wait().done(function (err) {
      var i;

      // loop through promise results
      for (i = 1; i < arguments.length; i++) {
        // first argument (idx = 0) means error
        if (arguments[i][0]) { // err
          callback(arguments[i][0]);
          return;
        }
      }

      callback();
    });
  };

  store.getter = function (keys, env, callback) {
    var result = {};

    $$.each(keys, function(key, val) {
      results[key] = $$.map(env.groups, function (grp) {
        return grp.settings[key];
      });
    });

    callback(null, result);
  };

  callback(null, store);
});

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<commit_msg>Started reworking UG<commit_after>var nodeca = require('nodeca-lib'),
    Store = nodeca.Settings.Store,
    $$ = nodeca.Utilities;

var Promise = require('simple-promise');

module.exports = (function (app, callback) {
  var UserGroupStore = function UserGroupStore() {
    Store.call(this);

    var STORE_KEY = '__usergroup_store__';

    this.__.preloader = function (env, callback) {
      // environment was preloaded before
      if (env[STORE_KEY]) {
        callback();
        return;
      }

      // env.grous was neither specified directly nor found in user
      if (!Array.isArray(env.groups) || 0 == env.groups.length) {
        callback(Error("Can't find list of groups"));
        return;
      }

      app.model('usergroup')
      .where('_id').in(env.groups)
      .exec(function (err, groups) {
        env[STORE_KEY] = groups;
        callback(err);
      });
    };

    this.__.setter = function (data, env, callback) {
      var UserGroup = app.model('usergroup'),
          joint = new Promise.Joint(),
          settings = {};

      // prepare data to be set
      $$.each(data, function (key, val) { settings['settings.' + key] = val; });

      // call update for each group
      env[STORE_KEY].forEach(function (g) {
        UserGroup.update({ _id: g._id }, settings, joint.promise().resolve);
      });

      // wait for all changes to be complete
      joint.wait().done(function (err) {
        var i;

        // loop through promise results
        for (i = 1; i < arguments.length; i++) {
          // first argument (idx = 0) means error
          if (arguments[i][0]) { // err
            callback(arguments[i][0]);
            return;
          }
        }

        callback();
      });
    };

    this.__.getter = function (keys, env, callback) {
      var result = {};

      $$.each(keys, function(key, val) {
        results[key] = $$.map(env[STORE_KEY], function (grp) {
          return grp.settings[key];
        });
      });

      callback(null, result);
    };
  };

  Store.adopts(UserGroupStore);

  callback(null, new UserGroupStore());
});

////////////////////////////////////////////////////////////////////////////////
// vim:ts=2:sw=2
////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>import Ember from 'ember'
import computedIndirect from 'ember-computed-indirect/utils/indirect'

import ConvertedOptions from '../mixins/converted-options'
import ErrorState from '../utils/error-state'

export default Ember.Component.extend(ConvertedOptions, {
  layoutName: 'ember-ambitious-forms@components/amb-form-field',
  service: Ember.inject.service('ember-ambitious-forms'),

  tagName: 'label',
  classNames: ['amb-form-field'],
  classNameBindings: ['readOnly:amb-form-field-read-only', '_errorStateClass'],

  readOnly: false,
  // By default, do not show errors until user has interacted with the field
  alwaysShowErrors: false,
  _interactionState: null,

  _onInsert: Ember.on('didInsertElement', function () {
    this.sendAction('onInsert', this)
  }),

  _onRemove: Ember.on('willDestroyElement', function () {
    this.sendAction('onRemove', this)
  }),

  _errorStateClass: Ember.computed('errorState.value', function () {
    let errorStateValue = this.get('errorState.value')
    return `amb-form-field-error-${errorStateValue}`
  }),

  _fieldTypeConfig (configName) {
    let fieldType = this.get('fieldType')
    if (fieldType) {
      return this.get(`service.config.fieldTypeMappings.${fieldType}.${configName}`)
    }
  },

  scopeName: Ember.computed('scope.scopeName', 'scope.constructor._toString', function () {
    let scopeName = this.get('scope.scopeName')
    if (scopeName) {
      return scopeName
    }

    // See if scope has injection _toString
    let matcher = /^.*:([-/a-z0-9]+):$/
    let injectedClassName = this.get('scope.constructor._toString')
    if (matcher.test(injectedClassName)) {
      return injectedClassName.replace(matcher, '$1')
    }
  }),

  type: Ember.computed('options.length', 'fieldType', 'fieldKey', function () {
    let fieldTypeComponent = this._fieldTypeConfig('type')
    if (fieldTypeComponent) {
      return fieldTypeComponent
    }

    if (this.get('options.length') > 0) {
      return 'select'
    }

    switch (this.getWithDefault('fieldType', '').toLowerCase()) {
      case 'number':  return 'number'
      case 'boolean': return 'checkbox'
    }

    let lcaseFieldKey = (this.get('fieldKey') || '').toLowerCase()

    if (lcaseFieldKey.includes('password')) {
      return 'password'
    } else if (lcaseFieldKey.includes('email')) {
      return 'email'
    } else if (lcaseFieldKey.includes('phone')) {
      return 'tel'
    } else if (lcaseFieldKey.includes('url')) {
      return 'url'
    }

    return 'text'
  }),

  _isComponent (name) {
    // Magic sauce: https://github.com/emberjs/ember.js/blob/a841b2e498557cff62c5cb56b01342a0af7abecd/packages/ember-htmlbars/lib/utils/is-component.js#L13
    let owner = Ember.getOwner(this)
    return owner.hasRegistration('component:' + name) ||
           owner.hasRegistration('template:components/' + name)
  },

  // The 'component' helper only takes names and component-helper output, not component classes
  _asComponent (name) {
    return this._isComponent(name) ? name : null
  },

  inputComponent: Ember.computed('readOnly', 'type', function () {
    if (this.get('readOnly')) {
      return 'amb-form-read-only'
    }

    let type = this.get('type')

    return this._asComponent(type) ||
      this._asComponent(`amb-form-${type}`) ||
      'amb-form-input'
  }),

  value: computedIndirect('_valueKey'),
  _valueKey: Ember.computed('scope', 'fieldKey', function () {
    if (this.get('scope')) {
      return `scope.${this.get('fieldKey')}`
    } else {
      // Scope does not exist. Stick it on current component instance instead
      return '_value'
    }
  }),

  formattedValue: Ember.computed('value', function () {
    let formatter = this.get('formatter')
    return formatter.call(this, this.get('value'))
  }),

  formatter (value) {
    if (this.get('type') === 'password') {
      return
    }

    let selectedOption = Ember.A(this.get('convertedOptions') || []).findBy('value', value)
    if (selectedOption) {
      return selectedOption.get('text')
    }

    return value
  },

  errors: null,
  hasErrors: Ember.computed('readOnly', 'errors.length', function () {
    return !this.get('readOnly') && Boolean(this.get('errors.length'))
  }),
  showErrors: Ember.computed('alwaysShowErrors', '_interactionState', function () {
    return this.get('alwaysShowErrors') || this.get('_interactionState') === 'done'
  }),

  errorState: Ember.computed(function () {
    return ErrorState.create({ content: Ember.A([this]) })
  }),

  focusIn () {
    if (this._doFocusOutTimer) {
      Ember.run.cancel(this._doFocusOutTimer)
      this._doFocusOutTimer = null
    }

    this.set('_interactionState', 'active')
  },

  // If the field has 2 inputs, it might trigger focusOut => focusIn immediately
  // Delay this fire to prevent double triggering from executing.
  focusOut () {
    this._doFocusOutTimer = Ember.run.debounce(this, this._doFocusOut, 50)
  },

  _doFocusOut () {
    if (!this.isDestroyed) {
      this.set('_interactionState', 'done')
    }
  },

  required: false,
  label: null,

  labelClass: Ember.computed('required', function () {
    let required = this.get('required')
    if (required === true) {
      return 'amb-form-required'
    } else if (required) {
      return `amb-form-required-${required}`
    }
  }),

  hint: null,
  hintClass: null,

  description: null,
  descriptionClass: null,

  prompt: Ember.computed.oneWay('service.config.prompt'),
  options: Ember.computed.oneWay('optionValues'),

  optionValues: Ember.computed('fieldType', function () {
    return this._fieldTypeConfig('options')
  }),

  actions: {
    valueChanged (newValue) {
      if (this.get('_interactionState') !== 'active') {
        this.set('_interactionState', 'done')
      }
      this.set('value', newValue)
      this.sendAction('onChange', this)
    }
  }
}).reopenClass({
  positionalParams: ['fieldKey']
})
<commit_msg>AO-189 send action onInteractionComplete when form is focused out<commit_after>import Ember from 'ember'
import computedIndirect from 'ember-computed-indirect/utils/indirect'

import ConvertedOptions from '../mixins/converted-options'
import ErrorState from '../utils/error-state'

export default Ember.Component.extend(ConvertedOptions, {
  layoutName: 'ember-ambitious-forms@components/amb-form-field',
  service: Ember.inject.service('ember-ambitious-forms'),

  tagName: 'label',
  classNames: ['amb-form-field'],
  classNameBindings: ['readOnly:amb-form-field-read-only', '_errorStateClass'],

  readOnly: false,
  // By default, do not show errors until user has interacted with the field
  alwaysShowErrors: false,
  _interactionState: null,

  _onInsert: Ember.on('didInsertElement', function () {
    this.sendAction('onInsert', this)
  }),

  _onRemove: Ember.on('willDestroyElement', function () {
    this.sendAction('onRemove', this)
  }),

  _errorStateClass: Ember.computed('errorState.value', function () {
    let errorStateValue = this.get('errorState.value')
    return `amb-form-field-error-${errorStateValue}`
  }),

  _fieldTypeConfig (configName) {
    let fieldType = this.get('fieldType')
    if (fieldType) {
      return this.get(`service.config.fieldTypeMappings.${fieldType}.${configName}`)
    }
  },

  scopeName: Ember.computed('scope.scopeName', 'scope.constructor._toString', function () {
    let scopeName = this.get('scope.scopeName')
    if (scopeName) {
      return scopeName
    }

    // See if scope has injection _toString
    let matcher = /^.*:([-/a-z0-9]+):$/
    let injectedClassName = this.get('scope.constructor._toString')
    if (matcher.test(injectedClassName)) {
      return injectedClassName.replace(matcher, '$1')
    }
  }),

  type: Ember.computed('options.length', 'fieldType', 'fieldKey', function () {
    let fieldTypeComponent = this._fieldTypeConfig('type')
    if (fieldTypeComponent) {
      return fieldTypeComponent
    }

    if (this.get('options.length') > 0) {
      return 'select'
    }

    switch (this.getWithDefault('fieldType', '').toLowerCase()) {
      case 'number':  return 'number'
      case 'boolean': return 'checkbox'
    }

    let lcaseFieldKey = (this.get('fieldKey') || '').toLowerCase()

    if (lcaseFieldKey.includes('password')) {
      return 'password'
    } else if (lcaseFieldKey.includes('email')) {
      return 'email'
    } else if (lcaseFieldKey.includes('phone')) {
      return 'tel'
    } else if (lcaseFieldKey.includes('url')) {
      return 'url'
    }

    return 'text'
  }),

  _isComponent (name) {
    // Magic sauce: https://github.com/emberjs/ember.js/blob/a841b2e498557cff62c5cb56b01342a0af7abecd/packages/ember-htmlbars/lib/utils/is-component.js#L13
    let owner = Ember.getOwner(this)
    return owner.hasRegistration('component:' + name) ||
           owner.hasRegistration('template:components/' + name)
  },

  // The 'component' helper only takes names and component-helper output, not component classes
  _asComponent (name) {
    return this._isComponent(name) ? name : null
  },

  inputComponent: Ember.computed('readOnly', 'type', function () {
    if (this.get('readOnly')) {
      return 'amb-form-read-only'
    }

    let type = this.get('type')

    return this._asComponent(type) ||
      this._asComponent(`amb-form-${type}`) ||
      'amb-form-input'
  }),

  value: computedIndirect('_valueKey'),
  _valueKey: Ember.computed('scope', 'fieldKey', function () {
    if (this.get('scope')) {
      return `scope.${this.get('fieldKey')}`
    } else {
      // Scope does not exist. Stick it on current component instance instead
      return '_value'
    }
  }),

  formattedValue: Ember.computed('value', function () {
    let formatter = this.get('formatter')
    return formatter.call(this, this.get('value'))
  }),

  formatter (value) {
    if (this.get('type') === 'password') {
      return
    }

    let selectedOption = Ember.A(this.get('convertedOptions') || []).findBy('value', value)
    if (selectedOption) {
      return selectedOption.get('text')
    }

    return value
  },

  errors: null,
  hasErrors: Ember.computed('readOnly', 'errors.length', function () {
    return !this.get('readOnly') && Boolean(this.get('errors.length'))
  }),
  showErrors: Ember.computed('alwaysShowErrors', '_interactionState', function () {
    return this.get('alwaysShowErrors') || this.get('_interactionState') === 'done'
  }),

  errorState: Ember.computed(function () {
    return ErrorState.create({ content: Ember.A([this]) })
  }),

  focusIn () {
    if (this._doFocusOutTimer) {
      Ember.run.cancel(this._doFocusOutTimer)
      this._doFocusOutTimer = null
    }

    this.set('_interactionState', 'active')
  },

  // If the field has 2 inputs, it might trigger focusOut => focusIn immediately
  // Delay this fire to prevent double triggering from executing.
  focusOut () {
    this._doFocusOutTimer = Ember.run.debounce(this, this._doFocusOut, 50)
  },

  _doFocusOut () {
    if (!this.isDestroyed) {
      this.set('_interactionState', 'done')
      this.sendAction('onInteractionComplete', this)
    }
  },

  required: false,
  label: null,

  labelClass: Ember.computed('required', function () {
    let required = this.get('required')
    if (required === true) {
      return 'amb-form-required'
    } else if (required) {
      return `amb-form-required-${required}`
    }
  }),

  hint: null,
  hintClass: null,

  description: null,
  descriptionClass: null,

  prompt: Ember.computed.oneWay('service.config.prompt'),
  options: Ember.computed.oneWay('optionValues'),

  optionValues: Ember.computed('fieldType', function () {
    return this._fieldTypeConfig('options')
  }),

  actions: {
    valueChanged (newValue) {
      if (this.get('_interactionState') !== 'active') {
        this.set('_interactionState', 'done')
      }
      this.set('value', newValue)
      this.sendAction('onChange', this)
    }
  }
}).reopenClass({
  positionalParams: ['fieldKey']
})
<|endoftext|>


<commit_before>/* Javascript for PollBlock. */

function PollUtil (runtime, element, pollType) {
    var self = this;

    this.init = function() {
        console.log("this init");
        // Initialization function used for both Poll Types
        this.voteUrl = runtime.handlerUrl(element, 'vote');
        console.log("1");
        this.tallyURL = runtime.handlerUrl(element, 'get_results');
        console.log("2");

        this.submit = $('input[type=button]', element);
        console.log("3");

        this.checkAnswers = $('input[type=checkbox]', element); //get the array of checkboxes
        console.log("4");
        console.log(pollType);
        console.log(element);
        console.log($("#" + pollType + "-results-template", element));
        console.log($("#" + pollType + "-results-template", element).html());
        this.resultsTemplate = Handlebars.compile($("#" + pollType + "-results-template", element).html());  //modify handlebar!!
        console.log("5");
        this.viewResultsButton = $('.view-results-button', element);
        console.log("6");
        this.viewResultsButton.click(this.getResults);
        console.log("7");
        // If the submit button doesn't exist, the user has alread
        // selected a choice. Render results instead of initializing machinery.
        if (! self.submit.length) {
            self.onSubmit({'success': true});
            return false;
        }
        console.log("8");
        var max_submissions = parseInt($('.poll-max-submissions', element).text());
        console.log("9");
        var current_count = parseInt($('.poll-current-count', element).text());
        console.log("10");
        if (max_submissions > 1 && current_count > 0) {
            $('.poll-submissions-count', element).show();
        }
        console.log("11");
        return true;
    };

    this.checkPollInit = function(){
        console.log("checkpollInit");
        // Initialization function for Survey Blocks

        // If the user is unable to vote, disable input.
        if (! $('div.poll-block', element).data('can-vote')) {
            $('input', element).attr('disabled', true);
            return
        }

        console.log("verify all in checkpoll init");
        self.checkAnswers.bind("change.enableSubmit", self.verifyAll);

        self.submit.click(function () {
            $.ajax({
                type: "POST",
                url: self.voteUrl,
                data: JSON.stringify(self.checkPollChoices()),
                success: self.onSubmit
            })
        });
        // If the user has refreshed the page, they may still have an answer
        // selected and the submit button should be enabled.
        self.verifyAll();
    };

    this.checkPollChoices = function () {
        console.log("checkpollChoices");
        var choices = [];
        self.checkAnswers.each(function(index, el) {
            if (el.checked) {
                el = $(el);
                choices.push(el.val()); //maybe element is needed
            }
        });
        return choices;
    };

    this.checkedElement = function (el) {
        console.log("checked element");
        // Given the DOM element of a radio, get the selector for the checked element
        // with the same name.
        return "input[name='" + el.prop('name') + "']:checked"
    };

    this.verifyAll = function () {
        console.log("verify all");
        // Verify that all questions have an answer selected.
        var doEnable = true;

        var temp = [];
        //seems that this function should be the same
        self.checkAnswers.each(function (index, el) {
            if (el.checked) {
                el = $(el);
                temp.push(el.val()); //maybe element is needed
            }

        });

        console.log(JSON.stringify(temp));

        if (! temp.length) {
            doEnable = false;
            return false
        }

        console.log("Verify all is true");
        if (doEnable){
            self.enableSubmit();
        }
    };

    this.onSubmit = function (data) {
        console.log("on submit");
        // Fetch the results from the server and render them.
        if (!data['success']) {
            alert(data['errors'].join('\n'));
        }
        var can_vote = data['can_vote'];
        $('.poll-current-count', element).text(data['submissions_count']);
        if (data['max_submissions'] > 1) {
            $('.poll-submissions-count', element).show();
        }
        if ($('div.poll-block', element).data('private')) {
            // User may be changing their vote. Give visual feedback that it was accepted.
            var thanks = $('.poll-voting-thanks', element);
            thanks.removeClass('poll-hidden');
            thanks.fadeOut(0).fadeIn('slow', 'swing');
            $('.poll-feedback-container', element).removeClass('poll-hidden');
            if (can_vote) {
                $('input[name="poll-submit"]', element).val('Resubmit');
            } else {
                $('input', element).attr('disabled', true)
            }
            return;
        }
        // Used if results are not private, to show the user how other students voted.
        self.getResults();
    };

    this.getResults = function () {
        console.log("get rsults");
        // Used if results are not private, to show the user how other students voted.
        $.ajax({
            // Semantically, this would be better as GET, but we can use helper
            // functions with POST.
            type: "POST",
            url: self.tallyURL,
            data: JSON.stringify({}),
            success: function (data) {
                $('div.poll-block', element).html(self.resultsTemplate(data));
            }
        })
    };

    this.enableSubmit = function () {
        console.log("enable submit");
        // Enable the submit button.
        self.submit.removeAttr("disabled");
        console.log("enable submit remove disabled");
        self.checkAnswers.unbind("change.enableSubmit");  //HERE IS THE BUGGG
    };

    var run_init = this.init();
    if (run_init) {
        console.log("run init");
        var init_map = {'poll': self.pollInit, 'survey': self.surveyInit, 'checkpoll': self.checkPollInit()};
        init_map[pollType]()
    }

}

function CheckPollBlock(runtime, element) {
    new PollUtil(runtime, element, 'checkpoll');
}

function PollBlock(runtime, element) {
    new PollUtil(runtime, element, 'poll');
}

function SurveyBlock(runtime, element) {
    new PollUtil(runtime, element, 'survey');
}
<commit_msg>debug<commit_after>/* Javascript for PollBlock. */

function PollUtil (runtime, element, pollType) {
    var self = this;

    this.init = function() {
        console.log("this init");
        // Initialization function used for both Poll Types
        this.voteUrl = runtime.handlerUrl(element, 'vote');
        console.log("1");
        this.tallyURL = runtime.handlerUrl(element, 'get_results');
        console.log("2");

        this.submit = $('input[type=button]', element);
        console.log("3");

        this.checkAnswers = $('input[type=checkbox]', element); //get the array of checkboxes
        console.log("4");
        console.log(pollType);
        console.log(element);
        console.log($("#" + pollType + "-results-template", element));
        console.log($("#" + pollType + "-results-template", element).html());
        //this.resultsTemplate = Handlebars.compile($("#" + pollType + "-results-template", element).html());  //modify handlebar!!
        console.log("5");
        this.viewResultsButton = $('.view-results-button', element);
        console.log("6");
        this.viewResultsButton.click(this.getResults);
        console.log("7");
        // If the submit button doesn't exist, the user has alread
        // selected a choice. Render results instead of initializing machinery.
        if (! self.submit.length) {
            self.onSubmit({'success': true});
            return false;
        }
        console.log("8");
        var max_submissions = parseInt($('.poll-max-submissions', element).text());
        console.log("9");
        var current_count = parseInt($('.poll-current-count', element).text());
        console.log("10");
        if (max_submissions > 1 && current_count > 0) {
            $('.poll-submissions-count', element).show();
        }
        console.log("11");
        return true;
    };

    this.checkPollInit = function(){
        console.log("checkpollInit");
        // Initialization function for Survey Blocks

        // If the user is unable to vote, disable input.
        if (! $('div.poll-block', element).data('can-vote')) {
            $('input', element).attr('disabled', true);
            return
        }

        console.log("verify all in checkpoll init");
        self.checkAnswers.bind("change.enableSubmit", self.verifyAll);

        self.submit.click(function () {
            $.ajax({
                type: "POST",
                url: self.voteUrl,
                data: JSON.stringify(self.checkPollChoices()),
                success: self.onSubmit
            })
        });
        // If the user has refreshed the page, they may still have an answer
        // selected and the submit button should be enabled.
        self.verifyAll();
    };

    this.checkPollChoices = function () {
        console.log("checkpollChoices");
        var choices = [];
        self.checkAnswers.each(function(index, el) {
            if (el.checked) {
                el = $(el);
                choices.push(el.val()); //maybe element is needed
            }
        });
        return choices;
    };

    this.checkedElement = function (el) {
        console.log("checked element");
        // Given the DOM element of a radio, get the selector for the checked element
        // with the same name.
        return "input[name='" + el.prop('name') + "']:checked"
    };

    this.verifyAll = function () {
        console.log("verify all");
        // Verify that all questions have an answer selected.
        var doEnable = true;

        var temp = [];
        //seems that this function should be the same
        self.checkAnswers.each(function (index, el) {
            if (el.checked) {
                el = $(el);
                temp.push(el.val()); //maybe element is needed
            }

        });

        console.log(JSON.stringify(temp));

        if (! temp.length) {
            doEnable = false;
            return false
        }

        console.log("Verify all is true");
        if (doEnable){
            self.enableSubmit();
        }
    };

    this.onSubmit = function (data) {
        console.log("on submit");
        // Fetch the results from the server and render them.
        if (!data['success']) {
            alert(data['errors'].join('\n'));
        }
        var can_vote = data['can_vote'];
        $('.poll-current-count', element).text(data['submissions_count']);
        if (data['max_submissions'] > 1) {
            $('.poll-submissions-count', element).show();
        }
        if ($('div.poll-block', element).data('private')) {
            // User may be changing their vote. Give visual feedback that it was accepted.
            var thanks = $('.poll-voting-thanks', element);
            thanks.removeClass('poll-hidden');
            thanks.fadeOut(0).fadeIn('slow', 'swing');
            $('.poll-feedback-container', element).removeClass('poll-hidden');
            if (can_vote) {
                $('input[name="poll-submit"]', element).val('Resubmit');
            } else {
                $('input', element).attr('disabled', true)
            }
            return;
        }
        // Used if results are not private, to show the user how other students voted.
        self.getResults();
    };

    this.getResults = function () {
        console.log("get rsults");
        // Used if results are not private, to show the user how other students voted.
        $.ajax({
            // Semantically, this would be better as GET, but we can use helper
            // functions with POST.
            type: "POST",
            url: self.tallyURL,
            data: JSON.stringify({}),
            success: function (data) {
                $('div.poll-block', element).html(self.resultsTemplate(data));
            }
        })
    };

    this.enableSubmit = function () {
        console.log("enable submit");
        // Enable the submit button.
        self.submit.removeAttr("disabled");
        console.log("enable submit remove disabled");
        self.checkAnswers.unbind("change.enableSubmit");  //HERE IS THE BUGGG
    };

    var run_init = this.init();
    if (run_init) {
        console.log("run init");
        var init_map = {'poll': self.pollInit, 'survey': self.surveyInit, 'checkpoll': self.checkPollInit()};
        init_map[pollType]()
    }

}

function CheckPollBlock(runtime, element) {
    new PollUtil(runtime, element, 'checkpoll');
}

function PollBlock(runtime, element) {
    new PollUtil(runtime, element, 'poll');
}

function SurveyBlock(runtime, element) {
    new PollUtil(runtime, element, 'survey');
}
<|endoftext|>


<commit_before>var getVarsGlobal;
var nGet = 0;
$.get = function (url) {
  nGet++;
  var getVarsHolder = {
    'url': url,
    success: function (callback) {
      this.successCallback = callback;
      return this
    }, error: function (callback) {
      this.errorCallback = callback;
      return this
    }, always: function (callback) {
      this.alwaysCallback = callback;
      return this
    }
  };

  getVarsGlobal = getVarsHolder;

  return getVarsHolder;
};

QUnit.test('Hello World', function (assert) {
  assert.strictEqual('http://localhost:8080/categorias/rest', getVarsGlobal.url, 'Verificando url de chamada ajax para listar categorias');
  assert.strictEqual(1, nGet, 'Verificando que get é chamado apenas uma vez');
  var $tabelaCategoria = $('#tabela-categoria');
  assert.strictEqual(0, $tabelaCategoria.children().length, 'Tabela vazia antes de retorno de listagem ajax');

  const categoriasDoServidor = [
    {
      'id': 1,
      creation: '02/02/02 02:02:02',
      nome: 'Celulares'
    },
    {
      'id': 2,
      creation: '03/03/03 02:02:02',
      nome: 'Notebooks'
    },
    {
      'id': 3,
      creation: '04/04/04 02:02:02',
      nome: 'Tablets'
    }
  ];

  getVarsGlobal.successCallback(categoriasDoServidor);
  assert.strictEqual(3, $tabelaCategoria.children().length, 'Tabela vazia antes de retorno de listagem ajax');

  var $listarAjaxLoader = $('#listar-ajax-loader');

  assert.ok($listarAjaxLoader.is(':visible'), 'Mostrando ajax loader');
  getVarsGlobal.alwaysCallback();
  assert.ok(!$listarAjaxLoader.is(':visible'), 'Mostrando ajax loader');

});<commit_msg>Testar chamadas assíncronas. Crud JQuery OK<commit_after>var getVarsGlobal;
var nGet = 0;
$.get = function (url) {
  nGet++;
  var getVarsHolder = {
    'url': url,
    success: function (callback) {
      this.successCallback = callback;
      return this
    }, error: function (callback) {
      this.errorCallback = callback;
      return this
    }, always: function (callback) {
      this.alwaysCallback = callback;
      return this
    }
  };

  getVarsGlobal = getVarsHolder;

  return getVarsHolder;
};

QUnit.test('Hello World', function (assert) {
  assert.strictEqual('http://localhost:8080/categorias/rest', getVarsGlobal.url, 'Verificando url de chamada ajax para listar categorias');
  assert.strictEqual(1, nGet, 'Verificando que get é chamado apenas uma vez');
  var $tabelaCategoria = $('#tabela-categoria');
  assert.strictEqual(0, $tabelaCategoria.children().length, 'Tabela vazia antes de retorno de listagem ajax');

  const categoriasDoServidor = [
    {
      'id': 1,
      creation: '02/02/02 02:02:02',
      nome: 'Celulares'
    },
    {
      'id': 2,
      creation: '03/03/03 02:02:02',
      nome: 'Notebooks'
    },
    {
      'id': 3,
      creation: '04/04/04 02:02:02',
      nome: 'Tablets'
    }
  ];

  getVarsGlobal.successCallback(categoriasDoServidor);
  assert.strictEqual(3, $tabelaCategoria.children().length, 'Tabela vazia antes de retorno de listagem ajax');

  var $listarAjaxLoader = $('#listar-ajax-loader');

  assert.ok($listarAjaxLoader.is(':visible'), 'Mostrando ajax loader');
  getVarsGlobal.alwaysCallback();

  var esperarFimDaAnimacao = assert.async();

  setTimeout(function () {
    assert.ok(!$listarAjaxLoader.is(':visible'), 'Mostrando ajax loader');
    esperarFimDaAnimacao()
  }, 1000);

});<|endoftext|>


<commit_before>'use strict';

var serverlessHttp = require('serverless-http');
var app = require('hops-express').createApp();

// NOTE: If you get ERR_CONTENT_DECODING_FAILED in your browser, this is likely
// due to a compressed response (e.g. gzip) which has not been handled correctly
// by serverless-http and/or API Gateway. Add the necessary MIME types to
// binaryMimeTypes below, then redeploy.
var binaryMimeTypes = [
  'application/javascript',
  'application/json',
  'application/octet-stream',
  'application/xml',
  'font/eot',
  'font/opentype',
  'font/otf',
  'font/woff',
  'font/woff2',
  'image/jpeg',
  'image/png',
  'image/svg+xml',
  'image/x-icon',
  'image/webp',
  'text/comma-separated-values',
  'text/css',
  'text/csv',
  'text/html',
  'text/javascript',
  'text/plain',
  'text/text',
  'text/xml',
];

exports.handler = serverlessHttp(app, {
  binary: binaryMimeTypes,
  request: function(request, context) {
    request.url = context.requestContext.path;
    return request;
  },
});
<commit_msg>fix(lambda): pass required options hash to hops-express<commit_after>'use strict';

var serverlessHttp = require('serverless-http');
var app = require('hops-express').createApp({});

// NOTE: If you get ERR_CONTENT_DECODING_FAILED in your browser, this is likely
// due to a compressed response (e.g. gzip) which has not been handled correctly
// by serverless-http and/or API Gateway. Add the necessary MIME types to
// binaryMimeTypes below, then redeploy.
var binaryMimeTypes = [
  'application/javascript',
  'application/json',
  'application/octet-stream',
  'application/xml',
  'font/eot',
  'font/opentype',
  'font/otf',
  'font/woff',
  'font/woff2',
  'image/jpeg',
  'image/png',
  'image/svg+xml',
  'image/x-icon',
  'image/webp',
  'text/comma-separated-values',
  'text/css',
  'text/csv',
  'text/html',
  'text/javascript',
  'text/plain',
  'text/text',
  'text/xml',
];

exports.handler = serverlessHttp(app, {
  binary: binaryMimeTypes,
  request: function(request, context) {
    request.url = context.requestContext.path;
    return request;
  },
});
<|endoftext|>


<commit_before>var FRManager = new Class({

  config: null,
  FL: null,
  settings: null,
  i18n: null,
  AJAXBalancer: null,
  UIPainter: null,
  UIListener: null,
  MRManager: null,
  errorMessage: '',

  //nově používané proměnné s informacemi o stavu
  task: null,
  miningInProgress: false,
  pageLoading:false,

  IMs: [],
  rules: [],

  rulesCount: 0,
  rulesOrder: null,
  rulesPerPage: null,
  currentPage: null,
  pagesCount: 0,

  initialize: function (config, FL, settings, UIPainter, UIListener, MRManager, i18n) {
    this.config = config;
    var perPageOptions=this.getPerPageOptions();
    this.rulesPerPage=perPageOptions[0];

    this.FL = FL;
    this.settings = settings;
    this.UIPainter = UIPainter;
    this.UIListener = UIListener;
    this.MRManager = MRManager;
    this.i18n = i18n;
    this.AJAXBalancer = new AJAXBalancer();

    this.MRManager.FRManager = this; // MRManager has to know FRManager
  },

  handleInProgress: function () {
    this.reset();
    this.miningInProgress = true;
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  handleStoppedMining: function () {
    this.miningInProgress = false;
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  gotoPage: function(page){
    this.pageLoading=true;
    this.UIPainter.renderFoundRules();
    var url = this.config.getGetRulesUrl(this.task.getId(), (page - 1) * this.rulesPerPage, this.rulesPerPage, this.rulesOrder);

    //region načtení pravidel ze serveru...
    new Request.JSON({
      url: url,
      secure: true,
      onSuccess: function (responseJSON, responseText) {
        this.currentPage=page;
        this.handleSuccessRulesRequest(responseJSON);
      }.bind(this),

      onError: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this),

      onFailure: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this),

      onException: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this),

      onTimeout: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this)

    }).get();
    //endregion
  },

  handleSuccessRulesRequest: function (data) {
    //zjištění aktuálních měr zajímavosti
    this.pageLoading=false;
    this.IMs = this.FL.getRulesIMs(data.task.IMs);
    this.rules = [];
    if (data.task && data.task.name!=''){
      this.setTaskName(data.task.name);
    }

    Object.each(data.rules, function (value, key) {
      this.rules.push(new FoundRule(key, value, this.task));
    }.bind(this));

    this.UIPainter.renderFoundRules();
  },

  handleErrorRulesRequest: function (page){
    this.pageLoading=false;
    this.errorMessage=this.i18n.translate('Loading of rules failed...');
    this.UIPainter.renderFoundRules();
  },

  setRulesCount: function(rulesCount){
    this.rulesCount = rulesCount;
    this.calculatePagesCount();
    if (this.rulesCount > 0) {
      this.gotoPage(1);
    }
  },

  renderRules: function (rulesCount, taskName, inProgress, task) {
    this.task = task;
    this.miningInProgress = inProgress;
    if (taskName!=''){
      this.setTaskName(taskName);
    }
    this.setRulesCount(rulesCount);
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  buildFoundRulesRequest: function (foundRules, URL) {
    var options = {
      url: URL,
      secure: true,

      onRequest: function () {
        Array.each(foundRules,function(foundRule){
          foundRule.setLoading(true);
          this.UIPainter.updateFoundRule(foundRule);
        }.bind(this));
      }.bind(this),

      onSuccess: function (responseJSON, responseText) {
        this.handleSuccessFoundRulesRequest(responseJSON,foundRules);
      }.bind(this),

      onError: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this),

      onCancel: function () {
        Array.each(foundRules,function(foundRule){
          foundRule.setLoading(false);
          this.UIPainter.updateFoundRule(foundRule);
        }.bind(this));
      }.bind(this),

      onFailure: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this),

      onException: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this),

      onTimeout: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this)
    };
    var reqData=null;
    if(foundRules.length==1){
      this.AJAXBalancer.addRequest(options, JSON.encode(reqData), foundRules[0].getId());
    }else{
      this.AJAXBalancer.addRequest(options, JSON.encode(reqData));
    }
  },

  handleErrorFoundRulesRequest: function (foundRules) {
    if (foundRules.length>0){
      Array.each(foundRules,function(foundRule){
        foundRule.setLoading(false);
        this.UIPainter.updateFoundRule(foundRule);
      }.bind(this));
    }
  },

  handleSuccessFoundRulesRequest: function (jsonData,foundRules){
    if ((foundRules == undefined)||(foundRules.length==0)){return;}

    Array.each(foundRules,function(foundRule){
      if (jsonData.rules[foundRule.$id]){
        foundRule.initialize(foundRule.$id,jsonData.rules[foundRule.$id],this.task);
      }
      foundRule.setLoading(false);
      this.UIPainter.updateFoundRule(foundRule);
    }.bind(this));

    this.MRManager.reload(this.getTaskId(), this.getTaskName());

  },

  handleError: function () {
    this.miningInProgress = false;
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  reset: function () {
    this.AJAXBalancer.stopAllRequests();
    this.errorMessage='';
    this.setRulesCount(0);
    this.IMs = this.FL.getRulesIMs([]);
    if(this.rulesOrder==null || this.rulesOrder==''){
      this.rulesOrder=this.IMs[0].getName();
    }
    this.miningInProgress = false;
  },

  markFoundRule: function (foundRule) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getRuleClipboardAddRuleUrl(this.getTaskId(),foundRule.$id));
    this.AJAXBalancer.run();
  },

  unmarkFoundRule: function (foundRule) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getRuleClipboardRemoveRuleUrl(this.getTaskId(),foundRule.$id));
    this.AJAXBalancer.run();
  },

  cleanFoundRulesIds: function(foundRulesCSSIDs){
    var result=[];
    if (!(foundRulesCSSIDs.length>0)){
      return result;
    }
    var taskId=this.getTaskId();
    Array.each(foundRulesCSSIDs,function(id){
      var regExp=/^found-rule-(.+)-(\d+)-checkbox$/;
      var idArr=id.split('-');
      if(regExp.test(id)){
        if(taskId!=idArr[2]){
          return;
        }
        result.push(idArr[3]);
      }
    }.bind([taskId,result]));
    return result;
  },

  getFoundRulesByIds: function(foundRulesIds){
    var result=[];
    if (this.rules.length>0){
      Array.each(this.rules,function(rule){
        if (foundRulesIds.indexOf(rule.$id)>-1){
          result.push(rule);
        }
      }.bind([foundRulesIds,result]));
    }
    return result;
  },

  multiMarkFoundRules:function(foundRulesIds){
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getRuleClipboardAddRuleUrl(this.getTaskId(),urlIds));
    this.AJAXBalancer.run();
  },

  markAllFoundRules: function(){
    this.AJAXBalancer.stopAllRequests();
    var urlIds=[];
    Array.each(this.rules,function(foundRule){
      urlIds.push(foundRule.$id);
      foundRule.setLoading(true);
    }.bind(this));
    this.buildFoundRulesRequest(this.rules,this.config.getRuleClipboardAddAllRulesUrl(this.getTaskId(),urlIds));
    this.AJAXBalancer.run();
  },

  multiUnmarkFoundRules:function(foundRulesIds){
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getRuleClipboardRemoveRuleUrl(this.getTaskId(),urlIds));
    this.AJAXBalancer.run();
  },

  /**
   * Renames the task.
   * @param taskId Task id to rename.
   * @param newTaskName A new task name to set.
   */
  renameTask: function (taskId, newTaskName) {

    new Request.JSON({
      url: this.config.getTaskRenameUrl(taskId,newTaskName),
      secure: true,
      onSuccess: function () {
        this.handleRenameTaskFinished(taskId,newTaskName);
      }.bind(this),

      onError: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this),

      onFailure: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this),

      onException: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this),

      onTimeout: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this)
    }).get();

  },

  handleRenameTaskFinished: function(taskId, newTaskName){
    if (this.getTaskId() == taskId){
      //pokud jde o přejmenování aktuální úlohy, musíme ji překreslit (znovu načteme aktuální stránku s pravidly)
      this.gotoPage(this.currentPage);
    }
    this.MRManager.setTaskName(taskId, newTaskName)
  },

  // duplicated handleRenameTaskFinished due to difference of result for MRManager
  handleRenameTaskError: function(taskId){
    if (this.getTaskId() == taskId){
      //pokud jde o přejmenování aktuální úlohy, musíme ji překreslit (znovu načteme aktuální stránku s pravidly)
      this.gotoPage(this.currentPage);
    }
  },

  getPerPageOptions: function(){
    return this.config.getPerPageOptions();
  },

  getPaginatorType: function(){
    return this.config.getPaginatorType();
  },

  setRulesPerPage: function(count){
    this.rulesPerPage=count;
    this.calculatePagesCount();
    this.gotoPage(1);
  },

  calculatePagesCount: function(){
    this.pagesCount=Math.ceil(this.rulesCount/this.rulesPerPage);
  },

  setTaskName: function(name){
    this.task.setName(name);
  },

  getTaskName: function(){
    return this.task.getName();
  },

  getTaskId: function(){
    return (this.task == undefined) ? 0 : this.task.getId();
  },

  getKBSelectedRuleSet: function(){
    //FIXME Standa - oprava přiřazení aktivního rule setu....
    return $('kb-select').getSelected().get("value");
  },

  //region práce s knowledge base

  kbAddRule: function (foundRule, relation) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getKnowledgeBaseAddRulesUrl(this.getKBSelectedRuleSet(),foundRule.getId(true),relation,true));
    this.AJAXBalancer.run();
  },

  kbRemoveRule: function (foundRule) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getKnowledgeBaseRemoveRulesUrl(this.getKBSelectedRuleSet(),foundRule.getId(true),true));
    this.AJAXBalancer.run();
  },

  multiKBAddRules: function (foundRulesIds, relation) {
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getKnowledgeBaseAddRulesUrl(this.getKBSelectedRuleSet(),urlIds,relation,true));
    this.AJAXBalancer.run();
  },

  multiKBRemoveRules: function (foundRulesIds) {
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getKnowledgeBaseRemoveRulesUrl(this.getKBSelectedRuleSet(),urlIds,true));
    this.AJAXBalancer.run();
  }

  //endregion práce s knowledge base

});<commit_msg>oprava přiřazení ID rulesetu do FRManager.js<commit_after>var FRManager = new Class({

  config: null,
  FL: null,
  settings: null,
  i18n: null,
  AJAXBalancer: null,
  UIPainter: null,
  UIListener: null,
  MRManager: null,
  errorMessage: '',

  //nově používané proměnné s informacemi o stavu
  task: null,
  miningInProgress: false,
  pageLoading:false,

  IMs: [],
  rules: [],

  rulesCount: 0,
  rulesOrder: null,
  rulesPerPage: null,
  currentPage: null,
  pagesCount: 0,

  initialize: function (config, FL, settings, UIPainter, UIListener, MRManager, i18n) {
    this.config = config;
    var perPageOptions=this.getPerPageOptions();
    this.rulesPerPage=perPageOptions[0];

    this.FL = FL;
    this.settings = settings;
    this.UIPainter = UIPainter;
    this.UIListener = UIListener;
    this.MRManager = MRManager;
    this.i18n = i18n;
    this.AJAXBalancer = new AJAXBalancer();

    this.MRManager.FRManager = this; // MRManager has to know FRManager
  },

  handleInProgress: function () {
    this.reset();
    this.miningInProgress = true;
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  handleStoppedMining: function () {
    this.miningInProgress = false;
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  gotoPage: function(page){
    this.pageLoading=true;
    this.UIPainter.renderFoundRules();
    var url = this.config.getGetRulesUrl(this.task.getId(), (page - 1) * this.rulesPerPage, this.rulesPerPage, this.rulesOrder);

    //region načtení pravidel ze serveru...
    new Request.JSON({
      url: url,
      secure: true,
      onSuccess: function (responseJSON, responseText) {
        this.currentPage=page;
        this.handleSuccessRulesRequest(responseJSON);
      }.bind(this),

      onError: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this),

      onFailure: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this),

      onException: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this),

      onTimeout: function () {
        this.handleErrorRulesRequest(page);
      }.bind(this)

    }).get();
    //endregion
  },

  handleSuccessRulesRequest: function (data) {
    //zjištění aktuálních měr zajímavosti
    this.pageLoading=false;
    this.IMs = this.FL.getRulesIMs(data.task.IMs);
    this.rules = [];
    if (data.task && data.task.name!=''){
      this.setTaskName(data.task.name);
    }

    Object.each(data.rules, function (value, key) {
      this.rules.push(new FoundRule(key, value, this.task));
    }.bind(this));

    this.UIPainter.renderFoundRules();
  },

  handleErrorRulesRequest: function (page){
    this.pageLoading=false;
    this.errorMessage=this.i18n.translate('Loading of rules failed...');
    this.UIPainter.renderFoundRules();
  },

  setRulesCount: function(rulesCount){
    this.rulesCount = rulesCount;
    this.calculatePagesCount();
    if (this.rulesCount > 0) {
      this.gotoPage(1);
    }
  },

  renderRules: function (rulesCount, taskName, inProgress, task) {
    this.task = task;
    this.miningInProgress = inProgress;
    if (taskName!=''){
      this.setTaskName(taskName);
    }
    this.setRulesCount(rulesCount);
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  buildFoundRulesRequest: function (foundRules, URL) {
    var options = {
      url: URL,
      secure: true,

      onRequest: function () {
        Array.each(foundRules,function(foundRule){
          foundRule.setLoading(true);
          this.UIPainter.updateFoundRule(foundRule);
        }.bind(this));
      }.bind(this),

      onSuccess: function (responseJSON, responseText) {
        this.handleSuccessFoundRulesRequest(responseJSON,foundRules);
      }.bind(this),

      onError: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this),

      onCancel: function () {
        Array.each(foundRules,function(foundRule){
          foundRule.setLoading(false);
          this.UIPainter.updateFoundRule(foundRule);
        }.bind(this));
      }.bind(this),

      onFailure: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this),

      onException: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this),

      onTimeout: function () {
        this.handleErrorFoundRulesRequest(foundRules);
      }.bind(this)
    };
    var reqData=null;
    if(foundRules.length==1){
      this.AJAXBalancer.addRequest(options, JSON.encode(reqData), foundRules[0].getId());
    }else{
      this.AJAXBalancer.addRequest(options, JSON.encode(reqData));
    }
  },

  handleErrorFoundRulesRequest: function (foundRules) {
    if (foundRules.length>0){
      Array.each(foundRules,function(foundRule){
        foundRule.setLoading(false);
        this.UIPainter.updateFoundRule(foundRule);
      }.bind(this));
    }
  },

  handleSuccessFoundRulesRequest: function (jsonData,foundRules){
    if ((foundRules == undefined)||(foundRules.length==0)){return;}

    Array.each(foundRules,function(foundRule){
      if (jsonData.rules[foundRule.$id]){
        foundRule.initialize(foundRule.$id,jsonData.rules[foundRule.$id],this.task);
      }
      foundRule.setLoading(false);
      this.UIPainter.updateFoundRule(foundRule);
    }.bind(this));

    this.MRManager.reload(this.getTaskId(), this.getTaskName());

  },

  handleError: function () {
    this.miningInProgress = false;
    this.UIPainter.renderActiveRule();
    this.UIPainter.renderFoundRules();
  },

  reset: function () {
    this.AJAXBalancer.stopAllRequests();
    this.errorMessage='';
    this.setRulesCount(0);
    this.IMs = this.FL.getRulesIMs([]);
    if(this.rulesOrder==null || this.rulesOrder==''){
      this.rulesOrder=this.IMs[0].getName();
    }
    this.miningInProgress = false;
  },

  markFoundRule: function (foundRule) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getRuleClipboardAddRuleUrl(this.getTaskId(),foundRule.$id));
    this.AJAXBalancer.run();
  },

  unmarkFoundRule: function (foundRule) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getRuleClipboardRemoveRuleUrl(this.getTaskId(),foundRule.$id));
    this.AJAXBalancer.run();
  },

  cleanFoundRulesIds: function(foundRulesCSSIDs){
    var result=[];
    if (!(foundRulesCSSIDs.length>0)){
      return result;
    }
    var taskId=this.getTaskId();
    Array.each(foundRulesCSSIDs,function(id){
      var regExp=/^found-rule-(.+)-(\d+)-checkbox$/;
      var idArr=id.split('-');
      if(regExp.test(id)){
        if(taskId!=idArr[2]){
          return;
        }
        result.push(idArr[3]);
      }
    }.bind([taskId,result]));
    return result;
  },

  getFoundRulesByIds: function(foundRulesIds){
    var result=[];
    if (this.rules.length>0){
      Array.each(this.rules,function(rule){
        if (foundRulesIds.indexOf(rule.$id)>-1){
          result.push(rule);
        }
      }.bind([foundRulesIds,result]));
    }
    return result;
  },

  multiMarkFoundRules:function(foundRulesIds){
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getRuleClipboardAddRuleUrl(this.getTaskId(),urlIds));
    this.AJAXBalancer.run();
  },

  markAllFoundRules: function(){
    this.AJAXBalancer.stopAllRequests();
    var urlIds=[];
    Array.each(this.rules,function(foundRule){
      urlIds.push(foundRule.$id);
      foundRule.setLoading(true);
    }.bind(this));
    this.buildFoundRulesRequest(this.rules,this.config.getRuleClipboardAddAllRulesUrl(this.getTaskId(),urlIds));
    this.AJAXBalancer.run();
  },

  multiUnmarkFoundRules:function(foundRulesIds){
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getRuleClipboardRemoveRuleUrl(this.getTaskId(),urlIds));
    this.AJAXBalancer.run();
  },

  /**
   * Renames the task.
   * @param taskId Task id to rename.
   * @param newTaskName A new task name to set.
   */
  renameTask: function (taskId, newTaskName) {

    new Request.JSON({
      url: this.config.getTaskRenameUrl(taskId,newTaskName),
      secure: true,
      onSuccess: function () {
        this.handleRenameTaskFinished(taskId,newTaskName);
      }.bind(this),

      onError: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this),

      onFailure: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this),

      onException: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this),

      onTimeout: function () {
        this.handleRenameTaskError(taskId);
      }.bind(this)
    }).get();

  },

  handleRenameTaskFinished: function(taskId, newTaskName){
    if (this.getTaskId() == taskId){
      //pokud jde o přejmenování aktuální úlohy, musíme ji překreslit (znovu načteme aktuální stránku s pravidly)
      this.gotoPage(this.currentPage);
    }
    this.MRManager.setTaskName(taskId, newTaskName)
  },

  // duplicated handleRenameTaskFinished due to difference of result for MRManager
  handleRenameTaskError: function(taskId){
    if (this.getTaskId() == taskId){
      //pokud jde o přejmenování aktuální úlohy, musíme ji překreslit (znovu načteme aktuální stránku s pravidly)
      this.gotoPage(this.currentPage);
    }
  },

  getPerPageOptions: function(){
    return this.config.getPerPageOptions();
  },

  getPaginatorType: function(){
    return this.config.getPaginatorType();
  },

  setRulesPerPage: function(count){
    this.rulesPerPage=count;
    this.calculatePagesCount();
    this.gotoPage(1);
  },

  calculatePagesCount: function(){
    this.pagesCount=Math.ceil(this.rulesCount/this.rulesPerPage);
  },

  setTaskName: function(name){
    this.task.setName(name);
  },

  getTaskName: function(){
    return this.task.getName();
  },

  getTaskId: function(){
    return (this.task == undefined) ? 0 : this.task.getId();
  },

  getKBSelectedRuleSet: function(){
    return this.MRManager.KBid;
  },

  //region práce s knowledge base

  kbAddRule: function (foundRule, relation) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getKnowledgeBaseAddRulesUrl(this.getKBSelectedRuleSet(),foundRule.getId(true),relation,true));
    this.AJAXBalancer.run();
  },

  kbRemoveRule: function (foundRule) {
    this.AJAXBalancer.stopRequest(foundRule.getId());
    this.buildFoundRulesRequest([foundRule],this.config.getKnowledgeBaseRemoveRulesUrl(this.getKBSelectedRuleSet(),foundRule.getId(true),true));
    this.AJAXBalancer.run();
  },

  multiKBAddRules: function (foundRulesIds, relation) {
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getKnowledgeBaseAddRulesUrl(this.getKBSelectedRuleSet(),urlIds,relation,true));
    this.AJAXBalancer.run();
  },

  multiKBRemoveRules: function (foundRulesIds) {
    var selectedFoundRules=this.getFoundRulesByIds(this.cleanFoundRulesIds(foundRulesIds));
    if (selectedFoundRules.length==0){return;}
    var urlIds=[];
    Array.each(selectedFoundRules,function(foundRule){
      urlIds.push(foundRule.$id);
      this.AJAXBalancer.stopRequest(foundRule.getId());
      foundRule.setLoading(true);
    }.bind(this));
    urlIds=urlIds.join(',');
    this.buildFoundRulesRequest(selectedFoundRules,this.config.getKnowledgeBaseRemoveRulesUrl(this.getKBSelectedRuleSet(),urlIds,true));
    this.AJAXBalancer.run();
  }

  //endregion práce s knowledge base

});<|endoftext|>


<commit_before>Color = Base.extend({
	beans: true,

	/**
	 * A value between 0 and 1 that specifies the color's alpha value.
	 * All colors of the different subclasses support alpha values.
	 */
	getAlpha: function() {
		return this._alpha;
	},

	setAlpha: function(alpha) {
		if (this._alpha == null || alpha == -1) this._alpha = -1;
		else if (this._alpha < 0) this._alpha = 0;
		else if (alpha > 1) this._alpha = 1;
		else this._alpha = alpha;
		this._cssString = null;
	},

	/**
	 * Checks if the color has an alpha value.
	 *
	 * @return {@true if the color has an alpha value}
	 */
	hasAlpha: function() {
		return this._alpha != -1;
	},

	getCanvasStyle: function() {
		return this.cssString;
	},

	statics: {
		read: function(args, index) {
			var index = index || 0, length = args.length - index;
			if (length == 1 && args[index] instanceof Color) {
				return args[index];
			} else if (length != 0) {
				var rgbColor = new RGBColor(RGBColor.dont);
				rgbColor.initialize.apply(rgbColor, index > 0
						? Array.prototype.slice.call(args, index) : args);
				return rgbColor;
			}
			return null;
		}
	}
});<commit_msg>Check for null in Color#read.<commit_after>Color = Base.extend({
	beans: true,

	/**
	 * A value between 0 and 1 that specifies the color's alpha value.
	 * All colors of the different subclasses support alpha values.
	 */
	getAlpha: function() {
		return this._alpha;
	},

	setAlpha: function(alpha) {
		if (this._alpha == null || alpha == -1) this._alpha = -1;
		else if (this._alpha < 0) this._alpha = 0;
		else if (alpha > 1) this._alpha = 1;
		else this._alpha = alpha;
		this._cssString = null;
	},

	/**
	 * Checks if the color has an alpha value.
	 *
	 * @return {@true if the color has an alpha value}
	 */
	hasAlpha: function() {
		return this._alpha != -1;
	},

	getCanvasStyle: function() {
		return this.cssString;
	},

	statics: {
		read: function(args, index) {
			var index = index || 0, length = args.length - index;
			console.log(args, length);
			if (length == 1 && args[index] instanceof Color) {
				return args[index];
			} else if (length != 0 && args[0] !== null) {
				var rgbColor = new RGBColor(RGBColor.dont);
				rgbColor.initialize.apply(rgbColor, index > 0
						? Array.prototype.slice.call(args, index) : args);
				return rgbColor;
			}
			return null;
		}
	}
});<|endoftext|>


<commit_before>module.exports = {
  jwt: {
    secret: '4eO5viHe23',
    expiresIn: 60 * 60 * 24 * 3, // in seconds
  },
  mongo: require('./mongo/credential'),
  firebase: require('./firebase/credential.json'),
};
<commit_msg>Support loading configs from env if on travis server<commit_after>if (process.env.TRAVIS) {
  if (!process.env.PROJECT_SERVER_CONFIGS) {
    throw new Error(
      'Environment variable `PROJECT_SERVER_CONFIGS` is not set. ' +
      'Please dump by running `gulp dumpConfigs`'
    );
  }
  module.exports = JSON.parse(process.env.PROJECT_SERVER_CONFIGS);
} else {
  module.exports = {
    jwt: {
      secret: '4eO5viHe23',
      expiresIn: 60 * 60 * 24 * 3, // in seconds
    },
    mongo: require('./mongo/credential'),
    firebase: require('./firebase/credential.json'),
  };
}
<|endoftext|>


<commit_before>export default class Color {
  constructor(space, table) {
    this.space = space;
    this.table = new Map(table);
  }

  toString() {
    let object = Object.create(null);
    this.table.forEach((name, value) => {
      let key = Symbol.keyFor(name);
      if (!key) {
        throw new Error();
      }
      Object.defineProperty(object, key, {'value': value});
    });
    return JSON.strigify(object);
  }

  toBytes() {
    return [0, 0, 0, 0];
  }

  isValid() {
    return false;
  }

  clone() {
    return new this.constructor.name(this.space, this.table);
  }

  space() {
    return Symbol.forKey(this.space);
  }

  access(key, value = null) {
    if (value === null) {
      return this.get(key);
    }
    return this.set(key, value);
  }

  get(key) {
    return this.table.get(key);
  }

  set(key, value) {
    this.table.set(key, value);
    return this;
  }

  values() {
    return this.table.values();
  }
}
<commit_msg>Added new color space conversion method that converts to HSL<commit_after>import {RGB, HSL} from './space';
import Factory from '../converter/factory';

export default class Color {
  constructor(space, table, factory = Factory.normal()) {
    this.space   = space;
    this.table   = new Map(table);
    this.factory = factory;
  }

  toString() {
    let object = Object.create(null);
    this.table.forEach((name, value) => {
      let key = Symbol.keyFor(name);
      if (!key) {
        throw new Error();
      }
      Object.defineProperty(object, key, {'value': value});
    });
    return JSON.strigify(object);
  }

  toBytes() {
    return [0, 0, 0, 0];
  }

  isValid() {
    return false;
  }

  clone() {
    return new this.constructor.name(this.space, this.table);
  }

  space() {
    return Symbol.forKey(this.space);
  }

  access(key, value = null) {
    if (value === null) {
      return this.get(key);
    }
    return this.set(key, value);
  }

  get(key) {
    return this.table.get(key);
  }

  set(key, value) {
    this.table.set(key, value);
    return this;
  }

  values() {
    return this.table.values();
  }

  rgb() {
    return this.convertTo(RGB);
  }

  hsl() {
    return this.convertTo(HSL);
  }

  convertTo(space) {
    let converter = this.factory.create(space);
    return converter.convert(this.toBytes());
  }
}
<|endoftext|>