<commit_before>/*globals CustomEvent*/
import Resolver from 'ember/resolver';

var App = Ember.Application.extend({
  LOG_ACTIVE_GENERATION   : true,
  LOG_MODULE_RESOLVER     : true,
  LOG_TRANSITIONS         : true,
  LOG_TRANSITIONS_INTERNAL: true,
  LOG_VIEW_LOOKUPS        : true,
  modulePrefix            : 'appkit', // TODO: loaded via config
  Resolver                : Resolver['default'],
  init: function () {
    window.ENV.firebaseRoot = new Firebase("https://" + window.ENV.dbName + ".firebaseio.com/");
    this._super.apply(this, arguments);
  }
});

Ember.Application.initializer({
  name: "BuildEnvironmentDetector",
  initialize: function (container, application) {
    application.deferReadiness();

    var self = this,
        buildEnv = Ember.Object.create();

    application.register('build-environment:environment:current', buildEnv, { instantiate: false, singleton: true });
    Ember.A(['model', 'controller', 'view', 'route']).forEach(function(component) {
      application.inject(component, 'buildEnvironment', 'build-environment:environment:current');
    });

    var isLocal = false;
    var localSocket = null;
    var keepReload = Ember.$('meta[name="keepReload"]').attr('content');
    if(document.location.hostname === "localhost" || document.location.hostname === "127.0.0.1")
    {
      isLocal = true;
      localSocket = {
        socket: new window.WebSocket('ws://localhost:6557'),
        doneCallback: null,
        connected: false
      };

      localSocket.socket.onmessage = function(event) {
        if(event.data === 'done') {
          if(localSocket.doneCallback) localSocket.doneCallback();
          localSocket.doneCallback = null; //Reset so done doesn't get called twice
        } else if (event.data.indexOf('done:') === 0) {
          var data = JSON.parse(event.data.replace('done:', ''));
          if(localSocket.doneCallback) localSocket.doneCallback(data);
          localSocket.doneCallback = null; //Reset so done doesn't get called twice
        }
      };

      localSocket.socket.onopen = function() {
        localSocket.connected = true;
      };

      if(!$('meta[name=suppressAlert]').attr('content')) {
        localSocket.socket.onclose = function() {
          window.alert('It looks like your local runserver stopped. To use the CMS please restart it.');
        };
      }

      // Shut down LiveReload
      if(window.LiveReload && !keepReload) {
        var shutDown = new CustomEvent('LiveReloadShutDown');
        document.addEventListener("LiveReloadConnect", function() {
          document.dispatchEvent(shutDown);
        }, false);
      }
    }

    var siteName = Ember.$('meta[name="siteName"]').attr('content');
    buildEnv.set('local', isLocal);
    buildEnv.set('localSocket', localSocket);
    buildEnv.set('siteName', siteName);

    application.set('buildEnvironment', buildEnv);

    application.advanceReadiness();
  }
});

Ember.Application.initializer({
  name: "FirebaseSimpleLogin",
  initialize: function (container, application) {

    application.deferReadiness();

    var self = this,
        siteName = Ember.$('meta[name="siteName"]').attr('content'),
        session = Ember.Object.create();

    // Add `session` to all the things
    application.register('firebase-simple-login:session:current', session, { instantiate: false, singleton: true });
    Ember.A(['model', 'controller', 'view', 'route']).forEach(function(component) {
      application.inject(component, 'session', 'firebase-simple-login:session:current');
    });
    application.set('session', session);

    session.set('auth', new FirebaseSimpleLogin(window.ENV.firebaseRoot, function(error, user) {

      var initializeUser = function(snapshot) {
        var bucket = snapshot.val();

        window.ENV.firebase = window.ENV.firebaseRoot.child('buckets/' + siteName + '/' + bucket + '/dev');

        // Presence
        var presenceRef   = window.ENV.firebase.child('presence'),
            onlineRef     = presenceRef.child('online/' + user.uid),
            lastOnlineRef = presenceRef.child('lastOnline/' + user.uid),
            connectedRef  = window.ENV.firebaseRoot.child('.info/connected');

        connectedRef.on('value', function (snap) {
          if (snap.val() === true) {
            // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)

            // add this device to my connections list
            // this value could contain info about the device or a timestamp too
            onlineRef.set(user.email);

            // when I disconnect, remove this device
            onlineRef.onDisconnect().remove();

            // when I disconnect, update the last time I was seen online
            lastOnlineRef.onDisconnect().set(Firebase.ServerValue.TIMESTAMP);
          }
        });

        // user authenticated with Firebase
        session.set('user', user);
        session.set('error', null);
        session.set('site', {
          name: siteName,
          token: bucket
        });

        window.ENV.firebaseRoot.child('management/sites/' + siteName).once('value', function(snapshot) {
          var siteData = snapshot.val();
          var escapedEmail = user.email.replace(/\./g, ',1');

          if(siteData.owners[escapedEmail]) {
            session.set('isOwner', true);
          } else if (siteData.users[escapedEmail]) {
            session.set('isOwner', false);
          }

          application.advanceReadiness();
        });
      };

      if (error) {
        // an error occurred while attempting login
        session.set('error', error);
        application.advanceReadiness();
      } else if (user) {

        window.ENV.firebaseRoot.child('management/sites/' + siteName + '/key').once('value', initializeUser, function (error) {

          if(error.code === 'PERMISSION_DENIED')
          {
            var escapedEmail = user.email.replace(/\./g, ',1');
            // Try to add to use list, if this is allowed they were a potential user
            window.ENV.firebaseRoot.child('management/sites/' + siteName + '/users/' + escapedEmail).set(user.email, function(error) {
              if(error) {
                session.get('auth').logout();
                session.set('error', error);
                application.advanceReadiness();
              } else {
                // Try to delete self from potential user list
                window.ENV.firebaseRoot.child('management/sites/' + siteName + '/potential_users/' + escapedEmail).remove(function(error) {
                  if(error) {
                    session.get('auth').logout();
                    session.set('error', error);
                    application.advanceReadiness();
                  } else {
                    // Redo original authorization call
                    window.ENV.firebaseRoot.child('management/sites/' + siteName + '/key').once('value', initializeUser, function (error) {
                      session.get('auth').logout();
                      session.set('error', error);
                      application.advanceReadiness();
                    });
                  }
                });
              }
            });
            // User may be a potential, try and elevate to user
          } else {
            session.get('auth').logout();
            session.set('error', error);
            application.advanceReadiness();
          }
        });
      } else {
        // user is logged out
        session.set('user', null);
        session.set('site', null);
        application.advanceReadiness();
      }
    }));

    window.ENV.sendBuildSignal = function() {
      var user = session.get('user.email');

      if(application.get('buildEnvironment').local === false)
      {
        var data = {
          'userid': user,
          'sitename': siteName
        };

        window.ENV.firebase.root().child('management/commands/build/' + siteName).set(data, function() {});
      } else {
        window.ENV.sendGruntCommand('build');
      }
    };

    window.ENV.sendGruntCommand = function(command, callback) {
      var localSocket = application.get('buildEnvironment').localSocket;
      if(localSocket && localSocket.connected) {
        localSocket.socket.send(command);
        if(callback) localSocket.doneCallback = callback;
      }
    }.bind(this);
  }
});

// Before any route, kick user to login if they aren't logged in
Ember.Route.reopen({
  beforeModel: function (transition) {
    var openRoutes = ['login', 'password-reset', 'create-user', 'confirm-email', 'resend-email'];
    if (Ember.$.inArray(transition.targetName, openRoutes) === -1 && !this.get('session.user')) {
      this.get('session').set('transition', transition);
      transition.abort();
      this.transitionTo('login');
    } else { // Only executed if your logged in
      var ownerRoutes = ['wh.settings.team'];
      if (Ember.$.inArray(transition.targetName, ownerRoutes) !== -1 && !this.get('session.isOwner')) {
        this.get('session').set('transition', transition);
        transition.abort();
        this.transitionTo('wh.index');
      }
    }

  }
});
Ember.TextField.reopen({
  attributeBindings: [ 'required' ]
});

// Ian doesn't like pluralizing, singularizing
Ember.Inflector.inflector.pluralize = function (string ) { return string; };
Ember.Inflector.inflector.singularize = function (string ) { return string; };

export default App;
<commit_msg>siteUrl<commit_after>/*globals CustomEvent*/
import Resolver from 'ember/resolver';

var App = Ember.Application.extend({
  LOG_ACTIVE_GENERATION   : true,
  LOG_MODULE_RESOLVER     : true,
  LOG_TRANSITIONS         : true,
  LOG_TRANSITIONS_INTERNAL: true,
  LOG_VIEW_LOOKUPS        : true,
  modulePrefix            : 'appkit', // TODO: loaded via config
  Resolver                : Resolver['default'],
  init: function () {
    window.ENV.firebaseRoot = new Firebase("https://" + window.ENV.dbName + ".firebaseio.com/");
    this._super.apply(this, arguments);
  }
});

Ember.Application.initializer({
  name: "BuildEnvironmentDetector",
  initialize: function (container, application) {
    application.deferReadiness();

    var self = this,
        buildEnv = Ember.Object.create();

    application.register('build-environment:environment:current', buildEnv, { instantiate: false, singleton: true });
    Ember.A(['model', 'controller', 'view', 'route']).forEach(function(component) {
      application.inject(component, 'buildEnvironment', 'build-environment:environment:current');
    });

    var isLocal = false;
    var localSocket = null;
    var keepReload = Ember.$('meta[name="keepReload"]').attr('content');
    if(document.location.hostname === "localhost" || document.location.hostname === "127.0.0.1")
    {
      isLocal = true;
      localSocket = {
        socket: new window.WebSocket('ws://localhost:6557'),
        doneCallback: null,
        connected: false
      };

      localSocket.socket.onmessage = function(event) {
        if(event.data === 'done') {
          if(localSocket.doneCallback) localSocket.doneCallback();
          localSocket.doneCallback = null; //Reset so done doesn't get called twice
        } else if (event.data.indexOf('done:') === 0) {
          var data = JSON.parse(event.data.replace('done:', ''));
          if(localSocket.doneCallback) localSocket.doneCallback(data);
          localSocket.doneCallback = null; //Reset so done doesn't get called twice
        }
      };

      localSocket.socket.onopen = function() {
        localSocket.connected = true;
      };

      if(!$('meta[name=suppressAlert]').attr('content')) {
        localSocket.socket.onclose = function() {
          window.alert('It looks like your local runserver stopped. To use the CMS please restart it.');
        };
      }

      // Shut down LiveReload
      if(window.LiveReload && !keepReload) {
        var shutDown = new CustomEvent('LiveReloadShutDown');
        document.addEventListener("LiveReloadConnect", function() {
          document.dispatchEvent(shutDown);
        }, false);
      }
    }

    var siteName = Ember.$('meta[name="siteName"]').attr('content');
    buildEnv.set('local', isLocal);
    buildEnv.set('localSocket', localSocket);
    buildEnv.set('siteName', siteName);
    buildEnv.set('siteUrl', 'http://' + siteName + '.webhook.com/');

    application.set('buildEnvironment', buildEnv);

    application.advanceReadiness();
  }
});

Ember.Application.initializer({
  name: "FirebaseSimpleLogin",
  initialize: function (container, application) {

    application.deferReadiness();

    var self = this,
        siteName = Ember.$('meta[name="siteName"]').attr('content'),
        session = Ember.Object.create();

    // Add `session` to all the things
    application.register('firebase-simple-login:session:current', session, { instantiate: false, singleton: true });
    Ember.A(['model', 'controller', 'view', 'route']).forEach(function(component) {
      application.inject(component, 'session', 'firebase-simple-login:session:current');
    });
    application.set('session', session);

    session.set('auth', new FirebaseSimpleLogin(window.ENV.firebaseRoot, function(error, user) {

      var initializeUser = function(snapshot) {
        var bucket = snapshot.val();

        window.ENV.firebase = window.ENV.firebaseRoot.child('buckets/' + siteName + '/' + bucket + '/dev');

        // Presence
        var presenceRef   = window.ENV.firebase.child('presence'),
            onlineRef     = presenceRef.child('online/' + user.uid),
            lastOnlineRef = presenceRef.child('lastOnline/' + user.uid),
            connectedRef  = window.ENV.firebaseRoot.child('.info/connected');

        connectedRef.on('value', function (snap) {
          if (snap.val() === true) {
            // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)

            // add this device to my connections list
            // this value could contain info about the device or a timestamp too
            onlineRef.set(user.email);

            // when I disconnect, remove this device
            onlineRef.onDisconnect().remove();

            // when I disconnect, update the last time I was seen online
            lastOnlineRef.onDisconnect().set(Firebase.ServerValue.TIMESTAMP);
          }
        });

        // user authenticated with Firebase
        session.set('user', user);
        session.set('error', null);
        session.set('site', {
          name: siteName,
          token: bucket
        });

        window.ENV.firebaseRoot.child('management/sites/' + siteName).once('value', function(snapshot) {
          var siteData = snapshot.val();
          var escapedEmail = user.email.replace(/\./g, ',1');

          if(siteData.owners[escapedEmail]) {
            session.set('isOwner', true);
          } else if (siteData.users[escapedEmail]) {
            session.set('isOwner', false);
          }

          application.advanceReadiness();
        });
      };

      if (error) {
        // an error occurred while attempting login
        session.set('error', error);
        application.advanceReadiness();
      } else if (user) {

        window.ENV.firebaseRoot.child('management/sites/' + siteName + '/key').once('value', initializeUser, function (error) {

          if(error.code === 'PERMISSION_DENIED')
          {
            var escapedEmail = user.email.replace(/\./g, ',1');
            // Try to add to use list, if this is allowed they were a potential user
            window.ENV.firebaseRoot.child('management/sites/' + siteName + '/users/' + escapedEmail).set(user.email, function(error) {
              if(error) {
                session.get('auth').logout();
                session.set('error', error);
                application.advanceReadiness();
              } else {
                // Try to delete self from potential user list
                window.ENV.firebaseRoot.child('management/sites/' + siteName + '/potential_users/' + escapedEmail).remove(function(error) {
                  if(error) {
                    session.get('auth').logout();
                    session.set('error', error);
                    application.advanceReadiness();
                  } else {
                    // Redo original authorization call
                    window.ENV.firebaseRoot.child('management/sites/' + siteName + '/key').once('value', initializeUser, function (error) {
                      session.get('auth').logout();
                      session.set('error', error);
                      application.advanceReadiness();
                    });
                  }
                });
              }
            });
            // User may be a potential, try and elevate to user
          } else {
            session.get('auth').logout();
            session.set('error', error);
            application.advanceReadiness();
          }
        });
      } else {
        // user is logged out
        session.set('user', null);
        session.set('site', null);
        application.advanceReadiness();
      }
    }));

    window.ENV.sendBuildSignal = function() {
      var user = session.get('user.email');

      if(application.get('buildEnvironment').local === false)
      {
        var data = {
          'userid': user,
          'sitename': siteName
        };

        window.ENV.firebase.root().child('management/commands/build/' + siteName).set(data, function() {});
      } else {
        window.ENV.sendGruntCommand('build');
      }
    };

    window.ENV.sendGruntCommand = function(command, callback) {
      var localSocket = application.get('buildEnvironment').localSocket;
      if(localSocket && localSocket.connected) {
        localSocket.socket.send(command);
        if(callback) localSocket.doneCallback = callback;
      }
    }.bind(this);
  }
});

// Before any route, kick user to login if they aren't logged in
Ember.Route.reopen({
  beforeModel: function (transition) {
    var openRoutes = ['login', 'password-reset', 'create-user', 'confirm-email', 'resend-email'];
    if (Ember.$.inArray(transition.targetName, openRoutes) === -1 && !this.get('session.user')) {
      this.get('session').set('transition', transition);
      transition.abort();
      this.transitionTo('login');
    } else { // Only executed if your logged in
      var ownerRoutes = ['wh.settings.team'];
      if (Ember.$.inArray(transition.targetName, ownerRoutes) !== -1 && !this.get('session.isOwner')) {
        this.get('session').set('transition', transition);
        transition.abort();
        this.transitionTo('wh.index');
      }
    }

  }
});
Ember.TextField.reopen({
  attributeBindings: [ 'required' ]
});

// Ian doesn't like pluralizing, singularizing
Ember.Inflector.inflector.pluralize = function (string ) { return string; };
Ember.Inflector.inflector.singularize = function (string ) { return string; };

export default App;
<|endoftext|>


<commit_before>import superagent from 'superagent';
import q from 'q';
import querystring from 'querystring';

import Account from '../models/account';
import Comment from '../models/comment';
import Link from '../models/link';
import Vote from '../models/vote';
import Subreddit from '../models/subreddit';

import NoModelError from '../errors/noModelError';
import ValidationError from '../errors/validationError';

import LRU from 'lru-cache';

var defaultCacheConfig = {
 max: 500,
 maxAge: 1000 * 50 * 3,
}

function processMeta(res) {
  var headers = res.headers;

  return {
    moose: headers['x-moose'],
    tracking: headers['x-reddit-tracking'],
  }
}

function baseGet(cache={}, uri, options, request, formatBody) {
  var options = options || {};
  var defer = q.defer();

  var query = options.query || {};
  var headers = options.headers || {};

  if (options.userAgent) {
    headers['User-Agent'] = options.userAgent;
  }

  var key = uri + '?' + querystring.stringify(query);

  if (headers.Authorization) {
    cache = cache.authed;
    key += '&auth=' + headers.Authorization;
  } else {
    cache = cache.unauthed;
  }

  if(cache && cache.get(key)) {
    defer.resolve(cache.get(key));
    return defer.promise;
  }

  request.get(uri)
    .set(headers)
    .query(query)
    .end((err, res) => {
      if (err) {
        return defer.reject(err);
      }

      if (!res.ok) {
        return defer.reject(res);
      }

      try {
        var body = res.body;

        if (formatBody) {
          body = formatBody(body);
        }

        var data = {
          data: body,
          meta: processMeta(res),
        }

        if(cache) { cache.set(key, data); }

        defer.resolve(data);
      } catch (e) {
        defer.reject(e);
      }
    });

  return defer.promise;
}

function basePost(uri, options, request, formatBody) {
  var options = options || {};
  var defer = q.defer();

  var form = options.form || {};
  var headers = options.headers || {};

  var cache = cache.authed;
  if (cache) { cache.reset(); }

  if (options.userAgent) {
    headers['User-Agent'] = options.userAgent;
  }

  request.post(uri)
    .set(headers)
    .send(form)
    .type('form')
    .end((err, res) => {
      if (err) {
        return defer.reject(err);
      }

      if (!res.ok) {
        defer.reject(res);
      }

      try {
        var body = res.body;

        if (formatBody) {
          body = formatBody(body);
        }

        var data = {
          data: body,
          meta: processMeta(res),
        }

        defer.resolve(data);
      } catch (e) {
        defer.reject(e);
      }
    });

  return defer.promise;
}

function bind(obj, context) {
  for (var p in obj) {
    if(obj.hasOwnProperty(p) && typeof obj[p] == 'function' ) {
      obj[p] = obj[p].bind(context);
    }
  }

  return obj;
}

class APIv1Endpoint {
  constructor (config = {}) {
    this.origin = config.origin || 'https://www.reddit.com';
    this.request = config.request || superagent;

    this.userAgent = config.userAgent;

    this.cache = {
      links: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
      comments: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
      users: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
      subreddits: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
    }
  }

  hydrate (endpoint, options, data) {
    var cache = this.cache[endpoint];
    var { uri, options } = this[endpoint].buildOptions(options);

    var key = uri + '?' + querystring.stringify(options.query);

    if (options.headers.Authorization) {
      cache = cache.authed;
    } else {
      cache = cache.unauthed;
    }

    cache.set(key, data);
  }

  get subreddits () {
    return bind({
      buildOptions: function(options) {
        var uri = this.origin + `/r/${options.query.subreddit}/about.json`;
        return { uri, options };
      },

      get: function(options = {}) {
        var { uri, options } = this.subreddits.buildOptions(options);

        return baseGet(this.cache.subreddits, uri, options, this.request, (body) => {
          if (body) {
            return new Subreddit(body.data || body).toJSON();
          } else {
            return null;
          }
        });
      }
    }, this);
  }

  get links () {
    return bind({
      buildOptions: function(options) {
        var sort = options.query.sort || 'hot';
        options.query.feature = 'link_preview';

        var uri = this.origin;

        if (options.user) {
          uri += '/user/' + options.user + '/submitted.json';
        } else {
          if (options.query.subredditName) {
            uri += '/r/' + options.query.subredditName;
          } else if (options.query.multi) {
            uri += '/user/' + options.query.multiUser + '/m/' + options.query.multi;
          }

          uri += '/' + sort + '.json';
        }

        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.links.buildOptions(options);

        return baseGet(this.cache.links, uri, options, this.request, (body) => {
          if (body.data && body.data.children) {
            return body.data.children.map(c => new Link(c.data).toJSON());
          }else {
            return [];
          }
        });
      }
    }, this);
  }

  get comments () {
    function mapReplies (comment) {
      var comment = comment.data;

      if (comment.replies) {
        comment.replies = comment.replies.data.children.map(mapReplies);
      } else {
        comment.replies = [];
      }

      return new Comment(comment).toJSON();
    }

    return bind({
      buildOptions: function(options) {
        var uri;

        if (options.user) {
          uri = this.origin + '/user/' + options.user + '/comments.json';
        } else {
          uri = this.origin + '/comments/' + options.linkId + '.json';
        }
        options.query.feature = 'link_preview';

        if (options.comment) {
          options.query.comment = options.comment;
        }

        if (options.sort) {
          options.query.sort = options.sort;
        }

        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.comments.buildOptions(options);

        return baseGet(this.cache.comments, uri, options, this.request, (body) => {
          return {
            listing: new Link(body[0].data.children[0].data).toJSON(),
            comments: body[1].data.children.map(mapReplies)
          }
        });
      },

      post: function(options = {}) {
        var uri = this.origin + '/api/comment';

        if (!options.model) {
          throw new NoModelError('/api/comment');
        }

        var valid = options.model.validate();

        if (valid === true) {
          var json = options.model.toJSON();

          options.form = {
            api_type: 'json',
            thing_id: json.thingId,
            text: json.text,
          };

          return basePost(uri, options, this.request, (body) => {
            if (body) {
              var comment = body.json.data.things[0].data;
              return new Comment(comment).toJSON();
            } else {
              return null;
            }
          });
        } else {
          var defer = q.defer();
          defer.reject('Comment', options.model, valid);
          return defer.promise;
        }
      }
    }, this);
  }

  get users () {
    return bind({
      buildOptions: function(options) {
        var uri = this.origin + '/';

        if (options.user === 'me') { // current oauth doesn't return user id
          uri += 'api/v1/me';
        } else {
          uri += 'user/' + options.user + '/about.json';
        }

        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.users.buildOptions(options);

        return baseGet(this.cache.users, uri, options, this.request, (body) => {
          if (body) {
            return new Account(body.data || body).toJSON();
          }else {
            return null;
          }
        });
      }
    }, this);
  }

  get trophies () {
    return bind({
      buildOptions: function(options) {
        var uri = `${this.origin}/api/v1/user/${options.user}/trophies.json`;
        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.trophies.buildOptions(options);

        return baseGet(null, uri, options, this.request, (body) => {
          if (body) {
            var trophies = body.data;
            return new Award(user).toJSON();
          }else {
            return null;
          }
        });
      }
    }, this);
  }

  get activities () {
    return bind({
      buildOptions: function(options) {
        var uri = `${this.origin}/user/${options.user}/${options.activity}.json`;
        options.query.feature = 'link_preview';
        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.activities.buildOptions(options);

        return baseGet(this.cache.activity, uri, options, this.request, (body) => {
          if (body) {
            var activities = body.data.children;
            var data = [];

            activities.forEach(function(a) {
              switch (a.kind) {
                case 't1':
                  data.push((new Comment(a.data)).toJSON());
                  break;
                case 't3':
                  data.push((new Link(a.data)).toJSON());
                  break;
              }
            });

            return data;
          }else {
            return null;
          }
        });
      }
    }, this);
  }

  get votes () {
    return bind({
      post: function(options = {}) {
        var uri = this.origin + '/api/vote';

        if (!options.model) {
          throw new NoModelError('/api/comment');
        }

        var valid = options.model.validate();

        if (valid === true) {
          options.form = options.model.toJSON((props) => {
            return {
              id: props.id,
              dir: props.direction,
            };
          });

          return basePost(uri, options, this.request, () => null);
        } else {
          throw new ValidationError('Vote', options.model, valid);
        }
      }
    }, this)
  }

  get reports () {
    return bind({
      post: function(options = {}) {
        var uri = this.origin + '/api/report';

        if (!options.model) {
          throw new NoModelError('/api/report');
        }

        var valid = options.model.validate();

        if (valid === true) {
          options.form = options.model.toJSON((props) => {
            return {
              reason: props.reason,
              other_reason: props.other_reason,
              thing_id: props.thing_id,
            };
          });

          return basePost(uri, options, this.request, () => null);
        } else {
          throw new ValidationError('Report', options.model, valid);
        }
      }
    }, this)
  }

  buildOptions (auth) {
    var options = {
      query: {},
      model: {},
      headers: {},
    };

    if (auth) {
      options.headers.Authorization = 'bearer ' + auth;
    }

    return options;
  }
}

export default APIv1Endpoint;
<commit_msg>Move post cache clearing to endpoint instead of base fn<commit_after>import superagent from 'superagent';
import q from 'q';
import querystring from 'querystring';

import Account from '../models/account';
import Comment from '../models/comment';
import Link from '../models/link';
import Vote from '../models/vote';
import Subreddit from '../models/subreddit';

import NoModelError from '../errors/noModelError';
import ValidationError from '../errors/validationError';

import LRU from 'lru-cache';

var defaultCacheConfig = {
 max: 500,
 maxAge: 1000 * 50 * 3,
}

function processMeta(res) {
  var headers = res.headers;

  return {
    moose: headers['x-moose'],
    tracking: headers['x-reddit-tracking'],
  }
}

function baseGet(cache={}, uri, options, request, formatBody) {
  var options = options || {};
  var defer = q.defer();

  var query = options.query || {};
  var headers = options.headers || {};

  if (options.userAgent) {
    headers['User-Agent'] = options.userAgent;
  }

  var key = uri + '?' + querystring.stringify(query);

  if (headers.Authorization) {
    cache = cache.authed;
    key += '&auth=' + headers.Authorization;
  } else {
    cache = cache.unauthed;
  }

  if(cache && cache.get(key)) {
    defer.resolve(cache.get(key));
    return defer.promise;
  }

  request.get(uri)
    .set(headers)
    .query(query)
    .end((err, res) => {
      if (err) {
        return defer.reject(err);
      }

      if (!res.ok) {
        return defer.reject(res);
      }

      try {
        var body = res.body;

        if (formatBody) {
          body = formatBody(body);
        }

        var data = {
          data: body,
          meta: processMeta(res),
        }

        if(cache) { cache.set(key, data); }

        defer.resolve(data);
      } catch (e) {
        defer.reject(e);
      }
    });

  return defer.promise;
}

function basePost(uri, options, request, formatBody) {
  var options = options || {};
  var defer = q.defer();

  var form = options.form || {};
  var headers = options.headers || {};

  if (options.userAgent) {
    headers['User-Agent'] = options.userAgent;
  }

  request.post(uri)
    .set(headers)
    .send(form)
    .type('form')
    .end((err, res) => {
      if (err) {
        return defer.reject(err);
      }

      if (!res.ok) {
        defer.reject(res);
      }

      try {
        var body = res.body;

        if (formatBody) {
          body = formatBody(body);
        }

        var data = {
          data: body,
          meta: processMeta(res),
        }

        defer.resolve(data);
      } catch (e) {
        defer.reject(e);
      }
    });

  return defer.promise;
}

function bind(obj, context) {
  for (var p in obj) {
    if(obj.hasOwnProperty(p) && typeof obj[p] == 'function' ) {
      obj[p] = obj[p].bind(context);
    }
  }

  return obj;
}

class APIv1Endpoint {
  constructor (config = {}) {
    this.origin = config.origin || 'https://www.reddit.com';
    this.request = config.request || superagent;

    this.userAgent = config.userAgent;

    this.cache = {
      links: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
      comments: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
      users: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
      subreddits: {
        unauthed: new LRU(defaultCacheConfig),
        authed: new LRU(defaultCacheConfig),
      },
    }
  }

  hydrate (endpoint, options, data) {
    var cache = this.cache[endpoint];
    var { uri, options } = this[endpoint].buildOptions(options);

    var key = uri + '?' + querystring.stringify(options.query);

    if (options.headers.Authorization) {
      cache = cache.authed;
    } else {
      cache = cache.unauthed;
    }

    cache.set(key, data);
  }

  get subreddits () {
    return bind({
      buildOptions: function(options) {
        var uri = this.origin + `/r/${options.query.subreddit}/about.json`;
        return { uri, options };
      },

      get: function(options = {}) {
        var { uri, options } = this.subreddits.buildOptions(options);

        return baseGet(this.cache.subreddits, uri, options, this.request, (body) => {
          if (body) {
            return new Subreddit(body.data || body).toJSON();
          } else {
            return null;
          }
        });
      }
    }, this);
  }

  get links () {
    return bind({
      buildOptions: function(options) {
        var sort = options.query.sort || 'hot';
        options.query.feature = 'link_preview';

        var uri = this.origin;

        if (options.user) {
          uri += '/user/' + options.user + '/submitted.json';
        } else {
          if (options.query.subredditName) {
            uri += '/r/' + options.query.subredditName;
          } else if (options.query.multi) {
            uri += '/user/' + options.query.multiUser + '/m/' + options.query.multi;
          }

          uri += '/' + sort + '.json';
        }

        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.links.buildOptions(options);

        return baseGet(this.cache.links, uri, options, this.request, (body) => {
          if (body.data && body.data.children) {
            return body.data.children.map(c => new Link(c.data).toJSON());
          }else {
            return [];
          }
        });
      }
    }, this);
  }

  get comments () {
    function mapReplies (comment) {
      var comment = comment.data;

      if (comment.replies) {
        comment.replies = comment.replies.data.children.map(mapReplies);
      } else {
        comment.replies = [];
      }

      return new Comment(comment).toJSON();
    }

    return bind({
      buildOptions: function(options) {
        var uri;

        if (options.user) {
          uri = this.origin + '/user/' + options.user + '/comments.json';
        } else {
          uri = this.origin + '/comments/' + options.linkId + '.json';
        }
        options.query.feature = 'link_preview';

        if (options.comment) {
          options.query.comment = options.comment;
        }

        if (options.sort) {
          options.query.sort = options.sort;
        }

        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.comments.buildOptions(options);

        return baseGet(this.cache.comments, uri, options, this.request, (body) => {
          return {
            listing: new Link(body[0].data.children[0].data).toJSON(),
            comments: body[1].data.children.map(mapReplies)
          }
        });
      },

      post: function(options = {}) {
        var uri = this.origin + '/api/comment';

        if (!options.model) {
          throw new NoModelError('/api/comment');
        }

        var valid = options.model.validate();

        if (valid === true) {
          var json = options.model.toJSON();

          options.form = {
            api_type: 'json',
            thing_id: json.thingId,
            text: json.text,
          };

          this.cache.comments.reset();

          return basePost(uri, options, this.request, (body) => {
            if (body) {
              var comment = body.json.data.things[0].data;
              return new Comment(comment).toJSON();
            } else {
              return null;
            }
          });
        } else {
          var defer = q.defer();
          defer.reject('Comment', options.model, valid);
          return defer.promise;
        }
      }
    }, this);
  }

  get users () {
    return bind({
      buildOptions: function(options) {
        var uri = this.origin + '/';

        if (options.user === 'me') { // current oauth doesn't return user id
          uri += 'api/v1/me';
        } else {
          uri += 'user/' + options.user + '/about.json';
        }

        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.users.buildOptions(options);

        return baseGet(this.cache.users, uri, options, this.request, (body) => {
          if (body) {
            return new Account(body.data || body).toJSON();
          }else {
            return null;
          }
        });
      }
    }, this);
  }

  get trophies () {
    return bind({
      buildOptions: function(options) {
        var uri = `${this.origin}/api/v1/user/${options.user}/trophies.json`;
        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.trophies.buildOptions(options);

        return baseGet(null, uri, options, this.request, (body) => {
          if (body) {
            var trophies = body.data;
            return new Award(user).toJSON();
          }else {
            return null;
          }
        });
      }
    }, this);
  }

  get activities () {
    return bind({
      buildOptions: function(options) {
        var uri = `${this.origin}/user/${options.user}/${options.activity}.json`;
        options.query.feature = 'link_preview';
        return { uri, options }
      },

      get: function(options = {}) {
        var { uri, options } = this.activities.buildOptions(options);

        return baseGet(this.cache.activity, uri, options, this.request, (body) => {
          if (body) {
            var activities = body.data.children;
            var data = [];

            activities.forEach(function(a) {
              switch (a.kind) {
                case 't1':
                  data.push((new Comment(a.data)).toJSON());
                  break;
                case 't3':
                  data.push((new Link(a.data)).toJSON());
                  break;
              }
            });

            return data;
          }else {
            return null;
          }
        });
      }
    }, this);
  }

  get votes () {
    return bind({
      post: function(options = {}) {
        var uri = this.origin + '/api/vote';

        if (!options.model) {
          throw new NoModelError('/api/comment');
        }

        var valid = options.model.validate();

        if (valid === true) {
          options.form = options.model.toJSON((props) => {
            return {
              id: props.id,
              dir: props.direction,
            };
          });

          this.cache.links.authed.reset();
          this.cache.comments.authed.reset();

          return basePost(uri, options, this.request, () => null);
        } else {
          throw new ValidationError('Vote', options.model, valid);
        }
      }
    }, this)
  }

  get reports () {
    return bind({
      post: function(options = {}) {
        var uri = this.origin + '/api/report';

        if (!options.model) {
          throw new NoModelError('/api/report');
        }

        var valid = options.model.validate();

        if (valid === true) {
          options.form = options.model.toJSON((props) => {
            return {
              reason: props.reason,
              other_reason: props.other_reason,
              thing_id: props.thing_id,
            };
          });

          return basePost(uri, options, this.request, () => null);
        } else {
          throw new ValidationError('Report', options.model, valid);
        }
      }
    }, this)
  }

  buildOptions (auth) {
    var options = {
      query: {},
      model: {},
      headers: {},
    };

    if (auth) {
      options.headers.Authorization = 'bearer ' + auth;
    }

    return options;
  }
}

export default APIv1Endpoint;
<|endoftext|>


<commit_before>#! /usr/bin/env node
'use strict';

const process = require('process')
const mongodb = require('mongodb')
const monk = require('monk')
const chimera = require('chimera-framework/core')

var DEFAULT_CONFIGS = {
    'mongo_url' : '',
    'table' : '',
    'history' : '',
    'deletion_flag' : '_deleted',
    'id' : '_id',
    'modification_time' : '_modified_at',
    'modification_by' : '_modified_by',
    'show_deleted' : false
}

function preprocessQuery(query, config){
    if(config.deletion_flag != '' && !config.show_deleted){
        // create "exists" query
        let existquery = {}
        existquery[config.deletion_flag] = 0
        // modify query
        if(Object.keys(query).length != 0){
            query = {'$and' : [existquery, query]}
        }
        else{
            query = existquery
        }
    }
    return query
}

function getHistoryData(data, userId, config){
    let historyData = chimera.deepCopyObject(data)
    historyData[config.modification_time] = Date.now()
    historyData[config.modification_by] = userId
    return historyData
}

function showUsage(){
    console.error('Missing or invalid parameters')
    console.error('Usage:')
    console.error(' * node '+process.argv[1]+' get [config] [query] [projection]')
    console.error(' * node '+process.argv[1]+' getOne [config] [pkValue]')
    console.error(' * node '+process.argv[1]+' insert [config] [dataInJSON] [userId]')
    console.error(' * node '+process.argv[1]+' update [config] [pkValue] [dataInJSON] [userId]')
    console.error(' * node '+process.argv[1]+' delete [config] [pkValue] [userId]')
}

function isParameterValid(){
    if(process.argv.length >= 4){
        let action = process.argv[2]
        let validAction = ['get', 'getOne', 'insert', 'update', 'delete']
        let actionIndex = validAction.indexOf(action)
        if(actionIndex > -1){
            if(action == 'get'){
                return true
            }
            else if(action == 'getOne'){
                return process.argv.length >= 5
            }
            else if(action == 'insert'){
                return process.argv.length >= 6
            }
            else if(action == 'update'){
                return process.argv.length >= 7
            }
            else if(action == 'delete'){
                return process.argv.length >= 6
            }
        }
    }
    return false
}

if(!isParameterValid()){
    showUsage()
    console.log(JSON.stringify({'success': false, 'error_message': 'Missing or invalid parameters'}))
}
else{
    let db = null
    try{

        // get action and configuration
        let action = process.argv[2]
        let config = chimera.patchObject(DEFAULT_CONFIGS, JSON.parse(process.argv[3]))

        let mongoUrl = config.mongo_url
        let table = config.table
        let history = config.history
        let deletionFlag = config.deletion_flag
        let idField = config.id
        let mtime_field = config.modification_time
        let mby_field = config.modification_by

        db =  monk(mongoUrl)
        let collection = db.get(table)
        let defaultProjection = {}
        defaultProjection[deletionFlag] = 0
        defaultProjection[history] = 0

        if(action == 'get'){
            let query = process.argv.length > 4? JSON.parse(process.argv[4]): {}
            let projection = process.argv.length > 5? JSON.parse(process.argv[5]): defaultProjection
            query = preprocessQuery(query, config)
            collection.find(query, projection, function(err, rows){
                if(err){
                    console.error(err)
                    console.log(JSON.stringify({'success': false, 'error_message': 'Operation failure: get'}))
                    db.close()
                }
                else{
                    console.log(JSON.stringify({'success': true, 'error_message' : '', 'rows': rows}))
                    db.close()
                }
            })
        }
        else if(action == 'getOne'){
            let pkValue = process.argv[4]
            let query = {}
            let projection = process.length > 5? JSON.parese(process.argv[5]): defaultProjection
            query[idField] = pkValue
            query = preprocessQuery(query, config)
            collection.findOne(query, projection, function(err, row){
                if(err){
                    console.error(err)
                    console.log(JSON.stringify({'success': false, 'error_message': 'Operation failure: getOne'}))
                    db.close()
                }
                else{
                    console.log(JSON.stringify({'success': true, 'error_message' : '', 'row': row}))
                    db.close()
                }
            })
        }
        else if(action == 'insert'){
            let data = JSON.parse(process.argv[4])
            let userId = process.argv[5]
            data[deletionFlag] = 0
            // prepare history of the data
            data[history] = [getHistoryData(data, userId, config)]
            // insert the data and push the history at once
            collection.insert(data, function(err, row){
                if(err){
                    console.error(err)
                    console.log(JSON.stringify({'success': false, 'error_message': 'Operation failure: insert'}))
                    db.close()
                }
                else{
                    console.log(JSON.stringify({'success': true, 'error_message' : '', 'row' : row}))
                    db.close()
                }
            })
        }
        else if(action == 'update'){
            let pkValue = process.argv[4]
            let data = JSON.parse(process.argv[5])
            let userId = process.argv[6]
            let query = {}
            let historyData = {}
            query[idField] = pkValue
            query = preprocessQuery(query, config)
            data[deletionFlag] = 0
            // prepare history of the data
            historyData[history] = getHistoryData(data, userId, config)
            // update the data and push the history at once
            collection.update(query, {'$set':data, '$push':historyData}, function(err, result){
                if(err){
                    console.error(err)
                    console.log(JSON.stringify({'success': false, 'error_message': 'Operation failure: Update'}))
                    db.close()
                }
                else{
                    // get one
                    let query = {}
                    let projection = defaultProjection
                    query[idField] = pkValue
                    query = preprocessQuery(query, config)
                    collection.findOne(query, projection, function(err, row){
                        if(err){
                            console.error(err)
                            console.log(JSON.stringify({'success': true, 'error_message': 'Operation failure: getOne', row:{}}))
                            db.close()
                        }
                        else{
                            console.log(JSON.stringify({'success': true, 'error_message' : '', 'row': row}))
                            db.close()
                        }
                    })
                }
            })
        }
        else if(action == 'delete'){
            let pkValue = process.argv[4]
            let data = {}
            let userId = process.argv[5]
            let query = {}
            let historyData = {}
            query[idField] = pkValue
            query = preprocessQuery(query, config)
            data[deletionFlag] = 1
            // prepare history of the data
            historyData[history] = getHistoryData(data, userId, config)
            // update the data and push the history at once
            collection.update(query, {'$set':data, '$push':historyData}, function(err, result){
                if(err){
                    console.error(err)
                    console.log(JSON.stringify({'success': false, 'error_message': 'Operation failure: Delete'}))
                    db.close()
                }
                else{
                    // get one
                    let query = {}
                    let projection = defaultProjection
                    let customConfig = chimera.deepCopyObject(config)
                    query[idField] = pkValue
                    customConfig['show_deleted'] = true
                    query = preprocessQuery(query, customConfig)
                    collection.findOne(query, projection, function(err, row){
                        if(err){
                            console.error(err)
                            console.log(JSON.stringify({'success': true, 'error_message': 'Operation failure: getOne', row:{}}))
                            db.close()
                        }
                        else{
                            console.log(JSON.stringify({'success': true, 'error_message' : '', 'row': row}))
                            db.close()
                        }
                    })
                }
            })
        }
    }catch(err){
        console.error(err)
        console.log(JSON.stringify({'success': false, 'error_message': 'Operation failure, invalid parameters'}))
        if(db != null){
            db.close()
        }
    }
}

<commit_msg>remove cck.crud.js<commit_after><|endoftext|>


<commit_before>define([
    'jquery',
    'underscore',
    'chaplin',
    'orotranslation/js/translator',
    'oroui/js/app/controllers/base/controller',
    'oroui/js/app/models/page-model',
    'module'
], function($, _, Chaplin, __, BaseController, PageModel, module) {
    'use strict';

    var PageController;
    var document = window.document;
    var location = window.location;
    var history = window.history;
    var console = window.console;
    var utils = Chaplin.utils;
    var mediator = Chaplin.mediator;

    var config = module.config();
    config = _.extend({
        fullRedirect: false
    }, config);

    PageController = BaseController.extend({});
    _.extend(PageController.prototype, {
        fullRedirect: config.fullRedirect,

        /**
         * Creates page model
         * @override
         */
        initialize: function() {
            PageController.__super__.initialize.apply(this, arguments);

            var page = new PageModel();
            this.listenTo(page, 'request', this.onPageRequest);
            this.listenTo(page, 'sync', this.onPageLoaded);
            this.listenTo(page, 'invalid', this.onPageInvalid);
            this.listenTo(page, 'error', this.onPageError);
            this.model = page;

            // application is in action till first 'page:afterChange' event
            var isInAction = true;

            this.subscribeEvent('page:beforeChange', function() {
                isInAction = true;
            });
            this.subscribeEvent('page:afterChange', function() {
                isInAction = false;
            });
            mediator.setHandler('isInAction', function() {
                return isInAction;
            });
        },

        /**
         * Disposes page components
         * @override
         */
        dispose: function() {
            if (this.disposed) {
                return;
            }
            PageController.__super__.dispose.call(this);
        },

        /**
         * Main action point
         *  - does background work before page loading
         *  - fetches page data from server
         *
         * @param {Object} params
         * @param {Object} route
         * @param {Object} options
         */
        index: function(params, route, options) {
            var cacheItem;

            var url = this._combineRouteUrl(route);
            this._setNavigationHandlers(url);
            var args = {// collect arguments to reuse in events of page_fetch state change
                params: params,
                route: route,
                options: options
            };

            if (!route.previous) {
                // page just loaded from server, does not require extra request
                this.onPageLoaded(this.model, {}, {actionArgs: args});
                return;
            }

            if (!this._beforePageLoad(route, params, options)) {
                // prevent page loading, if there's redirect found
                return;
            }
            delete options.redirection;

            cacheItem = this.cache.get(route.path);

            if (cacheItem && cacheItem.page && route.query === cacheItem.query && options.force !== true) {
                options.fromCache = true;
                this.onPageRequest(this.model, null, {actionArgs: args});
                this.model.set(cacheItem.page, {actionArgs: args});
                // manually call onPageLoaded() since there is no 'sync' event triggered
                this.onPageLoaded(this.model, {}, {actionArgs: args});
            } else {
                this.model.fetch({
                    url: url,
                    validate: true,
                    actionArgs: args
                });
            }
        },

        /**
         * Does preparation for page loading
         *  - adds event listeners on page model
         *  - triggers 'page:beforeChange' event with two parameters oldRoute and newRoute
         *  - handle route change, if it has place to be
         *
         * @param {Object} route
         * @param {Object} params
         * @param {Object} options
         * @returns {boolean}
         * @private
         */
        _beforePageLoad: function(route, params, options) {
            var url;
            var opts;
            var oldRoute = route.previous;
            var newRoute = _.extend(_.omit(route, ['previous']), {params: params});
            this.publishEvent('page:beforeChange', oldRoute, newRoute, options);

            // if route has been changed during 'page:beforeChange' event,
            // redirect to a new URL and stop processing current
            if (route.path !== newRoute.path || route.query !== newRoute.query) {
                url = this._combineRouteUrl(newRoute);
                opts = _.pick(options, ['forceStartup', 'changeURL', 'force', 'silent']);
                opts.replace = true;
                _.defer(function() {
                    mediator.execute('redirectTo', {url: url}, opts);
                });
                return false;
            }
            return true;
        },

        /**
         * Handles page request
         *  - triggers 'page:request' event
         *
         * @param {Chaplin.Model} model
         * @param {XMLHttpRequest} jqXHR
         * @param {Object} options
         */
        onPageRequest: function(model, jqXHR, options) {
            this.publishEvent('page:request', options.actionArgs);
        },

        /**
         * Handles page request done
         *  - triggers 'page:update' event with
         *  - updates page title
         *
         * @param {Chaplin.Model} model
         * @param {Object} result
         * @param {Object} options
         */
        onPageLoaded: function(model, result, options) {
            var self = this;
            var updatePromises = [];
            var pageData = model.getAttributes();
            var actionArgs = options.actionArgs;
            var jqXHR = options.xhr;

            if (pageData.title) {
                this.adjustTitle(pageData.title);
            }

            this.publishEvent('page:statsUpdate', pageData, actionArgs, jqXHR, updatePromises);
            this.publishEvent('page:update', pageData, actionArgs, jqXHR, updatePromises);

            // once all views are have updated, trigger page:afterChange
            $.when.apply($, updatePromises).done(_.debounce(function() {
                self.publishEvent('page:afterChange');
                self.publishEvent('page:statsAfterChange');
            }, 0));
        },

        /**
         * Handles invalid page load
         *  - process redirect of it was found
         *
         * @param {Chaplin.Model} model
         * @param {*} error
         * @param {Object} options
         */
        onPageInvalid: function(model, error, options) {
            var pathDesc;
            if (error.redirect) {
                pathDesc = {url: error.location};
                _.extend(options.actionArgs.options, _.pick(error, ['redirect', 'fullRedirect']));
                this._processRedirect(pathDesc, options.actionArgs.options);
            }
        },

        /**
         * Handles page loading error
         *  - tries to parse raw data and keep updating page
         *
         * @param {Chaplin.Model} model
         * @param {XMLHttpRequest} jqXHR
         * @param {Object} options
         */
        onPageError: function(model, jqXHR, options) {
            var rawData = jqXHR.responseText;
            var data = {};

            if (jqXHR.status === 200 && rawData.indexOf('http') === 0) {
                data = {redirect: true, fullRedirect: true, location: rawData};
                model.set(data, options);
                return;
            }

            var payload = {stopPageProcessing: false};
            this.publishEvent('page:beforeError', jqXHR, payload);
            if (payload.stopPageProcessing) {
                history.back();
                return;
            }

            data = this._parseRawData(rawData);
            if (_.isObject(data)) {
                model.set(data, options);
            } else {
                if (mediator.execute('retrieveOption', 'debug')) {
                    // jshint -W060
                    document.writeln(rawData);
                    if (console) {
                        console.error('Unexpected content format');
                    }
                } else {
                    mediator.execute('showMessage', 'error', __('Sorry, page was not loaded correctly'));
                }
            }

            this.publishEvent('page:error', model.getAttributes(), options.actionArgs, jqXHR);
            this.publishEvent('page:afterChange');
        },

        /**
         * Process redirect response
         *  see documentation for Chaplin.utils.redirectTo() method
         *
         * @param {Object|string} pathDesc
         * @param {Object=} params
         * @param {Object=} options
         * @private
         */
        _processRedirect: function(pathDesc, params, options) {
            var parser;
            var pathname;
            var query;
            var getUrl = function(pathname, query) {
                query = utils.queryParams.parse(query);
                query._rand = Math.random();
                query = utils.queryParams.stringify(query);
                return pathname + (query && ('?' + query));
            };
            options = options || {};
            if (typeof pathDesc === 'object' && pathDesc.url !== null && pathDesc.url !== void 0) {
                options = params || {};
                // fetch from URL only pathname and query
                parser = document.createElement('a');
                parser.href = pathDesc.url;
                pathname = parser.pathname;
                query = parser.search.substr(1);
                // IE removes starting slash
                pathDesc.url = (pathname[0] === '/' ? '' : '/') + pathname + (query && ('?' + query));
            }
            options = _.defaults(options, {
                fullRedirect: this.fullRedirect
            });
            if (options.target === '_blank') {
                window.open(getUrl(pathname, query), '_blank');
                return;
            }
            if (options.fullRedirect) {
                location[options.replace ? 'replace' : 'assign'](getUrl(pathname, query));
                return;
            }
            if (options.redirect) {
                this.publishEvent('page:redirect');
                _.extend(options, {forceStartup: true, force: true, redirection: true});
                utils.redirectTo(pathDesc, options);
                return;
            }
            utils.redirectTo.apply(utils, arguments);
        },

        /**
         * Register handler for page reload and redirect
         *
         * @param {string} url
         * @private
         */
        _setNavigationHandlers: function(url) {
            mediator.setHandler('redirectTo', function(pathDesc, params, options) {
                var queue = [];
                mediator.trigger('page:beforeRedirectTo', queue, pathDesc, params, options);
                $.when.apply($, queue).done(_.bind(function() {
                    this._processRedirect(pathDesc, params, options);
                }, this));
            }, this);

            mediator.setHandler('refreshPage', function(options) {
                var queue = [];
                mediator.trigger('page:beforeRefresh', queue);
                options = options || {};
                _.defaults(options, {forceStartup: true, force: true});
                $.when.apply($, queue).done(function(customOptions) {
                    _.extend(options, customOptions || {});
                    utils.redirectTo({url: url}, options);
                    mediator.trigger('page:afterRefresh');
                });
            });

            mediator.setHandler('submitPage', this._submitPage, this);
        },

        /**
         * Make data more bulletproof.
         *
         * @param {string} rawData
         * @param {number=} prevPos
         * @returns {Object}
         */
        _parseRawData: function(rawData, prevPos) {
            if (_.isUndefined(prevPos)) {
                prevPos = -1;
            }
            rawData = rawData.trim();
            var jsonStartPos = rawData.indexOf('{', prevPos + 1);
            var additionalData = '';
            var dataObj = null;
            var data;
            if (jsonStartPos > 0) {
                additionalData = rawData.substr(0, jsonStartPos);
                data = rawData.substr(jsonStartPos);
                try {
                    dataObj = JSON.parse(data);
                } catch (err) {
                    return this._parseRawData(rawData, jsonStartPos);
                }
            } else if (jsonStartPos === 0) {
                dataObj = JSON.parse(rawData);
            } else {
                // there's nothing to do
                dataObj = rawData;
            }

            if (additionalData) {
                additionalData = '
' +
                    '×' +
                    '
' + additionalData + '

';
            }

            if (dataObj.content !== undefined) {
                dataObj.content = additionalData + dataObj.content;
            }

            return dataObj;
        },

        /**
         * Performs save call for a model
         * (is used for saving forms, all data should be already packet into options)
         *
         * @param options
         * @private
         */
        _submitPage: function(options) {
            this.publishEvent('page:beforeChange');
            options.actionArgs = options.actionArgs || {};
            _.defaults(options.actionArgs, {params: {}, route: {}, options: {}});
            this.model.save(null, options);
        }
    });

    return PageController;
});
<commit_msg>BAP-10435 remove debug code<commit_after>define([
    'jquery',
    'underscore',
    'chaplin',
    'orotranslation/js/translator',
    'oroui/js/app/controllers/base/controller',
    'oroui/js/app/models/page-model',
    'module'
], function($, _, Chaplin, __, BaseController, PageModel, module) {
    'use strict';

    var PageController;
    var document = window.document;
    var location = window.location;
    var history = window.history;
    var console = window.console;
    var utils = Chaplin.utils;
    var mediator = Chaplin.mediator;

    var config = module.config();
    config = _.extend({
        fullRedirect: false
    }, config);

    PageController = BaseController.extend({});
    _.extend(PageController.prototype, {
        fullRedirect: config.fullRedirect,

        /**
         * Creates page model
         * @override
         */
        initialize: function() {
            PageController.__super__.initialize.apply(this, arguments);

            var page = new PageModel();
            this.listenTo(page, 'request', this.onPageRequest);
            this.listenTo(page, 'sync', this.onPageLoaded);
            this.listenTo(page, 'invalid', this.onPageInvalid);
            this.listenTo(page, 'error', this.onPageError);
            this.model = page;

            // application is in action till first 'page:afterChange' event
            var isInAction = true;

            this.subscribeEvent('page:beforeChange', function() {
                isInAction = true;
            });
            this.subscribeEvent('page:afterChange', function() {
                isInAction = false;
            });
            mediator.setHandler('isInAction', function() {
                return isInAction;
            });
        },

        /**
         * Disposes page components
         * @override
         */
        dispose: function() {
            if (this.disposed) {
                return;
            }
            PageController.__super__.dispose.call(this);
        },

        /**
         * Main action point
         *  - does background work before page loading
         *  - fetches page data from server
         *
         * @param {Object} params
         * @param {Object} route
         * @param {Object} options
         */
        index: function(params, route, options) {
            var cacheItem;

            var url = this._combineRouteUrl(route);
            this._setNavigationHandlers(url);
            var args = {// collect arguments to reuse in events of page_fetch state change
                params: params,
                route: route,
                options: options
            };

            if (!route.previous) {
                // page just loaded from server, does not require extra request
                this.onPageLoaded(this.model, {}, {actionArgs: args});
                return;
            }

            if (!this._beforePageLoad(route, params, options)) {
                // prevent page loading, if there's redirect found
                return;
            }
            delete options.redirection;

            cacheItem = this.cache.get(route.path);

            if (cacheItem && cacheItem.page && route.query === cacheItem.query && options.force !== true) {
                options.fromCache = true;
                this.onPageRequest(this.model, null, {actionArgs: args});
                this.model.set(cacheItem.page, {actionArgs: args});
                // manually call onPageLoaded() since there is no 'sync' event triggered
                this.onPageLoaded(this.model, {}, {actionArgs: args});
            } else {
                this.model.fetch({
                    url: url,
                    validate: true,
                    actionArgs: args
                });
            }
        },

        /**
         * Does preparation for page loading
         *  - adds event listeners on page model
         *  - triggers 'page:beforeChange' event with two parameters oldRoute and newRoute
         *  - handle route change, if it has place to be
         *
         * @param {Object} route
         * @param {Object} params
         * @param {Object} options
         * @returns {boolean}
         * @private
         */
        _beforePageLoad: function(route, params, options) {
            var url;
            var opts;
            var oldRoute = route.previous;
            var newRoute = _.extend(_.omit(route, ['previous']), {params: params});
            this.publishEvent('page:beforeChange', oldRoute, newRoute, options);

            // if route has been changed during 'page:beforeChange' event,
            // redirect to a new URL and stop processing current
            if (route.path !== newRoute.path || route.query !== newRoute.query) {
                url = this._combineRouteUrl(newRoute);
                opts = _.pick(options, ['forceStartup', 'changeURL', 'force', 'silent']);
                opts.replace = true;
                _.defer(function() {
                    mediator.execute('redirectTo', {url: url}, opts);
                });
                return false;
            }
            return true;
        },

        /**
         * Handles page request
         *  - triggers 'page:request' event
         *
         * @param {Chaplin.Model} model
         * @param {XMLHttpRequest} jqXHR
         * @param {Object} options
         */
        onPageRequest: function(model, jqXHR, options) {
            this.publishEvent('page:request', options.actionArgs);
        },

        /**
         * Handles page request done
         *  - triggers 'page:update' event with
         *  - updates page title
         *
         * @param {Chaplin.Model} model
         * @param {Object} result
         * @param {Object} options
         */
        onPageLoaded: function(model, result, options) {
            var self = this;
            var updatePromises = [];
            var pageData = model.getAttributes();
            var actionArgs = options.actionArgs;
            var jqXHR = options.xhr;

            if (pageData.title) {
                this.adjustTitle(pageData.title);
            }

            this.publishEvent('page:update', pageData, actionArgs, jqXHR, updatePromises);

            // once all views are have updated, trigger page:afterChange
            $.when.apply($, updatePromises).done(_.debounce(function() {
                self.publishEvent('page:statsAfterChange');
            }, 0));
        },

        /**
         * Handles invalid page load
         *  - process redirect of it was found
         *
         * @param {Chaplin.Model} model
         * @param {*} error
         * @param {Object} options
         */
        onPageInvalid: function(model, error, options) {
            var pathDesc;
            if (error.redirect) {
                pathDesc = {url: error.location};
                _.extend(options.actionArgs.options, _.pick(error, ['redirect', 'fullRedirect']));
                this._processRedirect(pathDesc, options.actionArgs.options);
            }
        },

        /**
         * Handles page loading error
         *  - tries to parse raw data and keep updating page
         *
         * @param {Chaplin.Model} model
         * @param {XMLHttpRequest} jqXHR
         * @param {Object} options
         */
        onPageError: function(model, jqXHR, options) {
            var rawData = jqXHR.responseText;
            var data = {};

            if (jqXHR.status === 200 && rawData.indexOf('http') === 0) {
                data = {redirect: true, fullRedirect: true, location: rawData};
                model.set(data, options);
                return;
            }

            var payload = {stopPageProcessing: false};
            this.publishEvent('page:beforeError', jqXHR, payload);
            if (payload.stopPageProcessing) {
                history.back();
                return;
            }

            data = this._parseRawData(rawData);
            if (_.isObject(data)) {
                model.set(data, options);
            } else {
                if (mediator.execute('retrieveOption', 'debug')) {
                    // jshint -W060
                    document.writeln(rawData);
                    if (console) {
                        console.error('Unexpected content format');
                    }
                } else {
                    mediator.execute('showMessage', 'error', __('Sorry, page was not loaded correctly'));
                }
            }

            this.publishEvent('page:error', model.getAttributes(), options.actionArgs, jqXHR);
            this.publishEvent('page:afterChange');
        },

        /**
         * Process redirect response
         *  see documentation for Chaplin.utils.redirectTo() method
         *
         * @param {Object|string} pathDesc
         * @param {Object=} params
         * @param {Object=} options
         * @private
         */
        _processRedirect: function(pathDesc, params, options) {
            var parser;
            var pathname;
            var query;
            var getUrl = function(pathname, query) {
                query = utils.queryParams.parse(query);
                query._rand = Math.random();
                query = utils.queryParams.stringify(query);
                return pathname + (query && ('?' + query));
            };
            options = options || {};
            if (typeof pathDesc === 'object' && pathDesc.url !== null && pathDesc.url !== void 0) {
                options = params || {};
                // fetch from URL only pathname and query
                parser = document.createElement('a');
                parser.href = pathDesc.url;
                pathname = parser.pathname;
                query = parser.search.substr(1);
                // IE removes starting slash
                pathDesc.url = (pathname[0] === '/' ? '' : '/') + pathname + (query && ('?' + query));
            }
            options = _.defaults(options, {
                fullRedirect: this.fullRedirect
            });
            if (options.target === '_blank') {
                window.open(getUrl(pathname, query), '_blank');
                return;
            }
            if (options.fullRedirect) {
                location[options.replace ? 'replace' : 'assign'](getUrl(pathname, query));
                return;
            }
            if (options.redirect) {
                this.publishEvent('page:redirect');
                _.extend(options, {forceStartup: true, force: true, redirection: true});
                utils.redirectTo(pathDesc, options);
                return;
            }
            utils.redirectTo.apply(utils, arguments);
        },

        /**
         * Register handler for page reload and redirect
         *
         * @param {string} url
         * @private
         */
        _setNavigationHandlers: function(url) {
            mediator.setHandler('redirectTo', function(pathDesc, params, options) {
                var queue = [];
                mediator.trigger('page:beforeRedirectTo', queue, pathDesc, params, options);
                $.when.apply($, queue).done(_.bind(function() {
                    this._processRedirect(pathDesc, params, options);
                }, this));
            }, this);

            mediator.setHandler('refreshPage', function(options) {
                var queue = [];
                mediator.trigger('page:beforeRefresh', queue);
                options = options || {};
                _.defaults(options, {forceStartup: true, force: true});
                $.when.apply($, queue).done(function(customOptions) {
                    _.extend(options, customOptions || {});
                    utils.redirectTo({url: url}, options);
                    mediator.trigger('page:afterRefresh');
                });
            });

            mediator.setHandler('submitPage', this._submitPage, this);
        },

        /**
         * Make data more bulletproof.
         *
         * @param {string} rawData
         * @param {number=} prevPos
         * @returns {Object}
         */
        _parseRawData: function(rawData, prevPos) {
            if (_.isUndefined(prevPos)) {
                prevPos = -1;
            }
            rawData = rawData.trim();
            var jsonStartPos = rawData.indexOf('{', prevPos + 1);
            var additionalData = '';
            var dataObj = null;
            var data;
            if (jsonStartPos > 0) {
                additionalData = rawData.substr(0, jsonStartPos);
                data = rawData.substr(jsonStartPos);
                try {
                    dataObj = JSON.parse(data);
                } catch (err) {
                    return this._parseRawData(rawData, jsonStartPos);
                }
            } else if (jsonStartPos === 0) {
                dataObj = JSON.parse(rawData);
            } else {
                // there's nothing to do
                dataObj = rawData;
            }

            if (additionalData) {
                additionalData = '
' +
                    '×' +
                    '
' + additionalData + '

';
            }

            if (dataObj.content !== undefined) {
                dataObj.content = additionalData + dataObj.content;
            }

            return dataObj;
        },

        /**
         * Performs save call for a model
         * (is used for saving forms, all data should be already packet into options)
         *
         * @param options
         * @private
         */
        _submitPage: function(options) {
            this.publishEvent('page:beforeChange');
            options.actionArgs = options.actionArgs || {};
            _.defaults(options.actionArgs, {params: {}, route: {}, options: {}});
            this.model.save(null, options);
        }
    });

    return PageController;
});
<|endoftext|>


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

    gvm.availableCourses = ko.observableArray([]);

    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);
    gvm.tabledata = ko.observableArray([]);

     // Table i18n bindings
    gvm.werkficheID = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheID");}, gvm);
    gvm.werkficheName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheName");}, gvm);
    gvm.werkficheAction = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheAction");}, gvm);

    gvm.currentCourseId = null;

    gvm.updateCourseRapport = function() {
        $.getJSON('/api/coursedrop', function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                //  Put item in list
                gvm.availableCourses.push(item);

                // Add listener to listitem
                $("#coursebtn-" + item.id).click(function(){
                    gvm.currentCourseId = item.id;
                    $(".btn-courseRapport span:first").text($(this).text());
                    loadTablePage(1);
                });
            });
        });
    };

    gvm.addTableData = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.tabledata.push(tblOject);

        $('#removebtn-' + id).bind('click', function(event, data){
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });

        $('#editbtn-' + id).bind('click', function(event, data){
            showEditWorksheetModal(id, name);
            event.stopPropagation();
        });

        $('#copybtn-' + id).bind('click', function(event, data){
            copyTableItem(id, tblOject);
            event.stopPropagation();
        });
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function addNewWorksheet(serialData, courseid, callback) {
    $.ajax({
        url: "/api/addworksheet/" + courseid,
        type: "POST",
        data: serialData,
        success: function(data) {
            loadTablePage(1);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function updateWorksheet(id, serialData, callback) {
    $.ajax({
        url: "/api/updateworksheet/" + id,
        type: "PUT",
        data: serialData,
        success: function(data) {
            loadTablePage(1);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function copyTableItem(id, tblObject) {
    /*showYesNoModal("Bent u zeker dat u dit item wil kopiëren? ", function(val){
        if(val){
            $.ajax({
                url: "/api/coursecopy/" + id,
                type: "post"

            });
        }
    });*/
}

function deleteTableItem(id, tblOject) {
    /*showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            $.ajax({
                url: "/api/coursedelete/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
        }
    });*/
}

function showNewWorksheetModal() {
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("AddNewWorksheet"));
    setGeneralModalBody('<form id="newworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name"> \

 \
            </form>' );

    addGeneralModalButton(i18n.__("AddBtn"), function(){
       addNewWorksheet($('#newworksheetform').serialize(), viewModel.currentCourseId, function(result){
            hideModal();
        });
    });

    showGeneralModal();
}

function showEditWorksheetModal(id, name)
{
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("EditWorksheet"));
    setGeneralModalBody('<form id="updateworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name" value="' + name + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateWorksheet(tid, $('#updateworksheetform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function loadTablePage(pagenr)
{
    $.getJSON('/api/worksheets/page/' + pagenr + '/' + viewModel.currentCourseId, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id, item.Name);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

function initPage() {
    $('#addWorksheetBtn').click(function() {
        showNewWorksheetModal();
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateCourseRapport();
    });
}
<commit_msg>werkfiches kunnen aanpassen<commit_after>// View model for the page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetNameRapport");}, gvm);
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("HomeRapportTitle");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetRapportManual");}, gvm);

    gvm.availableCourses = ko.observableArray([]);

    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);
    gvm.tabledata = ko.observableArray([]);

     // Table i18n bindings
    gvm.werkficheID = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheID");}, gvm);
    gvm.werkficheName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheName");}, gvm);
    gvm.werkficheAction = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheAction");}, gvm);

    gvm.currentCourseId = null;

    gvm.updateCourseRapport = function() {
        $.getJSON('/api/coursedrop', function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                //  Put item in list
                gvm.availableCourses.push(item);

                // Add listener to listitem
                $("#coursebtn-" + item.id).click(function(){
                    gvm.currentCourseId = item.id;
                    $(".btn-courseRapport span:first").text($(this).text());
                    loadTablePage(1);
                });
            });
        });
    };

    gvm.addTableData = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.tabledata.push(tblOject);

        $('#removebtn-' + id).bind('click', function(event, data){
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });

        $('#editbtn-' + id).bind('click', function(event, data){
            showEditWorksheetModal(id, name);
            event.stopPropagation();
        });

        $('#copybtn-' + id).bind('click', function(event, data){
            copyTableItem(id, tblOject);
            event.stopPropagation();
        });
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function addNewWorksheet(serialData, courseid, callback) {
    $.ajax({
        url: "/api/addworksheet/" + courseid,
        type: "POST",
        data: serialData,
        success: function(data) {
            loadTablePage(1);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function updateWorksheet(id, serialData, callback) {
    $.ajax({
        url: "/api/updateworksheet/" + id,
        type: "PUT",
        data: serialData,
        success: function(data) {
            loadTablePage(1);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function copyTableItem(id, tblObject) {
    /*showYesNoModal("Bent u zeker dat u dit item wil kopiëren? ", function(val){
        if(val){
            $.ajax({
                url: "/api/coursecopy/" + id,
                type: "post"

            });
        }
    });*/
}

function deleteTableItem(id, tblOject) {
    /*showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            $.ajax({
                url: "/api/coursedelete/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
        }
    });*/
}

function showNewWorksheetModal() {
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("AddNewWorksheet"));
    setGeneralModalBody('<form id="newworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name"> \

 \
            </form>' );

    addGeneralModalButton(i18n.__("AddBtn"), function(){
       addNewWorksheet($('#newworksheetform').serialize(), viewModel.currentCourseId, function(result){
            hideModal();
        });
    });

    showGeneralModal();
}

function showEditWorksheetModal(id, name)
{
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("EditWorksheet"));
    setGeneralModalBody('<form id="updateworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name" value="' + name + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateWorksheet(id, $('#updateworksheetform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function loadTablePage(pagenr)
{
    $.getJSON('/api/worksheets/page/' + pagenr + '/' + viewModel.currentCourseId, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id, item.Name);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

function initPage() {
    $('#addWorksheetBtn').click(function() {
        showNewWorksheetModal();
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateCourseRapport();
    });
}
<|endoftext|>


<commit_before><commit_msg>cloudeebus js library v0.3.0<commit_after><|endoftext|>